diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 703f6e5281d2c..f6df348b72140 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,7 +65,7 @@ jobs: defaults: run: shell: ${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }} - timeout-minutes: 240 + timeout-minutes: 360 env: CI_JOB_NAME: ${{ matrix.image }} CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse diff --git a/.gitignore b/.gitignore index 948133cd76e4c..ce9db8b861d04 100644 --- a/.gitignore +++ b/.gitignore @@ -46,8 +46,7 @@ no_llvm_build /inst/ /llvm/ /mingw-build/ -build/ -!/compiler/rustc_mir_build/src/build/ +/build /build-rust-analyzer/ /dist/ /unicode-downloads diff --git a/COPYRIGHT b/COPYRIGHT index 05993830a0fb4..428a438a086e9 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -343,49 +343,42 @@ their own copyright notices and license terms: * Portions of internationalization code use code or data from Unicode, which carry the following license: - UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE - - See Terms of Use - for definitions of Unicode Inc.’s Data Files and Software. - - NOTICE TO USER: Carefully read the following legal agreement. - BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S - DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), - YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE - TERMS AND CONDITIONS OF THIS AGREEMENT. - IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE - THE DATA FILES OR SOFTWARE. + UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE - Copyright © 1991-2022 Unicode, Inc. All rights reserved. - Distributed under the Terms of Use in https://www.unicode.org/copyright.html. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of the Unicode data files and any associated documentation - (the "Data Files") or Unicode software and any associated documentation - (the "Software") to deal in the Data Files or Software - without restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, and/or sell copies of - the Data Files or Software, and to permit persons to whom the Data Files - or Software are furnished to do so, provided that either - (a) this copyright and permission notice appear with all copies - of the Data Files or Software, or - (b) this copyright and permission notice appear in associated - Documentation. - - THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE - WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS - NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL - DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THE DATA FILES OR SOFTWARE. - - Except as contained in this notice, the name of a copyright holder - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in these Data Files or Software without prior - written authorization of the copyright holder. + Copyright © 1991-2024 Unicode, Inc. + + NOTICE TO USER: Carefully read the following legal agreement. BY + DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR + SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE + TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT + DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of data files and any associated documentation (the "Data Files") or + software and any associated documentation (the "Software") to deal in the + Data Files or Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, and/or sell + copies of the Data Files or Software, and to permit persons to whom the + Data Files or Software are furnished to do so, provided that either (a) + this copyright and permission notice appear with all copies of the Data + Files or Software, or (b) this copyright and permission notice appear in + associated Documentation. + + THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + THIRD PARTY RIGHTS. + + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE + BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, + OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA + FILES OR SOFTWARE. + + Except as contained in this notice, the name of a copyright holder shall + not be used in advertising or otherwise to promote the sale, use or other + dealings in these Data Files or Software without prior written + authorization of the copyright holder. diff --git a/Cargo.lock b/Cargo.lock index e4dcf13a84b73..21cb3d13d5ed4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -411,9 +411,9 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.1.34" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9" +checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" dependencies = [ "shlex", ] @@ -536,7 +536,7 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "clippy" -version = "0.1.84" +version = "0.1.85" dependencies = [ "anstream", "cargo_metadata", @@ -567,8 +567,9 @@ dependencies = [ [[package]] name = "clippy_config" -version = "0.1.84" +version = "0.1.85" dependencies = [ + "clippy_utils", "itertools", "serde", "toml 0.7.8", @@ -580,6 +581,7 @@ name = "clippy_dev" version = "0.0.1" dependencies = [ "aho-corasick", + "chrono", "clap", "indoc", "itertools", @@ -590,7 +592,7 @@ dependencies = [ [[package]] name = "clippy_lints" -version = "0.1.84" +version = "0.1.85" dependencies = [ "arrayvec", "cargo_metadata", @@ -613,12 +615,12 @@ dependencies = [ [[package]] name = "clippy_utils" -version = "0.1.84" +version = "0.1.85" dependencies = [ "arrayvec", - "clippy_config", "itertools", "rustc_apfloat", + "serde", ] [[package]] @@ -3820,7 +3822,6 @@ dependencies = [ name = "rustc_index" version = "0.0.0" dependencies = [ - "arrayvec", "rustc_index_macros", "rustc_macros", "rustc_serialize", @@ -4137,6 +4138,7 @@ name = "rustc_monomorphize" version = "0.0.0" dependencies = [ "rustc_abi", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", diff --git a/LICENSES/Unicode-3.0.txt b/LICENSES/Unicode-3.0.txt new file mode 100644 index 0000000000000..ee8e69b233293 --- /dev/null +++ b/LICENSES/Unicode-3.0.txt @@ -0,0 +1,39 @@ +UNICODE LICENSE V3 + +COPYRIGHT AND PERMISSION NOTICE + +Copyright © 1991-2024 Unicode, Inc. + +NOTICE TO USER: Carefully read the following legal agreement. BY +DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR +SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT +DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of data files and any associated documentation (the "Data Files") or +software and any associated documentation (the "Software") to deal in the +Data Files or Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, and/or sell +copies of the Data Files or Software, and to permit persons to whom the +Data Files or Software are furnished to do so, provided that either (a) +this copyright and permission notice appear with all copies of the Data +Files or Software, or (b) this copyright and permission notice appear in +associated Documentation. + +THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF +THIRD PARTY RIGHTS. + +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE +BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA +FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in these Data Files or Software without prior written +authorization of the copyright holder. diff --git a/LICENSES/Unicode-DFS-2016.txt b/LICENSES/Unicode-DFS-2016.txt deleted file mode 100644 index 71fd6ac5e12e1..0000000000000 --- a/LICENSES/Unicode-DFS-2016.txt +++ /dev/null @@ -1,22 +0,0 @@ -UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE - -Unicode Data Files include all data files under the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/, and http://www.unicode.org/utility/trac/browser/. - -Unicode Data Files do not include PDF online code charts under the directory http://www.unicode.org/Public/. - -Software includes any source code published in the Unicode Standard or under the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/, and http://www.unicode.org/utility/trac/browser/. - -NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. - -COPYRIGHT AND PERMISSION NOTICE - -Copyright © 1991-2016 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html. - -Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either - - (a) this copyright and permission notice appear with all copies of the Data Files or Software, or - (b) this copyright and permission notice appear in associated Documentation. - -THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. diff --git a/RELEASES.md b/RELEASES.md index 54465621b734b..8702bb021184a 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,235 @@ +Version 1.83.0 (2024-11-28) +========================== + + + +Language +-------- +- [Stabilize `&mut`, `*mut`, `&Cell`, and `*const Cell` in const.](https://github.com/rust-lang/rust/pull/129195) +- [Allow creating references to statics in `const` initializers.](https://github.com/rust-lang/rust/pull/129759) +- [Implement raw lifetimes and labels (`'r#ident`).](https://github.com/rust-lang/rust/pull/126452) +- [Define behavior when atomic and non-atomic reads race.](https://github.com/rust-lang/rust/pull/128778) +- [Non-exhaustive structs may now be empty.](https://github.com/rust-lang/rust/pull/128934) +- [Disallow implicit coercions from places of type `!`](https://github.com/rust-lang/rust/pull/129392) +- [`const extern` functions can now be defined for other calling conventions.](https://github.com/rust-lang/rust/pull/129753) +- [Stabilize `expr_2021` macro fragment specifier in all editions.](https://github.com/rust-lang/rust/pull/129972) +- [The `non_local_definitions` lint now fires on less code and warns by default.](https://github.com/rust-lang/rust/pull/127117) + + + + +Compiler +-------- +- [Deprecate unsound `-Csoft-float` flag.](https://github.com/rust-lang/rust/pull/129897) +- Add many new tier 3 targets: + - [`aarch64_unknown_nto_qnx700`](https://github.com/rust-lang/rust/pull/127897) + - [`arm64e-apple-tvos`](https://github.com/rust-lang/rust/pull/130614) + - [`armv7-rtems-eabihf`](https://github.com/rust-lang/rust/pull/127021) + - [`loongarch64-unknown-linux-ohos`](https://github.com/rust-lang/rust/pull/130750) + - [`riscv32-wrs-vxworks` and `riscv64-wrs-vxworks`](https://github.com/rust-lang/rust/pull/130549) + - [`riscv32{e|em|emc}-unknown-none-elf`](https://github.com/rust-lang/rust/pull/130555) + - [`x86_64-unknown-hurd-gnu`](https://github.com/rust-lang/rust/pull/128345) + - [`x86_64-unknown-trusty`](https://github.com/rust-lang/rust/pull/130453) + +Refer to Rust's [platform support page][platform-support-doc] +for more information on Rust's tiered platform support. + + + + +Libraries +--------- +- [Implement `PartialEq` for `ExitCode`.](https://github.com/rust-lang/rust/pull/127633) +- [Document that `catch_unwind` can deal with foreign exceptions without UB, although the exact behavior is unspecified.](https://github.com/rust-lang/rust/pull/128321) +- [Implement `Default` for `HashMap`/`HashSet` iterators that don't already have it.](https://github.com/rust-lang/rust/pull/128711) +- [Bump Unicode to version 16.0.0.](https://github.com/rust-lang/rust/pull/130183) +- [Change documentation of `ptr::add`/`sub` to not claim equivalence with `offset`.](https://github.com/rust-lang/rust/pull/130229) + + + + +Stabilized APIs +--------------- + +- [`BufRead::skip_until`](https://doc.rust-lang.org/stable/std/io/trait.BufRead.html#method.skip_until) +- [`ControlFlow::break_value`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.break_value) +- [`ControlFlow::continue_value`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.continue_value) +- [`ControlFlow::map_break`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.map_break) +- [`ControlFlow::map_continue`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.map_continue) +- [`DebugList::finish_non_exhaustive`](https://doc.rust-lang.org/stable/core/fmt/struct.DebugList.html#method.finish_non_exhaustive) +- [`DebugMap::finish_non_exhaustive`](https://doc.rust-lang.org/stable/core/fmt/struct.DebugMap.html#method.finish_non_exhaustive) +- [`DebugSet::finish_non_exhaustive`](https://doc.rust-lang.org/stable/core/fmt/struct.DebugSet.html#method.finish_non_exhaustive) +- [`DebugTuple::finish_non_exhaustive`](https://doc.rust-lang.org/stable/core/fmt/struct.DebugTuple.html#method.finish_non_exhaustive) +- [`ErrorKind::ArgumentListTooLong`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.ArgumentListTooLong) +- [`ErrorKind::Deadlock`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.Deadlock) +- [`ErrorKind::DirectoryNotEmpty`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.DirectoryNotEmpty) +- [`ErrorKind::ExecutableFileBusy`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.ExecutableFileBusy) +- [`ErrorKind::FileTooLarge`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.FileTooLarge) +- [`ErrorKind::HostUnreachable`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.HostUnreachable) +- [`ErrorKind::IsADirectory`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.IsADirectory) +- [`ErrorKind::NetworkDown`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.NetworkDown) +- [`ErrorKind::NetworkUnreachable`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.NetworkUnreachable) +- [`ErrorKind::NotADirectory`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.NotADirectory) +- [`ErrorKind::NotSeekable`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.NotSeekable) +- [`ErrorKind::ReadOnlyFilesystem`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.ReadOnlyFilesystem) +- [`ErrorKind::ResourceBusy`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.ResourceBusy) +- [`ErrorKind::StaleNetworkFileHandle`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.StaleNetworkFileHandle) +- [`ErrorKind::StorageFull`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.StorageFull) +- [`ErrorKind::TooManyLinks`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.TooManyLinks) +- [`Option::get_or_insert_default`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.get_or_insert_default) +- [`Waker::data`](https://doc.rust-lang.org/stable/core/task/struct.Waker.html#method.data) +- [`Waker::new`](https://doc.rust-lang.org/stable/core/task/struct.Waker.html#method.new) +- [`Waker::vtable`](https://doc.rust-lang.org/stable/core/task/struct.Waker.html#method.vtable) +- [`char::MIN`](https://doc.rust-lang.org/stable/core/primitive.char.html#associatedconstant.MIN) +- [`hash_map::Entry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/hash_map/enum.Entry.html#method.insert_entry) +- [`hash_map::VacantEntry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/hash_map/struct.VacantEntry.html#method.insert_entry) + +These APIs are now stable in const contexts: + +- [`Cell::into_inner`](https://doc.rust-lang.org/stable/core/cell/struct.Cell.html#method.into_inner) +- [`Duration::as_secs_f32`](https://doc.rust-lang.org/stable/core/time/struct.Duration.html#method.as_secs_f32) +- [`Duration::as_secs_f64`](https://doc.rust-lang.org/stable/core/time/struct.Duration.html#method.as_secs_f64) +- [`Duration::div_duration_f32`](https://doc.rust-lang.org/stable/core/time/struct.Duration.html#method.div_duration_f32) +- [`Duration::div_duration_f64`](https://doc.rust-lang.org/stable/core/time/struct.Duration.html#method.div_duration_f64) +- [`MaybeUninit::as_mut_ptr`](https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#method.as_mut_ptr) +- [`NonNull::as_mut`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.as_mut) +- [`NonNull::copy_from`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.copy_from) +- [`NonNull::copy_from_nonoverlapping`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.copy_from_nonoverlapping) +- [`NonNull::copy_to`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.copy_to) +- [`NonNull::copy_to_nonoverlapping`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.copy_to_nonoverlapping) +- [`NonNull::slice_from_raw_parts`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.slice_from_raw_parts) +- [`NonNull::write`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.write) +- [`NonNull::write_bytes`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.write_bytes) +- [`NonNull::write_unaligned`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.write_unaligned) +- [`OnceCell::into_inner`](https://doc.rust-lang.org/stable/core/cell/struct.OnceCell.html#method.into_inner) +- [`Option::as_mut`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.as_mut) +- [`Option::expect`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.expect) +- [`Option::replace`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.replace) +- [`Option::take`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.take) +- [`Option::unwrap`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.unwrap) +- [`Option::unwrap_unchecked`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.unwrap_unchecked) +- [`Option::<&_>::copied`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.copied) +- [`Option::<&mut _>::copied`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.copied-1) +- [`Option::>::flatten`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.flatten) +- [`Option::>::transpose`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.transpose) +- [`RefCell::into_inner`](https://doc.rust-lang.org/stable/core/cell/struct.RefCell.html#method.into_inner) +- [`Result::as_mut`](https://doc.rust-lang.org/stable/core/result/enum.Result.html#method.as_mut) +- [`Result::<&_, _>::copied`](https://doc.rust-lang.org/stable/core/result/enum.Result.html#method.copied) +- [`Result::<&mut _, _>::copied`](https://doc.rust-lang.org/stable/core/result/enum.Result.html#method.copied-1) +- [`Result::, _>::transpose`](https://doc.rust-lang.org/stable/core/result/enum.Result.html#method.transpose) +- [`UnsafeCell::get_mut`](https://doc.rust-lang.org/stable/core/cell/struct.UnsafeCell.html#method.get_mut) +- [`UnsafeCell::into_inner`](https://doc.rust-lang.org/stable/core/cell/struct.UnsafeCell.html#method.into_inner) +- [`array::from_mut`](https://doc.rust-lang.org/stable/core/array/fn.from_mut.html) +- [`char::encode_utf8`](https://doc.rust-lang.org/stable/core/primitive.char.html#method.encode_utf8) +- [`{float}::classify`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.classify) +- [`{float}::is_finite`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_finite) +- [`{float}::is_infinite`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_infinite) +- [`{float}::is_nan`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_nan) +- [`{float}::is_normal`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_normal) +- [`{float}::is_sign_negative`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_sign_negative) +- [`{float}::is_sign_positive`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_sign_positive) +- [`{float}::is_subnormal`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_subnormal) +- [`{float}::from_bits`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.from_bits) +- [`{float}::from_be_bytes`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.from_be_bytes) +- [`{float}::from_le_bytes`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.from_le_bytes) +- [`{float}::from_ne_bytes`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.from_ne_bytes) +- [`{float}::to_bits`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.to_bits) +- [`{float}::to_be_bytes`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.to_be_bytes) +- [`{float}::to_le_bytes`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.to_le_bytes) +- [`{float}::to_ne_bytes`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.to_ne_bytes) +- [`mem::replace`](https://doc.rust-lang.org/stable/core/mem/fn.replace.html) +- [`ptr::replace`](https://doc.rust-lang.org/stable/core/ptr/fn.replace.html) +- [`ptr::slice_from_raw_parts_mut`](https://doc.rust-lang.org/stable/core/ptr/fn.slice_from_raw_parts_mut.html) +- [`ptr::write`](https://doc.rust-lang.org/stable/core/ptr/fn.write.html) +- [`ptr::write_unaligned`](https://doc.rust-lang.org/stable/core/ptr/fn.write_unaligned.html) +- [`<*const _>::copy_to`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.copy_to) +- [`<*const _>::copy_to_nonoverlapping`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.copy_to_nonoverlapping) +- [`<*mut _>::copy_from`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.copy_from) +- [`<*mut _>::copy_from_nonoverlapping`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.copy_from_nonoverlapping) +- [`<*mut _>::copy_to`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.copy_to-1) +- [`<*mut _>::copy_to_nonoverlapping`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.copy_to_nonoverlapping-1) +- [`<*mut _>::write`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.write) +- [`<*mut _>::write_bytes`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.write_bytes) +- [`<*mut _>::write_unaligned`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.write_unaligned) +- [`slice::from_mut`](https://doc.rust-lang.org/stable/core/slice/fn.from_mut.html) +- [`slice::from_raw_parts_mut`](https://doc.rust-lang.org/stable/core/slice/fn.from_raw_parts_mut.html) +- [`<[_]>::first_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.first_mut) +- [`<[_]>::last_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.last_mut) +- [`<[_]>::first_chunk_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.first_chunk_mut) +- [`<[_]>::last_chunk_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.last_chunk_mut) +- [`<[_]>::split_at_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_at_mut) +- [`<[_]>::split_at_mut_checked`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_at_mut_checked) +- [`<[_]>::split_at_mut_unchecked`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_at_mut_unchecked) +- [`<[_]>::split_first_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_first_mut) +- [`<[_]>::split_last_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_last_mut) +- [`<[_]>::split_first_chunk_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_first_chunk_mut) +- [`<[_]>::split_last_chunk_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_last_chunk_mut) +- [`str::as_bytes_mut`](https://doc.rust-lang.org/stable/core/primitive.str.html#method.as_bytes_mut) +- [`str::as_mut_ptr`](https://doc.rust-lang.org/stable/core/primitive.str.html#method.as_mut_ptr) +- [`str::from_utf8_unchecked_mut`](https://doc.rust-lang.org/stable/core/str/fn.from_utf8_unchecked_mut.html) + + + + +Cargo +----- +- [Introduced a new `CARGO_MANIFEST_PATH` environment variable, similar to `CARGO_MANIFEST_DIR` but pointing directly to the manifest file.](https://github.com/rust-lang/cargo/pull/14404/) +- [Added `package.autolib` to the manifest, allowing `[lib]` auto-discovery to be disabled.](https://github.com/rust-lang/cargo/pull/14591/) +- [Declare support level for each crate in Cargo's Charter / crate docs.](https://github.com/rust-lang/cargo/pull/14600/) +- [Declare new Intentional Artifacts as 'small' changes.](https://github.com/rust-lang/cargo/pull/14599/) + + + + +Rustdoc +------- + +- [The sidebar / hamburger menu table of contents now includes the `# headers` from the main item's doc comment](https://github.com/rust-lang/rust/pull/120736). This is similar to a third-party feature provided by the rustdoc-search-enhancements browser extension. + + + + +Compatibility Notes +------------------- +- [Warn against function pointers using unsupported ABI strings.](https://github.com/rust-lang/rust/pull/128784) +- [Check well-formedness of the source type's signature in fn pointer casts.](https://github.com/rust-lang/rust/pull/129021) This partly closes a soundness hole that comes when casting a function item to function pointer +- [Use equality instead of subtyping when resolving type dependent paths.](https://github.com/rust-lang/rust/pull/129073) +- Linking on macOS now correctly includes Rust's default deployment target. Due to a linker bug, you might have to pass `MACOSX_DEPLOYMENT_TARGET` or fix your `#[link]` attributes to point to the correct frameworks. See . +- [Rust will now correctly raise an error for `repr(Rust)` written on non-`struct`/`enum`/`union` items, since it previous did not have any effect.](https://github.com/rust-lang/rust/pull/129422) +- The future incompatibility lint `deprecated_cfg_attr_crate_type_name` [has been made into a hard error](https://github.com/rust-lang/rust/pull/129670). It was used to deny usage of `#![crate_type]` and `#![crate_name]` attributes in `#![cfg_attr]`, which required a hack in the compiler to be able to change the used crate type and crate name after cfg expansion. + Users can use `--crate-type` instead of `#![cfg_attr(..., crate_type = "...")]` and `--crate-name` instead of `#![cfg_attr(..., crate_name = "...")]` when running `rustc`/`cargo rustc` on the command line. + Use of those two attributes outside of `#![cfg_attr]` continue to be fully supported. +- Until now, paths into the sysroot were always prefixed with `/rustc/$hash` in diagnostics, codegen, backtrace, e.g. + ``` + thread 'main' panicked at 'hello world', map-panic.rs:2:50 + stack backtrace: + 0: std::panicking::begin_panic + at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/std/src/panicking.rs:616:12 + 1: map_panic::main::{{closure}} + at ./map-panic.rs:2:50 + 2: core::option::Option::map + at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/option.rs:929:29 + 3: map_panic::main + at ./map-panic.rs:2:30 + 4: core::ops::function::FnOnce::call_once + at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/ops/function.rs:248:5 + note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. + ``` + [RFC 3127 said](https://rust-lang.github.io/rfcs/3127-trim-paths.html#changing-handling-of-sysroot-path-in-rustc) + > We want to change this behaviour such that, when `rust-src` source files can be discovered, the virtual path is discarded and therefore the local path will be embedded, unless there is a `--remap-path-prefix` that causes this local path to be remapped in the usual way. + + [#129687](https://github.com/rust-lang/rust/pull/129687) implements this behaviour, when `rust-src` is present at compile time, `rustc` replaces `/rustc/$hash` with a real path into the local `rust-src` component with best effort. + To sanitize this, users must explicitly supply `--remap-path-prefix==foo` or not have the `rust-src` component installed. + - The allow-by-default `missing_docs` lint used to disable itself when invoked through `rustc --test`/`cargo test`, resulting in `#[expect(missing_docs)]` emitting false positives due to the expectation being wrongly unfulfilled. This behavior [has now been removed](https://github.com/rust-lang/rust/pull/130025), which allows `#[expect(missing_docs)]` to be fulfilled in all scenarios, but will also report new `missing_docs` diagnostics for publicly reachable `#[cfg(test)]` items, [integration test](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#integration-tests) crate-level documentation, and publicly reachable items in integration tests. +- [The `armv8r-none-eabihf` target now uses the Armv8-R required set of floating-point features.](https://github.com/rust-lang/rust/pull/130295) +- [Fix a soundness bug where rustc wouldn't detect unconstrained higher-ranked lifetimes in a `dyn Trait`'s associated types that occur due to supertraits.](https://github.com/rust-lang/rust/pull/130367) +- [Update the minimum external LLVM version to 18.](https://github.com/rust-lang/rust/pull/130487) +- [Remove `aarch64-fuchsia` and `x86_64-fuchsia` target aliases in favor of `aarch64-unknown-fuchsia` and `x86_64-unknown-fuchsia` respectively.](https://github.com/rust-lang/rust/pull/130657) +- [The ABI-level exception class of a Rust panic is now encoded with native-endian bytes, so it is legible in hex dumps.](https://github.com/rust-lang/rust/pull/130897) +- [Visual Studio 2013 is no longer supported for MSVC targets.](https://github.com/rust-lang/rust/pull/131070) +- [The sysroot no longer contains the `std` dynamic library in its top-level `lib/` dir.](https://github.com/rust-lang/rust/pull/131188) + + Version 1.82.0 (2024-10-17) ========================== @@ -125,7 +357,7 @@ These APIs are now stable in const contexts: - [`std::task::Waker::from_raw`](https://doc.rust-lang.org/nightly/std/task/struct.Waker.html#method.from_raw) - [`std::task::Context::from_waker`](https://doc.rust-lang.org/nightly/std/task/struct.Context.html#method.from_waker) - [`std::task::Context::waker`](https://doc.rust-lang.org/nightly/std/task/struct.Context.html#method.waker) -- [`$integer::from_str_radix`](https://doc.rust-lang.org/nightly/std/primitive.u32.html#method.from_str_radix) +- [`{integer}::from_str_radix`](https://doc.rust-lang.org/nightly/std/primitive.u32.html#method.from_str_radix) - [`std::num::ParseIntError::kind`](https://doc.rust-lang.org/nightly/std/num/struct.ParseIntError.html#method.kind) diff --git a/REUSE.toml b/REUSE.toml index 3005bb56609b5..6b16d97ed8068 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -28,6 +28,7 @@ path = [ "COPYRIGHT", "INSTALL.md", "LICENSE-APACHE", + "license-metadata.json", "LICENSE-MIT", "README.md", "RELEASES.md", @@ -63,8 +64,8 @@ SPDX-License-Identifier = "Apache-2.0 WITH LLVM-exception AND (Apache-2.0 OR MIT [[annotations]] path = "library/core/src/unicode/unicode_data.rs" precedence = "override" -SPDX-FileCopyrightText = "1991-2022 Unicode, Inc. All rights reserved." -SPDX-License-Identifier = "Unicode-DFS-2016" +SPDX-FileCopyrightText = "1991-2024 Unicode, Inc." +SPDX-License-Identifier = "Unicode-3.0" [[annotations]] path = "library/std/src/sync/mpmc/**" diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 5f71fb97d768c..56b20e0ad8938 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -39,7 +39,9 @@ pub use crate::format::*; use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter}; use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream}; -pub use crate::util::parser::ExprPrecedence; +use crate::util::parser::{ + AssocOp, PREC_CLOSURE, PREC_JUMP, PREC_PREFIX, PREC_RANGE, PREC_UNAMBIGUOUS, +}; /// A "Label" is an identifier of some point in sources, /// e.g. in the following code: @@ -428,7 +430,15 @@ impl Default for WhereClause { /// A single predicate in a where-clause. #[derive(Clone, Encodable, Decodable, Debug)] -pub enum WherePredicate { +pub struct WherePredicate { + pub kind: WherePredicateKind, + pub id: NodeId, + pub span: Span, +} + +/// Predicate kind in where-clause. +#[derive(Clone, Encodable, Decodable, Debug)] +pub enum WherePredicateKind { /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). BoundPredicate(WhereBoundPredicate), /// A lifetime predicate (e.g., `'a: 'b + 'c`). @@ -437,22 +447,11 @@ pub enum WherePredicate { EqPredicate(WhereEqPredicate), } -impl WherePredicate { - pub fn span(&self) -> Span { - match self { - WherePredicate::BoundPredicate(p) => p.span, - WherePredicate::RegionPredicate(p) => p.span, - WherePredicate::EqPredicate(p) => p.span, - } - } -} - /// A type bound. /// /// E.g., `for<'c> Foo: Send + Clone + 'c`. #[derive(Clone, Encodable, Decodable, Debug)] pub struct WhereBoundPredicate { - pub span: Span, /// Any generics from a `for` binding. pub bound_generic_params: ThinVec, /// The type being bounded. @@ -466,7 +465,6 @@ pub struct WhereBoundPredicate { /// E.g., `'a: 'b + 'c`. #[derive(Clone, Encodable, Decodable, Debug)] pub struct WhereRegionPredicate { - pub span: Span, pub lifetime: Lifetime, pub bounds: GenericBounds, } @@ -476,7 +474,6 @@ pub struct WhereRegionPredicate { /// E.g., `T = int`. #[derive(Clone, Encodable, Decodable, Debug)] pub struct WhereEqPredicate { - pub span: Span, pub lhs_ty: P, pub rhs_ty: P, } @@ -1187,14 +1184,15 @@ pub struct Expr { } impl Expr { - /// Is this expr either `N`, or `{ N }`. + /// Could this expr be either `N`, or `{ N }`, where `N` is a const parameter. /// /// If this is not the case, name resolution does not resolve `N` when using /// `min_const_generics` as more complex expressions are not supported. /// /// Does not ensure that the path resolves to a const param, the caller should check this. - pub fn is_potential_trivial_const_arg(&self, strip_identity_block: bool) -> bool { - let this = if strip_identity_block { self.maybe_unwrap_block() } else { self }; + /// This also does not consider macros, so it's only correct after macro-expansion. + pub fn is_potential_trivial_const_arg(&self) -> bool { + let this = self.maybe_unwrap_block(); if let ExprKind::Path(None, path) = &this.kind && path.is_potential_trivial_const_arg() @@ -1319,53 +1317,71 @@ impl Expr { Some(P(Ty { kind, id: self.id, span: self.span, tokens: None })) } - pub fn precedence(&self) -> ExprPrecedence { + pub fn precedence(&self) -> i8 { match self.kind { - ExprKind::Array(_) => ExprPrecedence::Array, - ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock, - ExprKind::Call(..) => ExprPrecedence::Call, - ExprKind::MethodCall(..) => ExprPrecedence::MethodCall, - ExprKind::Tup(_) => ExprPrecedence::Tup, - ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node), - ExprKind::Unary(..) => ExprPrecedence::Unary, - ExprKind::Lit(_) | ExprKind::IncludedBytes(..) => ExprPrecedence::Lit, - ExprKind::Cast(..) => ExprPrecedence::Cast, - ExprKind::Let(..) => ExprPrecedence::Let, - ExprKind::If(..) => ExprPrecedence::If, - ExprKind::While(..) => ExprPrecedence::While, - ExprKind::ForLoop { .. } => ExprPrecedence::ForLoop, - ExprKind::Loop(..) => ExprPrecedence::Loop, - ExprKind::Match(_, _, MatchKind::Prefix) => ExprPrecedence::Match, - ExprKind::Match(_, _, MatchKind::Postfix) => ExprPrecedence::PostfixMatch, - ExprKind::Closure(..) => ExprPrecedence::Closure, - ExprKind::Block(..) => ExprPrecedence::Block, - ExprKind::TryBlock(..) => ExprPrecedence::TryBlock, - ExprKind::Gen(..) => ExprPrecedence::Gen, - ExprKind::Await(..) => ExprPrecedence::Await, - ExprKind::Assign(..) => ExprPrecedence::Assign, - ExprKind::AssignOp(..) => ExprPrecedence::AssignOp, - ExprKind::Field(..) => ExprPrecedence::Field, - ExprKind::Index(..) => ExprPrecedence::Index, - ExprKind::Range(..) => ExprPrecedence::Range, - ExprKind::Underscore => ExprPrecedence::Path, - ExprKind::Path(..) => ExprPrecedence::Path, - ExprKind::AddrOf(..) => ExprPrecedence::AddrOf, - ExprKind::Break(..) => ExprPrecedence::Break, - ExprKind::Continue(..) => ExprPrecedence::Continue, - ExprKind::Ret(..) => ExprPrecedence::Ret, - ExprKind::Struct(..) => ExprPrecedence::Struct, - ExprKind::Repeat(..) => ExprPrecedence::Repeat, - ExprKind::Paren(..) => ExprPrecedence::Paren, - ExprKind::Try(..) => ExprPrecedence::Try, - ExprKind::Yield(..) => ExprPrecedence::Yield, - ExprKind::Yeet(..) => ExprPrecedence::Yeet, - ExprKind::Become(..) => ExprPrecedence::Become, - ExprKind::InlineAsm(..) - | ExprKind::Type(..) - | ExprKind::OffsetOf(..) + ExprKind::Closure(..) => PREC_CLOSURE, + + ExprKind::Break(..) + | ExprKind::Continue(..) + | ExprKind::Ret(..) + | ExprKind::Yield(..) + | ExprKind::Yeet(..) + | ExprKind::Become(..) => PREC_JUMP, + + // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to + // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence + // ensures that `pprust` will add parentheses in the right places to get the desired + // parse. + ExprKind::Range(..) => PREC_RANGE, + + // Binop-like expr kinds, handled by `AssocOp`. + ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence() as i8, + ExprKind::Cast(..) => AssocOp::As.precedence() as i8, + + ExprKind::Assign(..) | + ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8, + + // Unary, prefix + ExprKind::AddrOf(..) + // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`. + // However, this is not exactly right. When `let _ = a` is the LHS of a binop we + // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b` + // but we need to print `(let _ = a) < b` as-is with parens. + | ExprKind::Let(..) + | ExprKind::Unary(..) => PREC_PREFIX, + + // Never need parens + ExprKind::Array(_) + | ExprKind::Await(..) + | ExprKind::Block(..) + | ExprKind::Call(..) + | ExprKind::ConstBlock(_) + | ExprKind::Field(..) + | ExprKind::ForLoop { .. } | ExprKind::FormatArgs(..) - | ExprKind::MacCall(..) => ExprPrecedence::Mac, - ExprKind::Err(_) | ExprKind::Dummy => ExprPrecedence::Err, + | ExprKind::Gen(..) + | ExprKind::If(..) + | ExprKind::IncludedBytes(..) + | ExprKind::Index(..) + | ExprKind::InlineAsm(..) + | ExprKind::Lit(_) + | ExprKind::Loop(..) + | ExprKind::MacCall(..) + | ExprKind::Match(..) + | ExprKind::MethodCall(..) + | ExprKind::OffsetOf(..) + | ExprKind::Paren(..) + | ExprKind::Path(..) + | ExprKind::Repeat(..) + | ExprKind::Struct(..) + | ExprKind::Try(..) + | ExprKind::TryBlock(..) + | ExprKind::Tup(_) + | ExprKind::Type(..) + | ExprKind::Underscore + | ExprKind::While(..) + | ExprKind::Err(_) + | ExprKind::Dummy => PREC_UNAMBIGUOUS, } } @@ -3063,6 +3079,7 @@ pub struct FieldDef { pub id: NodeId, pub span: Span, pub vis: Visibility, + pub safety: Safety, pub ident: Option, pub ty: P, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 61f2f91635df3..0aceed45028a1 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -332,7 +332,11 @@ pub trait MutVisitor: Sized { } fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) { - walk_where_predicate(self, where_predicate); + walk_where_predicate(self, where_predicate) + } + + fn visit_where_predicate_kind(&mut self, kind: &mut WherePredicateKind) { + walk_where_predicate_kind(self, kind) } fn visit_vis(&mut self, vis: &mut Visibility) { @@ -1065,26 +1069,30 @@ fn walk_where_clause(vis: &mut T, wc: &mut WhereClause) { vis.visit_span(span); } -fn walk_where_predicate(vis: &mut T, pred: &mut WherePredicate) { - match pred { - WherePredicate::BoundPredicate(bp) => { - let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp; +pub fn walk_where_predicate(vis: &mut T, pred: &mut WherePredicate) { + let WherePredicate { kind, id, span } = pred; + vis.visit_id(id); + vis.visit_where_predicate_kind(kind); + vis.visit_span(span); +} + +pub fn walk_where_predicate_kind(vis: &mut T, kind: &mut WherePredicateKind) { + match kind { + WherePredicateKind::BoundPredicate(bp) => { + let WhereBoundPredicate { bound_generic_params, bounded_ty, bounds } = bp; bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_ty(bounded_ty); visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); - vis.visit_span(span); } - WherePredicate::RegionPredicate(rp) => { - let WhereRegionPredicate { span, lifetime, bounds } = rp; + WherePredicateKind::RegionPredicate(rp) => { + let WhereRegionPredicate { lifetime, bounds } = rp; vis.visit_lifetime(lifetime); visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); - vis.visit_span(span); } - WherePredicate::EqPredicate(ep) => { - let WhereEqPredicate { span, lhs_ty, rhs_ty } = ep; + WherePredicateKind::EqPredicate(ep) => { + let WhereEqPredicate { lhs_ty, rhs_ty } = ep; vis.visit_ty(lhs_ty); vis.visit_ty(rhs_ty); - vis.visit_span(span); } } } @@ -1115,10 +1123,11 @@ fn walk_poly_trait_ref(vis: &mut T, p: &mut PolyTraitRef) { } pub fn walk_field_def(visitor: &mut T, fd: &mut FieldDef) { - let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = fd; + let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _, safety } = fd; visitor.visit_id(id); visit_attrs(visitor, attrs); visitor.visit_vis(vis); + visit_safety(visitor, safety); visit_opt(ident, |ident| visitor.visit_ident(ident)); visitor.visit_ty(ty); visitor.visit_span(span); diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index d8dad4550c0c5..ed9265d51598a 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -237,121 +237,6 @@ pub const PREC_PREFIX: i8 = 50; pub const PREC_UNAMBIGUOUS: i8 = 60; pub const PREC_FORCE_PAREN: i8 = 100; -#[derive(Debug, Clone, Copy)] -pub enum ExprPrecedence { - Closure, - Break, - Continue, - Ret, - Yield, - Yeet, - Become, - - Range, - - Binary(BinOpKind), - - Cast, - - Assign, - AssignOp, - - AddrOf, - Let, - Unary, - - Call, - MethodCall, - Field, - Index, - Try, - Mac, - - Array, - Repeat, - Tup, - Lit, - Path, - Paren, - If, - While, - ForLoop, - Loop, - Match, - PostfixMatch, - ConstBlock, - Block, - TryBlock, - Struct, - Gen, - Await, - Err, -} - -impl ExprPrecedence { - pub fn order(self) -> i8 { - match self { - ExprPrecedence::Closure => PREC_CLOSURE, - - ExprPrecedence::Break - | ExprPrecedence::Continue - | ExprPrecedence::Ret - | ExprPrecedence::Yield - | ExprPrecedence::Yeet - | ExprPrecedence::Become => PREC_JUMP, - - // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to - // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence - // ensures that `pprust` will add parentheses in the right places to get the desired - // parse. - ExprPrecedence::Range => PREC_RANGE, - - // Binop-like expr kinds, handled by `AssocOp`. - ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8, - ExprPrecedence::Cast => AssocOp::As.precedence() as i8, - - ExprPrecedence::Assign | - ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8, - - // Unary, prefix - ExprPrecedence::AddrOf - // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`. - // However, this is not exactly right. When `let _ = a` is the LHS of a binop we - // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b` - // but we need to print `(let _ = a) < b` as-is with parens. - | ExprPrecedence::Let - | ExprPrecedence::Unary => PREC_PREFIX, - - // Never need parens - ExprPrecedence::Array - | ExprPrecedence::Await - | ExprPrecedence::Block - | ExprPrecedence::Call - | ExprPrecedence::ConstBlock - | ExprPrecedence::Field - | ExprPrecedence::ForLoop - | ExprPrecedence::Gen - | ExprPrecedence::If - | ExprPrecedence::Index - | ExprPrecedence::Lit - | ExprPrecedence::Loop - | ExprPrecedence::Mac - | ExprPrecedence::Match - | ExprPrecedence::MethodCall - | ExprPrecedence::Paren - | ExprPrecedence::Path - | ExprPrecedence::PostfixMatch - | ExprPrecedence::Repeat - | ExprPrecedence::Struct - | ExprPrecedence::Try - | ExprPrecedence::TryBlock - | ExprPrecedence::Tup - | ExprPrecedence::While - | ExprPrecedence::Err => PREC_UNAMBIGUOUS, - } - } -} - /// In `let p = e`, operators with precedence `<=` this one requires parentheses in `e`. pub fn prec_let_scrutinee_needs_par() -> usize { AssocOp::LAnd.precedence() diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 0302c9fa7f8ed..718397e8ca004 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -192,6 +192,9 @@ pub trait Visitor<'ast>: Sized { fn visit_where_predicate(&mut self, p: &'ast WherePredicate) -> Self::Result { walk_where_predicate(self, p) } + fn visit_where_predicate_kind(&mut self, k: &'ast WherePredicateKind) -> Self::Result { + walk_where_predicate_kind(self, k) + } fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) -> Self::Result { walk_fn(self, fk) } @@ -794,22 +797,29 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>( visitor: &mut V, predicate: &'a WherePredicate, ) -> V::Result { - match predicate { - WherePredicate::BoundPredicate(WhereBoundPredicate { + let WherePredicate { kind, id: _, span: _ } = predicate; + visitor.visit_where_predicate_kind(kind) +} + +pub fn walk_where_predicate_kind<'a, V: Visitor<'a>>( + visitor: &mut V, + kind: &'a WherePredicateKind, +) -> V::Result { + match kind { + WherePredicateKind::BoundPredicate(WhereBoundPredicate { bounded_ty, bounds, bound_generic_params, - span: _, }) => { walk_list!(visitor, visit_generic_param, bound_generic_params); try_visit!(visitor.visit_ty(bounded_ty)); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); } - WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span: _ }) => { + WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => { try_visit!(visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound)); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); } - WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span: _ }) => { + WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => { try_visit!(visitor.visit_ty(lhs_ty)); try_visit!(visitor.visit_ty(rhs_ty)); } @@ -961,7 +971,7 @@ pub fn walk_struct_def<'a, V: Visitor<'a>>( } pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) -> V::Result { - let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _ } = field; + let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _, safety: _ } = field; walk_list!(visitor, visit_attribute, attrs); try_visit!(visitor.visit_vis(vis)); visit_opt!(visitor, visit_ident, ident); diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index f704320c71d72..a4dbf98111538 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -152,6 +152,8 @@ ast_lowering_register2 = register `{$reg2_name}` ast_lowering_register_class_only_clobber = register class `{$reg_class_name}` can only be used as a clobber, not as an input or output +ast_lowering_register_class_only_clobber_stable = + register class `{$reg_class_name}` can only be used as a clobber in stable ast_lowering_register_conflict = register `{$reg1_name}` conflicts with register `{$reg2_name}` @@ -181,6 +183,8 @@ ast_lowering_underscore_expr_lhs_assign = .label = `_` not allowed here 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 diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 215e6d84d0f0a..569a15b0e07ba 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -17,7 +17,8 @@ use super::errors::{ InlineAsmUnsupportedTarget, InvalidAbiClobberAbi, InvalidAsmTemplateModifierConst, InvalidAsmTemplateModifierLabel, InvalidAsmTemplateModifierRegClass, InvalidAsmTemplateModifierRegClassSub, InvalidAsmTemplateModifierSym, InvalidRegister, - InvalidRegisterClass, RegisterClassOnlyClobber, RegisterConflict, + InvalidRegisterClass, RegisterClassOnlyClobber, RegisterClassOnlyClobberStable, + RegisterConflict, }; use crate::{ AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode, @@ -61,6 +62,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .emit(); } } + let allow_experimental_reg = self.tcx.features().asm_experimental_reg(); if asm.options.contains(InlineAsmOptions::ATT_SYNTAX) && !matches!(asm_arch, Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64)) && !self.tcx.sess.opts.actually_rustdoc @@ -80,7 +82,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let mut clobber_abis = FxIndexMap::default(); if let Some(asm_arch) = asm_arch { for (abi_name, abi_span) in &asm.clobber_abis { - match asm::InlineAsmClobberAbi::parse(asm_arch, &self.tcx.sess.target, *abi_name) { + match asm::InlineAsmClobberAbi::parse( + asm_arch, + &self.tcx.sess.target, + &self.tcx.sess.unstable_target_features, + *abi_name, + ) { Ok(abi) => { // If the abi was already in the list, emit an error match clobber_abis.get(&abi) { @@ -220,18 +227,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; // Wrap the expression in an AnonConst. - let parent_def_id = self.current_def_id_parent; + let parent_def_id = self.current_hir_id_owner.def_id; let node_id = self.next_node_id(); - // HACK(min_generic_const_args): see lower_anon_const - if !expr.is_potential_trivial_const_arg(true) { - self.create_def( - parent_def_id, - node_id, - kw::Empty, - DefKind::AnonConst, - *op_sp, - ); - } + self.create_def( + parent_def_id, + node_id, + kw::Empty, + DefKind::AnonConst, + *op_sp, + ); let anon_const = AnonConst { id: node_id, value: P(expr) }; hir::InlineAsmOperand::SymFn { anon_const: self.lower_anon_const_to_anon_const(&anon_const), @@ -239,15 +243,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } InlineAsmOperand::Label { block } => { - if !self.tcx.features().asm_goto() { - feature_err( - sess, - sym::asm_goto, - *op_sp, - fluent::ast_lowering_unstable_inline_assembly_label_operands, - ) - .emit(); - } hir::InlineAsmOperand::Label { block: self.lower_block(block, false) } } }; @@ -333,11 +328,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // means that we disallow passing a value in/out of the asm and // require that the operand name an explicit register, not a // register class. - if reg_class.is_clobber_only(asm_arch.unwrap()) && !op.is_clobber() { - self.dcx().emit_err(RegisterClassOnlyClobber { - op_span: op_sp, - reg_class_name: reg_class.name(), - }); + if reg_class.is_clobber_only(asm_arch.unwrap(), allow_experimental_reg) + && !op.is_clobber() + { + if allow_experimental_reg || reg_class.is_clobber_only(asm_arch.unwrap(), true) + { + // always clobber-only + self.dcx().emit_err(RegisterClassOnlyClobber { + op_span: op_sp, + reg_class_name: reg_class.name(), + }); + } else { + // clobber-only in stable + self.tcx + .sess + .create_feature_err( + RegisterClassOnlyClobberStable { + op_span: op_sp, + reg_class_name: reg_class.name(), + }, + sym::asm_experimental_reg, + ) + .emit(); + } continue; } @@ -466,6 +479,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } + // Feature gate checking for asm goto. + 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. + let output_operand_used = operands.iter().any(|(op, _)| { + matches!( + op, + hir::InlineAsmOperand::Out { expr: Some(_), .. } + | hir::InlineAsmOperand::InOut { .. } + | hir::InlineAsmOperand::SplitInOut { out_expr: Some(_), .. } + ) + }); + if output_operand_used && !self.tcx.features().asm_goto_with_outputs() { + feature_err( + sess, + sym::asm_goto_with_outputs, + *op_sp, + fluent::ast_lowering_unstable_inline_assembly_label_operand_with_outputs, + ) + .emit(); + } + } + let operands = self.arena.alloc_from_iter(operands); let template = self.arena.alloc_from_iter(asm.template.iter().cloned()); let template_strs = self.arena.alloc_from_iter( diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index e6a3f939f2db1..447af57354fd6 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -279,6 +279,14 @@ pub(crate) struct RegisterClassOnlyClobber { pub reg_class_name: Symbol, } +#[derive(Diagnostic)] +#[diag(ast_lowering_register_class_only_clobber_stable)] +pub(crate) struct RegisterClassOnlyClobberStable { + #[primary_span] + pub op_span: Span, + pub reg_class_name: Symbol, +} + #[derive(Diagnostic)] #[diag(ast_lowering_register_conflict)] pub(crate) struct RegisterConflict<'a> { diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 3af29838b72c4..3032042ff9fee 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -109,9 +109,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ConstBlock { def_id, hir_id: this.lower_node_id(c.id), - body: this.with_def_id_parent(def_id, |this| { - this.lower_const_body(c.value.span, Some(&c.value)) - }), + body: this.lower_const_body(c.value.span, Some(&c.value)), } }); hir::ExprKind::ConstBlock(c) @@ -452,15 +450,9 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut generic_args = ThinVec::new(); for (idx, arg) in args.iter().cloned().enumerate() { if legacy_args_idx.contains(&idx) { - let parent_def_id = self.current_def_id_parent; + let parent_def_id = self.current_hir_id_owner.def_id; let node_id = self.next_node_id(); - - // HACK(min_generic_const_args): see lower_anon_const - if !arg.is_potential_trivial_const_arg(true) { - // Add a definition for the in-band const def. - self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span); - } - + self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span); let mut visitor = WillCreateDefIdsVisitor {}; let const_value = if let ControlFlow::Break(span) = visitor.visit_expr(&arg) { AstP(Expr { @@ -759,19 +751,17 @@ impl<'hir> LoweringContext<'_, 'hir> { lifetime_elision_allowed: false, }); - let body = self.with_def_id_parent(closure_def_id, move |this| { - this.lower_body(move |this| { - this.coroutine_kind = Some(coroutine_kind); + let body = self.lower_body(move |this| { + this.coroutine_kind = Some(coroutine_kind); - let old_ctx = this.task_context; - if task_context.is_some() { - this.task_context = task_context; - } - let res = body(this); - this.task_context = old_ctx; + let old_ctx = this.task_context; + if task_context.is_some() { + this.task_context = task_context; + } + let res = body(this); + this.task_context = old_ctx; - (params, res) - }) + (params, res) }); // `static |<_task_context?>| -> { }`: @@ -1056,26 +1046,24 @@ impl<'hir> LoweringContext<'_, 'hir> { let (binder_clause, generic_params) = self.lower_closure_binder(binder); let (body_id, closure_kind) = self.with_new_scopes(fn_decl_span, move |this| { - this.with_def_id_parent(closure_def_id, move |this| { - let mut coroutine_kind = if this - .attrs - .get(&closure_hir_id.local_id) - .is_some_and(|attrs| attrs.iter().any(|attr| attr.has_name(sym::coroutine))) - { - Some(hir::CoroutineKind::Coroutine(Movability::Movable)) - } else { - None - }; - let body_id = this.lower_fn_body(decl, |this| { - this.coroutine_kind = coroutine_kind; - let e = this.lower_expr_mut(body); - coroutine_kind = this.coroutine_kind; - e - }); - let coroutine_option = - this.closure_movability_for_fn(decl, fn_decl_span, coroutine_kind, movability); - (body_id, coroutine_option) - }) + let mut coroutine_kind = if this + .attrs + .get(&closure_hir_id.local_id) + .is_some_and(|attrs| attrs.iter().any(|attr| attr.has_name(sym::coroutine))) + { + Some(hir::CoroutineKind::Coroutine(Movability::Movable)) + } else { + None + }; + let body_id = this.lower_fn_body(decl, |this| { + this.coroutine_kind = coroutine_kind; + let e = this.lower_expr_mut(body); + coroutine_kind = this.coroutine_kind; + e + }); + let coroutine_option = + this.closure_movability_for_fn(decl, fn_decl_span, coroutine_kind, movability); + (body_id, coroutine_option) }); let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params); @@ -1165,28 +1153,26 @@ impl<'hir> LoweringContext<'_, 'hir> { ); let body = self.with_new_scopes(fn_decl_span, |this| { - this.with_def_id_parent(closure_def_id, |this| { - let inner_decl = - FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) }; - - // Transform `async |x: u8| -> X { ... }` into - // `|x: u8| || -> X { ... }`. - let body_id = this.lower_body(|this| { - let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments( - &inner_decl, - |this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)), - fn_decl_span, - body.span, - coroutine_kind, - hir::CoroutineSource::Closure, - ); + let inner_decl = + FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) }; + + // Transform `async |x: u8| -> X { ... }` into + // `|x: u8| || -> X { ... }`. + let body_id = this.lower_body(|this| { + let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments( + &inner_decl, + |this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)), + fn_decl_span, + body.span, + coroutine_kind, + hir::CoroutineSource::Closure, + ); - this.maybe_forward_track_caller(body.span, closure_hir_id, expr.hir_id); + this.maybe_forward_track_caller(body.span, closure_hir_id, expr.hir_id); - (parameters, expr) - }); - body_id - }) + (parameters, expr) + }); + body_id }); let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params); diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index 6289966561f58..65e387de800ce 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -381,15 +381,10 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_where_predicate(&mut self, predicate: &'hir WherePredicate<'hir>) { - match predicate { - WherePredicate::BoundPredicate(pred) => { - self.insert(pred.span, pred.hir_id, Node::WhereBoundPredicate(pred)); - self.with_parent(pred.hir_id, |this| { - intravisit::walk_where_predicate(this, predicate) - }) - } - _ => intravisit::walk_where_predicate(self, predicate), - } + self.insert(predicate.span, predicate.hir_id, Node::WherePredicate(predicate)); + self.with_parent(predicate.hir_id, |this| { + intravisit::walk_where_predicate(this, predicate) + }); } fn visit_array_length(&mut self, len: &'hir ArrayLen<'hir>) { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index d724560750114..fb09f1c7fee1f 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -724,6 +724,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }, vis_span: self.lower_span(f.vis.span), ty, + safety: self.lower_safety(f.safety, hir::Safety::Safe), } } @@ -1400,7 +1401,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // keep track of the Span info. Now, `::add_implicit_sized_bound` // checks both param bounds and where clauses for `?Sized`. for pred in &generics.where_clause.predicates { - let WherePredicate::BoundPredicate(bound_pred) = pred else { + let WherePredicateKind::BoundPredicate(bound_pred) = &pred.kind else { continue; }; let compute_is_param = || { @@ -1537,9 +1538,9 @@ impl<'hir> LoweringContext<'_, 'hir> { } }); let span = self.lower_span(span); - - match kind { - GenericParamKind::Const { .. } => None, + let hir_id = self.next_id(); + let kind = self.arena.alloc(match kind { + GenericParamKind::Const { .. } => return None, GenericParamKind::Type { .. } => { let def_id = self.local_def_id(id).to_def_id(); let hir_id = self.next_id(); @@ -1554,38 +1555,36 @@ impl<'hir> LoweringContext<'_, 'hir> { let ty_id = self.next_id(); let bounded_ty = self.ty_path(ty_id, param_span, hir::QPath::Resolved(None, ty_path)); - Some(hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { - hir_id: self.next_id(), + hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate { bounded_ty: self.arena.alloc(bounded_ty), bounds, - span, bound_generic_params: &[], origin, - })) + }) } 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); - Some(hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { + hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate { lifetime, - span, bounds, in_where_clause: false, - })) + }) } - } + }); + Some(hir::WherePredicate { hir_id, span, kind }) } fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> { - match pred { - WherePredicate::BoundPredicate(WhereBoundPredicate { + let hir_id = self.lower_node_id(pred.id); + let span = self.lower_span(pred.span); + let kind = self.arena.alloc(match &pred.kind { + WherePredicateKind::BoundPredicate(WhereBoundPredicate { bound_generic_params, bounded_ty, bounds, - span, - }) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { - hir_id: self.next_id(), + }) => hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate { bound_generic_params: self .lower_generic_params(bound_generic_params, hir::GenericParamSource::Binder), bounded_ty: self @@ -1594,12 +1593,10 @@ impl<'hir> LoweringContext<'_, 'hir> { bounds, ImplTraitContext::Disallowed(ImplTraitPosition::Bound), ), - span: self.lower_span(*span), origin: PredicateOrigin::WhereClause, }), - WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span }) => { - hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { - span: self.lower_span(*span), + WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => { + hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate { lifetime: self.lower_lifetime(lifetime), bounds: self.lower_param_bounds( bounds, @@ -1608,15 +1605,15 @@ impl<'hir> LoweringContext<'_, 'hir> { in_where_clause: true, }) } - WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span }) => { - hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { + WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => { + hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate { lhs_ty: self .lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)), rhs_ty: self .lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)), - span: self.lower_span(*span), }) } - } + }); + hir::WherePredicate { hir_id, span, kind } } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 0b2969a49ba88..96546239f4c27 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -117,18 +117,6 @@ struct LoweringContext<'a, 'hir> { is_in_dyn_type: bool, current_hir_id_owner: hir::OwnerId, - /// Why do we need this in addition to [`Self::current_hir_id_owner`]? - /// - /// Currently (as of June 2024), anonymous constants are not HIR owners; however, - /// they do get their own DefIds. Some of these DefIds have to be created during - /// AST lowering, rather than def collection, because we can't tell until after - /// name resolution whether an anonymous constant will end up instead being a - /// [`hir::ConstArgKind::Path`]. However, to compute which generics are - /// available to an anonymous constant nested inside another, we need to make - /// sure that the parent is recorded as the parent anon const, not the enclosing - /// item. So we need to track parent defs differently from HIR owners, since they - /// will be finer-grained in the case of anon consts. - current_def_id_parent: LocalDefId, item_local_id_counter: hir::ItemLocalId, trait_map: ItemLocalMap>, @@ -161,7 +149,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { attrs: SortedMap::default(), children: Vec::default(), current_hir_id_owner: hir::CRATE_OWNER_ID, - current_def_id_parent: CRATE_DEF_ID, item_local_id_counter: hir::ItemLocalId::ZERO, ident_and_label_to_local_id: Default::default(), #[cfg(debug_assertions)] @@ -565,7 +552,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { debug_assert_eq!(_old, None); } - let item = self.with_def_id_parent(def_id, f); + let item = f(self); debug_assert_eq!(def_id, item.def_id().def_id); // `f` should have consumed all the elements in these vectors when constructing `item`. debug_assert!(self.impl_trait_defs.is_empty()); @@ -590,13 +577,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.children.push((def_id, hir::MaybeOwner::Owner(info))); } - fn with_def_id_parent(&mut self, parent: LocalDefId, f: impl FnOnce(&mut Self) -> T) -> T { - let current_def_id_parent = std::mem::replace(&mut self.current_def_id_parent, parent); - let result = f(self); - self.current_def_id_parent = current_def_id_parent; - result - } - fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> { let attrs = std::mem::take(&mut self.attrs); let mut bodies = std::mem::take(&mut self.bodies); @@ -773,7 +753,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { LifetimeRes::Fresh { param, kind, .. } => { // Late resolution delegates to us the creation of the `LocalDefId`. let _def_id = self.create_def( - self.current_hir_id_owner.def_id, // FIXME: should this use self.current_def_id_parent? + self.current_hir_id_owner.def_id, param, kw::UnderscoreLifetime, DefKind::LifetimeParam, @@ -1466,17 +1446,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id); debug!(?opaque_ty_def_id, ?opaque_ty_hir_id); - let opaque_ty_def = self.with_def_id_parent(opaque_ty_def_id, |this| { - let bounds = lower_item_bounds(this); - let opaque_ty_def = hir::OpaqueTy { - hir_id: opaque_ty_hir_id, - def_id: opaque_ty_def_id, - bounds, - origin, - span: this.lower_span(opaque_ty_span), - }; - this.arena.alloc(opaque_ty_def) - }); + let bounds = lower_item_bounds(self); + let opaque_ty_def = hir::OpaqueTy { + hir_id: opaque_ty_hir_id, + def_id: opaque_ty_def_id, + bounds, + origin, + span: self.lower_span(opaque_ty_span), + }; + let opaque_ty_def = self.arena.alloc(opaque_ty_def); hir::TyKind::OpaqueDef(opaque_ty_def) } @@ -2084,7 +2062,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } else { // Construct an AnonConst where the expr is the "ty"'s path. - let parent_def_id = self.current_def_id_parent; + let parent_def_id = self.current_hir_id_owner.def_id; let node_id = self.next_node_id(); let span = self.lower_span(span); @@ -2108,20 +2086,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc(hir::AnonConst { def_id, hir_id, - body: this.with_def_id_parent(def_id, |this| { - this.lower_const_body(path_expr.span, Some(&path_expr)) - }), + body: this.lower_const_body(path_expr.span, Some(&path_expr)), span, }) }); hir::ConstArgKind::Anon(ct) }; - self.arena.alloc(hir::ConstArg { - hir_id: self.next_id(), - kind: ct_kind, - is_desugared_from_effects: false, - }) + self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind }) } /// See [`hir::ConstArg`] for when to use this function vs @@ -2164,46 +2136,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ); return ConstArg { - hir_id: self.next_id(), + hir_id: self.lower_node_id(anon.id), kind: hir::ConstArgKind::Path(qpath), - is_desugared_from_effects: false, }; } let lowered_anon = self.lower_anon_const_to_anon_const(anon); - ConstArg { - hir_id: self.next_id(), - kind: hir::ConstArgKind::Anon(lowered_anon), - is_desugared_from_effects: false, - } + ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) } } /// See [`hir::ConstArg`] for when to use this function vs /// [`Self::lower_anon_const_to_const_arg`]. fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst { - if c.value.is_potential_trivial_const_arg(true) { - // HACK(min_generic_const_args): see DefCollector::visit_anon_const - // Over there, we guess if this is a bare param and only create a def if - // we think it's not. However we may can guess wrong (see there for example) - // in which case we have to create the def here. - self.create_def( - self.current_def_id_parent, - c.id, - kw::Empty, - DefKind::AnonConst, - c.value.span, - ); - } - self.arena.alloc(self.with_new_scopes(c.value.span, |this| { let def_id = this.local_def_id(c.id); let hir_id = this.lower_node_id(c.id); hir::AnonConst { def_id, hir_id, - body: this.with_def_id_parent(def_id, |this| { - this.lower_const_body(c.value.span, Some(&c.value)) - }), + body: this.lower_const_body(c.value.span, Some(&c.value)), span: this.lower_span(c.value.span), } })) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 07a6f4e5ee73c..64e91c91e2ca3 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1200,14 +1200,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> { validate_generic_param_order(self.dcx(), &generics.params, generics.span); for predicate in &generics.where_clause.predicates { - if let WherePredicate::EqPredicate(predicate) = predicate { - deny_equality_constraints(self, predicate, generics); + let span = predicate.span; + if let WherePredicateKind::EqPredicate(predicate) = &predicate.kind { + deny_equality_constraints(self, predicate, span, generics); } } walk_list!(self, visit_generic_param, &generics.params); for predicate in &generics.where_clause.predicates { - match predicate { - WherePredicate::BoundPredicate(bound_pred) => { + match &predicate.kind { + WherePredicateKind::BoundPredicate(bound_pred) => { // This is slightly complicated. Our representation for poly-trait-refs contains a single // binder and thus we only allow a single level of quantification. However, // the syntax of Rust permits quantification in two places in where clauses, @@ -1504,9 +1505,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn deny_equality_constraints( this: &AstValidator<'_>, predicate: &WhereEqPredicate, + predicate_span: Span, generics: &Generics, ) { - let mut err = errors::EqualityInWhere { span: predicate.span, assoc: None, assoc2: None }; + let mut err = errors::EqualityInWhere { span: predicate_span, assoc: None, assoc2: None }; // Given `::Bar = RhsTy`, suggest `A: Foo`. if let TyKind::Path(Some(qself), full_path) = &predicate.lhs_ty.kind @@ -1550,7 +1552,7 @@ fn deny_equality_constraints( } } err.assoc = Some(errors::AssociatedSuggestion { - span: predicate.span, + span: predicate_span, ident: *ident, param: param.ident, path: pprust::path_to_string(&assoc_path), @@ -1580,23 +1582,23 @@ fn deny_equality_constraints( // We're removing th eonly where bound left, remove the whole thing. generics.where_clause.span } else { - let mut span = predicate.span; + let mut span = predicate_span; let mut prev: Option = None; let mut preds = generics.where_clause.predicates.iter().peekable(); // Find the predicate that shouldn't have been in the where bound list. while let Some(pred) = preds.next() { - if let WherePredicate::EqPredicate(pred) = pred - && pred.span == predicate.span + if let WherePredicateKind::EqPredicate(_) = pred.kind + && pred.span == predicate_span { if let Some(next) = preds.peek() { // This is the first predicate, remove the trailing comma as well. - span = span.with_hi(next.span().lo()); + span = span.with_hi(next.span.lo()); } else if let Some(prev) = prev { // Remove the previous comma as well. span = span.with_lo(prev.hi()); } } - prev = Some(pred.span()); + prev = Some(pred.span); } span }; @@ -1613,8 +1615,8 @@ fn deny_equality_constraints( if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind { // Given `A: Foo, Foo::Bar = RhsTy`, suggest `A: Foo`. for bounds in generics.params.iter().map(|p| &p.bounds).chain( - generics.where_clause.predicates.iter().filter_map(|pred| match pred { - WherePredicate::BoundPredicate(p) => Some(&p.bounds), + generics.where_clause.predicates.iter().filter_map(|pred| match &pred.kind { + WherePredicateKind::BoundPredicate(p) => Some(&p.bounds), _ => None, }), ) { @@ -1637,8 +1639,8 @@ fn deny_equality_constraints( // Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo`. if let [potential_param, potential_assoc] = &full_path.segments[..] { for (ident, bounds) in generics.params.iter().map(|p| (p.ident, &p.bounds)).chain( - generics.where_clause.predicates.iter().filter_map(|pred| match pred { - WherePredicate::BoundPredicate(p) + generics.where_clause.predicates.iter().filter_map(|pred| match &pred.kind { + WherePredicateKind::BoundPredicate(p) if let ast::TyKind::Path(None, path) = &p.bounded_ty.kind && let [segment] = &path.segments[..] => { diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index be6f2c152a4d2..8cdc7133cc070 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -345,8 +345,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_generics(&mut self, g: &'a ast::Generics) { for predicate in &g.where_clause.predicates { - match predicate { - ast::WherePredicate::BoundPredicate(bound_pred) => { + match &predicate.kind { + ast::WherePredicateKind::BoundPredicate(bound_pred) => { // A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params); } @@ -557,6 +557,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(global_registration, "global registration is experimental"); gate_all!(return_type_notation, "return type notation is experimental"); gate_all!(pin_ergonomics, "pinned reference syntax is experimental"); + gate_all!(unsafe_fields, "`unsafe` fields are experimental"); if !visitor.features.never_patterns() { if let Some(spans) = spans.get(&sym::never_patterns) { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 893bfaf8f712e..04ec135c4289d 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -59,7 +59,7 @@ impl<'a> State<'a> { } fn print_expr_maybe_paren(&mut self, expr: &ast::Expr, prec: i8, fixup: FixupContext) { - self.print_expr_cond_paren(expr, expr.precedence().order() < prec, fixup); + self.print_expr_cond_paren(expr, expr.precedence() < prec, fixup); } /// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in @@ -615,7 +615,7 @@ impl<'a> State<'a> { expr, // Parenthesize if required by precedence, or in the // case of `break 'inner: loop { break 'inner 1 } + 1` - expr.precedence().order() < parser::PREC_JUMP + expr.precedence() < parser::PREC_JUMP || (opt_label.is_none() && classify::leading_labeled_expr(expr)), fixup.subsequent_subexpression(), ); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs index 50fd12a4e8b68..6f5382ce61d3b 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs @@ -191,6 +191,6 @@ impl FixupContext { /// "let chain". pub(crate) fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool { self.parenthesize_exterior_struct_lit && parser::contains_exterior_struct_lit(expr) - || parser::needs_par_as_let_scrutinee(expr.precedence().order()) + || parser::needs_par_as_let_scrutinee(expr.precedence()) } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 8279c66836c0f..1ae765c0130f6 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -726,11 +726,12 @@ impl<'a> State<'a> { } pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) { - match predicate { - ast::WherePredicate::BoundPredicate(where_bound_predicate) => { + let ast::WherePredicate { kind, id: _, span: _ } = predicate; + match kind { + ast::WherePredicateKind::BoundPredicate(where_bound_predicate) => { self.print_where_bound_predicate(where_bound_predicate); } - ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate { + ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate { lifetime, bounds, .. @@ -742,7 +743,9 @@ impl<'a> State<'a> { self.print_lifetime_bounds(bounds); } } - ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => { + ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate { + lhs_ty, rhs_ty, .. + }) => { self.print_type(lhs_ty); self.space(); self.word_space("="); diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index bda9672673873..92afad62aa4c2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1062,8 +1062,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { && let spans = hir_generics .predicates .iter() - .filter_map(|pred| match pred { - hir::WherePredicate::BoundPredicate(pred) => Some(pred), + .filter_map(|pred| match pred.kind { + hir::WherePredicateKind::BoundPredicate(pred) => Some(pred), _ => None, }) .filter(|pred| { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index c38747f66759d..6ea5c44dc0170 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -5,7 +5,7 @@ use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::GenericBound::Trait; use rustc_hir::QPath::Resolved; -use rustc_hir::WherePredicate::BoundPredicate; +use rustc_hir::WherePredicateKind::BoundPredicate; use rustc_hir::def::Res::Def; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; @@ -236,7 +236,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let mut hrtb_bounds = vec![]; gat_id_and_generics.iter().flatten().for_each(|(gat_hir_id, generics)| { for pred in generics.predicates { - let BoundPredicate(WhereBoundPredicate { bound_generic_params, bounds, .. }) = pred + let BoundPredicate(WhereBoundPredicate { bound_generic_params, bounds, .. }) = + pred.kind else { continue; }; @@ -267,12 +268,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { }; debug!(?generics_fn); generics_fn.predicates.iter().for_each(|predicate| { - let BoundPredicate(WhereBoundPredicate { - span: bounded_span, - bounded_ty, - bounds, - .. - }) = predicate + let BoundPredicate(WhereBoundPredicate { bounded_ty, bounds, .. }) = predicate.kind else { return; }; @@ -287,7 +283,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { .rfind(|param| param.def_id.to_def_id() == defid) .is_some() { - suggestions.push((bounded_span.shrink_to_hi(), " + 'static".to_string())); + suggestions.push((predicate.span.shrink_to_hi(), " + 'static".to_string())); } }); }); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 16a4f69917746..9b7474c220848 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -34,6 +34,7 @@ use rustc_infer::infer::{ use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::*; use rustc_middle::query::Providers; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode}; use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::impls::{ @@ -502,7 +503,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> { for data in tcx.typeck(def_id).concrete_opaque_types.iter().map(|(k, v)| (*k, *v)) { // HIR typeck did not infer the regions of the opaque, so we instantiate // them with fresh inference variables. - let (key, hidden_ty) = tcx.fold_regions(data, |_, _| { + let (key, hidden_ty) = fold_regions(tcx, data, |_, _| { self.next_nll_region_var_in_universe( NllRegionVariableOrigin::Existential { from_forall: false }, ty::UniverseIndex::ROOT, diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 0ddb4e110e3f2..99af5500ac634 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -18,6 +18,7 @@ use rustc_middle::mir::{ TerminatorKind, }; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex}; use rustc_mir_dataflow::points::DenseLocationMap; use rustc_span::Span; @@ -1100,7 +1101,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let ty = ty.fold_with(&mut OpaqueFolder { tcx }); let mut failed = false; - let ty = tcx.fold_regions(ty, |r, _depth| { + let ty = fold_regions(tcx, ty, |r, _depth| { let r_vid = self.to_region_vid(r); let r_scc = self.constraint_sccs.scc(r_vid); @@ -1273,7 +1274,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { where T: TypeFoldable>, { - tcx.fold_regions(value, |r, _db| { + fold_regions(tcx, value, |r, _db| { let vid = self.to_region_vid(r); let scc = self.constraint_sccs.scc(vid); let repr = self.scc_representative(scc); diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 993d5d8633396..7164a129235f0 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -3,6 +3,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::LocalDefId; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, TyCtxtInferExt as _}; use rustc_macros::extension; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{ self, GenericArgKind, GenericArgs, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, @@ -117,7 +118,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { }); debug!(?opaque_type_key, ?arg_regions); - let concrete_type = infcx.tcx.fold_regions(concrete_type, |region, _| { + let concrete_type = fold_regions(infcx.tcx, concrete_type, |region, _| { arg_regions .iter() .find(|&&(arg_vid, _)| self.eval_equal(region.as_var(), arg_vid)) @@ -204,7 +205,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { where T: TypeFoldable>, { - tcx.fold_regions(ty, |region, _| match *region { + fold_regions(tcx, ty, |region, _| match *region { ty::ReVar(vid) => { let scc = self.constraint_sccs.scc(vid); @@ -442,7 +443,7 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> { let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); let mut seen = vec![tcx.lifetimes.re_static]; - let canonical_args = tcx.fold_regions(args, |r1, _| { + let canonical_args = fold_regions(tcx, args, |r1, _| { if r1.is_error() { r1 } else if let Some(&r2) = seen.iter().find(|&&r2| { diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index b7aef71eb54a0..d83d6ade2032c 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -2,6 +2,7 @@ use rustc_index::IndexSlice; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_middle::mir::visit::{MutVisitor, TyContext}; use rustc_middle::mir::{Body, ConstOperand, Location, Promoted}; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable}; use rustc_span::Symbol; use tracing::{debug, instrument}; @@ -68,7 +69,7 @@ impl<'a, 'tcx> RegionRenumberer<'a, 'tcx> { F: Fn() -> RegionCtxt, { let origin = NllRegionVariableOrigin::Existential { from_forall: false }; - self.infcx.tcx.fold_regions(value, |_region, _depth| { + fold_regions(self.infcx.tcx, value, |_region, _depth| { self.infcx.next_nll_region_var(origin, || region_ctxt_fn()) }) } diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 68b843d4d0d7a..585d0eabf5b97 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -7,6 +7,7 @@ use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast}; use rustc_span::Span; use rustc_span::def_id::DefId; +use rustc_trait_selection::solve::NoSolution; use rustc_trait_selection::traits::ObligationCause; use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput}; @@ -177,6 +178,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if self.infcx.next_trait_solver() { let body = self.body; let param_env = self.infcx.param_env; + // FIXME: Make this into a real type op? self.fully_perform_op( location.to_locations(), ConstraintCategory::Boring, @@ -213,6 +215,40 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } + #[instrument(skip(self), level = "debug")] + pub(super) fn structurally_resolve( + &mut self, + ty: Ty<'tcx>, + location: impl NormalizeLocation, + ) -> Ty<'tcx> { + if self.infcx.next_trait_solver() { + let body = self.body; + let param_env = self.infcx.param_env; + // FIXME: Make this into a real type op? + self.fully_perform_op( + location.to_locations(), + ConstraintCategory::Boring, + CustomTypeOp::new( + |ocx| { + ocx.structurally_normalize( + &ObligationCause::misc( + location.to_locations().span(body), + body.source.def_id().expect_local(), + ), + param_env, + ty, + ) + .map_err(|_| NoSolution) + }, + "normalizing struct tail", + ), + ) + .unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar)) + } else { + self.normalize(ty, location) + } + } + #[instrument(skip(self), level = "debug")] pub(super) fn ascribe_user_type( &mut self, diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 67915371b1f28..918efac2a2018 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -8,6 +8,7 @@ use rustc_middle::bug; use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory}; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::query::NoSolution; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_span::Span; use rustc_trait_selection::traits::ScrubbedTraitError; @@ -216,7 +217,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { /// are dealt with during trait solving. fn replace_placeholders_with_nll>>(&mut self, value: T) -> T { if value.has_placeholders() { - self.tcx.fold_regions(value, |r, _| match *r { + fold_regions(self.tcx, value, |r, _| match *r { ty::RePlaceholder(placeholder) => { self.constraints.placeholder_region(self.infcx, placeholder) } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 3a7ed711f681e..89e683b8ae3dc 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -26,6 +26,7 @@ use rustc_middle::mir::*; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::cast::CastTy; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{ self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt, @@ -213,7 +214,7 @@ pub(crate) fn type_check<'a, 'tcx>( // Convert all regions to nll vars. let (opaque_type_key, hidden_type) = - infcx.tcx.fold_regions((opaque_type_key, hidden_type), |region, _| { + fold_regions(infcx.tcx, (opaque_type_key, hidden_type), |region, _| { match region.kind() { ty::ReVar(_) => region, ty::RePlaceholder(placeholder) => { @@ -1064,7 +1065,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let tcx = self.infcx.tcx; for proj in &user_ty.projs { - if let ty::Alias(ty::Opaque, ..) = curr_projected_ty.ty.kind() { + if !self.infcx.next_trait_solver() + && let ty::Alias(ty::Opaque, ..) = curr_projected_ty.ty.kind() + { // There is nothing that we can compare here if we go through an opaque type. // We're always in its defining scope as we can otherwise not project through // it, so we're constraining it anyways. @@ -1075,7 +1078,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { proj, |this, field, ()| { let ty = this.field_ty(tcx, field); - self.normalize(ty, locations) + self.structurally_resolve(ty, locations) }, |_, _| unreachable!(), ); @@ -2071,7 +2074,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); let is_implicit_coercion = coercion_source == CoercionSource::Implicit; - let unsize_to = tcx.fold_regions(ty, |r, _| { + let unsize_to = fold_regions(tcx, ty, |r, _| { if let ty::ReVar(_) = r.kind() { tcx.lifetimes.re_erased } else { r } }); self.prove_trait_ref( diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index f1c23aa26a977..86a0111db49b4 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -26,7 +26,7 @@ use rustc_hir::lang_items::LangItem; use rustc_index::IndexVec; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_macros::extension; -use rustc_middle::ty::fold::TypeFoldable; +use rustc_middle::ty::fold::{TypeFoldable, fold_regions}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ self, GenericArgs, GenericArgsRef, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty, @@ -824,7 +824,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> { where T: TypeFoldable>, { - self.infcx.tcx.fold_regions(value, |region, _depth| { + fold_regions(self.infcx.tcx, value, |region, _depth| { let name = region.get_name_or_anon(); debug!(?region, ?name); @@ -906,7 +906,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> { where T: TypeFoldable>, { - tcx.fold_regions(value, |region, _| ty::Region::new_var(tcx, self.to_region_vid(region))) + fold_regions(tcx, value, |region, _| ty::Region::new_var(tcx, self.to_region_vid(region))) } } diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 9ae48024f445b..14ac3cd74e884 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -300,7 +300,10 @@ pub fn parse_asm_args<'a>( if args.options.contains(ast::InlineAsmOptions::PURE) && !have_real_output { dcx.emit_err(errors::AsmPureNoOutput { spans: args.options_spans.clone() }); } - if args.options.contains(ast::InlineAsmOptions::NORETURN) && !outputs_sp.is_empty() { + if args.options.contains(ast::InlineAsmOptions::NORETURN) + && !outputs_sp.is_empty() + && labels_sp.is_empty() + { let err = dcx.create_err(errors::AsmNoReturn { outputs_sp }); // Bail out now since this is likely to confuse MIR return Err(err); diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 53e938ee216b3..8adb9a3f4b0ea 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -288,19 +288,18 @@ pub(crate) fn expand_deriving_coerce_pointee( // // We should also write a few new `where` bounds from `#[pointee] T` to `__S` // as well as any bound that indirectly involves the `#[pointee] T` type. - for bound in &generics.where_clause.predicates { - if let ast::WherePredicate::BoundPredicate(bound) = bound { + for predicate in &generics.where_clause.predicates { + if let ast::WherePredicateKind::BoundPredicate(bound) = &predicate.kind { let mut substitution = TypeSubstitution { from_name: pointee_ty_ident.name, to_ty: &s_ty, rewritten: false, }; - let mut predicate = ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { - span: bound.span, - bound_generic_params: bound.bound_generic_params.clone(), - bounded_ty: bound.bounded_ty.clone(), - bounds: bound.bounds.clone(), - }); + let mut predicate = ast::WherePredicate { + kind: ast::WherePredicateKind::BoundPredicate(bound.clone()), + span: predicate.span, + id: ast::DUMMY_NODE_ID, + }; substitution.visit_where_predicate(&mut predicate); if substitution.rewritten { impl_generics.where_clause.predicates.push(predicate); @@ -319,7 +318,7 @@ pub(crate) fn expand_deriving_coerce_pointee( fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee: Symbol) -> bool { for bound in predicates { - if let ast::WherePredicate::BoundPredicate(bound) = bound + if let ast::WherePredicateKind::BoundPredicate(bound) = &bound.kind && bound.bounded_ty.kind.is_simple_path().is_some_and(|name| name == pointee) { for bound in &bound.bounds { @@ -385,8 +384,8 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> { } fn visit_where_predicate(&mut self, where_predicate: &mut ast::WherePredicate) { - match where_predicate { - rustc_ast::WherePredicate::BoundPredicate(bound) => { + match &mut where_predicate.kind { + rustc_ast::WherePredicateKind::BoundPredicate(bound) => { bound .bound_generic_params .flat_map_in_place(|param| self.flat_map_generic_param(param)); @@ -395,8 +394,8 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> { self.visit_param_bound(bound, BoundKind::Bound) } } - rustc_ast::WherePredicate::RegionPredicate(_) - | rustc_ast::WherePredicate::EqPredicate(_) => {} + rustc_ast::WherePredicateKind::RegionPredicate(_) + | rustc_ast::WherePredicateKind::EqPredicate(_) => {} } } } diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 79c198ed2d08d..f6eea0b21cad7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -690,25 +690,10 @@ impl<'a> TraitDef<'a> { // and similarly for where clauses where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| { - match clause { - ast::WherePredicate::BoundPredicate(wb) => { - let span = wb.span.with_ctxt(ctxt); - ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { - span, - ..wb.clone() - }) - } - ast::WherePredicate::RegionPredicate(wr) => { - let span = wr.span.with_ctxt(ctxt); - ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate { - span, - ..wr.clone() - }) - } - ast::WherePredicate::EqPredicate(we) => { - let span = we.span.with_ctxt(ctxt); - ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { span, ..we.clone() }) - } + ast::WherePredicate { + kind: clause.kind.clone(), + id: ast::DUMMY_NODE_ID, + span: clause.span.with_ctxt(ctxt), } })); @@ -757,13 +742,14 @@ impl<'a> TraitDef<'a> { if !bounds.is_empty() { let predicate = ast::WhereBoundPredicate { - span: self.span, bound_generic_params: field_ty_param.bound_generic_params, bounded_ty: field_ty_param.ty, bounds, }; - let predicate = ast::WherePredicate::BoundPredicate(predicate); + let kind = ast::WherePredicateKind::BoundPredicate(predicate); + let predicate = + ast::WherePredicate { kind, id: ast::DUMMY_NODE_ID, span: self.span }; where_clause.predicates.push(predicate); } } diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 9eee92164cf13..cc4a974e7578c 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -5,10 +5,10 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![cfg_attr(not(bootstrap), feature(autodiff))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] +#![feature(autodiff)] #![feature(box_patterns)] #![feature(decl_macro)] #![feature(if_let_guard)] diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 7dd2139cf90ca..cab5b35c18dc6 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -80,7 +80,7 @@ pub(crate) fn get_function_sig<'tcx>( clif_sig_from_fn_abi( tcx, default_call_conv, - &RevealAllLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()), + &FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()), ) } @@ -438,9 +438,9 @@ pub(crate) fn codegen_terminator_call<'tcx>( extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.node.ty(fx.mir, fx.tcx))), ); let fn_abi = if let Some(instance) = instance { - RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args) + FullyMonomorphizedLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args) } else { - RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_sig, extra_args) + FullyMonomorphizedLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_sig, extra_args) }; let is_cold = if fn_sig.abi() == ExternAbi::RustCold { @@ -721,8 +721,8 @@ pub(crate) fn codegen_drop<'tcx>( def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0), args: drop_instance.args, }; - let fn_abi = - RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty()); + let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx) + .fn_abi_of_instance(virtual_drop, ty::List::empty()); let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi); let sig = fx.bcx.import_signature(sig); @@ -764,8 +764,8 @@ pub(crate) fn codegen_drop<'tcx>( def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0), args: drop_instance.args, }; - let fn_abi = - RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty()); + let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx) + .fn_abi_of_instance(virtual_drop, ty::List::empty()); let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi); let sig = fx.bcx.import_signature(sig); @@ -774,8 +774,8 @@ pub(crate) fn codegen_drop<'tcx>( _ => { assert!(!matches!(drop_instance.def, InstanceKind::Virtual(_, _))); - let fn_abi = - RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(drop_instance, ty::List::empty()); + let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx) + .fn_abi_of_instance(drop_instance, ty::List::empty()); let arg_value = drop_place.place_ref( fx, diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 70b7d92ce15bf..06cc575489462 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -103,7 +103,7 @@ pub(crate) fn codegen_fn<'tcx>( let block_map: IndexVec = (0..mir.basic_blocks.len()).map(|_| bcx.create_block()).collect(); - let fn_abi = RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty()); + let fn_abi = FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty()); // Make FunctionCx let target_config = module.target_config(); diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index c663fa3296523..534557fcd41be 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -311,7 +311,7 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { - RevealAllLayoutCx(self.tcx).handle_layout_err(err, span, ty) + FullyMonomorphizedLayoutCx(self.tcx).handle_layout_err(err, span, ty) } } @@ -323,7 +323,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> { span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { - RevealAllLayoutCx(self.tcx).handle_fn_abi_err(err, span, fn_abi_request) + FullyMonomorphizedLayoutCx(self.tcx).handle_fn_abi_err(err, span, fn_abi_request) } } @@ -443,9 +443,9 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { } } -pub(crate) struct RevealAllLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>); +pub(crate) struct FullyMonomorphizedLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>); -impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> { +impl<'tcx> LayoutOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { @@ -459,7 +459,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> { } } -impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> { +impl<'tcx> FnAbiOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> { #[inline] fn handle_fn_abi_err( &self, @@ -485,25 +485,25 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> { } } -impl<'tcx> layout::HasTyCtxt<'tcx> for RevealAllLayoutCx<'tcx> { +impl<'tcx> layout::HasTyCtxt<'tcx> for FullyMonomorphizedLayoutCx<'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.0 } } -impl<'tcx> rustc_abi::HasDataLayout for RevealAllLayoutCx<'tcx> { +impl<'tcx> rustc_abi::HasDataLayout for FullyMonomorphizedLayoutCx<'tcx> { fn data_layout(&self) -> &rustc_abi::TargetDataLayout { &self.0.data_layout } } -impl<'tcx> layout::HasTypingEnv<'tcx> for RevealAllLayoutCx<'tcx> { +impl<'tcx> layout::HasTypingEnv<'tcx> for FullyMonomorphizedLayoutCx<'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> { ty::TypingEnv::fully_monomorphized() } } -impl<'tcx> HasTargetSpec for RevealAllLayoutCx<'tcx> { +impl<'tcx> HasTargetSpec for FullyMonomorphizedLayoutCx<'tcx> { fn target_spec(&self) -> &Target { &self.0.sess.target } diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs index 714742aeaffe0..a2f6691cdd232 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty, TyCtxt}; -use crate::{DebugContext, RevealAllLayoutCx, has_ptr_meta}; +use crate::{DebugContext, FullyMonomorphizedLayoutCx, has_ptr_meta}; #[derive(Default)] pub(crate) struct TypeDebugContext<'tcx> { @@ -85,7 +85,7 @@ impl DebugContext { type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(encoding)); type_entry.set( gimli::DW_AT_byte_size, - AttributeValue::Udata(RevealAllLayoutCx(tcx).layout_of(ty).size.bytes()), + AttributeValue::Udata(FullyMonomorphizedLayoutCx(tcx).layout_of(ty).size.bytes()), ); type_id @@ -159,7 +159,7 @@ impl DebugContext { return_if_type_created_in_meantime!(type_dbg, tuple_type); let name = type_names::compute_debuginfo_type_name(tcx, tuple_type, false); - let layout = RevealAllLayoutCx(tcx).layout_of(tuple_type); + let layout = FullyMonomorphizedLayoutCx(tcx).layout_of(tuple_type); let tuple_type_id = self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_structure_type); @@ -178,7 +178,9 @@ impl DebugContext { member_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty)); member_entry.set( gimli::DW_AT_alignment, - AttributeValue::Udata(RevealAllLayoutCx(tcx).layout_of(ty).align.pref.bytes()), + AttributeValue::Udata( + FullyMonomorphizedLayoutCx(tcx).layout_of(ty).align.pref.bytes(), + ), ); member_entry.set( gimli::DW_AT_data_member_location, @@ -198,7 +200,11 @@ impl DebugContext { self.debug_type( tcx, type_dbg, - Ty::new_array(tcx, tcx.types.u8, RevealAllLayoutCx(tcx).layout_of(ty).size.bytes()), + Ty::new_array( + tcx, + tcx.types.u8, + FullyMonomorphizedLayoutCx(tcx).layout_of(ty).size.bytes(), + ), ) } } diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs index 6f90d17920d61..c0a3ce84d5292 100644 --- a/compiler/rustc_codegen_cranelift/src/global_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs @@ -42,7 +42,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, tcx, op_sp, const_value, - RevealAllLayoutCx(tcx).layout_of(ty), + FullyMonomorphizedLayoutCx(tcx).layout_of(ty), ); global_asm.push_str(&string); } diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index 0df1a30fc0a49..d74c366a87ffb 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -238,7 +238,7 @@ pub(crate) fn codegen_naked_asm<'tcx>( tcx, span, const_value, - RevealAllLayoutCx(tcx).layout_of(cv.ty()), + FullyMonomorphizedLayoutCx(tcx).layout_of(cv.ty()), ); CInlineAsmOperand::Const { value } } @@ -462,8 +462,12 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { let mut slots_output = vec![None; self.operands.len()]; let new_slot_fn = |slot_size: &mut Size, reg_class: InlineAsmRegClass| { - let reg_size = - reg_class.supported_types(self.arch).iter().map(|(ty, _)| ty.size()).max().unwrap(); + let reg_size = reg_class + .supported_types(self.arch, true) + .iter() + .map(|(ty, _)| ty.size()) + .max() + .unwrap(); let align = rustc_abi::Align::from_bytes(reg_size.bytes()).unwrap(); let offset = slot_size.align_to(align); *slot_size = offset + reg_size; @@ -472,9 +476,14 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { let mut new_slot = |x| new_slot_fn(&mut slot_size, x); // Allocate stack slots for saving clobbered registers - let abi_clobber = InlineAsmClobberAbi::parse(self.arch, &self.tcx.sess.target, sym::C) - .unwrap() - .clobbered_regs(); + let abi_clobber = InlineAsmClobberAbi::parse( + self.arch, + &self.tcx.sess.target, + &self.tcx.sess.unstable_target_features, + sym::C, + ) + .unwrap() + .clobbered_regs(); for (i, reg) in self.registers.iter().enumerate().filter_map(|(i, r)| r.map(|r| (i, r))) { let mut need_save = true; // If the register overlaps with a register clobbered by function call, then diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 6b067b35e7127..341d1b9c179b7 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -186,7 +186,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { // `clobber_abi` can add lots of clobbers that are not supported by the target, // such as AVX-512 registers, so we just ignore unsupported registers let is_target_supported = - reg.reg_class().supported_types(asm_arch).iter().any( + reg.reg_class().supported_types(asm_arch, true).iter().any( |&(_, feature)| { if let Some(feature) = feature { self.tcx @@ -634,6 +634,9 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w", InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::preg) => { + unreachable!("clobber-only") + } InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r", InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f", InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r", @@ -683,9 +686,8 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::S390x( - S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg, - ) => { + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg) => "v", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::areg) => { unreachable!("clobber-only") } InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => "r", @@ -721,6 +723,9 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl cx.type_vector(cx.type_i64(), 2) } InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::preg) => { + unreachable!("clobber-only") + } InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(), InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(), @@ -766,7 +771,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr, ) => cx.type_i32(), InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(), - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => { + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i64(), 2), + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::areg) => { unreachable!("clobber-only") } InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => cx.type_i32(), diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index bb74dfe148703..9aa01bd1b956c 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -45,7 +45,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { match *op { InlineAsmOperandRef::Out { reg, late, place } => { let is_target_supported = |reg_class: InlineAsmRegClass| { - for &(_, feature) in reg_class.supported_types(asm_arch) { + for &(_, feature) in reg_class.supported_types(asm_arch, true) { if let Some(feature) = feature { if self .tcx @@ -85,7 +85,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } continue; } else if !is_target_supported(reg.reg_class()) - || reg.reg_class().is_clobber_only(asm_arch) + || reg.reg_class().is_clobber_only(asm_arch, true) { // We turn discarded outputs into clobber constraints // if the target feature needed by the register class is @@ -342,24 +342,32 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs }); - // Switch to the 'normal' basic block if we did an `invoke` instead of a `call` - if let Some(dest) = dest { - self.switch_to_block(dest); - } + // Write results to outputs. We need to do this for all possible control flow. + // + // Note that `dest` maybe populated with unreachable_block when asm goto with outputs + // is used (because we need to codegen callbr which always needs a destination), so + // here we use the NORETURN option to determine if `dest` should be used. + for block in (if options.contains(InlineAsmOptions::NORETURN) { None } else { Some(dest) }) + .into_iter() + .chain(labels.iter().copied().map(Some)) + { + if let Some(block) = block { + self.switch_to_block(block); + } - // Write results to outputs - for (idx, op) in operands.iter().enumerate() { - if let InlineAsmOperandRef::Out { reg, place: Some(place), .. } - | InlineAsmOperandRef::InOut { reg, out_place: Some(place), .. } = *op - { - let value = if output_types.len() == 1 { - result - } else { - self.extract_value(result, op_idx[&idx] as u64) - }; - let value = - llvm_fixup_output(self, value, reg.reg_class(), &place.layout, instance); - OperandValue::Immediate(value).store(self, place); + for (idx, op) in operands.iter().enumerate() { + if let InlineAsmOperandRef::Out { reg, place: Some(place), .. } + | InlineAsmOperandRef::InOut { reg, out_place: Some(place), .. } = *op + { + let value = if output_types.len() == 1 { + result + } else { + self.extract_value(result, op_idx[&idx] as u64) + }; + let value = + llvm_fixup_output(self, value, reg.reg_class(), &place.layout, instance); + OperandValue::Immediate(value).store(self, place); + } } } } @@ -637,6 +645,7 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> | Arm(ArmInlineAsmRegClass::qreg_low4) => "x", Arm(ArmInlineAsmRegClass::dreg) | Arm(ArmInlineAsmRegClass::qreg) => "w", Hexagon(HexagonInlineAsmRegClass::reg) => "r", + Hexagon(HexagonInlineAsmRegClass::preg) => unreachable!("clobber-only"), LoongArch(LoongArchInlineAsmRegClass::reg) => "r", LoongArch(LoongArchInlineAsmRegClass::freg) => "f", Mips(MipsInlineAsmRegClass::reg) => "r", @@ -678,7 +687,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> S390x(S390xInlineAsmRegClass::reg) => "r", S390x(S390xInlineAsmRegClass::reg_addr) => "a", S390x(S390xInlineAsmRegClass::freg) => "f", - S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => { + S390x(S390xInlineAsmRegClass::vreg) => "v", + S390x(S390xInlineAsmRegClass::areg) => { unreachable!("clobber-only") } Sparc(SparcInlineAsmRegClass::reg) => "r", @@ -804,6 +814,7 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' | Arm(ArmInlineAsmRegClass::qreg_low8) | Arm(ArmInlineAsmRegClass::qreg_low4) => cx.type_vector(cx.type_i64(), 2), Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(), + Hexagon(HexagonInlineAsmRegClass::preg) => unreachable!("clobber-only"), LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(), LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(), Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(), @@ -844,7 +855,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(), S390x(S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr) => cx.type_i32(), S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(), - S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => { + S390x(S390xInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i64(), 2), + S390x(S390xInlineAsmRegClass::areg) => { unreachable!("clobber-only") } Sparc(SparcInlineAsmRegClass::reg) => cx.type_i32(), diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index a65ae4df1e378..00f7b479fa761 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -955,24 +955,7 @@ pub(crate) fn bitcode_section_name(cgcx: &CodegenContext) -> } } -/// Embed the bitcode of an LLVM module in the LLVM module itself. -/// -/// This is done primarily for iOS where it appears to be standard to compile C -/// code at least with `-fembed-bitcode` which creates two sections in the -/// executable: -/// -/// * __LLVM,__bitcode -/// * __LLVM,__cmdline -/// -/// It appears *both* of these sections are necessary to get the linker to -/// recognize what's going on. A suitable cmdline value is taken from the -/// target spec. -/// -/// Furthermore debug/O1 builds don't actually embed bitcode but rather just -/// embed an empty section. -/// -/// Basically all of this is us attempting to follow in the footsteps of clang -/// on iOS. See #35968 for lots more info. +/// Embed the bitcode of an LLVM module for LTO in the LLVM module itself. unsafe fn embed_bitcode( cgcx: &CodegenContext, llcx: &llvm::Context, diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 3279389479499..f62310bd94808 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -172,3 +172,12 @@ pub(crate) fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility { Visibility::Protected => llvm::Visibility::Protected, } } + +pub(crate) fn set_variable_sanitizer_attrs(llval: &Value, attrs: &CodegenFnAttrs) { + if attrs.no_sanitize.contains(SanitizerSet::ADDRESS) { + unsafe { llvm::LLVMRustSetNoSanitizeAddress(llval) }; + } + if attrs.no_sanitize.contains(SanitizerSet::HWADDRESS) { + unsafe { llvm::LLVMRustSetNoSanitizeHWAddress(llval) }; + } +} diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index e0a2de3366c0d..ec77f32caf49a 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -104,7 +104,10 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t let is_hidden = if is_generic { // This is a monomorphization of a generic function. - if !cx.tcx.sess.opts.share_generics() { + if !(cx.tcx.sess.opts.share_generics() + || tcx.codegen_fn_attrs(instance_def_id).inline + == rustc_attr::InlineAttr::Never) + { // When not sharing generics, all instances are in the same // crate and have hidden visibility. true diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 6f5ffbb4b3456..c7114480d8bdf 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -470,6 +470,8 @@ impl<'ll> CodegenCx<'ll, '_> { base::set_link_section(g, attrs); } + base::set_variable_sanitizer_attrs(g, attrs); + if attrs.flags.contains(CodegenFnAttrFlags::USED) { // `USED` and `USED_LINKER` can't be used together. assert!(!attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)); diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 7f59264824e41..17b0ec4b9360a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2460,4 +2460,7 @@ unsafe extern "C" { pub fn LLVMRustIs64BitSymbolicFile(buf_ptr: *const u8, buf_len: usize) -> bool; pub fn LLVMRustIsECObject(buf_ptr: *const u8, buf_len: usize) -> bool; + + pub fn LLVMRustSetNoSanitizeAddress(Global: &Value); + pub fn LLVMRustSetNoSanitizeHWAddress(Global: &Value); } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 5149e3a12f232..651485a18763c 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1117,14 +1117,14 @@ fn link_natively( let stripcmd = "rust-objcopy"; match (strip, crate_type) { (Strip::Debuginfo, _) => { - strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-S")) + strip_symbols_with_external_utility(sess, stripcmd, out_filename, &["-S"]) } // Per the manpage, `-x` is the maximum safe strip level for dynamic libraries. (#93988) (Strip::Symbols, CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro) => { - strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-x")) + strip_symbols_with_external_utility(sess, stripcmd, out_filename, &["-x"]) } (Strip::Symbols, _) => { - strip_symbols_with_external_utility(sess, stripcmd, out_filename, None) + strip_symbols_with_external_utility(sess, stripcmd, out_filename, &[]) } (Strip::None, _) => {} } @@ -1141,7 +1141,7 @@ fn link_natively( match strip { // Always preserve the symbol table (-x). Strip::Debuginfo => { - strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-x")) + strip_symbols_with_external_utility(sess, stripcmd, out_filename, &["-x"]) } // Strip::Symbols is handled via the --strip-all linker option. Strip::Symbols => {} @@ -1158,11 +1158,15 @@ fn link_natively( match strip { Strip::Debuginfo => { // FIXME: AIX's strip utility only offers option to strip line number information. - strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-l")) + strip_symbols_with_external_utility(sess, stripcmd, out_filename, &[ + "-X32_64", "-l", + ]) } Strip::Symbols => { // Must be noted this option might remove symbol __aix_rust_metadata and thus removes .info section which contains metadata. - strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-r")) + strip_symbols_with_external_utility(sess, stripcmd, out_filename, &[ + "-X32_64", "-r", + ]) } Strip::None => {} } @@ -1181,12 +1185,10 @@ fn strip_symbols_with_external_utility( sess: &Session, util: &str, out_filename: &Path, - option: Option<&str>, + options: &[&str], ) { let mut cmd = Command::new(util); - if let Some(option) = option { - cmd.arg(option); - } + cmd.args(options); let mut new_path = sess.get_tools_search_paths(false); if let Some(path) = env::var_os("PATH") { diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index d9152c5d08074..788a8a13b3ee4 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -282,7 +282,7 @@ fn exported_symbols_provider_local( })); } - if tcx.sess.opts.share_generics() && tcx.local_crate_exports_generics() { + if tcx.local_crate_exports_generics() { use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility}; use rustc_middle::ty::InstanceKind; @@ -310,6 +310,16 @@ fn exported_symbols_provider_local( continue; } + if !tcx.sess.opts.share_generics() { + if tcx.codegen_fn_attrs(mono_item.def_id()).inline == rustc_attr::InlineAttr::Never + { + // this is OK, we explicitly allow sharing inline(never) across crates even + // without share-generics. + } else { + continue; + } + } + match *mono_item { MonoItem::Fn(Instance { def: InstanceKind::Item(def), args }) => { if args.non_erasable_generics().next().is_some() { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index a2285bf9204a4..7c0e9cfd5a768 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -432,11 +432,9 @@ struct CompiledModules { fn need_bitcode_in_object(tcx: TyCtxt<'_>) -> bool { let sess = tcx.sess; - let requested_for_rlib = sess.opts.cg.embed_bitcode + sess.opts.cg.embed_bitcode && tcx.crate_types().contains(&CrateType::Rlib) - && sess.opts.output_types.contains_key(&OutputType::Exe); - let forced_by_target = sess.target.forces_embed_bitcode; - requested_for_rlib || forced_by_target + && sess.opts.output_types.contains_key(&OutputType::Exe) } fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 32e9422e005ab..a5acd8170ab81 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -576,9 +576,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // If this closure is marked `#[inline(always)]`, simply skip adding `#[target_feature]`. // // At this point, `unsafe` has already been checked and `#[target_feature]` only affects codegen. - // Emitting both `#[inline(always)]` and `#[target_feature]` can potentially result in an - // ICE, because LLVM errors when the function fails to be inlined due to a target feature - // mismatch. + // Due to LLVM limitations, emitting both `#[inline(always)]` and `#[target_feature]` is *unsound*: + // the function may be inlined into a caller with fewer target features. Also see + // . // // Using `#[inline(always)]` implies that this closure will most likely be inlined into // its parent function, which effectively inherits the features anyway. Boxing this closure diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index cbf214763b425..7eab889edf05f 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -71,11 +71,11 @@ pub trait CodegenBackend { need_metadata_module: bool, ) -> Box; - /// This is called on the returned `Box` from `codegen_backend` + /// This is called on the returned `Box` from [`codegen_crate`](Self::codegen_crate) /// /// # Panics /// - /// Panics when the passed `Box` was not returned by `codegen_backend`. + /// Panics when the passed `Box` was not returned by [`codegen_crate`](Self::codegen_crate). fn join_codegen( &self, ongoing_codegen: Box, @@ -83,7 +83,7 @@ pub trait CodegenBackend { outputs: &OutputFilenames, ) -> (CodegenResults, FxIndexMap); - /// This is called on the returned `CodegenResults` from `join_codegen` + /// This is called on the returned [`CodegenResults`] from [`join_codegen`](Self::join_codegen). fn link( &self, sess: &Session, diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 1129b5caec54e..916929b6c0bb9 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -18,13 +18,12 @@ use rustc_middle::span_bug; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_mir_dataflow::Analysis; -use rustc_mir_dataflow::impls::MaybeStorageLive; -use rustc_mir_dataflow::storage::always_storage_live_locals; +use rustc_mir_dataflow::impls::{MaybeStorageLive, always_storage_live_locals}; use rustc_span::{Span, Symbol, sym}; use rustc_trait_selection::traits::{ Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt, }; -use tracing::{debug, instrument, trace}; +use tracing::{instrument, trace}; use super::ops::{self, NonConstOp, Status}; use super::qualifs::{self, HasMutInterior, NeedsDrop, NeedsNonConstDrop}; @@ -47,7 +46,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> { /// Returns `true` if `local` is `NeedsDrop` at the given `Location`. /// /// Only updates the cursor if absolutely necessary - fn needs_drop( + pub(crate) fn needs_drop( &mut self, ccx: &'mir ConstCx<'mir, 'tcx>, local: Local, @@ -421,6 +420,43 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { true } + + pub fn check_drop_terminator( + &mut self, + dropped_place: Place<'tcx>, + location: Location, + terminator_span: Span, + ) { + let ty_of_dropped_place = dropped_place.ty(self.body, self.tcx).ty; + + let needs_drop = if let Some(local) = dropped_place.as_local() { + self.qualifs.needs_drop(self.ccx, local, location) + } else { + qualifs::NeedsDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place) + }; + // If this type doesn't need a drop at all, then there's nothing to enforce. + if !needs_drop { + return; + } + + let mut err_span = self.span; + let needs_non_const_drop = if let Some(local) = dropped_place.as_local() { + // Use the span where the local was declared as the span of the drop error. + err_span = self.body.local_decls[local].source_info.span; + self.qualifs.needs_non_const_drop(self.ccx, local, location) + } else { + qualifs::NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place) + }; + + self.check_op_spanned( + ops::LiveDrop { + dropped_at: terminator_span, + dropped_ty: ty_of_dropped_place, + needs_non_const_drop, + }, + err_span, + ); + } } impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { @@ -866,35 +902,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { return; } - let mut err_span = self.span; - let ty_of_dropped_place = dropped_place.ty(self.body, self.tcx).ty; - - let ty_needs_non_const_drop = - qualifs::NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place); - - debug!(?ty_of_dropped_place, ?ty_needs_non_const_drop); - - if !ty_needs_non_const_drop { - return; - } - - let needs_non_const_drop = if let Some(local) = dropped_place.as_local() { - // Use the span where the local was declared as the span of the drop error. - err_span = self.body.local_decls[local].source_info.span; - self.qualifs.needs_non_const_drop(self.ccx, local, location) - } else { - true - }; - - if needs_non_const_drop { - self.check_op_spanned( - ops::LiveDrop { - dropped_at: Some(terminator.source_info.span), - dropped_ty: ty_of_dropped_place, - }, - err_span, - ); - } + self.check_drop_terminator(*dropped_place, location, terminator.source_info.span); } TerminatorKind::InlineAsm { .. } => self.check_op(ops::InlineAsm), diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 8ba6b89aad4d5..ab81e60a33f23 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -459,17 +459,43 @@ impl<'tcx> NonConstOp<'tcx> for InlineAsm { #[derive(Debug)] pub(crate) struct LiveDrop<'tcx> { - pub dropped_at: Option, + pub dropped_at: Span, pub dropped_ty: Ty<'tcx>, + pub needs_non_const_drop: bool, } impl<'tcx> NonConstOp<'tcx> for LiveDrop<'tcx> { + fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status { + if self.needs_non_const_drop { + Status::Forbidden + } else { + Status::Unstable { + gate: sym::const_destruct, + gate_already_checked: false, + safe_to_expose_on_stable: false, + is_function_call: false, + } + } + } + fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { - ccx.dcx().create_err(errors::LiveDrop { - span, - dropped_ty: self.dropped_ty, - kind: ccx.const_kind(), - dropped_at: self.dropped_at, - }) + if self.needs_non_const_drop { + ccx.dcx().create_err(errors::LiveDrop { + span, + dropped_ty: self.dropped_ty, + kind: ccx.const_kind(), + dropped_at: self.dropped_at, + }) + } else { + ccx.tcx.sess.create_feature_err( + errors::LiveDrop { + span, + dropped_ty: self.dropped_ty, + kind: ccx.const_kind(), + dropped_at: self.dropped_at, + }, + sym::const_destruct, + ) + } } } diff --git a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs index f6eb130fbd385..951e19b470bab 100644 --- a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs +++ b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs @@ -1,14 +1,11 @@ use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{self, BasicBlock, Location}; -use rustc_middle::ty::{Ty, TyCtxt}; -use rustc_span::Span; +use rustc_middle::ty::TyCtxt; use rustc_span::symbol::sym; use tracing::trace; use super::ConstCx; -use super::check::Qualifs; -use super::ops::{self, NonConstOp}; -use super::qualifs::{NeedsNonConstDrop, Qualif}; +use crate::check_consts::check::Checker; use crate::check_consts::rustc_allow_const_fn_unstable; /// Returns `true` if we should use the more precise live drop checker that runs after drop @@ -45,29 +42,16 @@ pub fn check_live_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) { return; } - let mut visitor = CheckLiveDrops { ccx: &ccx, qualifs: Qualifs::default() }; + // I know it's not great to be creating a new const checker, but I'd + // rather use it so we can deduplicate the error emitting logic that + // it contains. + let mut visitor = CheckLiveDrops { checker: Checker::new(&ccx) }; visitor.visit_body(body); } struct CheckLiveDrops<'mir, 'tcx> { - ccx: &'mir ConstCx<'mir, 'tcx>, - qualifs: Qualifs<'mir, 'tcx>, -} - -// So we can access `body` and `tcx`. -impl<'mir, 'tcx> std::ops::Deref for CheckLiveDrops<'mir, 'tcx> { - type Target = ConstCx<'mir, 'tcx>; - - fn deref(&self) -> &Self::Target { - self.ccx - } -} - -impl<'tcx> CheckLiveDrops<'_, 'tcx> { - fn check_live_drop(&self, span: Span, dropped_ty: Ty<'tcx>) { - ops::LiveDrop { dropped_at: None, dropped_ty }.build_error(self.ccx, span).emit(); - } + checker: Checker<'mir, 'tcx>, } impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> { @@ -87,28 +71,11 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> { match &terminator.kind { mir::TerminatorKind::Drop { place: dropped_place, .. } => { - let dropped_ty = dropped_place.ty(self.body, self.tcx).ty; - - if !NeedsNonConstDrop::in_any_value_of_ty(self.ccx, dropped_ty) { - // Instead of throwing a bug, we just return here. This is because we have to - // run custom `const Drop` impls. - return; - } - - if dropped_place.is_indirect() { - self.check_live_drop(terminator.source_info.span, dropped_ty); - return; - } - - // Drop elaboration is not precise enough to accept code like - // `tests/ui/consts/control-flow/drop-pass.rs`; e.g., when an `Option>` is - // initialized with `None` and never changed, it still emits drop glue. - // Hence we additionally check the qualifs here to allow more code to pass. - if self.qualifs.needs_non_const_drop(self.ccx, dropped_place.local, location) { - // Use the span where the dropped local was declared for the error. - let span = self.body.local_decls[dropped_place.local].source_info.span; - self.check_live_drop(span, dropped_ty); - } + self.checker.check_drop_terminator( + *dropped_place, + location, + terminator.source_info.span, + ); } mir::TerminatorKind::UnwindTerminate(_) diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index bc416acc58d7b..e244b50a4b5d9 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -2,11 +2,14 @@ //! //! See the `Qualif` trait for more info. +// FIXME(const_trait_impl): This API should be really reworked. It's dangerously general for +// having basically only two use-cases that act in different ways. + use rustc_errors::ErrorGuaranteed; use rustc_hir::LangItem; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::*; -use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty}; +use rustc_middle::ty::{self, AdtDef, Ty}; use rustc_middle::{bug, mir}; use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt}; use tracing::instrument; @@ -59,26 +62,12 @@ pub trait Qualif { /// It also determines the `Qualif`s for primitive types. fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool; - /// Returns `true` if this `Qualif` is inherent to the given struct or enum. - /// - /// By default, `Qualif`s propagate into ADTs in a structural way: An ADT only becomes - /// qualified if part of it is assigned a value with that `Qualif`. However, some ADTs *always* - /// have a certain `Qualif`, regardless of whether their fields have it. For example, a type - /// with a custom `Drop` impl is inherently `NeedsDrop`. - /// - /// Returning `true` for `in_adt_inherently` but `false` for `in_any_value_of_ty` is unsound. - fn in_adt_inherently<'tcx>( - cx: &ConstCx<'_, 'tcx>, - adt: AdtDef<'tcx>, - args: GenericArgsRef<'tcx>, - ) -> bool; - - /// Returns `true` if this `Qualif` behaves sructurally for pointers and references: - /// the pointer/reference qualifies if and only if the pointee qualifies. + /// Returns `true` if the `Qualif` is structural in an ADT's fields, i.e. if we may + /// recurse into an operand *value* to determine whether it has this `Qualif`. /// - /// (This is currently `false` for all our instances, but that may change in the future. Also, - /// by keeping it abstract, the handling of `Deref` in `in_place` becomes more clear.) - fn deref_structural<'tcx>(cx: &ConstCx<'_, 'tcx>) -> bool; + /// If this returns false, `in_any_value_of_ty` will be invoked to determine the + /// final qualif for this ADT. + fn is_structural_in_adt_value<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool; } /// Constant containing interior mutability (`UnsafeCell`). @@ -101,6 +90,11 @@ impl Qualif for HasMutInterior { return false; } + // Avoid selecting for `UnsafeCell` either. + if ty.ty_adt_def().is_some_and(|adt| adt.is_unsafe_cell()) { + return true; + } + // We do not use `ty.is_freeze` here, because that requires revealing opaque types, which // requires borrowck, which in turn will invoke mir_const_qualifs again, causing a cycle error. // Instead we invoke an obligation context manually, and provide the opaque type inference settings @@ -129,18 +123,10 @@ impl Qualif for HasMutInterior { !errors.is_empty() } - fn in_adt_inherently<'tcx>( - _cx: &ConstCx<'_, 'tcx>, - adt: AdtDef<'tcx>, - _: GenericArgsRef<'tcx>, - ) -> bool { + fn is_structural_in_adt_value<'tcx>(_cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool { // Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently. // It arises structurally for all other types. - adt.is_unsafe_cell() - } - - fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool { - false + !adt.is_unsafe_cell() } } @@ -154,6 +140,7 @@ pub struct NeedsDrop; impl Qualif for NeedsDrop { const ANALYSIS_NAME: &'static str = "flow_needs_drop"; const IS_CLEARED_ON_MOVE: bool = true; + const ALLOW_PROMOTED: bool = true; fn in_qualifs(qualifs: &ConstQualifs) -> bool { qualifs.needs_drop @@ -163,16 +150,8 @@ impl Qualif for NeedsDrop { ty.needs_drop(cx.tcx, cx.typing_env) } - fn in_adt_inherently<'tcx>( - cx: &ConstCx<'_, 'tcx>, - adt: AdtDef<'tcx>, - _: GenericArgsRef<'tcx>, - ) -> bool { - adt.has_dtor(cx.tcx) - } - - fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool { - false + fn is_structural_in_adt_value<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool { + !adt.has_dtor(cx.tcx) } } @@ -191,25 +170,46 @@ impl Qualif for NeedsNonConstDrop { #[instrument(level = "trace", skip(cx), ret)] fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool { - // Avoid selecting for simple cases, such as builtin types. - if ty::util::is_trivially_const_drop(ty) { + // If this doesn't need drop at all, then don't select `~const Destruct`. + if !ty.needs_drop(cx.tcx, cx.typing_env) { return false; } - // FIXME(const_trait_impl): Reimplement const drop checking. - NeedsDrop::in_any_value_of_ty(cx, ty) - } - - fn in_adt_inherently<'tcx>( - cx: &ConstCx<'_, 'tcx>, - adt: AdtDef<'tcx>, - _: GenericArgsRef<'tcx>, - ) -> bool { - adt.has_non_const_dtor(cx.tcx) + // We check that the type is `~const Destruct` since that will verify that + // the type is both `~const Drop` (if a drop impl exists for the adt), *and* + // that the components of this type are also `~const Destruct`. This + // amounts to verifying that there are no values in this ADT that may have + // a non-const drop. + let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, Some(cx.body.span)); + let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env); + let ocx = ObligationCtxt::new(&infcx); + ocx.register_obligation(Obligation::new( + cx.tcx, + ObligationCause::misc(cx.body.span, cx.def_id()), + param_env, + ty::Binder::dummy(ty::TraitRef::new(cx.tcx, destruct_def_id, [ty])) + .to_host_effect_clause(cx.tcx, match cx.const_kind() { + rustc_hir::ConstContext::ConstFn => ty::BoundConstness::Maybe, + rustc_hir::ConstContext::Static(_) | rustc_hir::ConstContext::Const { .. } => { + ty::BoundConstness::Const + } + }), + )); + !ocx.select_all_or_error().is_empty() } - fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool { - false + fn is_structural_in_adt_value<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool { + // As soon as an ADT has a destructor, then the drop becomes non-structural + // in its value since: + // 1. The destructor may have `~const` bounds which are not present on the type. + // Someone needs to check that those are satisfied. + // While this could be instead satisfied by checking that the `~const Drop` + // impl holds (i.e. replicating part of the `in_any_value_of_ty` logic above), + // even in this case, we have another problem, which is, + // 2. The destructor may *modify* the operand being dropped, so even if we + // did recurse on the components of the operand, we may not be even dropping + // the same values that were present before the custom destructor was invoked. + !adt.has_dtor(cx.tcx) } } @@ -261,14 +261,15 @@ where Rvalue::Aggregate(kind, operands) => { // Return early if we know that the struct or enum being constructed is always // qualified. - if let AggregateKind::Adt(adt_did, _, args, ..) = **kind { + if let AggregateKind::Adt(adt_did, ..) = **kind { let def = cx.tcx.adt_def(adt_did); - if Q::in_adt_inherently(cx, def, args) { - return true; - } // Don't do any value-based reasoning for unions. - if def.is_union() && Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)) { - return true; + // Also, if the ADT is not structural in its fields, + // then we cannot recurse on its fields. Instead, + // we fall back to checking the qualif for *any* value + // of the ADT. + if def.is_union() || !Q::is_structural_in_adt_value(cx, def) { + return Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)); } } @@ -305,7 +306,11 @@ where return false; } - if matches!(elem, ProjectionElem::Deref) && !Q::deref_structural(cx) { + // `Deref` currently unconditionally "qualifies" if `in_any_value_of_ty` returns true, + // i.e., we treat all qualifs as non-structural for deref projections. Generally, + // we can say very little about `*ptr` even if we know that `ptr` satisfies all + // sorts of properties. + if matches!(elem, ProjectionElem::Deref) { // We have to assume that this qualifies. return true; } diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 604e5ed61a35b..80236ee05b7ff 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -411,7 +411,7 @@ pub struct LiveDrop<'tcx> { pub kind: ConstContext, pub dropped_ty: Ty<'tcx>, #[label(const_eval_dropped_at_label)] - pub dropped_at: Option, + pub dropped_at: Span, } #[derive(Diagnostic)] diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index 8ce11c71b8bd3..a9ebf38661703 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -10,7 +10,7 @@ use rustc_index::IndexVec; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, mir}; -use rustc_mir_dataflow::storage::always_storage_live_locals; +use rustc_mir_dataflow::impls::always_storage_live_locals; use rustc_span::Span; use tracing::{info_span, instrument, trace}; diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index c270ce16726d1..85eaae8a10466 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -160,6 +160,9 @@ pub trait Callbacks { /// Called after parsing the crate root. Submodules are not yet parsed when /// this callback is called. Return value instructs the compiler whether to /// continue the compilation afterwards (defaults to `Compilation::Continue`) + #[deprecated = "This callback will likely be removed or stop giving access \ + to the TyCtxt in the future. Use either the after_expansion \ + or the after_analysis callback instead."] fn after_crate_root_parsing<'tcx>( &mut self, _compiler: &interface::Compiler, @@ -181,7 +184,7 @@ pub trait Callbacks { fn after_analysis<'tcx>( &mut self, _compiler: &interface::Compiler, - _queries: &'tcx Queries<'tcx>, + _tcx: TyCtxt<'tcx>, ) -> Compilation { Compilation::Continue } @@ -335,19 +338,12 @@ fn run_compiler( expanded_args: args, }; - let has_input = match make_input(&default_early_dcx, &matches.free) { - Err(reported) => return Err(reported), - Ok(Some(input)) => { + let has_input = match make_input(&default_early_dcx, &matches.free)? { + Some(input) => { config.input = input; true // has input: normal compilation } - Ok(None) => match matches.free.as_slice() { - [] => false, // no input: we will exit early - [_] => panic!("make_input should have provided valid inputs"), - [fst, snd, ..] => default_early_dcx.early_fatal(format!( - "multiple input filenames provided (first two filenames are `{fst}` and `{snd}`)" - )), - }, + None => false, // no input: we will exit early }; drop(default_early_dcx); @@ -405,10 +401,6 @@ fn run_compiler( queries.global_ctxt()?.enter(|tcx| { tcx.ensure().early_lint_checks(()); pretty::print(sess, pp_mode, pretty::PrintExtra::NeedsAstMap { tcx }); - Ok(()) - })?; - - queries.global_ctxt()?.enter(|tcx| { passes::write_dep_info(tcx); }); } else { @@ -421,11 +413,14 @@ fn run_compiler( return early_exit(); } + #[allow(deprecated)] if callbacks.after_crate_root_parsing(compiler, queries) == Compilation::Stop { return early_exit(); } - if sess.opts.unstable_opts.parse_only || sess.opts.unstable_opts.show_span.is_some() { + if sess.opts.unstable_opts.parse_crate_root_only + || sess.opts.unstable_opts.show_span.is_some() + { return early_exit(); } @@ -442,25 +437,23 @@ fn run_compiler( queries.global_ctxt()?.enter(|tcx| { passes::write_dep_info(tcx); - }); - if sess.opts.output_types.contains_key(&OutputType::DepInfo) - && sess.opts.output_types.len() == 1 - { - return early_exit(); - } + if sess.opts.output_types.contains_key(&OutputType::DepInfo) + && sess.opts.output_types.len() == 1 + { + return early_exit(); + } - if sess.opts.unstable_opts.no_analysis { - return early_exit(); - } + if sess.opts.unstable_opts.no_analysis { + return early_exit(); + } - queries.global_ctxt()?.enter(|tcx| tcx.analysis(()))?; + tcx.analysis(())?; - if callbacks.after_analysis(compiler, queries) == Compilation::Stop { - return early_exit(); - } + if callbacks.after_analysis(compiler, tcx) == Compilation::Stop { + return early_exit(); + } - queries.global_ctxt()?.enter(|tcx| { Ok(Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend)?)) }) })?; @@ -472,10 +465,6 @@ fn run_compiler( linker.link(sess, codegen_backend)? } - if let Some(fuel) = sess.opts.unstable_opts.print_fuel.as_deref() { - eprintln!("Fuel used by {}: {}", fuel, sess.print_fuel.load(Ordering::SeqCst)); - } - Ok(()) }) } @@ -513,37 +502,40 @@ fn make_input( early_dcx: &EarlyDiagCtxt, free_matches: &[String], ) -> Result, ErrorGuaranteed> { - let [input_file] = free_matches else { return Ok(None) }; - - if input_file != "-" { - // Normal `Input::File` - return Ok(Some(Input::File(PathBuf::from(input_file)))); - } - - // read from stdin as `Input::Str` - let mut input = String::new(); - if io::stdin().read_to_string(&mut input).is_err() { - // Immediately stop compilation if there was an issue reading - // the input (for example if the input stream is not UTF-8). - let reported = - early_dcx.early_err("couldn't read from stdin, as it did not contain valid UTF-8"); - return Err(reported); - } + match free_matches { + [] => Ok(None), // no input: we will exit early, + [ifile] if ifile == "-" => { + // read from stdin as `Input::Str` + let mut input = String::new(); + if io::stdin().read_to_string(&mut input).is_err() { + // Immediately stop compilation if there was an issue reading + // the input (for example if the input stream is not UTF-8). + let reported = early_dcx + .early_err("couldn't read from stdin, as it did not contain valid UTF-8"); + return Err(reported); + } - let name = match env::var("UNSTABLE_RUSTDOC_TEST_PATH") { - Ok(path) => { - let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect( - "when UNSTABLE_RUSTDOC_TEST_PATH is set \ + let name = match env::var("UNSTABLE_RUSTDOC_TEST_PATH") { + Ok(path) => { + let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect( + "when UNSTABLE_RUSTDOC_TEST_PATH is set \ UNSTABLE_RUSTDOC_TEST_LINE also needs to be set", - ); - let line = isize::from_str_radix(&line, 10) - .expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number"); - FileName::doc_test_source_code(PathBuf::from(path), line) - } - Err(_) => FileName::anon_source_code(&input), - }; + ); + let line = isize::from_str_radix(&line, 10) + .expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number"); + FileName::doc_test_source_code(PathBuf::from(path), line) + } + Err(_) => FileName::anon_source_code(&input), + }; - Ok(Some(Input::Str { name, input })) + Ok(Some(Input::Str { name, input })) + } + [ifile] => Ok(Some(Input::File(PathBuf::from(ifile)))), + [ifile1, ifile2, ..] => early_dcx.early_fatal(format!( + "multiple input filenames provided (first two filenames are `{}` and `{}`)", + ifile1, ifile2 + )), + } } /// Whether to stop or continue compilation. diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index bae16a18bcbfd..f044d964f1358 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -2,7 +2,7 @@ use rustc_ast::mut_visit::*; use rustc_ast::ptr::P; use rustc_ast::token::Delimiter; use rustc_ast::visit::AssocCtxt; -use rustc_ast::{self as ast}; +use rustc_ast::{self as ast, Safety}; use rustc_data_structures::fx::FxHashMap; use rustc_span::DUMMY_SP; use rustc_span::symbol::Ident; @@ -173,6 +173,7 @@ pub(crate) fn placeholder( ty: ty(), vis, is_placeholder: true, + safety: Safety::Default, }]), AstFragmentKind::Variants => AstFragment::Variants(smallvec![ast::Variant { attrs: Default::default(), diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index e910415c34574..53362cb252988 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -193,6 +193,9 @@ declare_features! ( (accepted, expr_fragment_specifier_2024, "1.83.0", Some(123742)), /// Allows arbitrary expressions in key-value attributes at parse time. (accepted, extended_key_value_attributes, "1.54.0", Some(78835)), + /// Allows using `efiapi`, `aapcs`, `sysv64` and `win64` as calling + /// convention for functions with varargs. + (accepted, extended_varargs_abi_support, "CURRENT_RUSTC_VERSION", Some(100189)), /// Allows resolving absolute paths as paths from other crates. (accepted, extern_absolute_paths, "1.30.0", Some(44660)), /// Allows `extern crate foo as bar;`. This puts `bar` into extern prelude. @@ -225,7 +228,7 @@ declare_features! ( /// Allows the use of `if let` expressions. (accepted, if_let, "1.0.0", None), /// Rescoping temporaries in `if let` to align with Rust 2024. - (accepted, if_let_rescope, "CURRENT_RUSTC_VERSION", Some(124085)), + (accepted, if_let_rescope, "1.84.0", Some(124085)), /// Allows top level or-patterns (`p | q`) in `if let` and `while let`. (accepted, if_while_or_patterns, "1.33.0", Some(48215)), /// Allows lifetime elision in `impl` headers. For example: @@ -357,7 +360,7 @@ declare_features! ( (accepted, repr_transparent, "1.28.0", Some(43036)), /// Allows enums like Result to be used across FFI, if T's niche value can /// be used to describe E or vice-versa. - (accepted, result_ffi_guarantees, "CURRENT_RUSTC_VERSION", Some(110503)), + (accepted, result_ffi_guarantees, "1.84.0", Some(110503)), /// Allows return-position `impl Trait` in traits. (accepted, return_position_impl_trait_in_trait, "1.75.0", Some(91611)), /// Allows code like `let x: &'static u32 = &42` to work (RFC 1414). @@ -367,7 +370,7 @@ declare_features! ( /// Allows `Self` struct constructor (RFC 2302). (accepted, self_struct_ctor, "1.32.0", Some(51994)), /// Shortern the tail expression lifetime - (accepted, shorter_tail_lifetimes, "CURRENT_RUSTC_VERSION", Some(123739)), + (accepted, shorter_tail_lifetimes, "1.84.0", Some(123739)), /// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`. (accepted, slice_patterns, "1.42.0", Some(62254)), /// Allows use of `&foo[a..b]` as a slicing syntax. diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 6ff70044eed44..69a14bd9f120f 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -101,7 +101,7 @@ declare_features! ( /// Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238). (removed, dropck_parametricity, "1.38.0", Some(28498), None), /// Uses generic effect parameters for ~const bounds - (removed, effects, "CURRENT_RUSTC_VERSION", Some(102090), + (removed, effects, "1.84.0", Some(102090), Some("removed, redundant with `#![feature(const_trait_impl)]`")), /// Allows defining `existential type`s. (removed, existential_type, "1.38.0", Some(63063), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index e3dc73c14014f..ec908762da724 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -338,7 +338,7 @@ declare_features! ( (unstable, riscv_target_feature, "1.45.0", Some(44839)), (unstable, rtm_target_feature, "1.35.0", Some(44839)), (unstable, s390x_target_feature, "1.82.0", Some(44839)), - (unstable, sparc_target_feature, "CURRENT_RUSTC_VERSION", Some(132783)), + (unstable, sparc_target_feature, "1.84.0", Some(132783)), (unstable, sse4a_target_feature, "1.27.0", Some(44839)), (unstable, tbm_target_feature, "1.27.0", Some(44839)), (unstable, wasm_target_feature, "1.30.0", Some(44839)), @@ -376,8 +376,12 @@ declare_features! ( (unstable, arbitrary_self_types_pointers, "1.83.0", Some(44874)), /// Enables experimental inline assembly support for additional architectures. (unstable, asm_experimental_arch, "1.58.0", Some(93335)), + /// Enables experimental register support in inline assembly. + (unstable, asm_experimental_reg, "CURRENT_RUSTC_VERSION", 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, "CURRENT_RUSTC_VERSION", Some(119364)), /// Allows the `may_unwind` option in inline assembly. (unstable, asm_unwind, "1.58.0", Some(93334)), /// Allows users to enforce equality of associated constants `TraitImpl`. @@ -426,6 +430,8 @@ declare_features! ( (unstable, const_async_blocks, "1.53.0", Some(85368)), /// Allows `const || {}` closures in const contexts. (incomplete, const_closures, "1.68.0", Some(106003)), + /// Allows using `~const Destruct` bounds and calling drop impls in const contexts. + (unstable, const_destruct, "CURRENT_RUSTC_VERSION", Some(133214)), /// Allows `for _ in _` loops in const contexts. (unstable, const_for, "1.56.0", Some(87575)), /// Be more precise when looking for live drops in a const context. @@ -469,9 +475,6 @@ declare_features! ( (unstable, exhaustive_patterns, "1.13.0", Some(51085)), /// Allows explicit tail calls via `become` expression. (incomplete, explicit_tail_calls, "1.72.0", Some(112788)), - /// Allows using `efiapi`, `sysv64` and `win64` as calling convention - /// for functions with varargs. - (unstable, extended_varargs_abi_support, "1.65.0", Some(100189)), /// Allows defining `extern type`s. (unstable, extern_types, "1.23.0", Some(43467)), /// Allow using 128-bit (quad precision) floating point numbers. @@ -532,7 +535,7 @@ declare_features! ( /// Allows `#[marker]` on certain traits allowing overlapping implementations. (unstable, marker_trait_attr, "1.30.0", Some(29864)), /// Enables the generic const args MVP (only bare paths, not arbitrary computation). - (incomplete, min_generic_const_args, "CURRENT_RUSTC_VERSION", Some(132980)), + (incomplete, min_generic_const_args, "1.84.0", Some(132980)), /// A minimal, sound subset of specialization intended to be used by the /// standard library until the soundness issues with specialization /// are fixed. @@ -627,6 +630,8 @@ declare_features! ( /// Allows creation of instances of a struct by moving fields that have /// not changed from prior instances of the same struct (RFC #2528) (unstable, type_changing_struct_update, "1.58.0", Some(86555)), + /// Allows declaring fields `unsafe`. + (incomplete, unsafe_fields, "CURRENT_RUSTC_VERSION", Some(132922)), /// Allows const generic parameters to be defined with types that /// are not `Sized`, e.g. `fn foo() {`. (incomplete, unsized_const_params, "1.82.0", Some(95174)), diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 3276f516a52a1..0b7ffc4af4590 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -109,7 +109,16 @@ pub enum DefKind { Use, /// An `extern` block. ForeignMod, - /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]` + /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`. + /// + /// Not all anon-consts are actually still relevant in the HIR. We lower + /// trivial const-arguments directly to `hir::ConstArgKind::Path`, at which + /// point the definition for the anon-const ends up unused and incomplete. + /// + /// We do not provide any a `Span` for the definition and pretty much all other + /// queries also ICE when using this `DefId`. Given that the `DefId` of such + /// constants should only be reachable by iterating all definitions of a + /// given crate, you should not have to worry about this. AnonConst, /// An inline constant, e.g. `const { 1 + 2 }` InlineConst, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 554097bf11515..12dec75e65cf0 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1,7 +1,7 @@ use std::fmt; use rustc_abi::ExternAbi; -use rustc_ast::util::parser::ExprPrecedence; +use rustc_ast::util::parser::{AssocOp, PREC_CLOSURE, PREC_JUMP, PREC_PREFIX, PREC_UNAMBIGUOUS}; use rustc_ast::{ self as ast, Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, LitKind, TraitObjectSyntax, UintTy, @@ -261,8 +261,6 @@ pub struct ConstArg<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, pub kind: ConstArgKind<'hir>, - /// Indicates whether this comes from a `~const` desugaring. - pub is_desugared_from_effects: bool, } impl<'hir> ConstArg<'hir> { @@ -462,14 +460,7 @@ impl<'hir> GenericArgs<'hir> { /// This function returns the number of type and const generic params. /// It should only be used for diagnostics. pub fn num_generic_params(&self) -> usize { - self.args - .iter() - .filter(|arg| match arg { - GenericArg::Lifetime(_) - | GenericArg::Const(ConstArg { is_desugared_from_effects: true, .. }) => false, - _ => true, - }) - .count() + self.args.iter().filter(|arg| !matches!(arg, GenericArg::Lifetime(_))).count() } /// The span encompassing the arguments and constraints[^1] inside the surrounding brackets. @@ -690,8 +681,8 @@ impl<'hir> Generics<'hir> { if self.has_where_clause_predicates { self.predicates .iter() - .rfind(|&p| p.in_where_clause()) - .map_or(end, |p| p.span()) + .rfind(|&p| p.kind.in_where_clause()) + .map_or(end, |p| p.span) .shrink_to_hi() .to(end) } else { @@ -714,8 +705,10 @@ impl<'hir> Generics<'hir> { &self, param_def_id: LocalDefId, ) -> impl Iterator> { - self.predicates.iter().filter_map(move |pred| match pred { - WherePredicate::BoundPredicate(bp) if bp.is_param_bound(param_def_id.to_def_id()) => { + self.predicates.iter().filter_map(move |pred| match pred.kind { + WherePredicateKind::BoundPredicate(bp) + if bp.is_param_bound(param_def_id.to_def_id()) => + { Some(bp) } _ => None, @@ -726,8 +719,8 @@ impl<'hir> Generics<'hir> { &self, param_def_id: LocalDefId, ) -> impl Iterator> { - self.predicates.iter().filter_map(move |pred| match pred { - WherePredicate::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp), + self.predicates.iter().filter_map(move |pred| match pred.kind { + WherePredicateKind::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp), _ => None, }) } @@ -779,9 +772,9 @@ impl<'hir> Generics<'hir> { pub fn span_for_predicate_removal(&self, pos: usize) -> Span { let predicate = &self.predicates[pos]; - let span = predicate.span(); + let span = predicate.span; - if !predicate.in_where_clause() { + if !predicate.kind.in_where_clause() { // // ^^^^^^^^ return span; @@ -790,19 +783,19 @@ impl<'hir> Generics<'hir> { // We need to find out which comma to remove. if pos < self.predicates.len() - 1 { let next_pred = &self.predicates[pos + 1]; - if next_pred.in_where_clause() { + if next_pred.kind.in_where_clause() { // where T: ?Sized, Foo: Bar, // ^^^^^^^^^^^ - return span.until(next_pred.span()); + return span.until(next_pred.span); } } if pos > 0 { let prev_pred = &self.predicates[pos - 1]; - if prev_pred.in_where_clause() { + if prev_pred.kind.in_where_clause() { // where Foo: Bar, T: ?Sized, // ^^^^^^^^^^^ - return prev_pred.span().shrink_to_hi().to(span); + return prev_pred.span.shrink_to_hi().to(span); } } @@ -814,7 +807,7 @@ impl<'hir> Generics<'hir> { pub fn span_for_bound_removal(&self, predicate_pos: usize, bound_pos: usize) -> Span { let predicate = &self.predicates[predicate_pos]; - let bounds = predicate.bounds(); + let bounds = predicate.kind.bounds(); if bounds.len() == 1 { return self.span_for_predicate_removal(predicate_pos); @@ -841,7 +834,15 @@ impl<'hir> Generics<'hir> { /// A single predicate in a where-clause. #[derive(Debug, Clone, Copy, HashStable_Generic)] -pub enum WherePredicate<'hir> { +pub struct WherePredicate<'hir> { + pub hir_id: HirId, + pub span: Span, + pub kind: &'hir WherePredicateKind<'hir>, +} + +/// The kind of a single predicate in a where-clause. +#[derive(Debug, Clone, Copy, HashStable_Generic)] +pub enum WherePredicateKind<'hir> { /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). BoundPredicate(WhereBoundPredicate<'hir>), /// A lifetime predicate (e.g., `'a: 'b + 'c`). @@ -850,28 +851,20 @@ pub enum WherePredicate<'hir> { EqPredicate(WhereEqPredicate<'hir>), } -impl<'hir> WherePredicate<'hir> { - pub fn span(&self) -> Span { - match self { - WherePredicate::BoundPredicate(p) => p.span, - WherePredicate::RegionPredicate(p) => p.span, - WherePredicate::EqPredicate(p) => p.span, - } - } - +impl<'hir> WherePredicateKind<'hir> { pub fn in_where_clause(&self) -> bool { match self { - WherePredicate::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause, - WherePredicate::RegionPredicate(p) => p.in_where_clause, - WherePredicate::EqPredicate(_) => false, + WherePredicateKind::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause, + WherePredicateKind::RegionPredicate(p) => p.in_where_clause, + WherePredicateKind::EqPredicate(_) => false, } } pub fn bounds(&self) -> GenericBounds<'hir> { match self { - WherePredicate::BoundPredicate(p) => p.bounds, - WherePredicate::RegionPredicate(p) => p.bounds, - WherePredicate::EqPredicate(_) => &[], + WherePredicateKind::BoundPredicate(p) => p.bounds, + WherePredicateKind::RegionPredicate(p) => p.bounds, + WherePredicateKind::EqPredicate(_) => &[], } } } @@ -886,8 +879,6 @@ pub enum PredicateOrigin { /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct WhereBoundPredicate<'hir> { - pub hir_id: HirId, - pub span: Span, /// Origin of the predicate. pub origin: PredicateOrigin, /// Any generics from a `for` binding. @@ -908,7 +899,6 @@ impl<'hir> WhereBoundPredicate<'hir> { /// A lifetime predicate (e.g., `'a: 'b + 'c`). #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct WhereRegionPredicate<'hir> { - pub span: Span, pub in_where_clause: bool, pub lifetime: &'hir Lifetime, pub bounds: GenericBounds<'hir>, @@ -924,7 +914,6 @@ impl<'hir> WhereRegionPredicate<'hir> { /// An equality predicate (e.g., `T = int`); currently unsupported. #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct WhereEqPredicate<'hir> { - pub span: Span, pub lhs_ty: &'hir Ty<'hir>, pub rhs_ty: &'hir Ty<'hir>, } @@ -1719,41 +1708,54 @@ pub struct Expr<'hir> { } impl Expr<'_> { - pub fn precedence(&self) -> ExprPrecedence { + pub fn precedence(&self) -> i8 { match self.kind { - ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock, - ExprKind::Array(_) => ExprPrecedence::Array, - ExprKind::Call(..) => ExprPrecedence::Call, - ExprKind::MethodCall(..) => ExprPrecedence::MethodCall, - ExprKind::Tup(_) => ExprPrecedence::Tup, - ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node), - ExprKind::Unary(..) => ExprPrecedence::Unary, - ExprKind::Lit(_) => ExprPrecedence::Lit, - ExprKind::Cast(..) => ExprPrecedence::Cast, + ExprKind::Closure { .. } => PREC_CLOSURE, + + ExprKind::Break(..) + | ExprKind::Continue(..) + | ExprKind::Ret(..) + | ExprKind::Yield(..) + | ExprKind::Become(..) => PREC_JUMP, + + // Binop-like expr kinds, handled by `AssocOp`. + ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence() as i8, + ExprKind::Cast(..) => AssocOp::As.precedence() as i8, + + ExprKind::Assign(..) | + ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8, + + // Unary, prefix + ExprKind::AddrOf(..) + // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`. + // However, this is not exactly right. When `let _ = a` is the LHS of a binop we + // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b` + // but we need to print `(let _ = a) < b` as-is with parens. + | ExprKind::Let(..) + | ExprKind::Unary(..) => PREC_PREFIX, + + // Never need parens + ExprKind::Array(_) + | ExprKind::Block(..) + | ExprKind::Call(..) + | ExprKind::ConstBlock(_) + | ExprKind::Field(..) + | ExprKind::If(..) + | ExprKind::Index(..) + | ExprKind::InlineAsm(..) + | ExprKind::Lit(_) + | ExprKind::Loop(..) + | ExprKind::Match(..) + | ExprKind::MethodCall(..) + | ExprKind::OffsetOf(..) + | ExprKind::Path(..) + | ExprKind::Repeat(..) + | ExprKind::Struct(..) + | ExprKind::Tup(_) + | ExprKind::Type(..) + | ExprKind::Err(_) => PREC_UNAMBIGUOUS, + ExprKind::DropTemps(ref expr, ..) => expr.precedence(), - ExprKind::If(..) => ExprPrecedence::If, - ExprKind::Let(..) => ExprPrecedence::Let, - ExprKind::Loop(..) => ExprPrecedence::Loop, - ExprKind::Match(..) => ExprPrecedence::Match, - ExprKind::Closure { .. } => ExprPrecedence::Closure, - ExprKind::Block(..) => ExprPrecedence::Block, - ExprKind::Assign(..) => ExprPrecedence::Assign, - ExprKind::AssignOp(..) => ExprPrecedence::AssignOp, - ExprKind::Field(..) => ExprPrecedence::Field, - ExprKind::Index(..) => ExprPrecedence::Index, - ExprKind::Path(..) => ExprPrecedence::Path, - ExprKind::AddrOf(..) => ExprPrecedence::AddrOf, - ExprKind::Break(..) => ExprPrecedence::Break, - ExprKind::Continue(..) => ExprPrecedence::Continue, - ExprKind::Ret(..) => ExprPrecedence::Ret, - ExprKind::Become(..) => ExprPrecedence::Become, - ExprKind::Struct(..) => ExprPrecedence::Struct, - ExprKind::Repeat(..) => ExprPrecedence::Repeat, - ExprKind::Yield(..) => ExprPrecedence::Yield, - ExprKind::Type(..) | ExprKind::InlineAsm(..) | ExprKind::OffsetOf(..) => { - ExprPrecedence::Mac - } - ExprKind::Err(_) => ExprPrecedence::Err, } } @@ -3177,6 +3179,7 @@ pub struct FieldDef<'hir> { pub hir_id: HirId, pub def_id: LocalDefId, pub ty: &'hir Ty<'hir>, + pub safety: Safety, } impl FieldDef<'_> { @@ -3797,7 +3800,7 @@ pub enum Node<'hir> { GenericParam(&'hir GenericParam<'hir>), Crate(&'hir Mod<'hir>), Infer(&'hir InferArg), - WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>), + WherePredicate(&'hir WherePredicate<'hir>), // FIXME: Merge into `Node::Infer`. ArrayLenInfer(&'hir InferArg), PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg), @@ -3852,7 +3855,7 @@ impl<'hir> Node<'hir> { | Node::TraitRef(..) | Node::OpaqueTy(..) | Node::Infer(..) - | Node::WhereBoundPredicate(..) + | Node::WherePredicate(..) | Node::ArrayLenInfer(..) | Node::Synthetic | Node::Err(..) => None, diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index a453af3f7fd3d..faaea41047fc7 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -961,30 +961,28 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>( visitor: &mut V, predicate: &'v WherePredicate<'v>, ) -> V::Result { - match *predicate { - WherePredicate::BoundPredicate(WhereBoundPredicate { - hir_id, + let &WherePredicate { hir_id, kind, span: _ } = predicate; + try_visit!(visitor.visit_id(hir_id)); + match *kind { + WherePredicateKind::BoundPredicate(WhereBoundPredicate { ref bounded_ty, bounds, bound_generic_params, origin: _, - span: _, }) => { - try_visit!(visitor.visit_id(hir_id)); try_visit!(visitor.visit_ty(bounded_ty)); walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_generic_param, bound_generic_params); } - WherePredicate::RegionPredicate(WhereRegionPredicate { + WherePredicateKind::RegionPredicate(WhereRegionPredicate { ref lifetime, bounds, - span: _, in_where_clause: _, }) => { try_visit!(visitor.visit_lifetime(lifetime)); walk_list!(visitor, visit_param_bound, bounds); } - WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, span: _ }) => { + WherePredicateKind::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty }) => { try_visit!(visitor.visit_ty(lhs_ty)); try_visit!(visitor.visit_ty(rhs_ty)); } diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 64a30e633cf9d..cb658111392c3 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -253,6 +253,13 @@ hir_analysis_invalid_union_field = hir_analysis_invalid_union_field_sugg = wrap the field type in `ManuallyDrop<...>` +hir_analysis_invalid_unsafe_field = + field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe + .note = unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>` + +hir_analysis_invalid_unsafe_field_sugg = + wrap the field type in `ManuallyDrop<...>` + hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl .label = const parameter declared here @@ -424,6 +431,9 @@ hir_analysis_recursive_generic_parameter = {$param_def_kind} `{$param_name}` is hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}` .note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}` +hir_analysis_register_type_unstable = + type `{$ty}` cannot be used with this register class in stable + hir_analysis_requires_note = the `{$trait_name}` impl for `{$ty}` requires that `{$error_predicate}` hir_analysis_return_type_notation_equality_bound = @@ -580,7 +590,7 @@ hir_analysis_value_of_associated_struct_already_specified = .label = re-bound here .previous_bound_label = `{$item_name}` bound here first -hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like {$conventions} +hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi` .label = C-variadic function must have a compatible calling convention hir_analysis_variances_of = {$variances} diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index cf3f3003bf514..192dc1b4d2299 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -6,7 +6,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::MultiSpan; use rustc_errors::codes::*; use rustc_hir::def::{CtorKind, DefKind}; -use rustc_hir::{Node, intravisit}; +use rustc_hir::{Node, Safety, intravisit}; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, ObligationCauseCode}; use rustc_lint_defs::builtin::{ @@ -17,7 +17,7 @@ use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::middle::stability::EvalResult; use rustc_middle::span_bug; use rustc_middle::ty::error::TypeErrorToStringExt; -use rustc_middle::ty::fold::BottomUpFolder; +use rustc_middle::ty::fold::{BottomUpFolder, fold_regions}; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt}; use rustc_middle::ty::{ @@ -70,6 +70,7 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) { check_transparent(tcx, def); check_packed(tcx, span, def); + check_unsafe_fields(tcx, def_id); } fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) { @@ -81,38 +82,45 @@ fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) { check_packed(tcx, span, def); } +fn allowed_union_or_unsafe_field<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + span: Span, +) -> bool { + // We don't just accept all !needs_drop fields, due to semver concerns. + let allowed = match ty.kind() { + ty::Ref(..) => true, // references never drop (even mutable refs, which are non-Copy and hence fail the later check) + ty::Tuple(tys) => { + // allow tuples of allowed types + tys.iter().all(|ty| allowed_union_or_unsafe_field(tcx, ty, typing_env, span)) + } + ty::Array(elem, _len) => { + // Like `Copy`, we do *not* special-case length 0. + allowed_union_or_unsafe_field(tcx, *elem, typing_env, span) + } + _ => { + // Fallback case: allow `ManuallyDrop` and things that are `Copy`, + // also no need to report an error if the type is unresolved. + ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop()) + || ty.is_copy_modulo_regions(tcx, typing_env) + || ty.references_error() + } + }; + if allowed && ty.needs_drop(tcx, typing_env) { + // This should never happen. But we can get here e.g. in case of name resolution errors. + tcx.dcx() + .span_delayed_bug(span, "we should never accept maybe-dropping union or unsafe fields"); + } + allowed +} + /// Check that the fields of the `union` do not need dropping. fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool { let item_type = tcx.type_of(item_def_id).instantiate_identity(); if let ty::Adt(def, args) = item_type.kind() { assert!(def.is_union()); - fn allowed_union_field<'tcx>( - ty: Ty<'tcx>, - tcx: TyCtxt<'tcx>, - typing_env: ty::TypingEnv<'tcx>, - ) -> bool { - // We don't just accept all !needs_drop fields, due to semver concerns. - match ty.kind() { - ty::Ref(..) => true, // references never drop (even mutable refs, which are non-Copy and hence fail the later check) - ty::Tuple(tys) => { - // allow tuples of allowed types - tys.iter().all(|ty| allowed_union_field(ty, tcx, typing_env)) - } - ty::Array(elem, _len) => { - // Like `Copy`, we do *not* special-case length 0. - allowed_union_field(*elem, tcx, typing_env) - } - _ => { - // Fallback case: allow `ManuallyDrop` and things that are `Copy`, - // also no need to report an error if the type is unresolved. - ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop()) - || ty.is_copy_modulo_regions(tcx, typing_env) - || ty.references_error() - } - } - } - let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id); for field in &def.non_enum_variant().fields { let Ok(field_ty) = tcx.try_normalize_erasing_regions(typing_env, field.ty(tcx, args)) @@ -121,7 +129,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b continue; }; - if !allowed_union_field(field_ty, tcx, typing_env) { + if !allowed_union_or_unsafe_field(tcx, field_ty, typing_env, span) { let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) { // We are currently checking the type this field came from, so it must be local. Some(Node::Field(field)) => (field.span, field.ty.span), @@ -136,10 +144,6 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b note: (), }); return false; - } else if field_ty.needs_drop(tcx, typing_env) { - // This should never happen. But we can get here e.g. in case of name resolution errors. - tcx.dcx() - .span_delayed_bug(span, "we should never accept maybe-dropping union fields"); } } } else { @@ -148,6 +152,41 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b true } +/// Check that the unsafe fields do not need dropping. +fn check_unsafe_fields(tcx: TyCtxt<'_>, item_def_id: LocalDefId) { + let span = tcx.def_span(item_def_id); + let item_type = tcx.type_of(item_def_id).instantiate_identity(); + let ty::Adt(def, args) = item_type.kind() else { + span_bug!(span, "structs/enums must be ty::Adt, but got {:?}", item_type.kind()); + }; + let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id); + for field in def.all_fields() { + if field.safety != Safety::Unsafe { + continue; + } + let Ok(field_ty) = tcx.try_normalize_erasing_regions(typing_env, field.ty(tcx, args)) + else { + tcx.dcx().span_delayed_bug(span, "could not normalize field type"); + continue; + }; + + if !allowed_union_or_unsafe_field(tcx, field_ty, typing_env, span) { + let hir::Node::Field(field) = tcx.hir_node_by_def_id(field.did.expect_local()) else { + unreachable!("field has to correspond to hir field") + }; + let ty_span = field.ty.span; + tcx.dcx().emit_err(errors::InvalidUnsafeField { + field_span: field.span, + sugg: errors::InvalidUnsafeFieldSuggestion { + lo: ty_span.shrink_to_lo(), + hi: ty_span.shrink_to_hi(), + }, + note: (), + }); + } + } +} + /// Check that a `static` is inhabited. fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { // Make sure statics are inhabited. @@ -283,8 +322,12 @@ fn check_opaque_meets_bounds<'tcx>( }; let param_env = tcx.param_env(defining_use_anchor); - // FIXME(#132279): This should eventually use the already defined hidden types. - let infcx = tcx.infer_ctxt().build(TypingMode::analysis_in_body(tcx, defining_use_anchor)); + // FIXME(#132279): Once `PostBorrowckAnalysis` is supported in the old solver, this branch should be removed. + let infcx = tcx.infer_ctxt().build(if tcx.next_trait_solver_globally() { + TypingMode::post_borrowck_analysis(tcx, defining_use_anchor) + } else { + TypingMode::analysis_in_body(tcx, defining_use_anchor) + }); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let args = match origin { @@ -307,7 +350,7 @@ fn check_opaque_meets_bounds<'tcx>( // FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it // here rather than using ReErased. let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args); - let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() { + let hidden_ty = fold_regions(tcx, hidden_ty, |re, _dbi| match re.kind() { ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)), _ => re, }); @@ -378,7 +421,11 @@ fn check_opaque_meets_bounds<'tcx>( let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?; - if let hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } = origin { + if infcx.next_trait_solver() { + Ok(()) + } else if let hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } = + origin + { // HACK: this should also fall through to the hidden type check below, but the original // implementation had a bug where equivalent lifetimes are not identical. This caused us // to reject existing stable code that is otherwise completely fine. The real fix is to @@ -1464,6 +1511,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) { detect_discriminant_duplicate(tcx, def); check_transparent(tcx, def); + check_unsafe_fields(tcx, def_id); } /// Part of enum check. Given the discriminants of an enum, errors if two or more discriminants are equal diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index bd0b0ceb92d5d..06dee6bda5409 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -26,7 +26,7 @@ use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::regions::InferCtxtRegionExt; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::{ - self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, Reveal, + self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, }; use tracing::{debug, instrument}; @@ -223,7 +223,7 @@ fn compare_method_predicate_entailment<'tcx>( } let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id); - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing); + let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); debug!(caller_bounds=?param_env.caller_bounds()); @@ -508,7 +508,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( .into_iter() .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args)) .map(|(clause, _)| clause); - let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing); + let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds)); let param_env = traits::normalize_param_env_or_error( tcx, param_env, @@ -523,8 +523,9 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( let impl_sig = ocx.normalize( &misc_cause, param_env, - tcx.liberate_late_bound_regions( - impl_m.def_id, + infcx.instantiate_binder_with_fresh_vars( + return_span, + infer::HigherRankedType, tcx.fn_sig(impl_m.def_id).instantiate_identity(), ), ); @@ -536,10 +537,9 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( // them with inference variables. // We will use these inference variables to collect the hidden types of RPITITs. let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_def_id); - let unnormalized_trait_sig = infcx - .instantiate_binder_with_fresh_vars( - return_span, - infer::HigherRankedType, + let unnormalized_trait_sig = tcx + .liberate_late_bound_regions( + impl_m.def_id, tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args), ) .fold_with(&mut collector); @@ -702,8 +702,8 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( let mut remapped_types = DefIdMap::default(); for (def_id, (ty, args)) in collected_types { - match infcx.fully_resolve((ty, args)) { - Ok((ty, args)) => { + match infcx.fully_resolve(ty) { + Ok(ty) => { // `ty` contains free regions that we created earlier while liberating the // trait fn signature. However, projection normalization expects `ty` to // contains `def_id`'s early-bound regions. @@ -883,33 +883,27 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> { self.tcx } - fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { - if let ty::Alias(ty::Opaque, ty::AliasTy { args, def_id, .. }) = *t.kind() { - let mut mapped_args = Vec::with_capacity(args.len()); - for (arg, v) in std::iter::zip(args, self.tcx.variances_of(def_id)) { - mapped_args.push(match (arg.unpack(), v) { - // Skip uncaptured opaque args - (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg, - _ => arg.try_fold_with(self)?, - }); - } - Ok(Ty::new_opaque(self.tcx, def_id, self.tcx.mk_args(&mapped_args))) - } else { - t.try_super_fold_with(self) - } - } - fn try_fold_region( &mut self, region: ty::Region<'tcx>, ) -> Result, Self::Error> { match region.kind() { - // Remap late-bound regions from the function. + // Never remap bound regions or `'static` + ty::ReBound(..) | ty::ReStatic | ty::ReError(_) => return Ok(region), + // We always remap liberated late-bound regions from the function. ty::ReLateParam(_) => {} // Remap early-bound regions as long as they don't come from the `impl` itself, // in which case we don't really need to renumber them. - ty::ReEarlyParam(ebr) if ebr.index as usize >= self.num_impl_args => {} - _ => return Ok(region), + ty::ReEarlyParam(ebr) => { + if ebr.index as usize >= self.num_impl_args { + // Remap + } else { + return Ok(region); + } + } + ty::ReVar(_) | ty::RePlaceholder(_) | ty::ReErased => unreachable!( + "should not have leaked vars or placeholders into hidden type of RPITIT" + ), } let e = if let Some(id_region) = self.map.get(®ion) { @@ -1100,7 +1094,7 @@ fn check_region_bounds_on_impl_item<'tcx>( // FIXME: we could potentially look at the impl's bounds to not point at bounds that // *are* present in the impl. for p in trait_generics.predicates { - if let hir::WherePredicate::BoundPredicate(pred) = p { + if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind { for b in pred.bounds { if let hir::GenericBound::Outlives(lt) = b { bounds_span.push(lt.ident.span); @@ -1113,7 +1107,7 @@ fn check_region_bounds_on_impl_item<'tcx>( { let mut impl_bounds = 0; for p in impl_generics.predicates { - if let hir::WherePredicate::BoundPredicate(pred) = p { + if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind { for b in pred.bounds { if let hir::GenericBound::Outlives(_) = b { impl_bounds += 1; @@ -1793,7 +1787,7 @@ fn compare_const_predicate_entailment<'tcx>( .map(|(predicate, _)| predicate), ); - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing); + let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); let param_env = traits::normalize_param_env_or_error( tcx, param_env, @@ -1946,7 +1940,7 @@ fn compare_type_predicate_entailment<'tcx>( ); } - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing); + let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); debug!(caller_bounds=?param_env.caller_bounds()); @@ -2306,7 +2300,7 @@ fn param_env_with_gat_bounds<'tcx>( }; } - ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing) + ty::ParamEnv::new(tcx.mk_clauses(&predicates)) } /// Manually check here that `async fn foo()` wasn't matched against `fn foo()`, diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index 25ba52b4d7bf7..67cbcc1566abb 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -6,7 +6,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE}; use rustc_middle::span_bug; -use rustc_middle::traits::{ObligationCause, Reveal}; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, @@ -134,7 +134,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( .into_iter() .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_m_to_impl_m_args)) .map(|(clause, _)| clause); - let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing); + let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds)); let param_env = normalize_param_env_or_error(tcx, param_env, ObligationCause::dummy()); let ref infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index dfddf93a5c273..b96469f503c8b 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -7,12 +7,14 @@ use rustc_hir::{self as hir, LangItem}; use rustc_middle::bug; use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_session::lint; -use rustc_span::Symbol; use rustc_span::def_id::LocalDefId; +use rustc_span::{Symbol, sym}; use rustc_target::asm::{ InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType, ModifierInfo, }; +use crate::errors::RegisterTypeUnstable; + pub struct InlineAsmCtxt<'a, 'tcx> { tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, @@ -218,17 +220,29 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // Check the type against the list of types supported by the selected // register class. let asm_arch = self.tcx.sess.asm_arch.unwrap(); + let allow_experimental_reg = self.tcx.features().asm_experimental_reg(); let reg_class = reg.reg_class(); - let supported_tys = reg_class.supported_types(asm_arch); + let supported_tys = reg_class.supported_types(asm_arch, allow_experimental_reg); let Some((_, feature)) = supported_tys.iter().find(|&&(t, _)| t == asm_ty) else { - let msg = format!("type `{ty}` cannot be used with this register class"); - let mut err = self.tcx.dcx().struct_span_err(expr.span, msg); - let supported_tys: Vec<_> = supported_tys.iter().map(|(t, _)| t.to_string()).collect(); - err.note(format!( - "register class `{}` supports these types: {}", - reg_class.name(), - supported_tys.join(", "), - )); + let mut err = if !allow_experimental_reg + && reg_class.supported_types(asm_arch, true).iter().any(|&(t, _)| t == asm_ty) + { + self.tcx.sess.create_feature_err( + RegisterTypeUnstable { span: expr.span, ty }, + sym::asm_experimental_reg, + ) + } else { + let msg = format!("type `{ty}` cannot be used with this register class"); + let mut err = self.tcx.dcx().struct_span_err(expr.span, msg); + let supported_tys: Vec<_> = + supported_tys.iter().map(|(t, _)| t.to_string()).collect(); + err.note(format!( + "register class `{}` supports these types: {}", + reg_class.name(), + supported_tys.join(", "), + )); + err + }; if let Some(suggest) = reg_class.suggest_class(asm_arch, asm_ty) { err.help(format!("consider using the `{}` register class instead", suggest.name())); } @@ -313,6 +327,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { self.tcx.dcx().delayed_bug("target architecture does not support asm"); return; }; + let allow_experimental_reg = self.tcx.features().asm_experimental_reg(); for (idx, (op, op_sp)) in asm.operands.iter().enumerate() { // Validate register classes against currently enabled target // features. We check that at least one type is available for @@ -352,7 +367,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if let InlineAsmRegClass::Err = reg_class { continue; } - for &(_, feature) in reg_class.supported_types(asm_arch) { + for &(_, feature) in reg_class.supported_types(asm_arch, allow_experimental_reg) + { match feature { Some(feature) => { if target_features.contains(&feature) { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 20bc34b8c793a..8fa797db24661 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -604,7 +604,7 @@ fn augment_param_env<'tcx>( ); // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this // i.e. traits::normalize_param_env_or_error - ty::ParamEnv::new(bounds, param_env.reveal()) + ty::ParamEnv::new(bounds) } /// We use the following trait as an example throughout this function. @@ -1921,8 +1921,8 @@ fn check_variances_for_type_defn<'tcx>( hir_generics .predicates .iter() - .filter_map(|predicate| match predicate { - hir::WherePredicate::BoundPredicate(predicate) => { + .filter_map(|predicate| match predicate.kind { + hir::WherePredicateKind::BoundPredicate(predicate) => { match icx.lower_ty(predicate.bounded_ty).kind() { ty::Param(data) => Some(Parameter(data.index)), _ => None, @@ -2202,8 +2202,8 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { span = predicates .iter() // There seems to be no better way to find out which predicate we are in - .find(|pred| pred.span().contains(obligation_span)) - .map(|pred| pred.span()) + .find(|pred| pred.span.contains(obligation_span)) + .map(|pred| pred.span) .unwrap_or(obligation_span); } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 73b73afb0a54b..cf062e82cb60a 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -34,6 +34,7 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::hir::nested_filter; use rustc_middle::query::Providers; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypingMode}; use rustc_middle::{bug, span_bug}; @@ -1040,6 +1041,7 @@ fn lower_variant( did: f.def_id.to_def_id(), name: f.ident.name, vis: tcx.visibility(f.def_id), + safety: f.safety, }) .collect(); let recovered = match def { @@ -1414,7 +1416,7 @@ fn infer_return_ty_for_fn_sig<'tcx>( GenericParamKind::Lifetime { .. } => true, _ => false, }); - let fn_sig = tcx.fold_regions(fn_sig, |r, _| match *r { + let fn_sig = fold_regions(tcx, fn_sig, |r, _| match *r { ty::ReErased => { if has_region_params { ty::Region::new_error_with_message( diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index b5dee5bd02112..bfee5d33598ad 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -238,11 +238,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen trace!(?predicates); // Add inline `` bounds and bounds in the where clause. for predicate in hir_generics.predicates { - match predicate { - hir::WherePredicate::BoundPredicate(bound_pred) => { + match predicate.kind { + hir::WherePredicateKind::BoundPredicate(bound_pred) => { let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty); - let bound_vars = tcx.late_bound_vars(bound_pred.hir_id); + let bound_vars = tcx.late_bound_vars(predicate.hir_id); // Keep the type around in a dummy predicate, in case of no bounds. // That way, `where Ty:` is not a complete noop (see #53696) and `Ty` // is still checked for WF. @@ -275,7 +275,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen predicates.extend(bounds.clauses()); } - hir::WherePredicate::RegionPredicate(region_pred) => { + hir::WherePredicateKind::RegionPredicate(region_pred) => { let r1 = icx .lowerer() .lower_lifetime(region_pred.lifetime, RegionInferReason::RegionPredicate); @@ -298,7 +298,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen })) } - hir::WherePredicate::EqPredicate(..) => { + hir::WherePredicateKind::EqPredicate(..) => { // FIXME(#20041) } } @@ -881,7 +881,8 @@ impl<'tcx> ItemCtxt<'tcx> { let mut bounds = Bounds::default(); for predicate in hir_generics.predicates { - let hir::WherePredicate::BoundPredicate(predicate) = predicate else { + let hir_id = predicate.hir_id; + let hir::WherePredicateKind::BoundPredicate(predicate) = predicate.kind else { continue; }; @@ -901,7 +902,7 @@ impl<'tcx> ItemCtxt<'tcx> { let bound_ty = self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty); - let bound_vars = self.tcx.late_bound_vars(predicate.hir_id); + let bound_vars = self.tcx.late_bound_vars(hir_id); self.lowerer().lower_bounds( bound_ty, predicate.bounds, @@ -974,10 +975,10 @@ pub(super) fn const_conditions<'tcx>( let mut bounds = Bounds::default(); for pred in generics.predicates { - match pred { - hir::WherePredicate::BoundPredicate(bound_pred) => { + match pred.kind { + hir::WherePredicateKind::BoundPredicate(bound_pred) => { let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty); - let bound_vars = tcx.late_bound_vars(bound_pred.hir_id); + let bound_vars = tcx.late_bound_vars(pred.hir_id); icx.lowerer().lower_bounds( ty, bound_pred.bounds.iter(), 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 b4b3ef31f97a1..74729ebe4882f 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -936,9 +936,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } fn visit_where_predicate(&mut self, predicate: &'tcx hir::WherePredicate<'tcx>) { - match predicate { - &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { - hir_id, + let hir_id = predicate.hir_id; + match predicate.kind { + &hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate { bounded_ty, bounds, bound_generic_params, @@ -979,7 +979,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { walk_list!(this, visit_param_bound, bounds); }) } - &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { + &hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate { lifetime, bounds, .. @@ -987,7 +987,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { self.visit_lifetime(lifetime); walk_list!(self, visit_param_bound, bounds); } - &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => { + &hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate { + lhs_ty, rhs_ty, .. + }) => { self.visit_ty(lhs_ty); self.visit_ty(rhs_ty); } @@ -2073,7 +2075,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // bounds since we'll be emitting a hard error in HIR lowering, so this // is purely speculative. let one_bound = generics.predicates.iter().find_map(|predicate| { - let hir::WherePredicate::BoundPredicate(predicate) = predicate else { + let hir::WherePredicateKind::BoundPredicate(predicate) = predicate.kind + else { return None; }; let hir::TyKind::Path(hir::QPath::Resolved(None, bounded_path)) = diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 816761fd00fa1..18fb5bfd912f6 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -5,6 +5,7 @@ use rustc_hir as hir; use rustc_hir::HirId; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::query::plumbing::CyclePlaceholder; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, Article, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; @@ -113,7 +114,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { // so no need for ConstArg. Node::Ty(&hir::Ty { kind: TyKind::Typeof(ref e), span, .. }) if e.hir_id == hir_id => { let ty = tcx.typeck(def_id).node_type(tcx.local_def_id_to_hir_id(def_id)); - let ty = tcx.fold_regions(ty, |r, _| { + let ty = fold_regions(tcx, ty, |r, _| { if r.is_erased() { ty::Region::new_error_misc(tcx) } else { r } }); let (ty, opt_sugg) = if let Some(ty) = ty.make_suggestable(tcx, false, None) { diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 07d3273b09c77..51115b11e86b8 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -672,11 +672,10 @@ pub(crate) struct MainFunctionGenericParameters { #[derive(Diagnostic)] #[diag(hir_analysis_variadic_function_compatible_convention, code = E0045)] -pub(crate) struct VariadicFunctionCompatibleConvention<'a> { +pub(crate) struct VariadicFunctionCompatibleConvention { #[primary_span] #[label] pub span: Span, - pub conventions: &'a str, } #[derive(Diagnostic)] @@ -734,6 +733,17 @@ pub(crate) struct InvalidUnionField { pub note: (), } +#[derive(Diagnostic)] +#[diag(hir_analysis_invalid_unsafe_field, code = E0740)] +pub(crate) struct InvalidUnsafeField { + #[primary_span] + pub field_span: Span, + #[subdiagnostic] + pub sugg: InvalidUnsafeFieldSuggestion, + #[note] + pub note: (), +} + #[derive(Diagnostic)] #[diag(hir_analysis_return_type_notation_on_non_rpitit)] pub(crate) struct ReturnTypeNotationOnNonRpitit<'tcx> { @@ -755,6 +765,18 @@ pub(crate) struct InvalidUnionFieldSuggestion { pub hi: Span, } +#[derive(Subdiagnostic)] +#[multipart_suggestion( + hir_analysis_invalid_unsafe_field_sugg, + applicability = "machine-applicable" +)] +pub(crate) struct InvalidUnsafeFieldSuggestion { + #[suggestion_part(code = "std::mem::ManuallyDrop<")] + pub lo: Span, + #[suggestion_part(code = ">")] + pub hi: Span, +} + #[derive(Diagnostic)] #[diag(hir_analysis_return_type_notation_equality_bound)] pub(crate) struct ReturnTypeNotationEqualityBound { @@ -1685,3 +1707,11 @@ pub(crate) struct CmseEntryGeneric { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_register_type_unstable)] +pub(crate) struct RegisterTypeUnstable<'a> { + #[primary_span] + pub span: Span, + pub ty: Ty<'a>, +} diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 6ebe1cedcafdc..9d60759ae4873 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -69,7 +69,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { search_bounds(hir_bounds); if let Some((self_ty, where_clause)) = self_ty_where_predicates { for clause in where_clause { - if let hir::WherePredicate::BoundPredicate(pred) = clause + if let hir::WherePredicateKind::BoundPredicate(pred) = clause.kind && pred.is_param_bound(self_ty.to_def_id()) { search_bounds(pred.bounds); 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 5e27ace4cbe4a..cab04ee09874b 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 @@ -8,7 +8,8 @@ use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS; use rustc_middle::span_bug; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::{ - self, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable, Upcast, + self, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable, + TypeVisitableExt, Upcast, }; use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility; @@ -92,11 +93,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id())); + + // We don't support >1 principal if regular_traits.len() > 1 { - let _ = self.report_trait_object_addition_traits_error(®ular_traits); - } else if regular_traits.is_empty() && auto_traits.is_empty() { - let reported = self.report_trait_object_with_no_traits_error(span, &trait_bounds); - return Ty::new_error(tcx, reported); + let guar = self.report_trait_object_addition_traits_error(®ular_traits); + return Ty::new_error(tcx, guar); + } + // We don't support empty trait objects. + if regular_traits.is_empty() && auto_traits.is_empty() { + let guar = self.report_trait_object_with_no_traits_error(span, &trait_bounds); + return Ty::new_error(tcx, guar); + } + // Don't create a dyn trait if we have errors in the principal. + if let Err(guar) = trait_bounds.error_reported() { + return Ty::new_error(tcx, guar); } // Check that there are no gross dyn-compatibility violations; @@ -126,7 +136,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { for (base_trait_ref, original_span) in regular_traits_refs_spans { let base_pred: ty::Predicate<'tcx> = base_trait_ref.upcast(tcx); - for ClauseWithSupertraitSpan { pred, original_span, supertrait_span } in + for ClauseWithSupertraitSpan { pred, supertrait_span } in traits::elaborate(tcx, [ClauseWithSupertraitSpan::new(base_pred, original_span)]) .filter_only_self() { @@ -194,7 +204,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { for def_ids in associated_types.values_mut() { for (projection_bound, span) in &projection_bounds { let def_id = projection_bound.projection_def_id(); - // FIXME(#120456) - is `swap_remove` correct? def_ids.swap_remove(&def_id); if tcx.generics_require_sized_self(def_id) { tcx.emit_node_span_lint( 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 4e5a8271e9ec7..0b58b807090de 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -727,7 +727,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); // FIXME: Marked `mut` so that we can replace the spans further below with a more // appropriate one, but this should be handled earlier in the span assignment. - let mut associated_types: FxIndexMap> = associated_types + let associated_types: FxIndexMap> = associated_types .into_iter() .map(|(span, def_ids)| { (span, def_ids.into_iter().map(|did| tcx.associated_item(did)).collect()) @@ -769,39 +769,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::Node::Expr(_) | hir::Node::Pat(_) => true, _ => false, }; - match bound.trait_ref.path.segments { - // FIXME: `trait_ref.path.span` can point to a full path with multiple - // segments, even though `trait_ref.path.segments` is of length `1`. Work - // around that bug here, even though it should be fixed elsewhere. - // This would otherwise cause an invalid suggestion. For an example, look at - // `tests/ui/issues/issue-28344.rs` where instead of the following: - // - // error[E0191]: the value of the associated type `Output` - // (from trait `std::ops::BitXor`) must be specified - // --> $DIR/issue-28344.rs:4:17 - // | - // LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); - // | ^^^^^^ help: specify the associated type: - // | `BitXor` - // - // we would output: - // - // error[E0191]: the value of the associated type `Output` - // (from trait `std::ops::BitXor`) must be specified - // --> $DIR/issue-28344.rs:4:17 - // | - // LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); - // | ^^^^^^^^^^^^^ help: specify the associated type: - // | `BitXor::bitor` - [segment] if segment.args.is_none() => { - trait_bound_spans = vec![segment.ident.span]; - associated_types = associated_types - .into_values() - .map(|items| (segment.ident.span, items)) - .collect(); - } - _ => {} - } } // We get all the associated items that _are_ set, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 01276abec22b9..cf780a3d3bba4 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -37,6 +37,7 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::print::PrintPolyTraitRefExt as _; use rustc_middle::ty::{ self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt, @@ -1569,7 +1570,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { infcx.fresh_args_for_item(DUMMY_SP, impl_def_id), ); - let value = tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased); + let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased); // FIXME: Don't bother dealing with non-lifetime binders here... if value.has_escaping_bound_vars() { return false; diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index 5b0165bf993da..c0fb94d2cb294 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -5,6 +5,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ObligationCause, WellFormedLoc}; use rustc_middle::bug; use rustc_middle::query::Providers; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::{self, TyCtxt, TypingMode}; use rustc_span::def_id::LocalDefId; use rustc_trait_selection::traits::{self, ObligationCtxt}; @@ -75,7 +76,7 @@ fn diagnostic_hir_wf_check<'tcx>( // This visitor can walk into binders, resulting in the `tcx_ty` to // potentially reference escaping bound variables. We simply erase // those here. - let tcx_ty = self.tcx.fold_regions(tcx_ty, |r, _| { + let tcx_ty = fold_regions(self.tcx, tcx_ty, |r, _| { if r.is_bound() { self.tcx.lifetimes.re_erased } else { r } }); let cause = traits::ObligationCause::new( diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 34effd199f152..246643d807470 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -70,6 +70,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::outlives::env::OutlivesEnvironment; +use rustc_infer::traits::ObligationCause; use rustc_infer::traits::specialization_graph::Node; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ @@ -210,13 +211,7 @@ fn get_impl_args( impl1_def_id.to_def_id(), impl1_args, impl2_node, - |_, span| { - traits::ObligationCause::new( - impl1_span, - impl1_def_id, - traits::ObligationCauseCode::WhereClause(impl2_node.def_id(), span), - ) - }, + &ObligationCause::misc(impl1_span, impl1_def_id), ); let errors = ocx.select_all_or_error(); diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 0a26b6776bbd5..b25acfb30077b 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -98,9 +98,7 @@ use rustc_middle::middle; use rustc_middle::mir::interpret::GlobalId; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Const, Ty, TyCtxt}; -use rustc_session::parse::feature_err; use rustc_span::Span; -use rustc_span::symbol::sym; use rustc_trait_selection::traits; use self::hir_ty_lowering::{FeedConstTy, HirTyLowerer}; @@ -113,34 +111,9 @@ fn require_c_abi_if_c_variadic( abi: ExternAbi, span: Span, ) { - const CONVENTIONS_UNSTABLE: &str = - "`C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`"; - const CONVENTIONS_STABLE: &str = "`C` or `cdecl`"; - const UNSTABLE_EXPLAIN: &str = - "using calling conventions other than `C` or `cdecl` for varargs functions is unstable"; - - if !decl.c_variadic || matches!(abi, ExternAbi::C { .. } | ExternAbi::Cdecl { .. }) { - return; + if decl.c_variadic && !abi.supports_varargs() { + tcx.dcx().emit_err(errors::VariadicFunctionCompatibleConvention { span }); } - - let extended_abi_support = tcx.features().extended_varargs_abi_support(); - let conventions = match (extended_abi_support, abi.supports_varargs()) { - // User enabled additional ABI support for varargs and function ABI matches those ones. - (true, true) => return, - - // Using this ABI would be ok, if the feature for additional ABI support was enabled. - // Return CONVENTIONS_STABLE, because we want the other error to look the same. - (false, true) => { - feature_err(&tcx.sess, sym::extended_varargs_abi_support, span, UNSTABLE_EXPLAIN) - .emit(); - CONVENTIONS_STABLE - } - - (false, false) => CONVENTIONS_STABLE, - (true, false) => CONVENTIONS_UNSTABLE, - }; - - tcx.dcx().emit_err(errors::VariadicFunctionCompatibleConvention { span, conventions }); } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 0a3aa8fec9005..64c6969d4b9c5 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -117,11 +117,7 @@ impl<'a> State<'a> { Node::Ctor(..) => panic!("cannot print isolated Ctor"), Node::LetStmt(a) => self.print_local_decl(a), Node::Crate(..) => panic!("cannot print Crate"), - Node::WhereBoundPredicate(pred) => { - self.print_formal_generic_params(pred.bound_generic_params); - self.print_type(pred.bounded_ty); - self.print_bounds(":", pred.bounds); - } + Node::WherePredicate(pred) => self.print_where_predicate(pred), Node::ArrayLenInfer(_) => self.word("_"), Node::Synthetic => unreachable!(), Node::Err(_) => self.word("/*ERROR*/"), @@ -1015,7 +1011,7 @@ impl<'a> State<'a> { } fn print_expr_maybe_paren(&mut self, expr: &hir::Expr<'_>, prec: i8) { - self.print_expr_cond_paren(expr, expr.precedence().order() < prec) + self.print_expr_cond_paren(expr, expr.precedence() < prec) } /// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in @@ -1049,7 +1045,7 @@ impl<'a> State<'a> { } self.space(); self.word_space("="); - let npals = || parser::needs_par_as_let_scrutinee(init.precedence().order()); + let npals = || parser::needs_par_as_let_scrutinee(init.precedence()); self.print_expr_cond_paren(init, Self::cond_needs_par(init) || npals()) } @@ -2160,47 +2156,50 @@ impl<'a> State<'a> { if i != 0 { self.word_space(","); } + self.print_where_predicate(predicate); + } + } - match *predicate { - hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { - bound_generic_params, - bounded_ty, - bounds, - .. - }) => { - self.print_formal_generic_params(bound_generic_params); - self.print_type(bounded_ty); - self.print_bounds(":", bounds); - } - hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { - lifetime, - bounds, - .. - }) => { - self.print_lifetime(lifetime); - self.word(":"); - - for (i, bound) in bounds.iter().enumerate() { - match bound { - GenericBound::Outlives(lt) => { - self.print_lifetime(lt); - } - _ => panic!("unexpected bound on lifetime param: {bound:?}"), - } + fn print_where_predicate(&mut self, predicate: &hir::WherePredicate<'_>) { + match *predicate.kind { + hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate { + bound_generic_params, + bounded_ty, + bounds, + .. + }) => { + self.print_formal_generic_params(bound_generic_params); + self.print_type(bounded_ty); + self.print_bounds(":", bounds); + } + hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate { + lifetime, + bounds, + .. + }) => { + self.print_lifetime(lifetime); + self.word(":"); - if i != 0 { - self.word(":"); + for (i, bound) in bounds.iter().enumerate() { + match bound { + GenericBound::Outlives(lt) => { + self.print_lifetime(lt); } + _ => panic!("unexpected bound on lifetime param: {bound:?}"), + } + + if i != 0 { + self.word(":"); } } - hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { - lhs_ty, rhs_ty, .. - }) => { - self.print_type(lhs_ty); - self.space(); - self.word_space("="); - self.print_type(rhs_ty); - } + } + hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate { + lhs_ty, rhs_ty, .. + }) => { + self.print_type(lhs_ty); + self.space(); + self.word_space("="); + self.print_type(rhs_ty); } } } diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 3669100ed9167..b27f7215ae4ae 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -79,6 +79,11 @@ hir_typeck_field_multiply_specified_in_initializer = .label = used more than once .previous_use_label = first use of `{$ident}` +hir_typeck_fn_item_to_variadic_function = can't pass a function item to a variadic function + .suggestion = use a function pointer instead + .help = a function item is zero-sized and needs to be cast into a function pointer to be used in FFI + .note = for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html + hir_typeck_fru_expr = this expression does not end in a comma... hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression @@ -141,7 +146,6 @@ hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value in hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function .suggestion = cast the value to `{$cast_ty}` - .help = cast the value to `{$cast_ty}` .teach_help = certain types, like `{$ty}`, must be casted before passing them to a variadic function, because of arcane ABI rules dictated by the C standard hir_typeck_ptr_cast_add_auto_to_object = adding {$traits_len -> diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index e6e0f62b54d2f..a92482e6a0e39 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -606,7 +606,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; if let Ok(rest_snippet) = rest_snippet { - let sugg = if callee_expr.precedence().order() >= PREC_UNAMBIGUOUS { + let sugg = if callee_expr.precedence() >= PREC_UNAMBIGUOUS { vec![ (up_to_rcvr_span, "".to_string()), (rest_span, format!(".{}({rest_snippet}", segment.ident)), diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 483a8d1d9a9dc..0c3f21d540dcd 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -1107,7 +1107,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { } fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) { - let expr_prec = self.expr.precedence().order(); + let expr_prec = self.expr.precedence(); let needs_parens = expr_prec < rustc_ast::util::parser::PREC_UNAMBIGUOUS; let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize)); diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 11e03229265a9..bf41dcbe4a365 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -215,7 +215,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } } - // Examine the supertype and consider auto-borrowing. + // Examine the supertype and consider type-specific coercions, such + // as auto-borrowing, coercing pointer mutability, a `dyn*` coercion, + // or pin-ergonomics. match *b.kind() { ty::RawPtr(_, b_mutbl) => { return self.coerce_unsafe_ptr(a, b, b_mutbl); @@ -230,7 +232,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { if self.tcx.features().pin_ergonomics() && self.tcx.is_lang_item(pin.did(), hir::LangItem::Pin) => { - return self.coerce_pin(a, b); + let pin_coerce = self.commit_if_ok(|_| self.coerce_pin_ref(a, b)); + if pin_coerce.is_ok() { + return pin_coerce; + } } _ => {} } @@ -797,7 +802,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { /// - `Pin>` as `Pin<&T>` /// - `Pin>` as `Pin<&mut T>` #[instrument(skip(self), level = "trace")] - fn coerce_pin(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> { + fn coerce_pin_ref(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> { // We need to make sure the two types are compatible for coercion. // Then we will build a ReborrowPin adjustment and return that as an InferOk. diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 4f579b05d83b6..a2e008593077f 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -789,11 +789,20 @@ pub(crate) struct PassToVariadicFunction<'a, 'tcx> { pub span: Span, pub ty: Ty<'tcx>, pub cast_ty: &'a str, - #[suggestion(code = "{replace}", applicability = "machine-applicable")] - pub sugg_span: Option, - pub replace: String, - #[help] - pub help: bool, + #[suggestion(code = " as {cast_ty}", applicability = "machine-applicable", style = "verbose")] + pub sugg_span: Span, #[note(hir_typeck_teach_help)] pub(crate) teach: bool, } + +#[derive(Diagnostic)] +#[diag(hir_typeck_fn_item_to_variadic_function, code = E0617)] +#[help] +#[note] +pub(crate) struct PassFnItemToVariadicFunction { + #[primary_span] + pub span: Span, + #[suggestion(code = " as {replace}", applicability = "machine-applicable", style = "verbose")] + pub sugg_span: Span, + pub replace: String, +} diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 1610848958e59..b4715839cf56e 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -68,7 +68,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // While we don't allow *arbitrary* coercions here, we *do* allow // coercions from ! to `expected`. - if ty.is_never() && self.expr_guaranteed_to_constitute_read_for_never(expr) { + if self.try_structurally_resolve_type(expr.span, ty).is_never() + && self.expr_guaranteed_to_constitute_read_for_never(expr) + { if let Some(_) = self.typeck_results.borrow().adjustments().get(expr.hir_id) { let reported = self.dcx().span_delayed_bug( expr.span, @@ -274,7 +276,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // unless it's a place expression that isn't being read from, in which case // diverging would be unsound since we may never actually read the `!`. // e.g. `let _ = *never_ptr;` with `never_ptr: *const !`. - if ty.is_never() && self.expr_guaranteed_to_constitute_read_for_never(expr) { + if self.try_structurally_resolve_type(expr.span, ty).is_never() + && self.expr_guaranteed_to_constitute_read_for_never(expr) + { self.diverges.set(self.diverges.get() | Diverges::always(expr.span)); } @@ -420,7 +424,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | hir::Node::GenericParam(_) | hir::Node::Crate(_) | hir::Node::Infer(_) - | hir::Node::WhereBoundPredicate(_) + | hir::Node::WherePredicate(_) | hir::Node::ArrayLenInfer(_) | hir::Node::PreciseCapturingNonLifetimeArg(_) | hir::Node::OpaqueTy(_) => { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index ce6ce0381a91b..47af8c681da00 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -269,13 +269,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } Adjust::Deref(None) => { - // FIXME(effects): We *could* enforce `&T: ~const Deref` here. + // FIXME(const_trait_impl): We *could* enforce `&T: ~const Deref` here. } Adjust::Pointer(_pointer_coercion) => { - // FIXME(effects): We should probably enforce these. + // FIXME(const_trait_impl): We should probably enforce these. } Adjust::ReborrowPin(_mutability) => { - // FIXME(effects): We could enforce these; they correspond to + // FIXME(const_trait_impl): We could enforce these; they correspond to // `&mut T: DerefMut` tho, so it's kinda moot. } Adjust::Borrow(_) => { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 961526831fbfd..30c838b74af6a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -440,20 +440,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty: Ty<'tcx>, cast_ty: &str, ) { - let (sugg_span, replace, help) = - if let Ok(snippet) = sess.source_map().span_to_snippet(span) { - (Some(span), format!("{snippet} as {cast_ty}"), false) - } else { - (None, "".to_string(), true) - }; - sess.dcx().emit_err(errors::PassToVariadicFunction { span, ty, cast_ty, - help, - replace, - sugg_span, + sugg_span: span.shrink_to_hi(), teach: sess.teach(E0617), }); } @@ -472,9 +463,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { variadic_error(tcx.sess, arg.span, arg_ty, "c_uint"); } ty::FnDef(..) => { - let ptr_ty = Ty::new_fn_ptr(self.tcx, arg_ty.fn_sig(self.tcx)); - let ptr_ty = self.resolve_vars_if_possible(ptr_ty); - variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string()); + let fn_ptr = Ty::new_fn_ptr(self.tcx, arg_ty.fn_sig(self.tcx)); + let fn_ptr = self.resolve_vars_if_possible(fn_ptr).to_string(); + + let fn_item_spa = arg.span; + tcx.sess.dcx().emit_err(errors::PassFnItemToVariadicFunction { + span: fn_item_spa, + sugg_span: fn_item_spa.shrink_to_hi(), + replace: fn_ptr, + }); } _ => {} } @@ -729,7 +726,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let can_coerce = self.may_coerce(arg_ty, coerced_ty); if !can_coerce { return Compatibility::Incompatible(Some(ty::error::TypeError::Sorts( - ty::error::ExpectedFound::new(true, coerced_ty, arg_ty), + ty::error::ExpectedFound::new(coerced_ty, arg_ty), ))); } @@ -758,7 +755,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { expected_ty }; - TypeTrace::types(&self.misc(span), true, mismatched_ty, provided_ty) + TypeTrace::types(&self.misc(span), mismatched_ty, provided_ty) }; // The algorithm here is inspired by levenshtein distance and longest common subsequence. @@ -2347,9 +2344,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let check_for_matched_generics = || { if matched_inputs.iter().any(|x| x.is_some()) - && params_with_generics.iter().any(|x| x.0.is_some()) + && params_with_generics.iter().any(|x| x.1.is_some()) { - for (idx, (generic, _)) in params_with_generics.iter().enumerate() { + for &(idx, generic, _) in ¶ms_with_generics { // Param has to have a generic and be matched to be relevant if matched_inputs[idx.into()].is_none() { continue; @@ -2362,7 +2359,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for unmatching_idx in idx + 1..params_with_generics.len() { if matched_inputs[unmatching_idx.into()].is_none() && let Some(unmatched_idx_param_generic) = - params_with_generics[unmatching_idx].0 + params_with_generics[unmatching_idx].1 && unmatched_idx_param_generic.name.ident() == generic.name.ident() { @@ -2377,8 +2374,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let check_for_matched_generics = check_for_matched_generics(); - for (idx, (generic_param, param)) in - params_with_generics.iter().enumerate().filter(|(idx, _)| { + for &(idx, generic_param, param) in + params_with_generics.iter().filter(|&(idx, _, _)| { check_for_matched_generics || expected_idx.is_none_or(|expected_idx| expected_idx == *idx) }) @@ -2390,8 +2387,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let other_params_matched: Vec<(usize, &hir::Param<'_>)> = params_with_generics .iter() - .enumerate() - .filter(|(other_idx, (other_generic_param, _))| { + .filter(|(other_idx, other_generic_param, _)| { if *other_idx == idx { return false; } @@ -2410,18 +2406,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } other_generic_param.name.ident() == generic_param.name.ident() }) - .map(|(other_idx, (_, other_param))| (other_idx, *other_param)) + .map(|&(other_idx, _, other_param)| (other_idx, other_param)) .collect(); if !other_params_matched.is_empty() { let other_param_matched_names: Vec = other_params_matched .iter() - .map(|(_, other_param)| { + .map(|(idx, other_param)| { if let hir::PatKind::Binding(_, _, ident, _) = other_param.pat.kind { format!("`{ident}`") } else { - "{unknown}".to_string() + format!("parameter #{}", idx + 1) } }) .collect(); @@ -2478,18 +2474,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let param_idents_matching: Vec = params_with_generics .iter() - .filter(|(generic, _)| { + .filter(|(_, generic, _)| { if let Some(generic) = generic { generic.name.ident() == generic_param.name.ident() } else { false } }) - .map(|(_, param)| { + .map(|(idx, _, param)| { if let hir::PatKind::Binding(_, _, ident, _) = param.pat.kind { format!("`{ident}`") } else { - "{unknown}".to_string() + format!("parameter #{}", idx + 1) } }) .collect(); @@ -2498,8 +2494,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { spans.push_span_label( generic_param.span, format!( - "{} all reference this parameter {}", + "{} {} reference this parameter `{}`", display_list_with_comma_and(¶m_idents_matching), + if param_idents_matching.len() == 2 { "both" } else { "all" }, generic_param.name.ident().name, ), ); @@ -2580,7 +2577,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(params_with_generics) = self.get_hir_params_with_generics(def_id, is_method) { debug_assert_eq!(params_with_generics.len(), matched_inputs.len()); - for (idx, (generic_param, _)) in params_with_generics.iter().enumerate() { + for &(idx, generic_param, _) in ¶ms_with_generics { if matched_inputs[idx.into()].is_none() { continue; } @@ -2594,20 +2591,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let mut idxs_matched: Vec = vec![]; - for (other_idx, (_, _)) in params_with_generics.iter().enumerate().filter( - |(other_idx, (other_generic_param, _))| { - if *other_idx == idx { + for &(other_idx, _, _) in + params_with_generics.iter().filter(|&&(other_idx, other_generic_param, _)| { + if other_idx == idx { return false; } let Some(other_generic_param) = other_generic_param else { return false; }; - if matched_inputs[(*other_idx).into()].is_some() { + if matched_inputs[other_idx.into()].is_some() { return false; } other_generic_param.name.ident() == generic_param.name.ident() - }, - ) { + }) + { idxs_matched.push(other_idx); } @@ -2642,7 +2639,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, def_id: DefId, is_method: bool, - ) -> Option>, &hir::Param<'_>)>> { + ) -> Option>, &hir::Param<'_>)>> { let fn_node = self.tcx.hir().get_if_local(def_id)?; let fn_decl = fn_node.fn_decl()?; @@ -2685,7 +2682,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } debug_assert_eq!(params.len(), generic_params.len()); - Some(generic_params.into_iter().zip(params).collect()) + Some( + generic_params + .into_iter() + .zip(params) + .enumerate() + .map(|(a, (b, c))| (a, b, c)) + .collect(), + ) } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index c4c4c2f200bac..b493a61b9f44d 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2,7 +2,7 @@ use core::cmp::min; use core::iter; use hir::def_id::LocalDefId; -use rustc_ast::util::parser::{ExprPrecedence, PREC_UNAMBIGUOUS}; +use rustc_ast::util::parser::PREC_UNAMBIGUOUS; use rustc_data_structures::packed::Pu128; use rustc_errors::{Applicability, Diag, MultiSpan}; use rustc_hir as hir; @@ -10,7 +10,7 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::lang_items::LangItem; use rustc_hir::{ Arm, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, GenericBound, HirId, - Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicate, + Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicateKind, }; use rustc_hir_analysis::collect::suggest_impl_trait; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; @@ -398,7 +398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // so we remove the user's `clone` call. { vec![(receiver_method.ident.span, conversion_method.name.to_string())] - } else if expr.precedence().order() < ExprPrecedence::MethodCall.order() { + } else if expr.precedence() < PREC_UNAMBIGUOUS { vec![ (expr.span.shrink_to_lo(), "(".to_string()), (expr.span.shrink_to_hi(), format!(").{}()", conversion_method.name)), @@ -1004,8 +1004,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // get all where BoundPredicates here, because they are used in two cases below let where_predicates = predicates .iter() - .filter_map(|p| match p { - WherePredicate::BoundPredicate(hir::WhereBoundPredicate { + .filter_map(|p| match p.kind { + WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate { bounds, bounded_ty, .. @@ -1376,7 +1376,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let span = expr.span.find_oldest_ancestor_in_same_ctxt(); - let mut sugg = if expr.precedence().order() >= PREC_UNAMBIGUOUS { + let mut sugg = if expr.precedence() >= PREC_UNAMBIGUOUS { vec![(span.shrink_to_hi(), ".into()".to_owned())] } else { vec![ @@ -3000,7 +3000,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "change the type of the numeric literal from `{checked_ty}` to `{expected_ty}`", ); - let close_paren = if expr.precedence().order() < PREC_UNAMBIGUOUS { + let close_paren = if expr.precedence() < PREC_UNAMBIGUOUS { sugg.push((expr.span.shrink_to_lo(), "(".to_string())); ")" } else { @@ -3025,7 +3025,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let len = src.trim_end_matches(&checked_ty.to_string()).len(); expr.span.with_lo(expr.span.lo() + BytePos(len as u32)) }, - if expr.precedence().order() < PREC_UNAMBIGUOUS { + if expr.precedence() < PREC_UNAMBIGUOUS { // Readd `)` format!("{expected_ty})") } else { diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 63dccf8b0ce04..91ea34eb54d35 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -364,7 +364,7 @@ fn report_unexpected_variant_res( .with_code(err_code); match res { Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == E0164 => { - let patterns_url = "https://doc.rust-lang.org/book/ch18-00-patterns.html"; + let patterns_url = "https://doc.rust-lang.org/book/ch19-00-patterns.html"; err.with_span_label(span, "`fn` calls are not allowed in patterns") .with_help(format!("for more information, visit {patterns_url}")) } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 640729576fcc6..039c117c09995 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1574,7 +1574,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // Thus we need to prevent them from trying to match the `&_` autoref // candidates that get created for `&self` trait methods. ty::Alias(ty::Opaque, alias_ty) - if self.infcx.can_define_opaque_ty(alias_ty.def_id) + if !self.next_trait_solver() + && self.infcx.can_define_opaque_ty(alias_ty.def_id) && !xform_self_ty.is_ty_var() => { return ProbeResult::NoMatch; @@ -1642,6 +1643,28 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } + // FIXME(-Znext-solver): See the linked issue below. + // + // + // In the new solver, check the well-formedness of the return type. + // This emulates, in a way, the predicates that fall out of + // normalizing the return type in the old solver. + // + // We alternatively could check the predicates of the method itself hold, + // but we intentionally do not do this in the old solver b/c of cycles, + // and doing it in the new solver would be stronger. This should be fixed + // in the future, since it likely leads to much better method winnowing. + if let Some(xform_ret_ty) = xform_ret_ty + && self.infcx.next_trait_solver() + { + ocx.register_obligation(traits::Obligation::new( + self.tcx, + cause.clone(), + self.param_env, + ty::ClauseKind::WellFormed(xform_ret_ty.into()), + )); + } + // Evaluate those obligations to see if they might possibly hold. for error in ocx.select_where_possible() { result = ProbeResult::NoMatch; diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index d50eff0deb0bc..b0c020dd7cbed 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1802,7 +1802,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut is_mutbl = bm.1; for pointer_ty in place.deref_tys() { - match pointer_ty.kind() { + match self.structurally_resolve_type(self.tcx.hir().span(var_hir_id), pointer_ty).kind() + { // We don't capture derefs of raw ptrs ty::RawPtr(_, _) => unreachable!(), @@ -1816,7 +1817,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Dereferencing a box doesn't change mutability ty::Adt(def, ..) if def.is_box() => {} - unexpected_ty => bug!("deref of unexpected pointer type {:?}", unexpected_ty), + unexpected_ty => span_bug!( + self.tcx.hir().span(var_hir_id), + "deref of unexpected pointer type {:?}", + unexpected_ty + ), } } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 2f436ce77a40c..e17a68c869215 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -12,7 +12,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::span_bug; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; -use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; +use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, fold_regions}; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperFoldable}; use rustc_span::Span; @@ -827,7 +827,10 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { // no reason to keep regions around. They will be repopulated during MIR // borrowck, and specifically region constraints will be populated during // MIR typeck which is run on the new body. - value = tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased); + // + // We're not using `tcx.erase_regions` as that also anonymizes bound variables, + // regressing borrowck diagnostics. + value = fold_regions(tcx, value, |_, _| tcx.lifetimes.re_erased); // Normalize consts in writeback, because GCE doesn't normalize eagerly. if tcx.features().generic_const_exprs() { diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index e8735cba9bd23..6dab6468870a5 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -16,8 +16,15 @@ mod persist; pub use persist::{ LoadResult, copy_cgu_workproduct_to_incr_comp_cache_dir, finalize_session_directory, - in_incr_comp_dir, in_incr_comp_dir_sess, load_query_result_cache, save_dep_graph, - save_work_product_index, setup_dep_graph, + in_incr_comp_dir, in_incr_comp_dir_sess, load_query_result_cache, save_work_product_index, + setup_dep_graph, }; +use rustc_middle::util::Providers; + +#[allow(missing_docs)] +pub fn provide(providers: &mut Providers) { + providers.hooks.save_dep_graph = + |tcx| tcx.sess.time("serialize_dep_graph", || persist::save_dep_graph(tcx.tcx)); +} rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_incremental/src/persist/mod.rs b/compiler/rustc_incremental/src/persist/mod.rs index 186db0a60a38f..f5d5167e0e2cd 100644 --- a/compiler/rustc_incremental/src/persist/mod.rs +++ b/compiler/rustc_incremental/src/persist/mod.rs @@ -12,5 +12,6 @@ mod work_product; pub use fs::{finalize_session_directory, in_incr_comp_dir, in_incr_comp_dir_sess}; pub use load::{LoadResult, load_query_result_cache, setup_dep_graph}; -pub use save::{save_dep_graph, save_work_product_index}; +pub(crate) use save::save_dep_graph; +pub use save::save_work_product_index; pub use work_product::copy_cgu_workproduct_to_incr_comp_cache_dir; diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 53726df459797..8fc50ca1b4354 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -25,7 +25,7 @@ use crate::errors; /// /// This function should only run after all queries have completed. /// Trying to execute a query afterwards would attempt to read the result cache we just dropped. -pub fn save_dep_graph(tcx: TyCtxt<'_>) { +pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) { debug!("save_dep_graph()"); tcx.dep_graph.with_ignore(|| { let sess = tcx.sess; diff --git a/compiler/rustc_index/Cargo.toml b/compiler/rustc_index/Cargo.toml index f7d18f84e3452..33e8e2824c7a9 100644 --- a/compiler/rustc_index/Cargo.toml +++ b/compiler/rustc_index/Cargo.toml @@ -5,7 +5,6 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -arrayvec = { version = "0.7", default-features = false } rustc_index_macros = { path = "../rustc_index_macros", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index a923948922241..de6fa132ca070 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -4,7 +4,6 @@ use std::rc::Rc; use std::{fmt, iter, mem, slice}; use Chunk::*; -use arrayvec::ArrayVec; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_Generic, Encodable_Generic}; use smallvec::{SmallVec, smallvec}; @@ -240,45 +239,6 @@ impl BitSet { BitIter::new(&self.words) } - /// Set `self = self | other`. In contrast to `union` returns `true` if the set contains at - /// least one bit that is not in `other` (i.e. `other` is not a superset of `self`). - /// - /// This is an optimization for union of a hybrid bitset. - fn reverse_union_sparse(&mut self, sparse: &SparseBitSet) -> bool { - assert!(sparse.domain_size == self.domain_size); - self.clear_excess_bits(); - - let mut not_already = false; - // Index of the current word not yet merged. - let mut current_index = 0; - // Mask of bits that came from the sparse set in the current word. - let mut new_bit_mask = 0; - for (word_index, mask) in sparse.iter().map(|x| word_index_and_mask(*x)) { - // Next bit is in a word not inspected yet. - if word_index > current_index { - self.words[current_index] |= new_bit_mask; - // Were there any bits in the old word that did not occur in the sparse set? - not_already |= (self.words[current_index] ^ new_bit_mask) != 0; - // Check all words we skipped for any set bit. - not_already |= self.words[current_index + 1..word_index].iter().any(|&x| x != 0); - // Update next word. - current_index = word_index; - // Reset bit mask, no bits have been merged yet. - new_bit_mask = 0; - } - // Add bit and mark it as coming from the sparse set. - // self.words[word_index] |= mask; - new_bit_mask |= mask; - } - self.words[current_index] |= new_bit_mask; - // Any bits in the last inspected word that were not in the sparse set? - not_already |= (self.words[current_index] ^ new_bit_mask) != 0; - // Any bits in the tail? Note `clear_excess_bits` before. - not_already |= self.words[current_index + 1..].iter().any(|&x| x != 0); - - not_already - } - pub fn last_set_in(&self, range: impl RangeBounds) -> Option { let (start, end) = inclusive_start_end(range, self.domain_size)?; let (start_word_index, _) = word_index_and_mask(start); @@ -369,9 +329,11 @@ pub struct ChunkedBitSet { #[derive(Clone, Debug, PartialEq, Eq)] enum Chunk { /// A chunk that is all zeros; we don't represent the zeros explicitly. + /// The `ChunkSize` is always non-zero. Zeros(ChunkSize), /// A chunk that is all ones; we don't represent the ones explicitly. + /// `ChunkSize` is always non-zero. Ones(ChunkSize), /// A chunk that has a mix of zeros and ones, which are represented @@ -381,11 +343,12 @@ enum Chunk { /// turns out to be both simpler and have better performance than /// allocating the minimum number of words, largely because we avoid having /// to store the length, which would make this type larger. These excess - /// words are always be zero, as are any excess bits in the final in-use - /// word. + /// words are always zero, as are any excess bits in the final in-use word. /// - /// The second field is the count of 1s set in the chunk, and must satisfy - /// `0 < count < chunk_domain_size`. + /// The first `ChunkSize` field is always non-zero. + /// + /// The second `ChunkSize` field is the count of 1s set in the chunk, and + /// must satisfy `0 < count < chunk_domain_size`. /// /// The words are within an `Rc` because it's surprisingly common to /// duplicate an entire chunk, e.g. in `ChunkedBitSet::clone_from()`, or @@ -450,6 +413,11 @@ impl ChunkedBitSet { ChunkedBitSet::new(domain_size, /* is_empty */ false) } + pub fn clear(&mut self) { + let domain_size = self.domain_size(); + *self = ChunkedBitSet::new_empty(domain_size); + } + #[cfg(test)] fn chunks(&self) -> &[Chunk] { &self.chunks @@ -461,7 +429,7 @@ impl ChunkedBitSet { } pub fn is_empty(&self) -> bool { - self.chunks.iter().all(|chunk| matches!(chunk, Chunk::Zeros(..) | Chunk::Ones(0))) + self.chunks.iter().all(|chunk| matches!(chunk, Zeros(..))) } /// Returns `true` if `self` contains `elem`. @@ -610,6 +578,18 @@ impl ChunkedBitSet { } } + fn chunk_iter(&self, chunk_index: usize) -> ChunkIter<'_> { + match self.chunks.get(chunk_index) { + Some(Zeros(_chunk_domain_size)) => ChunkIter::Zeros, + Some(Ones(chunk_domain_size)) => ChunkIter::Ones(0..*chunk_domain_size as usize), + Some(Mixed(chunk_domain_size, _, ref words)) => { + let num_words = num_words(*chunk_domain_size as usize); + ChunkIter::Mixed(BitIter::new(&words[0..num_words])) + } + None => ChunkIter::Finished, + } + } + bit_relations_inherent_impls! {} } @@ -809,30 +789,6 @@ impl BitRelations> for ChunkedBitSet { } } -impl BitRelations> for ChunkedBitSet { - fn union(&mut self, other: &HybridBitSet) -> bool { - // FIXME: This is slow if `other` is dense, but it hasn't been a problem - // in practice so far. - // If a faster implementation of this operation is required, consider - // reopening https://github.com/rust-lang/rust/pull/94625 - assert_eq!(self.domain_size, other.domain_size()); - sequential_update(|elem| self.insert(elem), other.iter()) - } - - fn subtract(&mut self, other: &HybridBitSet) -> bool { - // FIXME: This is slow if `other` is dense, but it hasn't been a problem - // in practice so far. - // If a faster implementation of this operation is required, consider - // reopening https://github.com/rust-lang/rust/pull/94625 - assert_eq!(self.domain_size, other.domain_size()); - sequential_update(|elem| self.remove(elem), other.iter()) - } - - fn intersect(&mut self, _other: &HybridBitSet) -> bool { - unimplemented!("implement if/when necessary"); - } -} - impl BitRelations> for BitSet { fn union(&mut self, other: &ChunkedBitSet) -> bool { sequential_update(|elem| self.insert(elem), other.iter()) @@ -851,7 +807,7 @@ impl BitRelations> for BitSet { words = &mut words[..CHUNK_WORDS]; } match chunk { - Chunk::Zeros(..) => { + Zeros(..) => { for word in words { if *word != 0 { changed = true; @@ -859,8 +815,8 @@ impl BitRelations> for BitSet { } } } - Chunk::Ones(..) => (), - Chunk::Mixed(_, _, data) => { + Ones(..) => (), + Mixed(_, _, data) => { for (i, word) in words.iter_mut().enumerate() { let new_val = *word & data[i]; if new_val != *word { @@ -897,78 +853,44 @@ impl Clone for ChunkedBitSet { } pub struct ChunkedBitIter<'a, T: Idx> { - index: usize, - bitset: &'a ChunkedBitSet, + bit_set: &'a ChunkedBitSet, + + // The index of the current chunk. + chunk_index: usize, + + // The sub-iterator for the current chunk. + chunk_iter: ChunkIter<'a>, } impl<'a, T: Idx> ChunkedBitIter<'a, T> { #[inline] - fn new(bitset: &'a ChunkedBitSet) -> ChunkedBitIter<'a, T> { - ChunkedBitIter { index: 0, bitset } + fn new(bit_set: &'a ChunkedBitSet) -> ChunkedBitIter<'a, T> { + ChunkedBitIter { bit_set, chunk_index: 0, chunk_iter: bit_set.chunk_iter(0) } } } impl<'a, T: Idx> Iterator for ChunkedBitIter<'a, T> { type Item = T; - fn next(&mut self) -> Option { - while self.index < self.bitset.domain_size() { - let elem = T::new(self.index); - let chunk = &self.bitset.chunks[chunk_index(elem)]; - match &chunk { - Zeros(chunk_domain_size) => { - self.index += *chunk_domain_size as usize; - } - Ones(_chunk_domain_size) => { - self.index += 1; - return Some(elem); - } - Mixed(_chunk_domain_size, _, words) => loop { - let elem = T::new(self.index); - self.index += 1; - let (word_index, mask) = chunk_word_index_and_mask(elem); - if (words[word_index] & mask) != 0 { - return Some(elem); - } - if self.index % CHUNK_BITS == 0 { - break; - } - }, - } - } - None - } - fn fold(mut self, mut init: B, mut f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - // If `next` has already been called, we may not be at the start of a chunk, so we first - // advance the iterator to the start of the next chunk, before proceeding in chunk sized - // steps. - while self.index % CHUNK_BITS != 0 { - let Some(item) = self.next() else { return init }; - init = f(init, item); - } - let start_chunk = self.index / CHUNK_BITS; - let chunks = &self.bitset.chunks[start_chunk..]; - for (i, chunk) in chunks.iter().enumerate() { - let base = (start_chunk + i) * CHUNK_BITS; - match chunk { - Chunk::Zeros(_) => (), - Chunk::Ones(limit) => { - for j in 0..(*limit as usize) { - init = f(init, T::new(base + j)); + fn next(&mut self) -> Option { + loop { + match &mut self.chunk_iter { + ChunkIter::Zeros => {} + ChunkIter::Ones(iter) => { + if let Some(next) = iter.next() { + return Some(T::new(next + self.chunk_index * CHUNK_BITS)); } } - Chunk::Mixed(_, _, words) => { - init = BitIter::new(&**words).fold(init, |val, mut item: T| { - item.increment_by(base); - f(val, item) - }); + ChunkIter::Mixed(iter) => { + if let Some(next) = iter.next() { + return Some(T::new(next + self.chunk_index * CHUNK_BITS)); + } } + ChunkIter::Finished => return None, } + self.chunk_index += 1; + self.chunk_iter = self.bit_set.chunk_iter(self.chunk_index); } - init } } @@ -1005,7 +927,7 @@ impl Chunk { } fn new(chunk_domain_size: usize, is_empty: bool) -> Self { - debug_assert!(chunk_domain_size <= CHUNK_BITS); + debug_assert!(0 < chunk_domain_size && chunk_domain_size <= CHUNK_BITS); let chunk_domain_size = chunk_domain_size as ChunkSize; if is_empty { Zeros(chunk_domain_size) } else { Ones(chunk_domain_size) } } @@ -1020,6 +942,13 @@ impl Chunk { } } +enum ChunkIter<'a> { + Zeros, + Ones(Range), + Mixed(BitIter<'a, usize>), + Finished, +} + // Applies a function to mutate a bitset, and returns true if any // of the applications return true fn sequential_update( @@ -1029,176 +958,6 @@ fn sequential_update( it.fold(false, |changed, elem| self_update(elem) | changed) } -// Optimization of intersection for SparseBitSet that's generic -// over the RHS -fn sparse_intersect( - set: &mut SparseBitSet, - other_contains: impl Fn(&T) -> bool, -) -> bool { - let size = set.elems.len(); - set.elems.retain(|elem| other_contains(elem)); - set.elems.len() != size -} - -// Optimization of dense/sparse intersection. The resulting set is -// guaranteed to be at most the size of the sparse set, and hence can be -// represented as a sparse set. Therefore the sparse set is copied and filtered, -// then returned as the new set. -fn dense_sparse_intersect( - dense: &BitSet, - sparse: &SparseBitSet, -) -> (SparseBitSet, bool) { - let mut sparse_copy = sparse.clone(); - sparse_intersect(&mut sparse_copy, |el| dense.contains(*el)); - let n = sparse_copy.len(); - (sparse_copy, n != dense.count()) -} - -// hybrid REL dense -impl BitRelations> for HybridBitSet { - fn union(&mut self, other: &BitSet) -> bool { - assert_eq!(self.domain_size(), other.domain_size); - match self { - HybridBitSet::Sparse(sparse) => { - // `self` is sparse and `other` is dense. To - // merge them, we have two available strategies: - // * Densify `self` then merge other - // * Clone other then integrate bits from `self` - // The second strategy requires dedicated method - // since the usual `union` returns the wrong - // result. In the dedicated case the computation - // is slightly faster if the bits of the sparse - // bitset map to only few words of the dense - // representation, i.e. indices are near each - // other. - // - // Benchmarking seems to suggest that the second - // option is worth it. - let mut new_dense = other.clone(); - let changed = new_dense.reverse_union_sparse(sparse); - *self = HybridBitSet::Dense(new_dense); - changed - } - - HybridBitSet::Dense(dense) => dense.union(other), - } - } - - fn subtract(&mut self, other: &BitSet) -> bool { - assert_eq!(self.domain_size(), other.domain_size); - match self { - HybridBitSet::Sparse(sparse) => { - sequential_update(|elem| sparse.remove(elem), other.iter()) - } - HybridBitSet::Dense(dense) => dense.subtract(other), - } - } - - fn intersect(&mut self, other: &BitSet) -> bool { - assert_eq!(self.domain_size(), other.domain_size); - match self { - HybridBitSet::Sparse(sparse) => sparse_intersect(sparse, |elem| other.contains(*elem)), - HybridBitSet::Dense(dense) => dense.intersect(other), - } - } -} - -// dense REL hybrid -impl BitRelations> for BitSet { - fn union(&mut self, other: &HybridBitSet) -> bool { - assert_eq!(self.domain_size, other.domain_size()); - match other { - HybridBitSet::Sparse(sparse) => { - sequential_update(|elem| self.insert(elem), sparse.iter().cloned()) - } - HybridBitSet::Dense(dense) => self.union(dense), - } - } - - fn subtract(&mut self, other: &HybridBitSet) -> bool { - assert_eq!(self.domain_size, other.domain_size()); - match other { - HybridBitSet::Sparse(sparse) => { - sequential_update(|elem| self.remove(elem), sparse.iter().cloned()) - } - HybridBitSet::Dense(dense) => self.subtract(dense), - } - } - - fn intersect(&mut self, other: &HybridBitSet) -> bool { - assert_eq!(self.domain_size, other.domain_size()); - match other { - HybridBitSet::Sparse(sparse) => { - let (updated, changed) = dense_sparse_intersect(self, sparse); - - // We can't directly assign the SparseBitSet to the BitSet, and - // doing `*self = updated.to_dense()` would cause a drop / reallocation. Instead, - // the BitSet is cleared and `updated` is copied into `self`. - self.clear(); - for elem in updated.iter() { - self.insert(*elem); - } - changed - } - HybridBitSet::Dense(dense) => self.intersect(dense), - } - } -} - -// hybrid REL hybrid -impl BitRelations> for HybridBitSet { - fn union(&mut self, other: &HybridBitSet) -> bool { - assert_eq!(self.domain_size(), other.domain_size()); - match self { - HybridBitSet::Sparse(_) => { - match other { - HybridBitSet::Sparse(other_sparse) => { - // Both sets are sparse. Add the elements in - // `other_sparse` to `self` one at a time. This - // may or may not cause `self` to be densified. - let mut changed = false; - for elem in other_sparse.iter() { - changed |= self.insert(*elem); - } - changed - } - - HybridBitSet::Dense(other_dense) => self.union(other_dense), - } - } - - HybridBitSet::Dense(self_dense) => self_dense.union(other), - } - } - - fn subtract(&mut self, other: &HybridBitSet) -> bool { - assert_eq!(self.domain_size(), other.domain_size()); - match self { - HybridBitSet::Sparse(self_sparse) => { - sequential_update(|elem| self_sparse.remove(elem), other.iter()) - } - HybridBitSet::Dense(self_dense) => self_dense.subtract(other), - } - } - - fn intersect(&mut self, other: &HybridBitSet) -> bool { - assert_eq!(self.domain_size(), other.domain_size()); - match self { - HybridBitSet::Sparse(self_sparse) => { - sparse_intersect(self_sparse, |elem| other.contains(*elem)) - } - HybridBitSet::Dense(self_dense) => match other { - HybridBitSet::Sparse(other_sparse) => { - let (updated, changed) = dense_sparse_intersect(self_dense, other_sparse); - *self = HybridBitSet::Sparse(updated); - changed - } - HybridBitSet::Dense(other_dense) => self_dense.intersect(other_dense), - }, - } - } -} - impl Clone for BitSet { fn clone(&self) -> Self { BitSet { domain_size: self.domain_size, words: self.words.clone(), marker: PhantomData } @@ -1298,15 +1057,13 @@ impl<'a, T: Idx> Iterator for BitIter<'a, T> { // Get the position of the next set bit in the current word, // then clear the bit. let bit_pos = self.word.trailing_zeros() as usize; - let bit = 1 << bit_pos; - self.word ^= bit; + self.word ^= 1 << bit_pos; return Some(T::new(bit_pos + self.offset)); } // Move onto the next word. `wrapping_add()` is needed to handle // the degenerate initial value given to `offset` in `new()`. - let word = self.iter.next()?; - self.word = *word; + self.word = *self.iter.next()?; self.offset = self.offset.wrapping_add(WORD_BITS); } } @@ -1349,286 +1106,6 @@ where false } -const SPARSE_MAX: usize = 8; - -/// A fixed-size bitset type with a sparse representation and a maximum of -/// `SPARSE_MAX` elements. The elements are stored as a sorted `ArrayVec` with -/// no duplicates. -/// -/// This type is used by `HybridBitSet`; do not use directly. -#[derive(Clone, Debug)] -pub struct SparseBitSet { - domain_size: usize, - elems: ArrayVec, -} - -impl SparseBitSet { - fn new_empty(domain_size: usize) -> Self { - SparseBitSet { domain_size, elems: ArrayVec::new() } - } - - fn len(&self) -> usize { - self.elems.len() - } - - fn is_empty(&self) -> bool { - self.elems.len() == 0 - } - - fn contains(&self, elem: T) -> bool { - assert!(elem.index() < self.domain_size); - self.elems.contains(&elem) - } - - fn insert(&mut self, elem: T) -> bool { - assert!(elem.index() < self.domain_size); - let changed = if let Some(i) = self.elems.iter().position(|&e| e.index() >= elem.index()) { - if self.elems[i] == elem { - // `elem` is already in the set. - false - } else { - // `elem` is smaller than one or more existing elements. - self.elems.insert(i, elem); - true - } - } else { - // `elem` is larger than all existing elements. - self.elems.push(elem); - true - }; - assert!(self.len() <= SPARSE_MAX); - changed - } - - fn remove(&mut self, elem: T) -> bool { - assert!(elem.index() < self.domain_size); - if let Some(i) = self.elems.iter().position(|&e| e == elem) { - self.elems.remove(i); - true - } else { - false - } - } - - fn to_dense(&self) -> BitSet { - let mut dense = BitSet::new_empty(self.domain_size); - for elem in self.elems.iter() { - dense.insert(*elem); - } - dense - } - - fn iter(&self) -> slice::Iter<'_, T> { - self.elems.iter() - } - - bit_relations_inherent_impls! {} -} - -impl SparseBitSet { - pub fn last_set_in(&self, range: impl RangeBounds) -> Option { - let mut last_leq = None; - for e in self.iter() { - if range.contains(e) { - last_leq = Some(*e); - } - } - last_leq - } -} - -/// A fixed-size bitset type with a hybrid representation: sparse when there -/// are up to a `SPARSE_MAX` elements in the set, but dense when there are more -/// than `SPARSE_MAX`. -/// -/// This type is especially efficient for sets that typically have a small -/// number of elements, but a large `domain_size`, and are cleared frequently. -/// -/// `T` is an index type, typically a newtyped `usize` wrapper, but it can also -/// just be `usize`. -/// -/// All operations that involve an element will panic if the element is equal -/// to or greater than the domain size. All operations that involve two bitsets -/// will panic if the bitsets have differing domain sizes. -#[derive(Clone)] -pub enum HybridBitSet { - Sparse(SparseBitSet), - Dense(BitSet), -} - -impl fmt::Debug for HybridBitSet { - fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Sparse(b) => b.fmt(w), - Self::Dense(b) => b.fmt(w), - } - } -} - -impl HybridBitSet { - pub fn new_empty(domain_size: usize) -> Self { - HybridBitSet::Sparse(SparseBitSet::new_empty(domain_size)) - } - - pub fn domain_size(&self) -> usize { - match self { - HybridBitSet::Sparse(sparse) => sparse.domain_size, - HybridBitSet::Dense(dense) => dense.domain_size, - } - } - - pub fn clear(&mut self) { - let domain_size = self.domain_size(); - *self = HybridBitSet::new_empty(domain_size); - } - - pub fn contains(&self, elem: T) -> bool { - match self { - HybridBitSet::Sparse(sparse) => sparse.contains(elem), - HybridBitSet::Dense(dense) => dense.contains(elem), - } - } - - pub fn superset(&self, other: &HybridBitSet) -> bool { - match (self, other) { - (HybridBitSet::Dense(self_dense), HybridBitSet::Dense(other_dense)) => { - self_dense.superset(other_dense) - } - _ => { - assert!(self.domain_size() == other.domain_size()); - other.iter().all(|elem| self.contains(elem)) - } - } - } - - pub fn is_empty(&self) -> bool { - match self { - HybridBitSet::Sparse(sparse) => sparse.is_empty(), - HybridBitSet::Dense(dense) => dense.is_empty(), - } - } - - /// Returns the previous element present in the bitset from `elem`, - /// inclusively of elem. That is, will return `Some(elem)` if elem is in the - /// bitset. - pub fn last_set_in(&self, range: impl RangeBounds) -> Option - where - T: Ord, - { - match self { - HybridBitSet::Sparse(sparse) => sparse.last_set_in(range), - HybridBitSet::Dense(dense) => dense.last_set_in(range), - } - } - - pub fn insert(&mut self, elem: T) -> bool { - // No need to check `elem` against `self.domain_size` here because all - // the match cases check it, one way or another. - match self { - HybridBitSet::Sparse(sparse) if sparse.len() < SPARSE_MAX => { - // The set is sparse and has space for `elem`. - sparse.insert(elem) - } - HybridBitSet::Sparse(sparse) if sparse.contains(elem) => { - // The set is sparse and does not have space for `elem`, but - // that doesn't matter because `elem` is already present. - false - } - HybridBitSet::Sparse(sparse) => { - // The set is sparse and full. Convert to a dense set. - let mut dense = sparse.to_dense(); - let changed = dense.insert(elem); - assert!(changed); - *self = HybridBitSet::Dense(dense); - changed - } - HybridBitSet::Dense(dense) => dense.insert(elem), - } - } - - pub fn insert_range(&mut self, elems: impl RangeBounds) { - // No need to check `elem` against `self.domain_size` here because all - // the match cases check it, one way or another. - let start = match elems.start_bound().cloned() { - Bound::Included(start) => start.index(), - Bound::Excluded(start) => start.index() + 1, - Bound::Unbounded => 0, - }; - let end = match elems.end_bound().cloned() { - Bound::Included(end) => end.index() + 1, - Bound::Excluded(end) => end.index(), - Bound::Unbounded => self.domain_size() - 1, - }; - let Some(len) = end.checked_sub(start) else { return }; - match self { - HybridBitSet::Sparse(sparse) if sparse.len() + len < SPARSE_MAX => { - // The set is sparse and has space for `elems`. - for elem in start..end { - sparse.insert(T::new(elem)); - } - } - HybridBitSet::Sparse(sparse) => { - // The set is sparse and full. Convert to a dense set. - let mut dense = sparse.to_dense(); - dense.insert_range(elems); - *self = HybridBitSet::Dense(dense); - } - HybridBitSet::Dense(dense) => dense.insert_range(elems), - } - } - - pub fn insert_all(&mut self) { - let domain_size = self.domain_size(); - match self { - HybridBitSet::Sparse(_) => { - *self = HybridBitSet::Dense(BitSet::new_filled(domain_size)); - } - HybridBitSet::Dense(dense) => dense.insert_all(), - } - } - - pub fn remove(&mut self, elem: T) -> bool { - // Note: we currently don't bother going from Dense back to Sparse. - match self { - HybridBitSet::Sparse(sparse) => sparse.remove(elem), - HybridBitSet::Dense(dense) => dense.remove(elem), - } - } - - /// Converts to a dense set, consuming itself in the process. - pub fn to_dense(self) -> BitSet { - match self { - HybridBitSet::Sparse(sparse) => sparse.to_dense(), - HybridBitSet::Dense(dense) => dense, - } - } - - pub fn iter(&self) -> HybridIter<'_, T> { - match self { - HybridBitSet::Sparse(sparse) => HybridIter::Sparse(sparse.iter()), - HybridBitSet::Dense(dense) => HybridIter::Dense(dense.iter()), - } - } - - bit_relations_inherent_impls! {} -} - -pub enum HybridIter<'a, T: Idx> { - Sparse(slice::Iter<'a, T>), - Dense(BitIter<'a, T>), -} - -impl<'a, T: Idx> Iterator for HybridIter<'a, T> { - type Item = T; - - fn next(&mut self) -> Option { - match self { - HybridIter::Sparse(sparse) => sparse.next().copied(), - HybridIter::Dense(dense) => dense.next(), - } - } -} - /// A resizable bitset type with a dense representation. /// /// `T` is an index type, typically a newtyped `usize` wrapper, but it can also @@ -1897,7 +1374,7 @@ impl fmt::Debug for BitMatrix { /// sparse representation. /// /// Initially, every row has no explicit representation. If any bit within a -/// row is set, the entire row is instantiated as `Some()`. +/// row is set, the entire row is instantiated as `Some()`. /// Furthermore, any previously uninstantiated rows prior to it will be /// instantiated as `None`. Those prior rows may themselves become fully /// instantiated later on if any of their bits are set. @@ -1911,7 +1388,7 @@ where C: Idx, { num_columns: usize, - rows: IndexVec>>, + rows: IndexVec>>, } impl SparseBitMatrix { @@ -1920,10 +1397,10 @@ impl SparseBitMatrix { Self { num_columns, rows: IndexVec::new() } } - fn ensure_row(&mut self, row: R) -> &mut HybridBitSet { - // Instantiate any missing rows up to and including row `row` with an empty HybridBitSet. - // Then replace row `row` with a full HybridBitSet if necessary. - self.rows.get_or_insert_with(row, || HybridBitSet::new_empty(self.num_columns)) + fn ensure_row(&mut self, row: R) -> &mut ChunkedBitSet { + // Instantiate any missing rows up to and including row `row` with an empty ChunkedBitSet. + // Then replace row `row` with a full ChunkedBitSet if necessary. + self.rows.get_or_insert_with(row, || ChunkedBitSet::new_empty(self.num_columns)) } /// Sets the cell at `(row, column)` to true. Put another way, insert @@ -1997,17 +1474,17 @@ impl SparseBitMatrix { self.row(row).into_iter().flat_map(|r| r.iter()) } - pub fn row(&self, row: R) -> Option<&HybridBitSet> { + pub fn row(&self, row: R) -> Option<&ChunkedBitSet> { self.rows.get(row)?.as_ref() } /// Intersects `row` with `set`. `set` can be either `BitSet` or - /// `HybridBitSet`. Has no effect if `row` does not exist. + /// `ChunkedBitSet`. Has no effect if `row` does not exist. /// /// Returns true if the row was changed. pub fn intersect_row(&mut self, row: R, set: &Set) -> bool where - HybridBitSet: BitRelations, + ChunkedBitSet: BitRelations, { match self.rows.get_mut(row) { Some(Some(row)) => row.intersect(set), @@ -2016,12 +1493,12 @@ impl SparseBitMatrix { } /// Subtracts `set` from `row`. `set` can be either `BitSet` or - /// `HybridBitSet`. Has no effect if `row` does not exist. + /// `ChunkedBitSet`. Has no effect if `row` does not exist. /// /// Returns true if the row was changed. pub fn subtract_row(&mut self, row: R, set: &Set) -> bool where - HybridBitSet: BitRelations, + ChunkedBitSet: BitRelations, { match self.rows.get_mut(row) { Some(Some(row)) => row.subtract(set), @@ -2030,12 +1507,12 @@ impl SparseBitMatrix { } /// Unions `row` with `set`. `set` can be either `BitSet` or - /// `HybridBitSet`. + /// `ChunkedBitSet`. /// /// Returns true if the row was changed. pub fn union_row(&mut self, row: R, set: &Set) -> bool where - HybridBitSet: BitRelations, + ChunkedBitSet: BitRelations, { self.ensure_row(row).union(set) } diff --git a/compiler/rustc_index/src/bit_set/tests.rs b/compiler/rustc_index/src/bit_set/tests.rs index 21e681d63f69b..3f9198ce37f10 100644 --- a/compiler/rustc_index/src/bit_set/tests.rs +++ b/compiler/rustc_index/src/bit_set/tests.rs @@ -75,96 +75,6 @@ fn union_two_sets() { assert!(set1.contains(64)); } -#[test] -fn hybrid_bitset() { - let mut sparse038: HybridBitSet = HybridBitSet::new_empty(256); - assert!(sparse038.is_empty()); - assert!(sparse038.insert(0)); - assert!(sparse038.insert(1)); - assert!(sparse038.insert(8)); - assert!(sparse038.insert(3)); - assert!(!sparse038.insert(3)); - assert!(sparse038.remove(1)); - assert!(!sparse038.is_empty()); - assert_eq!(sparse038.iter().collect::>(), [0, 3, 8]); - - for i in 0..256 { - if i == 0 || i == 3 || i == 8 { - assert!(sparse038.contains(i)); - } else { - assert!(!sparse038.contains(i)); - } - } - - let mut sparse01358 = sparse038.clone(); - assert!(sparse01358.insert(1)); - assert!(sparse01358.insert(5)); - assert_eq!(sparse01358.iter().collect::>(), [0, 1, 3, 5, 8]); - - let mut dense10 = HybridBitSet::new_empty(256); - for i in 0..10 { - assert!(dense10.insert(i)); - } - assert!(!dense10.is_empty()); - assert_eq!(dense10.iter().collect::>(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - - let mut dense256 = HybridBitSet::new_empty(256); - assert!(dense256.is_empty()); - dense256.insert_all(); - assert!(!dense256.is_empty()); - for i in 0..256 { - assert!(dense256.contains(i)); - } - - assert!(sparse038.superset(&sparse038)); // sparse + sparse (self) - assert!(sparse01358.superset(&sparse038)); // sparse + sparse - assert!(dense10.superset(&sparse038)); // dense + sparse - assert!(dense10.superset(&dense10)); // dense + dense (self) - assert!(dense256.superset(&dense10)); // dense + dense - - let mut hybrid = sparse038.clone(); - assert!(!sparse01358.union(&hybrid)); // no change - assert!(hybrid.union(&sparse01358)); - assert!(hybrid.superset(&sparse01358) && sparse01358.superset(&hybrid)); - assert!(!dense256.union(&dense10)); - - // dense / sparse where dense superset sparse - assert!(!dense10.clone().union(&sparse01358)); - assert!(sparse01358.clone().union(&dense10)); - assert!(dense10.clone().intersect(&sparse01358)); - assert!(!sparse01358.clone().intersect(&dense10)); - assert!(dense10.clone().subtract(&sparse01358)); - assert!(sparse01358.clone().subtract(&dense10)); - - // dense / sparse where sparse superset dense - let dense038 = sparse038.to_dense(); - assert!(!sparse01358.clone().union(&dense038)); - assert!(dense038.clone().union(&sparse01358)); - assert!(sparse01358.clone().intersect(&dense038)); - assert!(!dense038.clone().intersect(&sparse01358)); - assert!(sparse01358.clone().subtract(&dense038)); - assert!(dense038.clone().subtract(&sparse01358)); - - let mut dense = dense10.clone(); - assert!(dense.union(&dense256)); - assert!(dense.superset(&dense256) && dense256.superset(&dense)); - assert!(hybrid.union(&dense256)); - assert!(hybrid.superset(&dense256) && dense256.superset(&hybrid)); - - assert!(!dense10.clone().intersect(&dense256)); - assert!(dense256.clone().intersect(&dense10)); - assert!(dense10.clone().subtract(&dense256)); - assert!(dense256.clone().subtract(&dense10)); - - assert_eq!(dense256.iter().count(), 256); - let mut dense0 = dense256; - for i in 0..256 { - assert!(dense0.remove(i)); - } - assert!(!dense0.remove(0)); - assert!(dense0.is_empty()); -} - #[test] fn chunked_bitset() { let mut b0 = ChunkedBitSet::::new_empty(0); @@ -593,15 +503,15 @@ fn sparse_matrix_operations() { matrix.insert(2, 99); matrix.insert(4, 0); - let mut disjoint: HybridBitSet = HybridBitSet::new_empty(100); + let mut disjoint: ChunkedBitSet = ChunkedBitSet::new_empty(100); disjoint.insert(33); - let mut superset = HybridBitSet::new_empty(100); + let mut superset = ChunkedBitSet::new_empty(100); superset.insert(22); superset.insert(75); superset.insert(33); - let mut subset = HybridBitSet::new_empty(100); + let mut subset = ChunkedBitSet::new_empty(100); subset.insert(22); // SparseBitMatrix::remove @@ -746,90 +656,6 @@ fn dense_last_set_before() { } } -/// Merge dense hybrid set into empty sparse hybrid set. -#[bench] -fn union_hybrid_sparse_empty_to_dense(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(256); - for i in 0..10 { - assert!(pre_dense.insert(i)); - } - let pre_sparse: HybridBitSet = HybridBitSet::new_empty(256); - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} - -/// Merge dense hybrid set into full hybrid set with same indices. -#[bench] -fn union_hybrid_sparse_full_to_dense(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(256); - for i in 0..10 { - assert!(pre_dense.insert(i)); - } - let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(256); - for i in 0..SPARSE_MAX { - assert!(pre_sparse.insert(i)); - } - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} - -/// Merge dense hybrid set into full hybrid set with indices over the whole domain. -#[bench] -fn union_hybrid_sparse_domain_to_dense(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX * 64); - for i in 0..10 { - assert!(pre_dense.insert(i)); - } - let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX * 64); - for i in 0..SPARSE_MAX { - assert!(pre_sparse.insert(i * 64)); - } - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} - -/// Merge dense hybrid set into empty hybrid set where the domain is very small. -#[bench] -fn union_hybrid_sparse_empty_small_domain(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); - for i in 0..SPARSE_MAX { - assert!(pre_dense.insert(i)); - } - let pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} - -/// Merge dense hybrid set into full hybrid set where the domain is very small. -#[bench] -fn union_hybrid_sparse_full_small_domain(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); - for i in 0..SPARSE_MAX { - assert!(pre_dense.insert(i)); - } - let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); - for i in 0..SPARSE_MAX { - assert!(pre_sparse.insert(i)); - } - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} - #[bench] fn bench_insert(b: &mut Bencher) { let mut bs = BitSet::new_filled(99999usize); diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 3eda3e9c67e85..12e2bbc968f0f 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -308,17 +308,14 @@ impl<'tcx> ToTrace<'tcx> for Ty<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())), + values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())), } } } impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { - TypeTrace { - cause: cause.clone(), - values: ValuePairs::Regions(ExpectedFound::new(true, a, b)), - } + TypeTrace { cause: cause.clone(), values: ValuePairs::Regions(ExpectedFound::new(a, b)) } } } @@ -326,7 +323,7 @@ impl<'tcx> ToTrace<'tcx> for Const<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())), + values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())), } } } @@ -337,13 +334,13 @@ impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> { cause: cause.clone(), values: match (a.unpack(), b.unpack()) { (GenericArgKind::Lifetime(a), GenericArgKind::Lifetime(b)) => { - ValuePairs::Regions(ExpectedFound::new(true, a, b)) + ValuePairs::Regions(ExpectedFound::new(a, b)) } (GenericArgKind::Type(a), GenericArgKind::Type(b)) => { - ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())) + ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())) } (GenericArgKind::Const(a), GenericArgKind::Const(b)) => { - ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())) + ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())) } _ => bug!("relating different kinds: {a:?} {b:?}"), }, @@ -353,19 +350,13 @@ impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> { impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { - TypeTrace { - cause: cause.clone(), - values: ValuePairs::Terms(ExpectedFound::new(true, a, b)), - } + TypeTrace { cause: cause.clone(), values: ValuePairs::Terms(ExpectedFound::new(a, b)) } } } impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { - TypeTrace { - cause: cause.clone(), - values: ValuePairs::TraitRefs(ExpectedFound::new(true, a, b)), - } + TypeTrace { cause: cause.clone(), values: ValuePairs::TraitRefs(ExpectedFound::new(a, b)) } } } @@ -373,17 +364,14 @@ impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::Aliases(ExpectedFound::new(true, a.into(), b.into())), + values: ValuePairs::Aliases(ExpectedFound::new(a.into(), b.into())), } } } impl<'tcx> ToTrace<'tcx> for ty::AliasTerm<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { - TypeTrace { - cause: cause.clone(), - values: ValuePairs::Aliases(ExpectedFound::new(true, a, b)), - } + TypeTrace { cause: cause.clone(), values: ValuePairs::Aliases(ExpectedFound::new(a, b)) } } } @@ -392,7 +380,6 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> { TypeTrace { cause: cause.clone(), values: ValuePairs::PolySigs(ExpectedFound::new( - true, ty::Binder::dummy(a), ty::Binder::dummy(b), )), @@ -402,10 +389,7 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> { impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { - TypeTrace { - cause: cause.clone(), - values: ValuePairs::PolySigs(ExpectedFound::new(true, a, b)), - } + TypeTrace { cause: cause.clone(), values: ValuePairs::PolySigs(ExpectedFound::new(a, b)) } } } @@ -413,7 +397,7 @@ impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialTraitRef<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(true, a, b)), + values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(a, b)), } } } @@ -422,7 +406,7 @@ impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::ExistentialProjection(ExpectedFound::new(true, a, b)), + values: ValuePairs::ExistentialProjection(ExpectedFound::new(a, b)), } } } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index f87c43a0ecd59..fe66d306ceb80 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -72,7 +72,7 @@ impl<'tcx> InferCtxt<'tcx> { query_state, ) .unchecked_map(|(param_env, value)| param_env.and(value)); - CanonicalQueryInput { canonical, typing_mode: self.typing_mode(param_env) } + CanonicalQueryInput { canonical, typing_mode: self.typing_mode() } } /// Canonicalizes a query *response* `V`. When we canonicalize a diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index ecda9c6eb000a..5fc9b679c8acf 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::relate::combine::PredicateEmittingRelation; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::{DUMMY_SP, ErrorGuaranteed}; -use super::{BoundRegionConversionTime, InferCtxt, SubregionOrigin}; +use super::{BoundRegionConversionTime, InferCtxt, RegionVariableOrigin, SubregionOrigin}; impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { type Interner = TyCtxt<'tcx>; @@ -20,11 +20,8 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.next_trait_solver } - fn typing_mode( - &self, - param_env_for_debug_assertion: ty::ParamEnv<'tcx>, - ) -> ty::TypingMode<'tcx> { - self.typing_mode(param_env_for_debug_assertion) + fn typing_mode(&self) -> ty::TypingMode<'tcx> { + self.typing_mode() } fn universe(&self) -> ty::UniverseIndex { @@ -90,6 +87,10 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid) } + fn next_region_infer(&self) -> ty::Region<'tcx> { + self.next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP)) + } + fn next_ty_infer(&self) -> Ty<'tcx> { self.next_ty_var(DUMMY_SP) } diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 6af49accc8411..e454a88e847fd 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -9,7 +9,7 @@ use rustc_data_structures::graph::implementation::{ use rustc_data_structures::intern::Interned; use rustc_data_structures::unord::UnordSet; use rustc_index::{IndexSlice, IndexVec}; -use rustc_middle::ty::fold::TypeFoldable; +use rustc_middle::ty::fold::{TypeFoldable, fold_regions}; use rustc_middle::ty::{ self, ReBound, ReEarlyParam, ReErased, ReError, ReLateParam, RePlaceholder, ReStatic, ReVar, Region, RegionVid, Ty, TyCtxt, @@ -974,7 +974,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> { where T: TypeFoldable>, { - tcx.fold_regions(value, |r, _db| self.resolve_region(tcx, r)) + fold_regions(tcx, value, |r, _db| self.resolve_region(tcx, r)) } fn value(&self, rid: RegionVid) -> &VarValue<'tcx> { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index b29dc7f909dd5..544f941dda574 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -33,7 +33,7 @@ use rustc_middle::traits::select; pub use rustc_middle::ty::IntVarValue; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::{ - BoundVarReplacerDelegate, TypeFoldable, TypeFolder, TypeSuperFoldable, + BoundVarReplacerDelegate, TypeFoldable, TypeFolder, TypeSuperFoldable, fold_regions, }; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{ @@ -43,7 +43,6 @@ use rustc_middle::ty::{ }; use rustc_span::Span; use rustc_span::symbol::Symbol; -use rustc_type_ir::solve::Reveal; use snapshot::undo_log::InferCtxtUndoLogs; use tracing::{debug, instrument}; use type_variable::TypeVariableOrigin; @@ -265,11 +264,12 @@ pub struct InferCtxt<'tcx> { lexical_region_resolutions: RefCell>>, /// Caches the results of trait selection. This cache is used - /// for things that have to do with the parameters in scope. - pub selection_cache: select::SelectionCache<'tcx>, + /// for things that depends on inference variables or placeholders. + pub selection_cache: select::SelectionCache<'tcx, ty::ParamEnv<'tcx>>, - /// Caches the results of trait evaluation. - pub evaluation_cache: select::EvaluationCache<'tcx>, + /// Caches the results of trait evaluation. This cache is used + /// for things that depends on inference variables or placeholders. + pub evaluation_cache: select::EvaluationCache<'tcx, ty::ParamEnv<'tcx>>, /// The set of predicates on which errors have been reported, to /// avoid reporting the same error twice. @@ -624,22 +624,7 @@ impl<'tcx> InferCtxt<'tcx> { } #[inline(always)] - pub fn typing_mode( - &self, - param_env_for_debug_assertion: ty::ParamEnv<'tcx>, - ) -> TypingMode<'tcx> { - if cfg!(debug_assertions) { - match (param_env_for_debug_assertion.reveal(), self.typing_mode) { - (Reveal::All, TypingMode::PostAnalysis) - | (Reveal::UserFacing, TypingMode::Coherence | TypingMode::Analysis { .. }) => {} - (r, t) => unreachable!("TypingMode x Reveal mismatch: {r:?} {t:?}"), - } - } - self.typing_mode - } - - #[inline(always)] - pub fn typing_mode_unchecked(&self) -> TypingMode<'tcx> { + pub fn typing_mode(&self) -> TypingMode<'tcx> { self.typing_mode } @@ -1005,11 +990,17 @@ impl<'tcx> InferCtxt<'tcx> { #[inline(always)] pub fn can_define_opaque_ty(&self, id: impl Into) -> bool { - match self.typing_mode_unchecked() { + debug_assert!(!self.next_trait_solver()); + match self.typing_mode() { TypingMode::Analysis { defining_opaque_types } => { id.into().as_local().is_some_and(|def_id| defining_opaque_types.contains(&def_id)) } - TypingMode::Coherence | TypingMode::PostAnalysis => false, + // FIXME(#132279): This function is quite weird in post-analysis + // and post-borrowck analysis mode. We may need to modify its uses + // to support PostBorrowckAnalysis in the old solver as well. + TypingMode::Coherence + | TypingMode::PostBorrowckAnalysis { .. } + | TypingMode::PostAnalysis => false, } } @@ -1180,7 +1171,7 @@ impl<'tcx> InferCtxt<'tcx> { } if value.has_infer_regions() { let guar = self.dcx().delayed_bug(format!("`{value:?}` is not fully resolved")); - Ok(self.tcx.fold_regions(value, |re, _| { + Ok(fold_regions(self.tcx, value, |re, _| { if re.is_var() { ty::Region::new_error(self.tcx, guar) } else { re } })) } else { @@ -1290,8 +1281,7 @@ impl<'tcx> InferCtxt<'tcx> { /// which contains the necessary information to use the trait system without /// using canonicalization or carrying this inference context around. pub fn typing_env(&self, param_env: ty::ParamEnv<'tcx>) -> ty::TypingEnv<'tcx> { - let typing_mode = match self.typing_mode(param_env) { - ty::TypingMode::Coherence => ty::TypingMode::Coherence, + let typing_mode = match self.typing_mode() { // FIXME(#132279): This erases the `defining_opaque_types` as it isn't possible // to handle them without proper canonicalization. This means we may cause cycle // errors and fail to reveal opaques while inside of bodies. We should rename this @@ -1299,7 +1289,9 @@ impl<'tcx> InferCtxt<'tcx> { ty::TypingMode::Analysis { defining_opaque_types: _ } => { TypingMode::non_body_analysis() } - ty::TypingMode::PostAnalysis => ty::TypingMode::PostAnalysis, + mode @ (ty::TypingMode::Coherence + | ty::TypingMode::PostBorrowckAnalysis { .. } + | ty::TypingMode::PostAnalysis) => mode, }; ty::TypingEnv { typing_mode, param_env } } @@ -1478,39 +1470,29 @@ impl<'tcx> TypeTrace<'tcx> { self.cause.span } - pub fn types( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Ty<'tcx>, - b: Ty<'tcx>, - ) -> TypeTrace<'tcx> { + pub fn types(cause: &ObligationCause<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())), + values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())), } } pub fn trait_refs( cause: &ObligationCause<'tcx>, - a_is_expected: bool, a: ty::TraitRef<'tcx>, b: ty::TraitRef<'tcx>, ) -> TypeTrace<'tcx> { - TypeTrace { - cause: cause.clone(), - values: ValuePairs::TraitRefs(ExpectedFound::new(a_is_expected, a, b)), - } + TypeTrace { cause: cause.clone(), values: ValuePairs::TraitRefs(ExpectedFound::new(a, b)) } } pub fn consts( cause: &ObligationCause<'tcx>, - a_is_expected: bool, a: ty::Const<'tcx>, b: ty::Const<'tcx>, ) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())), + values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())), } } } diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 0aff46203144a..b64686afd2340 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -98,10 +98,11 @@ impl<'tcx> InferCtxt<'tcx> { span: Span, param_env: ty::ParamEnv<'tcx>, ) -> Result>>, TypeError<'tcx>> { + debug_assert!(!self.next_trait_solver()); let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => { let def_id = def_id.expect_local(); - if let ty::TypingMode::Coherence = self.typing_mode(param_env) { + if let ty::TypingMode::Coherence = self.typing_mode() { // See comment on `insert_hidden_type` for why this is sufficient in coherence return Some(self.register_hidden_type( OpaqueTypeKey { def_id, args }, @@ -177,7 +178,7 @@ impl<'tcx> InferCtxt<'tcx> { res } else { let (a, b) = self.resolve_vars_if_possible((a, b)); - Err(TypeError::Sorts(ExpectedFound::new(true, a, b))) + Err(TypeError::Sorts(ExpectedFound::new(a, b))) } } @@ -522,7 +523,7 @@ impl<'tcx> InferCtxt<'tcx> { // value being folded. In simple cases like `-> impl Foo`, // these are the same span, but not in cases like `-> (impl // Foo, impl Bar)`. - match self.typing_mode(param_env) { + match self.typing_mode() { ty::TypingMode::Coherence => { // During intercrate we do not define opaque types but instead always // force ambiguity unless the hidden type is known to not implement @@ -546,7 +547,9 @@ impl<'tcx> InferCtxt<'tcx> { ); } } - ty::TypingMode::PostAnalysis => bug!("insert hidden type post-analysis"), + mode @ (ty::TypingMode::PostBorrowckAnalysis { .. } | ty::TypingMode::PostAnalysis) => { + bug!("insert hidden type in {mode:?}") + } } Ok(()) diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 4c80bf4e07e8c..21c47967eada9 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -520,10 +520,7 @@ impl<'tcx> TypeRelation> for Generalizer<'_, 'tcx> { // // cc trait-system-refactor-initiative#108 if self.infcx.next_trait_solver() - && !matches!( - self.infcx.typing_mode_unchecked(), - TypingMode::Coherence - ) + && !matches!(self.infcx.typing_mode(), TypingMode::Coherence) && self.in_alias { inner.type_variables().equate(vid, new_var_id); @@ -654,10 +651,7 @@ impl<'tcx> TypeRelation> for Generalizer<'_, 'tcx> { // See the comment for type inference variables // for more details. if self.infcx.next_trait_solver() - && !matches!( - self.infcx.typing_mode_unchecked(), - TypingMode::Coherence - ) + && !matches!(self.infcx.typing_mode(), TypingMode::Coherence) && self.in_alias { variable_table.union(vid, new_var_id); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 43a98782016b5..2905fe688b501 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -689,10 +689,12 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock = LazyLock::new(|| { rustc_const_eval::provide(providers); rustc_middle::hir::provide(providers); rustc_borrowck::provide(providers); + rustc_incremental::provide(providers); rustc_mir_build::provide(providers); rustc_mir_transform::provide(providers); rustc_monomorphize::provide(providers); rustc_privacy::provide(providers); + rustc_query_impl::provide(providers); rustc_resolve::provide(providers); rustc_hir_analysis::provide(providers); rustc_hir_typeck::provide(providers); diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index b6837ec764f24..cd3a2fb70490f 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -12,13 +12,12 @@ use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; use rustc_middle::ty::{GlobalCtxt, TyCtxt}; -use rustc_serialize::opaque::FileEncodeResult; use rustc_session::Session; use rustc_session::config::{self, OutputFilenames, OutputType}; use crate::errors::FailedWritingFile; use crate::interface::{Compiler, Result}; -use crate::{errors, passes}; +use crate::passes; /// Represent the result of a query. /// @@ -62,7 +61,7 @@ impl<'a, T> std::ops::DerefMut for QueryResult<'a, T> { impl<'a, 'tcx> QueryResult<'a, &'tcx GlobalCtxt<'tcx>> { pub fn enter(&mut self, f: impl FnOnce(TyCtxt<'tcx>) -> T) -> T { - (*self.0).get_mut().enter(f) + (*self.0).borrow().enter(f) } } @@ -90,8 +89,10 @@ impl<'tcx> Queries<'tcx> { } } - pub fn finish(&self) -> FileEncodeResult { - if let Some(gcx) = self.gcx_cell.get() { gcx.finish() } else { Ok(0) } + pub fn finish(&'tcx self) { + if let Some(gcx) = self.gcx_cell.get() { + gcx.finish(); + } } pub fn parse(&self) -> Result> { @@ -209,29 +210,10 @@ impl Compiler { let queries = Queries::new(self); let ret = f(&queries); - // NOTE: intentionally does not compute the global context if it hasn't been built yet, - // since that likely means there was a parse error. - if let Some(Ok(gcx)) = &mut *queries.gcx.result.borrow_mut() { - let gcx = gcx.get_mut(); - // We assume that no queries are run past here. If there are new queries - // after this point, they'll show up as "" in self-profiling data. - { - let _prof_timer = - queries.compiler.sess.prof.generic_activity("self_profile_alloc_query_strings"); - gcx.enter(rustc_query_impl::alloc_self_profile_query_strings); - } - - self.sess.time("serialize_dep_graph", || gcx.enter(rustc_incremental::save_dep_graph)); - - gcx.enter(rustc_query_impl::query_key_hash_verify_all); - } - // The timer's lifetime spans the dropping of `queries`, which contains // the global context. _timer = self.sess.timer("free_global_ctxt"); - if let Err((path, error)) = queries.finish() { - self.sess.dcx().emit_fatal(errors::FailedWritingFile { path: &path, error }); - } + queries.finish(); ret } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index e48c4d46b597c..c1b2d8562522a 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -712,7 +712,7 @@ fn test_unstable_options_tracking_hash() { untracked!(no_analysis, true); untracked!(no_leak_check, true); untracked!(no_parallel_backend, true); - untracked!(parse_only, true); + untracked!(parse_crate_root_only, true); // `pre_link_arg` is omitted because it just forwards to `pre_link_args`. untracked!(pre_link_args, vec![String::from("abc"), String::from("def")]); untracked!(print_codegen_stats, true); @@ -784,7 +784,6 @@ fn test_unstable_options_tracking_hash() { tracked!(flatten_format_args, false); tracked!(fmt_debug, FmtDebug::Shallow); tracked!(force_unstable_if_unmarked, true); - tracked!(fuel, Some(("abc".to_string(), 99))); tracked!(function_return, FunctionReturn::ThunkExtern); tracked!(function_sections, Some(false)); tracked!(human_readable_cgu_names, true); @@ -830,7 +829,6 @@ fn test_unstable_options_tracking_hash() { tracked!(plt, Some(true)); tracked!(polonius, Polonius::Legacy); tracked!(precise_enum_drop_elaboration, false); - tracked!(print_fuel, Some("abc".to_string())); tracked!(profile_sample_use, Some(PathBuf::from("abc"))); tracked!(profiler_runtime, "abc".to_string()); tracked!(regparm, Some(3)); diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index bcb103957badf..b584e7afd98fa 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -566,19 +566,19 @@ impl Cursor<'_> { fn c_or_byte_string( &mut self, - mk_kind: impl FnOnce(bool) -> LiteralKind, - mk_kind_raw: impl FnOnce(Option) -> LiteralKind, + mk_kind: fn(bool) -> LiteralKind, + mk_kind_raw: fn(Option) -> LiteralKind, single_quoted: Option LiteralKind>, ) -> TokenKind { match (self.first(), self.second(), single_quoted) { - ('\'', _, Some(mk_kind)) => { + ('\'', _, Some(single_quoted)) => { self.bump(); let terminated = self.single_quoted_string(); let suffix_start = self.pos_within_token(); if terminated { self.eat_literal_suffix(); } - let kind = mk_kind(terminated); + let kind = single_quoted(terminated); Literal { kind, suffix_start } } ('"', _, _) => { diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs index 556bbf1f5182e..db7225fc2a810 100644 --- a/compiler/rustc_lexer/src/tests.rs +++ b/compiler/rustc_lexer/src/tests.rs @@ -77,61 +77,51 @@ fn test_too_many_hashes() { check_raw_str(&s2, Err(RawStrError::TooManyDelimiters { found: u32::from(max_count) + 1 })); } +// https://github.com/rust-lang/rust/issues/70528 #[test] fn test_valid_shebang() { - // https://github.com/rust-lang/rust/issues/70528 - let input = "#!/usr/bin/rustrun\nlet x = 5;"; - assert_eq!(strip_shebang(input), Some(18)); -} + let input = "#!/bin/bash"; + assert_eq!(strip_shebang(input), Some(input.len())); -#[test] -fn test_invalid_shebang_valid_rust_syntax() { - // https://github.com/rust-lang/rust/issues/70528 - let input = "#! [bad_attribute]"; + let input = "#![attribute]"; assert_eq!(strip_shebang(input), None); -} -#[test] -fn test_shebang_second_line() { - // Because shebangs are interpreted by the kernel, they must be on the first line - let input = "\n#!/bin/bash"; + let input = "#! /bin/bash"; + assert_eq!(strip_shebang(input), Some(input.len())); + + let input = "#! [attribute]"; assert_eq!(strip_shebang(input), None); -} -#[test] -fn test_shebang_space() { - let input = "#! /bin/bash"; + let input = "#! /* blah */ /bin/bash"; assert_eq!(strip_shebang(input), Some(input.len())); -} -#[test] -fn test_shebang_empty_shebang() { - let input = "#! \n[attribute(foo)]"; + let input = "#! /* blah */ [attribute]"; assert_eq!(strip_shebang(input), None); -} -#[test] -fn test_invalid_shebang_comment() { - let input = "#!//bin/ami/a/comment\n["; - assert_eq!(strip_shebang(input), None) -} + let input = "#! // blah\n/bin/bash"; + assert_eq!(strip_shebang(input), Some(10)); // strip up to the newline -#[test] -fn test_invalid_shebang_another_comment() { - let input = "#!/*bin/ami/a/comment*/\n[attribute"; - assert_eq!(strip_shebang(input), None) -} + let input = "#! // blah\n[attribute]"; + assert_eq!(strip_shebang(input), None); -#[test] -fn test_shebang_valid_rust_after() { - let input = "#!/*bin/ami/a/comment*/\npub fn main() {}"; - assert_eq!(strip_shebang(input), Some(23)) -} + let input = "#! /* blah\nblah\nblah */ /bin/bash"; + assert_eq!(strip_shebang(input), Some(10)); -#[test] -fn test_shebang_followed_by_attrib() { - let input = "#!/bin/rust-scripts\n#![allow_unused(true)]"; - assert_eq!(strip_shebang(input), Some(19)); + let input = "#! /* blah\nblah\nblah */ [attribute]"; + assert_eq!(strip_shebang(input), None); + + let input = "#!\n/bin/sh"; + assert_eq!(strip_shebang(input), Some(2)); + + let input = "#!\n[attribute]"; + assert_eq!(strip_shebang(input), None); + + // Because shebangs are interpreted by the kernel, they must be on the first line + let input = "\n#!/bin/bash"; + assert_eq!(strip_shebang(input), None); + + let input = "\n#![attribute]"; + assert_eq!(strip_shebang(input), None); } fn check_lexing(src: &str, expect: Expect) { diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 69fd7f2d8b25f..9df0c50868cb1 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -733,6 +733,9 @@ lint_renamed_lint = lint `{$name}` has been renamed to `{$replace}` lint_requested_level = requested on the command line with `{$level} {$lint_name}` +lint_reserved_multihash = reserved token in Rust 2024 + .suggestion = insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 + lint_reserved_prefix = prefix `{$prefix}` is unknown .label = unknown prefix .suggestion = insert whitespace here to avoid this being parsed as a prefix in Rust 2021 diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index bda982a367538..e130cfc1d736d 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1407,7 +1407,7 @@ declare_lint_pass!(TypeAliasBounds => [TYPE_ALIAS_BOUNDS]); impl TypeAliasBounds { pub(crate) fn affects_object_lifetime_defaults(pred: &hir::WherePredicate<'_>) -> bool { // Bounds of the form `T: 'a` with `T` type param affect object lifetime defaults. - if let hir::WherePredicate::BoundPredicate(pred) = pred + if let hir::WherePredicateKind::BoundPredicate(pred) = pred.kind && pred.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Outlives(_))) && pred.bound_generic_params.is_empty() // indeed, even if absent from the RHS && pred.bounded_ty.as_generic_param().is_some() @@ -1451,11 +1451,11 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { let mut inline_sugg = Vec::new(); for p in generics.predicates { - let span = p.span(); - if p.in_where_clause() { + let span = p.span; + if p.kind.in_where_clause() { where_spans.push(span); } else { - for b in p.bounds() { + for b in p.kind.bounds() { inline_spans.push(b.span()); } inline_sugg.push((span, String::new())); @@ -2071,7 +2071,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { let num_where_predicates = hir_generics .predicates .iter() - .filter(|predicate| predicate.in_where_clause()) + .filter(|predicate| predicate.kind.in_where_clause()) .count(); let mut bound_count = 0; @@ -2080,8 +2080,8 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { let mut dropped_where_predicate_count = 0; for (i, where_predicate) in hir_generics.predicates.iter().enumerate() { let (relevant_lifetimes, bounds, predicate_span, in_where_clause) = - match where_predicate { - hir::WherePredicate::RegionPredicate(predicate) => { + match where_predicate.kind { + hir::WherePredicateKind::RegionPredicate(predicate) => { if let Some(ResolvedArg::EarlyBound(region_def_id)) = cx.tcx.named_bound_var(predicate.lifetime.hir_id) { @@ -2090,21 +2090,21 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { cx.tcx, // don't warn if the inferred span actually came from the predicate we're looking at // this happens if the type is recursively defined - inferred_outlives - .iter() - .filter(|(_, span)| !predicate.span.contains(*span)), + inferred_outlives.iter().filter(|(_, span)| { + !where_predicate.span.contains(*span) + }), item.owner_id.def_id, region_def_id, ), &predicate.bounds, - predicate.span, + where_predicate.span, predicate.in_where_clause, ) } else { continue; } } - hir::WherePredicate::BoundPredicate(predicate) => { + hir::WherePredicateKind::BoundPredicate(predicate) => { // FIXME we can also infer bounds on associated types, // and should check for them here. match predicate.bounded_ty.kind { @@ -2118,12 +2118,12 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { // don't warn if the inferred span actually came from the predicate we're looking at // this happens if the type is recursively defined inferred_outlives.iter().filter(|(_, span)| { - !predicate.span.contains(*span) + !where_predicate.span.contains(*span) }), index, ), &predicate.bounds, - predicate.span, + where_predicate.span, predicate.origin == PredicateOrigin::WhereClause, ) } @@ -2161,7 +2161,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { } else if i + 1 < num_where_predicates { // If all the bounds on a predicate were inferable and there are // further predicates, we want to eat the trailing comma. - let next_predicate_span = hir_generics.predicates[i + 1].span(); + let next_predicate_span = hir_generics.predicates[i + 1].span; if next_predicate_span.from_expansion() { where_lint_spans.push(predicate_span); } else { diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 6eec32beab007..7248b19276381 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -14,7 +14,6 @@ use rustc_feature::Features; use rustc_hir::def::Res; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; -use rustc_infer::traits::Reveal; use rustc_middle::bug; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; @@ -702,7 +701,6 @@ impl<'tcx> LateContext<'tcx> { /// The typing mode of the currently visited node. Use this when /// building a new `InferCtxt`. pub fn typing_mode(&self) -> TypingMode<'tcx> { - debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing); // FIXME(#132279): In case we're in a body, we should use a typing // mode which reveals the opaque types defined by that body. TypingMode::non_body_analysis() diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index 565c3c0425256..a3731e31c2bd6 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -176,8 +176,12 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: & lints::RawPrefix { label: label_span, suggestion: label_span.shrink_to_hi() } .decorate_lint(diag); } - BuiltinLintDiag::ReservedString(suggestion) => { - lints::ReservedString { suggestion }.decorate_lint(diag); + BuiltinLintDiag::ReservedString { is_string, suggestion } => { + if is_string { + lints::ReservedString { suggestion }.decorate_lint(diag); + } else { + lints::ReservedMultihash { suggestion }.decorate_lint(diag); + } } BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, macro_name, invoc_span } => { lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name }.decorate_lint(diag); diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs index e3e51ba263d0f..7e298a9a63c79 100644 --- a/compiler/rustc_lint/src/dangling.rs +++ b/compiler/rustc_lint/src/dangling.rs @@ -130,11 +130,11 @@ impl DanglingPointerSearcher<'_, '_> { fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) { if let ExprKind::MethodCall(method, receiver, _args, _span) = expr.kind - && let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) - && cx.tcx.has_attr(fn_id, sym::rustc_as_ptr) && is_temporary_rvalue(receiver) && let ty = cx.typeck_results().expr_ty(receiver) && owns_allocation(cx.tcx, ty) + && let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) + && cx.tcx.has_attr(fn_id, sym::rustc_as_ptr) { // FIXME: use `emit_node_lint` when `#[primary_span]` is added. cx.tcx.emit_node_span_lint( diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 352155729e51c..3a854796f6735 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -300,7 +300,7 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> { let affect_object_lifetime_defaults = self .preds .iter() - .filter(|pred| pred.in_where_clause() == self.in_where_clause) + .filter(|pred| pred.kind.in_where_clause() == self.in_where_clause) .any(|pred| TypeAliasBounds::affects_object_lifetime_defaults(pred)); // If there are any shorthand assoc tys, then the bounds can't be removed automatically. @@ -3059,3 +3059,10 @@ pub(crate) struct ReservedString { #[suggestion(code = " ", applicability = "machine-applicable")] pub suggestion: Span, } + +#[derive(LintDiagnostic)] +#[diag(lint_reserved_multihash)] +pub(crate) struct ReservedMultihash { + #[suggestion(code = " ", applicability = "machine-applicable")] + pub suggestion: Span, +} diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 5ec920d39f49f..e1a0e1ec5791d 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1304,12 +1304,12 @@ impl EarlyLintPass for UnusedParens { } fn enter_where_predicate(&mut self, _: &EarlyContext<'_>, pred: &ast::WherePredicate) { - use rustc_ast::{WhereBoundPredicate, WherePredicate}; - if let WherePredicate::BoundPredicate(WhereBoundPredicate { + use rustc_ast::{WhereBoundPredicate, WherePredicateKind}; + if let WherePredicateKind::BoundPredicate(WhereBoundPredicate { bounded_ty, bound_generic_params, .. - }) = pred + }) = &pred.kind && let ast::TyKind::Paren(_) = &bounded_ty.kind && bound_generic_params.is_empty() { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 9036741e07877..3b406c7e161a0 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -5173,7 +5173,7 @@ declare_lint! { Warn, "this function call or definition uses a vector type which is not enabled", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, reference: "issue #116558 ", }; } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index c74fceeedba8b..eb761bd6475fb 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -663,8 +663,11 @@ pub enum BuiltinLintDiag { ReservedPrefix(Span, String), /// `'r#` in edition < 2021. RawPrefix(Span), - /// `##` or `#"` is edition < 2024. - ReservedString(Span), + /// `##` or `#"` in edition < 2024. + ReservedString { + is_string: bool, + suggestion: Span, + }, TrailingMacro(bool, Ident), BreakWithLabelAndLoop(Span), UnicodeTextFlow(Span, String), diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index cd70c3f266920..06550728f0f66 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -2051,6 +2051,25 @@ extern "C" bool LLVMRustLLVMHasZstdCompressionForDebugSymbols() { return llvm::compression::zstd::isAvailable(); } +extern "C" void LLVMRustSetNoSanitizeAddress(LLVMValueRef Global) { + GlobalValue &GV = *unwrap(Global); + GlobalValue::SanitizerMetadata MD; + if (GV.hasSanitizerMetadata()) + MD = GV.getSanitizerMetadata(); + MD.NoAddress = true; + MD.IsDynInit = false; + GV.setSanitizerMetadata(MD); +} + +extern "C" void LLVMRustSetNoSanitizeHWAddress(LLVMValueRef Global) { + GlobalValue &GV = *unwrap(Global); + GlobalValue::SanitizerMetadata MD; + if (GV.hasSanitizerMetadata()) + MD = GV.getSanitizerMetadata(); + MD.NoHWAddress = true; + GV.setSanitizerMetadata(MD); +} + // Operations on composite constants. // These are clones of LLVM api functions that will become available in future // releases. They can be removed once Rust's minimum supported LLVM version diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index d80aa0cc4f414..6d7d88fa8d7af 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -233,9 +233,6 @@ metadata_prev_alloc_error_handler = metadata_prev_global_alloc = previous global allocator defined here -metadata_profiler_builtins_needs_core = - `profiler_builtins` crate (required by compiler options) is not compatible with crate attribute `#![no_core]` - metadata_raw_dylib_no_nul = link name must not contain NUL characters if link kind is `raw-dylib` diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index a611e8010be36..a18c6baec00f2 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -724,8 +724,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { fn inject_panic_runtime(&mut self, krate: &ast::Crate) { // If we're only compiling an rlib, then there's no need to select a // panic runtime, so we just skip this section entirely. - let any_non_rlib = self.tcx.crate_types().iter().any(|ct| *ct != CrateType::Rlib); - if !any_non_rlib { + let only_rlib = self.tcx.crate_types().iter().all(|ct| *ct == CrateType::Rlib); + if only_rlib { info!("panic runtime injection skipped, only generating rlib"); return; } @@ -799,20 +799,16 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { self.inject_dependency_if(cnum, "a panic runtime", &|data| data.needs_panic_runtime()); } - fn inject_profiler_runtime(&mut self, krate: &ast::Crate) { - if self.sess.opts.unstable_opts.no_profiler_runtime - || !(self.sess.instrument_coverage() || self.sess.opts.cg.profile_generate.enabled()) - { + fn inject_profiler_runtime(&mut self) { + let needs_profiler_runtime = + self.sess.instrument_coverage() || self.sess.opts.cg.profile_generate.enabled(); + if !needs_profiler_runtime || self.sess.opts.unstable_opts.no_profiler_runtime { return; } info!("loading profiler"); let name = Symbol::intern(&self.sess.opts.unstable_opts.profiler_runtime); - if name == sym::profiler_builtins && attr::contains_name(&krate.attrs, sym::no_core) { - self.dcx().emit_err(errors::ProfilerBuiltinsNeedsCore); - } - let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { return; }; @@ -1046,7 +1042,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { pub fn postprocess(&mut self, krate: &ast::Crate) { self.inject_forced_externs(); - self.inject_profiler_runtime(krate); + self.inject_profiler_runtime(); self.inject_allocator_crate(krate); self.inject_panic_runtime(krate); @@ -1172,7 +1168,7 @@ fn attempt_load_dylib(path: &Path) -> Result.a(libname.so) for the actual // dynamic library let library_name = path.file_stem().expect("expect a library name"); - let mut archive_member = OsString::from("a("); + let mut archive_member = std::ffi::OsString::from("a("); archive_member.push(library_name); archive_member.push(".so)"); let new_path = path.with_extension(archive_member); diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 16684ae6f263a..b6c5619ec18ae 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -339,10 +339,6 @@ pub struct NoPanicStrategy { pub strategy: PanicStrategy, } -#[derive(Diagnostic)] -#[diag(metadata_profiler_builtins_needs_core)] -pub struct ProfilerBuiltinsNeedsCore; - #[derive(Diagnostic)] #[diag(metadata_not_profiler_runtime)] pub struct NotProfilerRuntime { diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index ace46891f83da..8bd2281981b4b 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -54,9 +54,13 @@ pub fn walk_native_lib_search_dirs( // The targets here should be in sync with `copy_third_party_objects` in bootstrap. // FIXME: implement `-Clink-self-contained=+/-unwind,+/-sanitizers`, move the shipped libunwind // and sanitizers to self-contained directory, and stop adding this search path. + // FIXME: On AIX this also has the side-effect of making the list of library search paths + // non-empty, which is needed or the linker may decide to record the LIBPATH env, if + // defined, as the search path instead of appending the default search paths. if sess.target.vendor == "fortanix" || sess.target.os == "linux" || sess.target.os == "fuchsia" + || sess.target.is_like_aix || sess.target.is_like_osx && !sess.opts.unstable_opts.sanitizer.is_empty() { f(&sess.target_tlib_path.dir, false)?; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 87357b74c411e..56beff5aa6425 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -15,6 +15,7 @@ use rustc_data_structures::sync::{Lock, Lrc, OnceLock}; use rustc_data_structures::unhash::UnhashMap; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro}; +use rustc_hir::Safety; use rustc_hir::def::Res; use rustc_hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::{DefPath, DefPathData}; @@ -1101,6 +1102,7 @@ impl<'a> CrateMetadataRef<'a> { did, name: self.item_name(did.index), vis: self.get_visibility(did.index), + safety: self.get_safety(did.index), }) .collect(), adt_kind, @@ -1162,6 +1164,10 @@ impl<'a> CrateMetadataRef<'a> { .map_id(|index| self.local_def_id(index)) } + fn get_safety(self, id: DefIndex) -> Safety { + self.root.tables.safety.get(self, id).unwrap_or_else(|| self.missing("safety", id)) + } + fn get_trait_item_def_id(self, id: DefIndex) -> Option { self.root.tables.trait_item_def_id.get(self, id).map(|d| d.decode_from_cdata(self)) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 8378e7c6e9b99..068a5d31a8e12 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1383,6 +1383,20 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let def_id = local_id.to_def_id(); let def_kind = tcx.def_kind(local_id); self.tables.def_kind.set_some(def_id.index, def_kind); + + // The `DefCollector` will sometimes create unnecessary `DefId`s + // for trivial const arguments which are directly lowered to + // `ConstArgKind::Path`. We never actually access this `DefId` + // anywhere so we don't need to encode it for other crates. + if def_kind == DefKind::AnonConst + && matches!( + tcx.hir_node_by_def_id(local_id), + hir::Node::ConstArg(hir::ConstArg { kind: hir::ConstArgKind::Path(..), .. }) + ) + { + continue; + } + if should_encode_span(def_kind) { let def_span = tcx.def_span(local_id); record!(self.tables.def_span[def_id] <- def_span); @@ -1599,6 +1613,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { f.did.index })); + for field in &variant.fields { + self.tables.safety.set_some(field.did.index, field.safety); + } + if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor { let fn_sig = tcx.fn_sig(ctor_def_id); // FIXME only encode signature for ctor_def_id diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 4a8f8521b4ff7..a486ad42482a6 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -411,6 +411,7 @@ define_tables! { associated_item_or_field_def_ids: Table>, def_kind: Table, visibility: Table>>, + safety: Table, def_span: Table>, def_ident_span: Table>, lookup_stability: Table>, diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 63abd2be9a57a..9438350ca0972 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -198,6 +198,13 @@ fixed_size_enum! { } } +fixed_size_enum! { + hir::Safety { + ( Unsafe ) + ( Safe ) + } +} + fixed_size_enum! { ty::Asyncness { ( Yes ) diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl index 52c3212ab803a..5dd85978f007f 100644 --- a/compiler/rustc_middle/messages.ftl +++ b/compiler/rustc_middle/messages.ftl @@ -73,6 +73,9 @@ middle_drop_check_overflow = middle_erroneous_constant = erroneous constant encountered +middle_failed_writing_file = + failed to write file {$path}: {$error}" + middle_layout_references_error = the type has an unknown layout diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index 5c2aa0005d405..6300d856393c6 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -1,5 +1,5 @@ -use std::fmt; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; +use std::{fmt, io}; use rustc_errors::codes::*; use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage}; @@ -18,6 +18,13 @@ pub struct DropCheckOverflow<'tcx> { pub overflow_ty: Ty<'tcx>, } +#[derive(Diagnostic)] +#[diag(middle_failed_writing_file)] +pub struct FailedWritingFile<'a> { + pub path: &'a Path, + pub error: io::Error, +} + #[derive(Diagnostic)] #[diag(middle_opaque_hidden_type_mismatch)] pub struct OpaqueHiddenTypeMismatch<'tcx> { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 007e6f46006e3..4900575c36e3a 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -947,7 +947,7 @@ impl<'hir> Map<'hir> { Node::Infer(i) => i.span, Node::LetStmt(local) => local.span, Node::Crate(item) => item.spans.inner_span, - Node::WhereBoundPredicate(pred) => pred.span, + Node::WherePredicate(pred) => pred.span, Node::ArrayLenInfer(inf) => inf.span, Node::PreciseCapturingNonLifetimeArg(param) => param.ident.span, Node::Synthetic => unreachable!(), @@ -1225,7 +1225,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { format!("{id} (generic_param {})", path_str(param.def_id)) } Node::Crate(..) => String::from("(root_crate)"), - Node::WhereBoundPredicate(_) => node_str("where bound predicate"), + Node::WherePredicate(_) => node_str("where predicate"), Node::ArrayLenInfer(_) => node_str("array len infer"), Node::Synthetic => unreachable!(), Node::Err(_) => node_str("error"), diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index 742797fdeef14..92fa64b0987ff 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs @@ -108,6 +108,19 @@ declare_hooks! { /// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we /// can just link to the upstream crate and therefore don't need a mono item. hook should_codegen_locally(instance: crate::ty::Instance<'tcx>) -> bool; + + hook alloc_self_profile_query_strings() -> (); + + /// Saves and writes the DepGraph to the file system. + /// + /// This function saves both the dep-graph and the query result cache, + /// and drops the result cache. + /// + /// This function should only run after all queries have completed. + /// Trying to execute a query afterwards would attempt to read the result cache we just dropped. + hook save_dep_graph() -> (); + + hook query_key_hash_verify_all() -> (); } #[cold] diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index b20673fe8daf5..7a91bfad4836c 100644 --- a/compiler/rustc_middle/src/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs @@ -68,6 +68,17 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Given a [`ty::ClosureKind`], get the [`DefId`] of its corresponding `Fn`-family + /// trait, if it is defined. + pub fn async_fn_trait_kind_to_def_id(self, kind: ty::ClosureKind) -> Option { + let items = self.lang_items(); + match kind { + ty::ClosureKind::Fn => items.async_fn_trait(), + ty::ClosureKind::FnMut => items.async_fn_mut_trait(), + ty::ClosureKind::FnOnce => items.async_fn_once_trait(), + } + } + /// Returns `true` if `id` is a `DefId` of [`Fn`], [`FnMut`] or [`FnOnce`] traits. pub fn is_fn_trait(self, id: DefId) -> bool { self.fn_trait_kind_from_def_id(id).is_some() diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index a51370369b8b5..7983329b0f7ef 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -105,8 +105,10 @@ impl<'tcx> ConstValue<'tcx> { typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, ) -> Option { - let size = - tcx.layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(ty)).ok()?.size; + let size = tcx + .layout_of(typing_env.with_post_analysis_normalized(tcx).as_query_input(ty)) + .ok()? + .size; self.try_to_bits(size) } @@ -376,7 +378,7 @@ impl<'tcx> Const<'tcx> { ) -> Option { let int = self.try_eval_scalar_int(tcx, typing_env)?; let size = tcx - .layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(self.ty())) + .layout_of(typing_env.with_post_analysis_normalized(tcx).as_query_input(self.ty())) .ok()? .size; Some(int.to_bits(size)) diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 6eeafe18b354d..e540f0194ec02 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -162,7 +162,7 @@ impl<'tcx> TyCtxt<'tcx> { // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = - self.erase_regions(typing_env.with_reveal_all_normalized(self).as_query_input(cid)); + self.erase_regions(typing_env.with_post_analysis_normalized(self).as_query_input(cid)); if !span.is_dummy() { // The query doesn't know where it is being invoked, so we need to fix the span. self.at(span).eval_to_const_value_raw(inputs).map_err(|e| e.with_span(span)) @@ -182,7 +182,7 @@ impl<'tcx> TyCtxt<'tcx> { // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = - self.erase_regions(typing_env.with_reveal_all_normalized(self).as_query_input(cid)); + self.erase_regions(typing_env.with_post_analysis_normalized(self).as_query_input(cid)); debug!(?inputs); if !span.is_dummy() { // The query doesn't know where it is being invoked, so we need to fix the span. diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index e2379f282ec83..56340ff009553 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -629,8 +629,7 @@ impl<'tcx> Body<'tcx> { ) -> Option<(u128, &'a SwitchTargets)> { // There are two places here we need to evaluate a constant. let eval_mono_const = |constant: &ConstOperand<'tcx>| { - // FIXME(#132279): what is this, why are we using an empty environment with - // `RevealAll` here. + // FIXME(#132279): what is this, why are we using an empty environment here. let typing_env = ty::TypingEnv::fully_monomorphized(); let mono_literal = instance.instantiate_mir_and_normalize_erasing_regions( tcx, diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 244d22d082f48..161716610fe63 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -111,6 +111,13 @@ impl<'tcx> MonoItem<'tcx> { return InstantiationMode::GloballyShared { may_conflict: false }; } + if let InlineAttr::Never = tcx.codegen_fn_attrs(instance.def_id()).inline + && self.is_generic_fn() + { + // Upgrade inline(never) to a globally shared instance. + return InstantiationMode::GloballyShared { may_conflict: true }; + } + // At this point we don't have explicit linkage and we're an // inlined function. If we're inlining into all CGUs then we'll // be creating a local copy per CGU. diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 86abeb5038234..8a70836871353 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -17,6 +17,7 @@ use smallvec::SmallVec; use super::{ConstValue, SourceInfo}; use crate::mir; +use crate::ty::fold::fold_regions; use crate::ty::{self, CoroutineArgsExt, OpaqueHiddenType, Ty, TyCtxt}; rustc_index::newtype_index! { @@ -315,7 +316,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> { /// All regions of `ty` must be of kind `ReVar` and must represent /// universal regions *external* to the closure. pub fn bind(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self { - let inner = tcx.fold_regions(ty, |r, depth| match r.kind() { + let inner = fold_regions(tcx, ty, |r, depth| match r.kind() { ty::ReVar(vid) => { let br = ty::BoundRegion { var: ty::BoundVar::new(vid.index()), @@ -334,7 +335,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> { tcx: TyCtxt<'tcx>, mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>, ) -> Ty<'tcx> { - tcx.fold_regions(self.inner, |r, depth| match r.kind() { + fold_regions(tcx, self.inner, |r, depth| match r.kind() { ty::ReBound(debruijn, br) => { debug_assert_eq!(debruijn, depth); map(ty::RegionVid::new(br.var.index())) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 76338be33aad8..0f2a6d598a0fd 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1373,18 +1373,20 @@ rustc_queries! { /// Gets the ParameterEnvironment for a given item; this environment /// will be in "user-facing" mode, meaning that it is suitable for /// type-checking etc, and it does not normalize specializable - /// associated types. This is almost always what you want, - /// unless you are doing MIR optimizations, in which case you - /// might want to use `reveal_all()` method to change modes. + /// associated types. + /// + /// You should almost certainly not use this. If you already have an InferCtxt, then + /// you should also probably have a `ParamEnv` from when it was built. If you don't, + /// then you should take a `TypingEnv` to ensure that you handle opaque types correctly. query param_env(def_id: DefId) -> ty::ParamEnv<'tcx> { desc { |tcx| "computing normalized predicates of `{}`", tcx.def_path_str(def_id) } feedable } - /// Like `param_env`, but returns the `ParamEnv` in `Reveal::All` mode. - /// Prefer this over `tcx.param_env(def_id).with_reveal_all_normalized(tcx)`, - /// as this method is more efficient. - query param_env_reveal_all_normalized(def_id: DefId) -> ty::ParamEnv<'tcx> { + /// Like `param_env`, but returns the `ParamEnv` after all opaque types have been + /// replaced with their hidden type. This is used in the old trait solver + /// when in `PostAnalysis` mode and should not be called directly. + query param_env_normalized_for_post_analysis(def_id: DefId) -> ty::ParamEnv<'tcx> { desc { |tcx| "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) } } @@ -1465,13 +1467,13 @@ rustc_queries! { /// *IMPORTANT*: *DO NOT* run this query before promoted MIR body is constructed, /// because this query partially depends on that query. /// Otherwise, there is a risk of query cycles. - query list_significant_drop_tys(ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> &'tcx ty::List> { + query list_significant_drop_tys(ty: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> &'tcx ty::List> { desc { |tcx| "computing when `{}` has a significant destructor", ty.value } cache_on_disk_if { false } } /// Computes the layout of a type. Note that this implicitly - /// executes in "reveal all" mode, and will normalize the input type. + /// executes in `TypingMode::PostAnalysis`, and will normalize the input type. query layout_of( key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>> ) -> Result, &'tcx ty::layout::LayoutError<'tcx>> { diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 09731d565b619..d61ef7641ee9f 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -23,7 +23,7 @@ use rustc_span::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_span::symbol::Symbol; use rustc_span::{DUMMY_SP, Span}; // FIXME: Remove this import and import via `solve::` -pub use rustc_type_ir::solve::{BuiltinImplSource, Reveal}; +pub use rustc_type_ir::solve::BuiltinImplSource; use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; @@ -551,7 +551,7 @@ pub struct DerivedCause<'tcx> { pub parent_code: InternedObligationCauseCode<'tcx>, } -#[derive(Clone, Debug, TypeVisitable)] +#[derive(Clone, Debug, PartialEq, Eq, TypeVisitable)] pub enum SelectionError<'tcx> { /// The trait is not implemented. Unimplemented, @@ -573,7 +573,7 @@ pub enum SelectionError<'tcx> { ConstArgHasWrongType { ct: ty::Const<'tcx>, ct_ty: Ty<'tcx>, expected_ty: Ty<'tcx> }, } -#[derive(Clone, Debug, TypeVisitable)] +#[derive(Clone, Debug, PartialEq, Eq, TypeVisitable)] pub struct SignatureMismatchData<'tcx> { pub found_trait_ref: ty::TraitRef<'tcx>, pub expected_trait_ref: ty::TraitRef<'tcx>, diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index 05556ae38a8e2..094fc62afbbf1 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -11,20 +11,10 @@ use self::EvaluationResult::*; use super::{SelectionError, SelectionResult}; use crate::ty; -pub type SelectionCache<'tcx> = Cache< - // This cache does not use `ParamEnvAnd` in its keys because `ParamEnv::and` can replace - // caller bounds with an empty list if the `TraitPredicate` looks global, which may happen - // after erasing lifetimes from the predicate. - (ty::ParamEnv<'tcx>, ty::TraitPredicate<'tcx>), - SelectionResult<'tcx, SelectionCandidate<'tcx>>, ->; - -pub type EvaluationCache<'tcx> = Cache< - // See above: this cache does not use `ParamEnvAnd` in its keys due to sometimes incorrectly - // caching with the wrong `ParamEnv`. - (ty::ParamEnv<'tcx>, ty::PolyTraitPredicate<'tcx>), - EvaluationResult, ->; +pub type SelectionCache<'tcx, ENV> = + Cache<(ENV, ty::TraitPredicate<'tcx>), SelectionResult<'tcx, SelectionCandidate<'tcx>>>; + +pub type EvaluationCache<'tcx, ENV> = Cache<(ENV, ty::PolyTraitPredicate<'tcx>), EvaluationResult>; /// The selection process begins by considering all impls, where /// clauses, and so forth that might resolve an obligation. Sometimes diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 79d56702be256..447cbc8932ee5 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -18,6 +18,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_query_system::ich::StableHashingContext; use rustc_session::DataTypeKind; use rustc_span::symbol::sym; +use rustc_type_ir::solve::AdtDestructorKind; use tracing::{debug, info, trace}; use super::{ @@ -232,6 +233,13 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef> for AdtDef<'tcx> { fn is_fundamental(self) -> bool { self.is_fundamental() } + + fn destructor(self, tcx: TyCtxt<'tcx>) -> Option { + Some(match self.destructor(tcx)?.constness { + hir::Constness::Const => AdtDestructorKind::Const, + hir::Constness::NotConst => AdtDestructorKind::NotConst, + }) + } } #[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable, TyEncodable, TyDecodable)] @@ -402,10 +410,6 @@ impl<'tcx> AdtDef<'tcx> { self.destructor(tcx).is_some() } - pub fn has_non_const_dtor(self, tcx: TyCtxt<'tcx>) -> bool { - matches!(self.destructor(tcx), Some(Destructor { constness: hir::Constness::NotConst, .. })) - } - /// Asserts this is a struct or union and returns its unique variant. pub fn non_enum_variant(self) -> &'tcx VariantDef { assert!(self.is_struct() || self.is_union()); diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 47a84d4b25821..aba5719138c55 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -174,7 +174,6 @@ impl<'tcx, E: TyEncoder>> Encodable for CtfeProvenance { impl<'tcx, E: TyEncoder>> Encodable for ty::ParamEnv<'tcx> { fn encode(&self, e: &mut E) { self.caller_bounds().encode(e); - self.reveal().encode(e); } } @@ -310,8 +309,7 @@ impl<'tcx, D: TyDecoder>> Decodable for ty::SymbolName<'tcx> impl<'tcx, D: TyDecoder>> Decodable for ty::ParamEnv<'tcx> { fn decode(d: &mut D) -> Self { let caller_bounds = Decodable::decode(d); - let reveal = Decodable::decode(d); - ty::ParamEnv::new(caller_bounds, reveal) + ty::ParamEnv::new(caller_bounds) } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index d853edb34c9cf..d27205e26abbe 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -151,10 +151,6 @@ impl<'tcx> Const<'tcx> { } impl<'tcx> rustc_type_ir::inherent::Const> for Const<'tcx> { - fn try_to_target_usize(self, interner: TyCtxt<'tcx>) -> Option { - self.try_to_target_usize(interner) - } - fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst) -> Self { Const::new_infer(tcx, infer) } @@ -336,7 +332,7 @@ impl<'tcx> Const<'tcx> { pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option { let (scalar, ty) = self.try_to_scalar()?; let scalar = scalar.try_to_scalar_int().ok()?; - let input = typing_env.with_reveal_all_normalized(tcx).as_query_input(ty); + let input = typing_env.with_post_analysis_normalized(tcx).as_query_input(ty); let size = tcx.layout_of(input).ok()?.size; Some(scalar.to_bits(size)) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 55c29825fbcb7..3cbb2a3acf592 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -4,7 +4,7 @@ pub mod tls; -use std::assert_matches::assert_matches; +use std::assert_matches::{assert_matches, debug_assert_matches}; use std::borrow::Borrow; use std::cmp::Ordering; use std::hash::{Hash, Hasher}; @@ -377,10 +377,17 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } fn impl_is_const(self, def_id: DefId) -> bool { + debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true }); self.is_conditionally_const(def_id) } fn fn_is_const(self, def_id: DefId) -> bool { + debug_assert_matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn); + self.is_conditionally_const(def_id) + } + + fn alias_has_const_conditions(self, def_id: DefId) -> bool { + debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy); self.is_conditionally_const(def_id) } @@ -663,6 +670,7 @@ bidirectional_lang_item_map! { CoroutineYield, Destruct, DiscriminantKind, + Drop, DynMetadata, Fn, FnMut, @@ -1318,12 +1326,12 @@ pub struct GlobalCtxt<'tcx> { /// Caches the results of trait selection. This cache is used /// for things that do not have to do with the parameters in scope. - pub selection_cache: traits::SelectionCache<'tcx>, + pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>, /// Caches the results of trait evaluation. This cache is used /// for things that do not have to do with the parameters in scope. /// Merge this with `selection_cache`? - pub evaluation_cache: traits::EvaluationCache<'tcx>, + pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>, /// Caches the results of goal evaluation in the new solver. pub new_solver_evaluation_cache: Lock>>, @@ -1363,8 +1371,17 @@ impl<'tcx> GlobalCtxt<'tcx> { tls::enter_context(&icx, || f(icx.tcx)) } - pub fn finish(&self) -> FileEncodeResult { - self.dep_graph.finish_encoding() + pub fn finish(&'tcx self) { + // We assume that no queries are run past here. If there are new queries + // after this point, they'll show up as "" in self-profiling data. + self.enter(|tcx| tcx.alloc_self_profile_query_strings()); + + self.enter(|tcx| tcx.save_dep_graph()); + self.enter(|tcx| tcx.query_key_hash_verify_all()); + + if let Err((path, error)) = self.dep_graph.finish_encoding() { + self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error }); + } } } @@ -1558,10 +1575,6 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub fn consider_optimizing String>(self, msg: T) -> bool { - self.sess.consider_optimizing(|| self.crate_name(LOCAL_CRATE), msg) - } - /// Obtain all lang items of this crate and all dependencies (recursively) pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems { self.get_lang_items(()) @@ -1942,8 +1955,6 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn local_crate_exports_generics(self) -> bool { - debug_assert!(self.sess.opts.share_generics()); - self.crate_types().iter().any(|crate_type| { match crate_type { CrateType::Executable diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 84f52bfe48f23..fd807882e0f7c 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, Diag, DiagArgValue, IntoDiagArg, into_diag_arg_using_display}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir, LangItem, PredicateOrigin, WherePredicate}; +use rustc_hir::{self as hir, LangItem, PredicateOrigin, WherePredicateKind}; use rustc_span::{BytePos, Span}; use rustc_type_ir::TyKind::*; @@ -180,7 +180,7 @@ fn suggest_changing_unsized_bound( // First look at the `where` clause because we can have `where T: ?Sized`, // then look at params. for (where_pos, predicate) in generics.predicates.iter().enumerate() { - let WherePredicate::BoundPredicate(predicate) = predicate else { + let WherePredicateKind::BoundPredicate(predicate) = predicate.kind else { continue; }; if !predicate.is_param_bound(param.def_id.to_def_id()) { diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 43d243b0584e4..4a82af3255950 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -58,12 +58,9 @@ impl<'tcx> TypeError<'tcx> { pluralize!(values.found) ) .into(), - TypeError::FixedArraySize(values) => format!( - "expected an array with a fixed size of {} element{}, found one with {} element{}", - values.expected, - pluralize!(values.expected), - values.found, - pluralize!(values.found) + TypeError::ArraySize(values) => format!( + "expected an array with a size of {}, found one with a size of {}", + values.expected, values.found, ) .into(), TypeError::ArgCount => "incorrect number of function parameters".into(), diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 7adbd556141fe..1b073d3c466d3 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -2,9 +2,9 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::DefId; use rustc_type_ir::data_structures::DelayedMap; pub use rustc_type_ir::fold::{ - FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable, shift_region, shift_vars, + FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable, fold_regions, shift_region, + shift_vars, }; -use tracing::{debug, instrument}; use crate::ty::{self, Binder, BoundTy, Ty, TyCtxt, TypeVisitableExt}; @@ -50,85 +50,6 @@ where } } -/////////////////////////////////////////////////////////////////////////// -// Region folder - -impl<'tcx> TyCtxt<'tcx> { - /// Folds the escaping and free regions in `value` using `f`. - pub fn fold_regions( - self, - value: T, - mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>, - ) -> T - where - T: TypeFoldable>, - { - value.fold_with(&mut RegionFolder::new(self, &mut f)) - } -} - -/// Folds over the substructure of a type, visiting its component -/// types and all regions that occur *free* within it. -/// -/// That is, function pointer types and trait object can introduce -/// new bound regions which are not visited by this visitors as -/// they are not free; only regions that occur free will be -/// visited by `fld_r`. -pub struct RegionFolder<'a, 'tcx> { - tcx: TyCtxt<'tcx>, - - /// Stores the index of a binder *just outside* the stuff we have - /// visited. So this begins as INNERMOST; when we pass through a - /// binder, it is incremented (via `shift_in`). - current_index: ty::DebruijnIndex, - - /// Callback invokes for each free region. The `DebruijnIndex` - /// points to the binder *just outside* the ones we have passed - /// through. - fold_region_fn: - &'a mut (dyn FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx> + 'a), -} - -impl<'a, 'tcx> RegionFolder<'a, 'tcx> { - #[inline] - pub fn new( - tcx: TyCtxt<'tcx>, - fold_region_fn: &'a mut dyn FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>, - ) -> RegionFolder<'a, 'tcx> { - RegionFolder { tcx, current_index: ty::INNERMOST, fold_region_fn } - } -} - -impl<'a, 'tcx> TypeFolder> for RegionFolder<'a, 'tcx> { - fn cx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn fold_binder>>( - &mut self, - t: ty::Binder<'tcx, T>, - ) -> ty::Binder<'tcx, T> { - self.current_index.shift_in(1); - let t = t.super_fold_with(self); - self.current_index.shift_out(1); - t - } - - #[instrument(skip(self), level = "debug", ret)] - fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - match *r { - ty::ReBound(debruijn, _) if debruijn < self.current_index => { - debug!(?self.current_index, "skipped bound region"); - r - } - _ => { - debug!(?self.current_index, "folding free region"); - (self.fold_region_fn)(r, self.current_index) - } - } - } -} - /////////////////////////////////////////////////////////////////////////// // Bound vars replacer diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index dab3e18de33c9..3d4ce112a64a1 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -190,19 +190,23 @@ impl<'tcx> Instance<'tcx> { /// This method already takes into account the global `-Zshare-generics` /// setting, always returning `None` if `share-generics` is off. pub fn upstream_monomorphization(&self, tcx: TyCtxt<'tcx>) -> Option { - // If we are not in share generics mode, we don't link to upstream - // monomorphizations but always instantiate our own internal versions - // instead. - if !tcx.sess.opts.share_generics() { - return None; - } - // If this is an item that is defined in the local crate, no upstream // crate can know about it/provide a monomorphization. if self.def_id().is_local() { return None; } + // If we are not in share generics mode, we don't link to upstream + // monomorphizations but always instantiate our own internal versions + // instead. + if !tcx.sess.opts.share_generics() + // However, if the def_id is marked inline(never), then it's fine to just reuse the + // upstream monomorphization. + && tcx.codegen_fn_attrs(self.def_id()).inline != rustc_attr::InlineAttr::Never + { + return None; + } + // If this a non-generic instance, it cannot be a shared monomorphization. self.args.non_erasable_generics().next()?; @@ -504,8 +508,8 @@ impl<'tcx> Instance<'tcx> { /// ``` /// /// trying to resolve `Debug::fmt` applied to `T` will yield `Ok(None)`, because we do not - /// know what code ought to run. (Note that this setting is also affected by the - /// `RevealMode` in the parameter environment.) + /// know what code ought to run. This setting is also affected by the current `TypingMode` + /// of the environment. /// /// Presuming that coherence and type-check have succeeded, if this method is invoked /// in a monomorphic context (i.e., like during codegen), then it is guaranteed to return diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index fc29b438d3aca..01ad76aedc375 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -682,14 +682,14 @@ pub trait LayoutOfHelpers<'tcx>: HasDataLayout + HasTyCtxt<'tcx> + HasTypingEnv< /// Blanket extension trait for contexts that can compute layouts of types. pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> { /// Computes the layout of a type. Note that this implicitly - /// executes in "reveal all" mode, and will normalize the input type. + /// executes in `TypingMode::PostAnalysis`, and will normalize the input type. #[inline] fn layout_of(&self, ty: Ty<'tcx>) -> Self::LayoutOfResult { self.spanned_layout_of(ty, DUMMY_SP) } /// Computes the layout of a type, at `span`. Note that this implicitly - /// executes in "reveal all" mode, and will normalize the input type. + /// executes in `TypingMode::PostAnalysis`, and will normalize the input type. // FIXME(eddyb) avoid passing information like this, and instead add more // `TyCtxt::at`-like APIs to be able to do e.g. `cx.at(span).layout_of(ty)`. #[inline] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2bc055453a40c..c7a2223ecd78b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -32,11 +32,10 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; -use rustc_data_structures::tagged_ptr::CopyTaggedPtr; use rustc_errors::{Diag, ErrorGuaranteed, StashKey}; -use rustc_hir::LangItem; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; +use rustc_hir::{LangItem, Safety}; use rustc_index::IndexVec; use rustc_macros::{ Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, @@ -104,7 +103,6 @@ use crate::metadata::ModChild; use crate::middle::privacy::EffectiveVisibilities; use crate::mir::{Body, CoroutineLayout}; use crate::query::{IntoQueryParam, Providers}; -use crate::traits::{self, Reveal}; use crate::ty; pub use crate::ty::diagnostics::*; use crate::ty::fast_reject::SimplifiedType; @@ -960,147 +958,50 @@ impl<'tcx> rustc_type_ir::visit::Flags for Clauses<'tcx> { /// [dev guide chapter][param_env_guide] for more information. /// /// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/param_env/param_env_summary.html -#[derive(Copy, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +#[derive(HashStable, TypeVisitable, TypeFoldable)] pub struct ParamEnv<'tcx> { - /// This packs both caller bounds and the reveal enum into one pointer. - /// /// Caller bounds are `Obligation`s that the caller must satisfy. This is /// basically the set of bounds on the in-scope type parameters, translated /// into `Obligation`s, and elaborated and normalized. /// /// Use the `caller_bounds()` method to access. - /// - /// Typically, this is `Reveal::UserFacing`, but during codegen we - /// want `Reveal::All`. - /// - /// Note: This is packed, use the reveal() method to access it. - packed: CopyTaggedPtr, ParamTag, true>, + caller_bounds: Clauses<'tcx>, } impl<'tcx> rustc_type_ir::inherent::ParamEnv> for ParamEnv<'tcx> { - fn reveal(self) -> Reveal { - self.reveal() - } - fn caller_bounds(self) -> impl IntoIterator> { self.caller_bounds() } } -#[derive(Copy, Clone)] -struct ParamTag { - reveal: traits::Reveal, -} - -rustc_data_structures::impl_tag! { - impl Tag for ParamTag; - ParamTag { reveal: traits::Reveal::UserFacing }, - ParamTag { reveal: traits::Reveal::All }, -} - -impl<'tcx> fmt::Debug for ParamEnv<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("ParamEnv") - .field("caller_bounds", &self.caller_bounds()) - .field("reveal", &self.reveal()) - .finish() - } -} - -impl<'a, 'tcx> HashStable> for ParamEnv<'tcx> { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - self.caller_bounds().hash_stable(hcx, hasher); - self.reveal().hash_stable(hcx, hasher); - } -} - -impl<'tcx> TypeFoldable> for ParamEnv<'tcx> { - fn try_fold_with>>( - self, - folder: &mut F, - ) -> Result { - Ok(ParamEnv::new( - self.caller_bounds().try_fold_with(folder)?, - self.reveal().try_fold_with(folder)?, - )) - } -} - -impl<'tcx> TypeVisitable> for ParamEnv<'tcx> { - fn visit_with>>(&self, visitor: &mut V) -> V::Result { - try_visit!(self.caller_bounds().visit_with(visitor)); - self.reveal().visit_with(visitor) - } -} - impl<'tcx> ParamEnv<'tcx> { - /// Construct a trait environment suitable for contexts where - /// there are no where-clauses in scope. Hidden types (like `impl - /// Trait`) are left hidden. In majority of cases it is incorrect + /// Construct a trait environment suitable for contexts where there are + /// no where-clauses in scope. In the majority of cases it is incorrect /// to use an empty environment. See the [dev guide section][param_env_guide] /// for information on what a `ParamEnv` is and how to acquire one. /// /// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/param_env/param_env_summary.html #[inline] pub fn empty() -> Self { - Self::new(ListWithCachedTypeInfo::empty(), Reveal::UserFacing) + Self::new(ListWithCachedTypeInfo::empty()) } #[inline] pub fn caller_bounds(self) -> Clauses<'tcx> { - self.packed.pointer() - } - - #[inline] - pub fn reveal(self) -> traits::Reveal { - self.packed.tag().reveal - } - - /// Construct a trait environment with no where-clauses in scope - /// where the values of all `impl Trait` and other hidden types - /// are revealed. This is suitable for monomorphized, post-typeck - /// environments like codegen or doing optimizations. - /// - /// N.B., if you want to have predicates in scope, use `ParamEnv::new`, - /// or invoke `param_env.with_reveal_all()`. - #[inline] - pub fn reveal_all() -> Self { - Self::new(ListWithCachedTypeInfo::empty(), Reveal::All) + self.caller_bounds } /// Construct a trait environment with the given set of predicates. #[inline] - pub fn new(caller_bounds: Clauses<'tcx>, reveal: Reveal) -> Self { - ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) } - } - - /// Returns a new parameter environment with the same clauses, but - /// which "reveals" the true results of projections in all cases - /// (even for associated types that are specializable). This is - /// the desired behavior during codegen and certain other special - /// contexts; normally though we want to use `Reveal::UserFacing`, - /// which is the default. - /// All opaque types in the caller_bounds of the `ParamEnv` - /// will be normalized to their underlying types. - /// See PR #65989 and issue #65918 for more details - pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> Self { - if self.packed.tag().reveal == traits::Reveal::All { - return self; - } - - // No need to reveal opaques with the new solver enabled, - // since we have lazy norm. - if tcx.next_trait_solver_globally() { - return ParamEnv::new(self.caller_bounds(), Reveal::All); - } - - ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), Reveal::All) + pub fn new(caller_bounds: Clauses<'tcx>) -> Self { + ParamEnv { caller_bounds } } /// Returns this same environment but with no caller bounds. #[inline] pub fn without_caller_bounds(self) -> Self { - Self::new(ListWithCachedTypeInfo::empty(), self.reveal()) + Self::new(ListWithCachedTypeInfo::empty()) } /// Creates a pair of param-env and value for use in queries. @@ -1148,7 +1049,7 @@ impl<'tcx> TypingEnv<'tcx> { /// use `TypingMode::PostAnalysis`, they may still have where-clauses /// in scope. pub fn fully_monomorphized() -> TypingEnv<'tcx> { - TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::reveal_all() } + TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::empty() } } /// Create a typing environment for use during analysis outside of a body. @@ -1166,15 +1067,25 @@ impl<'tcx> TypingEnv<'tcx> { pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam) -> TypingEnv<'tcx> { TypingEnv { typing_mode: TypingMode::PostAnalysis, - param_env: tcx.param_env_reveal_all_normalized(def_id), + param_env: tcx.param_env_normalized_for_post_analysis(def_id), } } /// Modify the `typing_mode` to `PostAnalysis` and eagerly reveal all /// opaque types in the `param_env`. - pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> { - let TypingEnv { typing_mode: _, param_env } = self; - let param_env = param_env.with_reveal_all_normalized(tcx); + pub fn with_post_analysis_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> { + let TypingEnv { typing_mode, param_env } = self; + if let TypingMode::PostAnalysis = typing_mode { + return self; + } + + // No need to reveal opaques with the new solver enabled, + // since we have lazy norm. + let param_env = if tcx.next_trait_solver_globally() { + ParamEnv::new(param_env.caller_bounds()) + } else { + ParamEnv::new(tcx.reveal_opaque_types_in_bounds(param_env.caller_bounds())) + }; TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env } } @@ -1365,6 +1276,11 @@ impl VariantDef { pub fn tail(&self) -> &FieldDef { self.tail_opt().expect("expected unsized ADT to have a tail field") } + + /// Returns whether this variant has unsafe fields. + pub fn has_unsafe_fields(&self) -> bool { + self.fields.iter().any(|x| x.safety == Safety::Unsafe) + } } impl PartialEq for VariantDef { @@ -1447,6 +1363,7 @@ pub struct FieldDef { pub did: DefId, pub name: Symbol, pub vis: Visibility, + pub safety: hir::Safety, } impl PartialEq for FieldDef { @@ -1459,15 +1376,16 @@ impl PartialEq for FieldDef { // of `FieldDef` changes, a compile-error will be produced, reminding // us to revisit this assumption. - let Self { did: lhs_did, name: _, vis: _ } = &self; + let Self { did: lhs_did, name: _, vis: _, safety: _ } = &self; - let Self { did: rhs_did, name: _, vis: _ } = other; + let Self { did: rhs_did, name: _, vis: _, safety: _ } = other; let res = lhs_did == rhs_did; // Double check that implicit assumption detailed above. if cfg!(debug_assertions) && res { - let deep = self.name == other.name && self.vis == other.vis; + let deep = + self.name == other.name && self.vis == other.vis && self.safety == other.safety; assert!(deep, "FieldDef for the same def-id has differing data"); } @@ -1487,7 +1405,7 @@ impl Hash for FieldDef { // of `FieldDef` changes, a compile-error will be produced, reminding // us to revisit this assumption. - let Self { did, name: _, vis: _ } = &self; + let Self { did, name: _, vis: _, safety: _ } = &self; did.hash(s) } @@ -1640,10 +1558,7 @@ impl<'tcx> TyCtxt<'tcx> { let is_box = self.is_lang_item(did.to_def_id(), LangItem::OwnedBox); // This is here instead of layout because the choice must make it into metadata. - if is_box - || !self - .consider_optimizing(|| format!("Reorder fields of {:?}", self.def_path_str(did))) - { + if is_box { flags.insert(ReprFlags::IS_LINEAR); } diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 7c280bc8b49e9..f7322217aa33f 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -86,6 +86,7 @@ trivially_parameterized_over_tcx! { rustc_attr::Stability, rustc_hir::Constness, rustc_hir::Defaultness, + rustc_hir::Safety, rustc_hir::CoroutineKind, rustc_hir::IsAsync, rustc_hir::LangItem, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 039c988f5c972..cd4123f0a3f56 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -16,8 +16,8 @@ use rustc_hir::definitions::{DefKey, DefPathDataName}; use rustc_macros::{Lift, extension}; use rustc_session::Limit; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; -use rustc_span::FileNameDisplayPreference; use rustc_span::symbol::{Ident, Symbol, kw}; +use rustc_span::{FileNameDisplayPreference, sym}; use rustc_type_ir::{Upcast as _, elaborate}; use smallvec::SmallVec; @@ -26,8 +26,8 @@ use super::*; use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; use crate::query::{IntoQueryParam, Providers}; use crate::ty::{ - ConstInt, Expr, GenericArgKind, ParamConst, ScalarInt, Term, TermKind, TypeFoldable, - TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, + ConstInt, Expr, GenericArgKind, ParamConst, ScalarInt, Term, TermKind, TraitPredicate, + TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, }; macro_rules! p { @@ -993,10 +993,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { match bound_predicate.skip_binder() { ty::ClauseKind::Trait(pred) => { - let trait_ref = bound_predicate.rebind(pred.trait_ref); - // Don't print `+ Sized`, but rather `+ ?Sized` if absent. - if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) { + if tcx.is_lang_item(pred.def_id(), LangItem::Sized) { match pred.polarity { ty::PredicatePolarity::Positive => { has_sized_bound = true; @@ -1007,24 +1005,22 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } self.insert_trait_and_projection( - trait_ref, - pred.polarity, + bound_predicate.rebind(pred), None, &mut traits, &mut fn_traits, ); } ty::ClauseKind::Projection(pred) => { - let proj_ref = bound_predicate.rebind(pred); - let trait_ref = proj_ref.required_poly_trait_ref(tcx); - - // Projection type entry -- the def-id for naming, and the ty. - let proj_ty = (proj_ref.projection_def_id(), proj_ref.term()); + let proj = bound_predicate.rebind(pred); + let trait_ref = proj.map_bound(|proj| TraitPredicate { + trait_ref: proj.projection_term.trait_ref(tcx), + polarity: ty::PredicatePolarity::Positive, + }); self.insert_trait_and_projection( trait_ref, - ty::PredicatePolarity::Positive, - Some(proj_ty), + Some((proj.projection_def_id(), proj.term())), &mut traits, &mut fn_traits, ); @@ -1042,88 +1038,66 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { // Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !has_sized_bound; - for (fn_once_trait_ref, entry) in fn_traits { + for ((bound_args, is_async), entry) in fn_traits { write!(self, "{}", if first { "" } else { " + " })?; write!(self, "{}", if paren_needed { "(" } else { "" })?; - self.wrap_binder(&fn_once_trait_ref, |trait_ref, cx| { - define_scoped_cx!(cx); - // Get the (single) generic ty (the args) of this FnOnce trait ref. - let generics = tcx.generics_of(trait_ref.def_id); - let own_args = generics.own_args_no_defaults(tcx, trait_ref.args); - - match (entry.return_ty, own_args[0].expect_ty()) { - // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded - // a return type. - (Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => { - let name = if entry.fn_trait_ref.is_some() { - "Fn" - } else if entry.fn_mut_trait_ref.is_some() { - "FnMut" - } else { - "FnOnce" - }; - - p!(write("{}(", name)); + let trait_def_id = if is_async { + tcx.async_fn_trait_kind_to_def_id(entry.kind).expect("expected AsyncFn lang items") + } else { + tcx.fn_trait_kind_to_def_id(entry.kind).expect("expected Fn lang items") + }; - for (idx, ty) in arg_tys.tuple_fields().iter().enumerate() { - if idx > 0 { - p!(", "); - } - p!(print(ty)); - } + if let Some(return_ty) = entry.return_ty { + self.wrap_binder(&bound_args, |args, cx| { + define_scoped_cx!(cx); + p!(write("{}", tcx.item_name(trait_def_id))); + p!("("); - p!(")"); - if let Some(ty) = return_ty.skip_binder().as_type() { - if !ty.is_unit() { - p!(" -> ", print(return_ty)); - } + for (idx, ty) in args.iter().enumerate() { + if idx > 0 { + p!(", "); } - p!(write("{}", if paren_needed { ")" } else { "" })); - - first = false; + p!(print(ty)); } - // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the - // trait_refs we collected in the OpaqueFnEntry as normal trait refs. - _ => { - if entry.has_fn_once { - traits - .entry((fn_once_trait_ref, ty::PredicatePolarity::Positive)) - .or_default() - .extend( - // Group the return ty with its def id, if we had one. - entry.return_ty.map(|ty| { - (tcx.require_lang_item(LangItem::FnOnceOutput, None), ty) - }), - ); - } - if let Some(trait_ref) = entry.fn_mut_trait_ref { - traits.entry((trait_ref, ty::PredicatePolarity::Positive)).or_default(); - } - if let Some(trait_ref) = entry.fn_trait_ref { - traits.entry((trait_ref, ty::PredicatePolarity::Positive)).or_default(); + + p!(")"); + if let Some(ty) = return_ty.skip_binder().as_type() { + if !ty.is_unit() { + p!(" -> ", print(return_ty)); } } - } + p!(write("{}", if paren_needed { ")" } else { "" })); - Ok(()) - })?; + first = false; + Ok(()) + })?; + } else { + // Otherwise, render this like a regular trait. + traits.insert( + bound_args.map_bound(|args| ty::TraitPredicate { + polarity: ty::PredicatePolarity::Positive, + trait_ref: ty::TraitRef::new(tcx, trait_def_id, [Ty::new_tup(tcx, args)]), + }), + FxIndexMap::default(), + ); + } } // Print the rest of the trait types (that aren't Fn* family of traits) - for ((trait_ref, polarity), assoc_items) in traits { + for (trait_pred, assoc_items) in traits { write!(self, "{}", if first { "" } else { " + " })?; - self.wrap_binder(&trait_ref, |trait_ref, cx| { + self.wrap_binder(&trait_pred, |trait_pred, cx| { define_scoped_cx!(cx); - if polarity == ty::PredicatePolarity::Negative { + if trait_pred.polarity == ty::PredicatePolarity::Negative { p!("!"); } - p!(print(trait_ref.print_only_trait_name())); + p!(print(trait_pred.trait_ref.print_only_trait_name())); - let generics = tcx.generics_of(trait_ref.def_id); - let own_args = generics.own_args_no_defaults(tcx, trait_ref.args); + let generics = tcx.generics_of(trait_pred.def_id()); + let own_args = generics.own_args_no_defaults(tcx, trait_pred.trait_ref.args); if !own_args.is_empty() || !assoc_items.is_empty() { let mut first = true; @@ -1230,51 +1204,48 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { /// traits map or fn_traits map, depending on if the trait is in the Fn* family of traits. fn insert_trait_and_projection( &mut self, - trait_ref: ty::PolyTraitRef<'tcx>, - polarity: ty::PredicatePolarity, + trait_pred: ty::PolyTraitPredicate<'tcx>, proj_ty: Option<(DefId, ty::Binder<'tcx, Term<'tcx>>)>, traits: &mut FxIndexMap< - (ty::PolyTraitRef<'tcx>, ty::PredicatePolarity), + ty::PolyTraitPredicate<'tcx>, FxIndexMap>>, >, - fn_traits: &mut FxIndexMap, OpaqueFnEntry<'tcx>>, + fn_traits: &mut FxIndexMap< + (ty::Binder<'tcx, &'tcx ty::List>>, bool), + OpaqueFnEntry<'tcx>, + >, ) { - let trait_def_id = trait_ref.def_id(); - - // If our trait_ref is FnOnce or any of its children, project it onto the parent FnOnce - // super-trait ref and record it there. - // We skip negative Fn* bounds since they can't use parenthetical notation anyway. - if polarity == ty::PredicatePolarity::Positive - && let Some(fn_once_trait) = self.tcx().lang_items().fn_once_trait() - { - // If we have a FnOnce, then insert it into - if trait_def_id == fn_once_trait { - let entry = fn_traits.entry(trait_ref).or_default(); - // Optionally insert the return_ty as well. - if let Some((_, ty)) = proj_ty { - entry.return_ty = Some(ty); - } - entry.has_fn_once = true; - return; - } else if self.tcx().is_lang_item(trait_def_id, LangItem::FnMut) { - let super_trait_ref = elaborate::supertraits(self.tcx(), trait_ref) - .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait) - .unwrap(); + let tcx = self.tcx(); + let trait_def_id = trait_pred.def_id(); - fn_traits.entry(super_trait_ref).or_default().fn_mut_trait_ref = Some(trait_ref); - return; - } else if self.tcx().is_lang_item(trait_def_id, LangItem::Fn) { - let super_trait_ref = elaborate::supertraits(self.tcx(), trait_ref) - .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait) - .unwrap(); + let fn_trait_and_async = if let Some(kind) = tcx.fn_trait_kind_from_def_id(trait_def_id) { + Some((kind, false)) + } else if let Some(kind) = tcx.async_fn_trait_kind_from_def_id(trait_def_id) { + Some((kind, true)) + } else { + None + }; - fn_traits.entry(super_trait_ref).or_default().fn_trait_ref = Some(trait_ref); - return; + if trait_pred.polarity() == ty::PredicatePolarity::Positive + && let Some((kind, is_async)) = fn_trait_and_async + && let ty::Tuple(types) = *trait_pred.skip_binder().trait_ref.args.type_at(1).kind() + { + let entry = fn_traits + .entry((trait_pred.rebind(types), is_async)) + .or_insert_with(|| OpaqueFnEntry { kind, return_ty: None }); + if kind.extends(entry.kind) { + entry.kind = kind; + } + if let Some((proj_def_id, proj_ty)) = proj_ty + && tcx.item_name(proj_def_id) == sym::Output + { + entry.return_ty = Some(proj_ty); } + return; } // Otherwise, just group our traits and projection types. - traits.entry((trait_ref, polarity)).or_default().extend(proj_ty); + traits.entry(trait_pred).or_default().extend(proj_ty); } fn pretty_print_inherent_projection( @@ -3189,10 +3160,10 @@ define_print_and_forward_display! { TraitRefPrintSugared<'tcx> { if !with_reduced_queries() - && let Some(kind) = cx.tcx().fn_trait_kind_from_def_id(self.0.def_id) + && cx.tcx().trait_def(self.0.def_id).paren_sugar && let ty::Tuple(args) = self.0.args.type_at(1).kind() { - p!(write("{}", kind.as_str()), "("); + p!(write("{}", cx.tcx().item_name(self.0.def_id)), "("); for (i, arg) in args.iter().enumerate() { if i > 0 { p!(", "); @@ -3415,11 +3386,7 @@ pub fn provide(providers: &mut Providers) { *providers = Providers { trimmed_def_paths, ..*providers }; } -#[derive(Default)] pub struct OpaqueFnEntry<'tcx> { - // The trait ref is already stored as a key, so just track if we have it as a real predicate - has_fn_once: bool, - fn_mut_trait_ref: Option>, - fn_trait_ref: Option>, + kind: ty::ClosureKind, return_ty: Option>>, } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 504a3c8a6d832..afdec7a86d445 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -3,7 +3,6 @@ use std::iter; pub use rustc_type_ir::relate::*; use crate::ty::error::{ExpectedFound, TypeError}; -use crate::ty::predicate::ExistentialPredicateStableCmpExt as _; use crate::ty::{self as ty, Ty, TyCtxt}; pub type RelateResult<'tcx, T> = rustc_type_ir::relate::RelateResult, T>; @@ -86,13 +85,10 @@ impl<'tcx> Relate> for &'tcx ty::List = a.into_iter().collect(); let mut b_v: Vec<_> = b.into_iter().collect(); - // `skip_binder` here is okay because `stable_cmp` doesn't look at binders - a_v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); a_v.dedup(); - b_v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); b_v.dedup(); if a_v.len() != b_v.len() { - return Err(TypeError::ExistentialMismatch(ExpectedFound::new(true, a, b))); + return Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b))); } let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| { @@ -112,7 +108,7 @@ impl<'tcx> Relate> for &'tcx ty::List Ok(ep_a.rebind(ty::ExistentialPredicate::AutoTrait(a))), - _ => Err(TypeError::ExistentialMismatch(ExpectedFound::new(true, a, b))), + _ => Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b))), } }); tcx.mk_poly_existential_predicates_from_iter(v) diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index e48fac6c7e8bb..0af0a5f170d73 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -237,7 +237,6 @@ TrivialTypeTraversalImpls! { crate::mir::coverage::ConditionId, crate::mir::Local, crate::mir::Promoted, - crate::traits::Reveal, crate::ty::adjustment::AutoBorrowMutability, crate::ty::AdtKind, crate::ty::BoundRegion, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 20c3f84bb4d88..797ac9685b1e0 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -21,6 +21,7 @@ use tracing::{debug, instrument}; use super::TypingEnv; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::query::Providers; +use crate::ty::fold::fold_regions; use crate::ty::layout::{FloatExt, IntegerExt}; use crate::ty::{ self, Asyncness, FallibleTypeFolder, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeFoldable, @@ -423,8 +424,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn async_drop_glue_morphology(self, did: DefId) -> AsyncDropGlueMorphology { let ty: Ty<'tcx> = self.type_of(did).instantiate_identity(); - // Async drop glue morphology is an internal detail, so reveal_all probably - // should be fine + // Async drop glue morphology is an internal detail, so + // using `TypingMode::PostAnalysis` probably should be fine. let typing_env = ty::TypingEnv::fully_monomorphized(); if ty.needs_async_drop(self, typing_env) { AsyncDropGlueMorphology::Custom @@ -735,7 +736,7 @@ impl<'tcx> TyCtxt<'tcx> { .filter(|decl| !decl.ignore_for_traits) .map(move |decl| { let mut vars = vec![]; - let ty = self.fold_regions(decl.ty, |re, debruijn| { + let ty = fold_regions(self, decl.ty, |re, debruijn| { assert_eq!(re, self.lifetimes.re_erased); let var = ty::BoundVar::from_usize(vars.len()); vars.push(ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon)); @@ -1053,7 +1054,7 @@ impl<'tcx> TypeFolder> for OpaqueTypeExpander<'tcx> { // This is because for default trait methods with RPITITs, we // install a `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))` // predicate, which would trivially cause a cycle when we do - // anything that requires `ParamEnv::with_reveal_all_normalized`. + // anything that requires `TypingEnv::with_post_analysis_normalized`. term: projection_pred.term, }) .upcast(self.tcx) @@ -1672,45 +1673,6 @@ pub fn needs_drop_components_with_async<'tcx>( } } -pub fn is_trivially_const_drop(ty: Ty<'_>) -> bool { - match *ty.kind() { - ty::Bool - | ty::Char - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Infer(ty::IntVar(_)) - | ty::Infer(ty::FloatVar(_)) - | ty::Str - | ty::RawPtr(_, _) - | ty::Ref(..) - | ty::FnDef(..) - | ty::FnPtr(..) - | ty::Never - | ty::Foreign(_) => true, - - ty::Alias(..) - | ty::Dynamic(..) - | ty::Error(_) - | ty::Bound(..) - | ty::Param(_) - | ty::Placeholder(_) - | ty::Infer(_) => false, - - // Not trivial because they have components, and instead of looking inside, - // we'll just perform trait selection. - ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Coroutine(..) - | ty::CoroutineWitness(..) - | ty::Adt(..) => false, - - ty::Array(ty, _) | ty::Slice(ty) | ty::Pat(ty, _) => is_trivially_const_drop(ty), - - ty::Tuple(tys) => tys.iter().all(|ty| is_trivially_const_drop(ty)), - } -} - /// Does the equivalent of /// ```ignore (illustrative) /// let v = self.iter().map(|p| p.fold_with(folder)).collect::>(); diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 55149570dbc4d..f28cf84fa693e 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -125,6 +125,16 @@ mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior .label = initializing type with `rustc_layout_scalar_valid_range` attr +mir_build_initializing_type_with_unsafe_field_requires_unsafe = + initializing type with an unsafe field is unsafe and requires unsafe block + .note = unsafe fields may carry library invariants + .label = initialization of struct with unsafe field + +mir_build_initializing_type_with_unsafe_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = + initializing type with an unsafe field is unsafe and requires unsafe block + .note = unsafe fields may carry library invariants + .label = initialization of struct with unsafe field + mir_build_inline_assembly_requires_unsafe = use of inline assembly is unsafe and requires unsafe block .note = inline assembly is entirely unchecked and can cause undefined behavior @@ -203,7 +213,7 @@ mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper = mir_build_lower_range_bound_must_be_less_than_upper = lower range bound must be less than upper -mir_build_more_information = for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +mir_build_more_information = for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html mir_build_moved = value is moved into `{$name}` here @@ -338,8 +348,25 @@ mir_build_unreachable_pattern = unreachable pattern .unreachable_covered_by_catchall = matches any value .unreachable_covered_by_one = matches all the relevant values .unreachable_covered_by_many = multiple earlier patterns match some of the same values + .unreachable_pattern_const_reexport_accessible = there is a constant of the same name imported in another scope, which could have been used to pattern match against its value instead of introducing a new catch-all binding, but it needs to be imported in the pattern's scope + .unreachable_pattern_wanted_const = you might have meant to pattern match against the value of {$is_typo -> + [true] similarly named constant + *[false] constant + } `{$const_name}` instead of introducing a new catch-all binding + .unreachable_pattern_const_inaccessible = there is a constant of the same name, which could have been used to pattern match against its value instead of introducing a new catch-all binding, but it is not accessible from this scope + .unreachable_pattern_let_binding = there is a binding of the same name; if you meant to pattern match against the value of that binding, that is a feature of constants that is not available for `let` bindings .suggestion = remove the match arm +mir_build_unsafe_field_requires_unsafe = + use of unsafe field is unsafe and requires unsafe block + .note = unsafe fields may carry library invariants + .label = use of unsafe field + +mir_build_unsafe_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = + use of unsafe field is unsafe and requires unsafe block + .note = unsafe fields may carry library invariants + .label = use of unsafe field + mir_build_unsafe_fn_safe_body = an unsafe function restricts its caller, but its body is safe by default mir_build_unsafe_not_inherited = items do not inherit unsafety from separate enclosing items @@ -388,6 +415,11 @@ mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe = .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior .label = initializing type with `rustc_layout_scalar_valid_range` attr +mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_unsafe_field_requires_unsafe = + initializing type with an unsafe field is unsafe and requires unsafe block + .note = unsafe fields may carry library invariants + .label = initialization of struct with unsafe field + mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe = use of inline assembly is unsafe and requires unsafe block .note = inline assembly is entirely unchecked and can cause undefined behavior @@ -408,6 +440,11 @@ mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe = .note = the field may not be properly initialized: using uninitialized data will cause undefined behavior .label = access to union field +mir_build_unsafe_op_in_unsafe_fn_unsafe_field_requires_unsafe = + use of unsafe field is unsafe and requires unsafe block + .note = unsafe fields may carry library invariants + .label = use of unsafe field + mir_build_unsized_pattern = cannot use unsized non-slice type `{$non_sm_ty}` in constant patterns mir_build_unused_unsafe = unnecessary `unsafe` block diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 3f89e337781e5..c66af118453e5 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -231,7 +231,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if range.start <= range.end { BinOp::BitAnd } else { BinOp::BitOr }; let mut comparer = |range: u128, bin_op: BinOp| -> Place<'tcx> { - // We can use `ty::TypingEnv::fully_monomorphized()`` here + // We can use `ty::TypingEnv::fully_monomorphized()` here // as we only need it to compute the layout of a primitive. let range_val = Const::from_bits( this.tcx, diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index b497e54d480d2..f37b3f977fa25 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -4,7 +4,7 @@ use std::ops::Bound; use rustc_errors::DiagArgValue; use rustc_hir::def::DefKind; -use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability}; +use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability, Safety}; use rustc_middle::middle::codegen_fn_attrs::TargetFeature; use rustc_middle::mir::BorrowKind; use rustc_middle::span_bug; @@ -339,8 +339,13 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { }; match &pat.kind { - PatKind::Leaf { .. } => { + PatKind::Leaf { subpatterns, .. } => { if let ty::Adt(adt_def, ..) = pat.ty.kind() { + for pat in subpatterns { + if adt_def.non_enum_variant().fields[pat.field].safety == Safety::Unsafe { + self.requires_unsafe(pat.pattern.span, UseOfUnsafeField); + } + } if adt_def.is_union() { let old_in_union_destructure = std::mem::replace(&mut self.in_union_destructure, true); @@ -359,6 +364,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { visit::walk_pat(self, pat); } } + PatKind::Variant { adt_def, args: _, variant_index, subpatterns } => { + for pat in subpatterns { + let field = &pat.field; + if adt_def.variant(*variant_index).fields[*field].safety == Safety::Unsafe { + self.requires_unsafe(pat.pattern.span, UseOfUnsafeField); + } + } + visit::walk_pat(self, pat); + } PatKind::Binding { mode: BindingMode(ByRef::Yes(rm), _), ty, .. } => { if self.inside_adt { let ty::Ref(_, ty, _) = ty.kind() else { @@ -579,15 +593,20 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } ExprKind::Adt(box AdtExpr { adt_def, - variant_index: _, + variant_index, args: _, user_ty: _, fields: _, base: _, - }) => match self.tcx.layout_scalar_valid_range(adt_def.did()) { - (Bound::Unbounded, Bound::Unbounded) => {} - _ => self.requires_unsafe(expr.span, InitializingTypeWith), - }, + }) => { + if adt_def.variant(variant_index).has_unsafe_fields() { + self.requires_unsafe(expr.span, InitializingTypeWithUnsafeField) + } + match self.tcx.layout_scalar_valid_range(adt_def.did()) { + (Bound::Unbounded, Bound::Unbounded) => {} + _ => self.requires_unsafe(expr.span, InitializingTypeWith), + } + } ExprKind::Closure(box ClosureExpr { closure_id, args: _, @@ -601,23 +620,24 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { let def_id = did.expect_local(); self.visit_inner_body(def_id); } - ExprKind::Field { lhs, .. } => { + ExprKind::Field { lhs, variant_index, name } => { let lhs = &self.thir[lhs]; - if let ty::Adt(adt_def, _) = lhs.ty.kind() - && adt_def.is_union() - { - if let Some(assigned_ty) = self.assignment_info { - if assigned_ty.needs_drop(self.tcx, self.typing_env) { - // This would be unsafe, but should be outright impossible since we - // reject such unions. - assert!( - self.tcx.dcx().has_errors().is_some(), - "union fields that need dropping should be impossible: \ - {assigned_ty}" - ); + if let ty::Adt(adt_def, _) = lhs.ty.kind() { + if adt_def.variant(variant_index).fields[name].safety == Safety::Unsafe { + self.requires_unsafe(expr.span, UseOfUnsafeField); + } else if adt_def.is_union() { + if let Some(assigned_ty) = self.assignment_info { + if assigned_ty.needs_drop(self.tcx, self.typing_env) { + // This would be unsafe, but should be outright impossible since we + // reject such unions. + assert!( + self.tcx.dcx().has_errors().is_some(), + "union fields that need dropping should be impossible: {assigned_ty}" + ); + } + } else { + self.requires_unsafe(expr.span, AccessToUnionField); } - } else { - self.requires_unsafe(expr.span, AccessToUnionField); } } } @@ -689,8 +709,10 @@ enum UnsafeOpKind { CallToUnsafeFunction(Option), UseOfInlineAssembly, InitializingTypeWith, + InitializingTypeWithUnsafeField, UseOfMutableStatic, UseOfExternStatic, + UseOfUnsafeField, DerefOfRawPointer, AccessToUnionField, MutationOfLayoutConstrainedField, @@ -770,6 +792,15 @@ impl UnsafeOpKind { unsafe_not_inherited_note, }, ), + InitializingTypeWithUnsafeField => tcx.emit_node_span_lint( + UNSAFE_OP_IN_UNSAFE_FN, + hir_id, + span, + UnsafeOpInUnsafeFnInitializingTypeWithUnsafeFieldRequiresUnsafe { + span, + unsafe_not_inherited_note, + }, + ), UseOfMutableStatic => tcx.emit_node_span_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, @@ -788,6 +819,15 @@ impl UnsafeOpKind { unsafe_not_inherited_note, }, ), + UseOfUnsafeField => tcx.emit_node_span_lint( + UNSAFE_OP_IN_UNSAFE_FN, + hir_id, + span, + UnsafeOpInUnsafeFnUseOfUnsafeFieldRequiresUnsafe { + span, + unsafe_not_inherited_note, + }, + ), DerefOfRawPointer => tcx.emit_node_span_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, @@ -927,6 +967,20 @@ impl UnsafeOpKind { unsafe_not_inherited_note, }); } + InitializingTypeWithUnsafeField if unsafe_op_in_unsafe_fn_allowed => { + dcx.emit_err( + InitializingTypeWithUnsafeFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + span, + unsafe_not_inherited_note, + }, + ); + } + InitializingTypeWithUnsafeField => { + dcx.emit_err(InitializingTypeWithUnsafeFieldRequiresUnsafe { + span, + unsafe_not_inherited_note, + }); + } UseOfMutableStatic if unsafe_op_in_unsafe_fn_allowed => { dcx.emit_err(UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span, @@ -945,6 +999,15 @@ impl UnsafeOpKind { UseOfExternStatic => { dcx.emit_err(UseOfExternStaticRequiresUnsafe { span, unsafe_not_inherited_note }); } + UseOfUnsafeField if unsafe_op_in_unsafe_fn_allowed => { + dcx.emit_err(UseOfUnsafeFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + span, + unsafe_not_inherited_note, + }); + } + UseOfUnsafeField => { + dcx.emit_err(UseOfUnsafeFieldRequiresUnsafe { span, unsafe_not_inherited_note }); + } DerefOfRawPointer if unsafe_op_in_unsafe_fn_allowed => { dcx.emit_err(DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span, diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 676f7c98b8f88..58487a48184ad 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -86,6 +86,16 @@ pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { pub(crate) unsafe_not_inherited_note: Option, } +#[derive(LintDiagnostic)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_unsafe_field_requires_unsafe, code = E0133)] +#[note] +pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithUnsafeFieldRequiresUnsafe { + #[label] + pub(crate) span: Span, + #[subdiagnostic] + pub(crate) unsafe_not_inherited_note: Option, +} + #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe, code = E0133)] #[note] @@ -106,6 +116,16 @@ pub(crate) struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { pub(crate) unsafe_not_inherited_note: Option, } +#[derive(LintDiagnostic)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_unsafe_field_requires_unsafe, code = E0133)] +#[note] +pub(crate) struct UnsafeOpInUnsafeFnUseOfUnsafeFieldRequiresUnsafe { + #[label] + pub(crate) span: Span, + #[subdiagnostic] + pub(crate) unsafe_not_inherited_note: Option, +} + #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe, code = E0133)] #[note] @@ -250,6 +270,17 @@ pub(crate) struct InitializingTypeWithRequiresUnsafe { pub(crate) unsafe_not_inherited_note: Option, } +#[derive(Diagnostic)] +#[diag(mir_build_initializing_type_with_unsafe_field_requires_unsafe, code = E0133)] +#[note] +pub(crate) struct InitializingTypeWithUnsafeFieldRequiresUnsafe { + #[primary_span] + #[label] + pub(crate) span: Span, + #[subdiagnostic] + pub(crate) unsafe_not_inherited_note: Option, +} + #[derive(Diagnostic)] #[diag( mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, @@ -264,6 +295,20 @@ pub(crate) struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { pub(crate) unsafe_not_inherited_note: Option, } +#[derive(Diagnostic)] +#[diag( + mir_build_initializing_type_with_unsafe_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, + code = E0133 +)] +#[note] +pub(crate) struct InitializingTypeWithUnsafeFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + #[primary_span] + #[label] + pub(crate) span: Span, + #[subdiagnostic] + pub(crate) unsafe_not_inherited_note: Option, +} + #[derive(Diagnostic)] #[diag(mir_build_mutable_static_requires_unsafe, code = E0133)] #[note] @@ -308,6 +353,28 @@ pub(crate) struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { pub(crate) unsafe_not_inherited_note: Option, } +#[derive(Diagnostic)] +#[diag(mir_build_unsafe_field_requires_unsafe, code = E0133)] +#[note] +pub(crate) struct UseOfUnsafeFieldRequiresUnsafe { + #[primary_span] + #[label] + pub(crate) span: Span, + #[subdiagnostic] + pub(crate) unsafe_not_inherited_note: Option, +} + +#[derive(Diagnostic)] +#[diag(mir_build_unsafe_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] +#[note] +pub(crate) struct UseOfUnsafeFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + #[primary_span] + #[label] + pub(crate) span: Span, + #[subdiagnostic] + pub(crate) unsafe_not_inherited_note: Option, +} + #[derive(Diagnostic)] #[diag(mir_build_deref_raw_pointer_requires_unsafe, code = E0133)] #[note] @@ -528,7 +595,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo } if let ty::Ref(_, sub_ty, _) = self.ty.kind() { - if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.typing_env()) { + if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.typing_env) { diag.note(fluent::mir_build_reference_note); } } @@ -593,6 +660,14 @@ pub(crate) struct UnreachablePattern<'tcx> { pub(crate) uninhabited_note: Option<()>, #[label(mir_build_unreachable_covered_by_catchall)] pub(crate) covered_by_catchall: Option, + #[subdiagnostic] + pub(crate) wanted_constant: Option, + #[note(mir_build_unreachable_pattern_const_reexport_accessible)] + pub(crate) accessible_constant: Option, + #[note(mir_build_unreachable_pattern_const_inaccessible)] + pub(crate) inaccessible_constant: Option, + #[note(mir_build_unreachable_pattern_let_binding)] + pub(crate) pattern_let_binding: Option, #[label(mir_build_unreachable_covered_by_one)] pub(crate) covered_by_one: Option, #[note(mir_build_unreachable_covered_by_many)] @@ -602,6 +677,20 @@ pub(crate) struct UnreachablePattern<'tcx> { pub(crate) suggest_remove: Option, } +#[derive(Subdiagnostic)] +#[suggestion( + mir_build_unreachable_pattern_wanted_const, + code = "{const_path}", + applicability = "machine-applicable" +)] +pub(crate) struct WantedConstant { + #[primary_span] + pub(crate) span: Span, + pub(crate) is_typo: bool, + pub(crate) const_name: String, + pub(crate) const_path: String, +} + #[derive(Diagnostic)] #[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)] pub(crate) struct ConstPatternDependsOnGenericParameter { diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 47b7f33295185..ee9bcce104e0b 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -284,7 +284,7 @@ impl<'tcx> Cx<'tcx> { let discr_ty = ty.to_ty(tcx); let size = tcx - .layout_of(self.typing_env().as_query_input(discr_ty)) + .layout_of(self.typing_env.as_query_input(discr_ty)) .unwrap_or_else(|e| panic!("could not compute layout for {discr_ty:?}: {e:?}")) .size; @@ -1040,7 +1040,7 @@ impl<'tcx> Cx<'tcx> { // but distinguish between &STATIC and &THREAD_LOCAL as they have different semantics Res::Def(DefKind::Static { .. }, id) => { // this is &raw for extern static or static mut, and & for other statics - let ty = self.tcx.static_ptr_ty(id, self.typing_env()); + let ty = self.tcx.static_ptr_ty(id, self.typing_env); let (temp_lifetime, backwards_incompatible) = self .rvalue_scopes .temporary_scope(self.region_scope_tree, expr.hir_id.local_id); diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index d47f7154c4b5d..a98c2bb61f666 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -12,7 +12,6 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::bug; use rustc_middle::middle::region; use rustc_middle::thir::*; -use rustc_middle::ty::solve::Reveal; use rustc_middle::ty::{self, RvalueScopes, TyCtxt}; use tracing::instrument; @@ -57,7 +56,7 @@ struct Cx<'tcx> { tcx: TyCtxt<'tcx>, thir: Thir<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, region_scope_tree: &'tcx region::ScopeTree, typeck_results: &'tcx ty::TypeckResults<'tcx>, @@ -98,7 +97,9 @@ impl<'tcx> Cx<'tcx> { Cx { tcx, thir: Thir::new(body_type), - param_env: tcx.param_env(def), + // FIXME(#132279): We're in a body, we should use a typing + // mode which reveals the opaque types defined by that body. + typing_env: ty::TypingEnv::non_body_analysis(tcx, def), region_scope_tree: tcx.region_scope_tree(def), typeck_results, rvalue_scopes: &typeck_results.rvalue_scopes, @@ -110,20 +111,9 @@ impl<'tcx> Cx<'tcx> { } } - fn typing_mode(&self) -> ty::TypingMode<'tcx> { - debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing); - // FIXME(#132279): In case we're in a body, we should use a typing - // mode which reveals the opaque types defined by that body. - ty::TypingMode::non_body_analysis() - } - - fn typing_env(&self) -> ty::TypingEnv<'tcx> { - ty::TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env } - } - #[instrument(level = "debug", skip(self))] fn pattern_from_hir(&mut self, p: &'tcx hir::Pat<'tcx>) -> Box> { - pat_from_hir(self.tcx, self.typing_env(), self.typeck_results(), p) + pat_from_hir(self.tcx, self.typing_env, self.typeck_results(), p) } fn closure_env_param(&self, owner_def: LocalDefId, expr_id: HirId) -> Option> { 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 27920008c80b9..e55cd35e2436d 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -7,7 +7,8 @@ use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, struct_span_code_e use rustc_hir::def::*; use rustc_hir::def_id::LocalDefId; use rustc_hir::{self as hir, BindingMode, ByRef, HirId}; -use rustc_infer::traits::Reveal; +use rustc_infer::infer::TyCtxtInferExt; +use rustc_lint::Level; use rustc_middle::bug; use rustc_middle::middle::limits::get_limit_size; use rustc_middle::thir::visit::Visitor; @@ -22,8 +23,10 @@ use rustc_pattern_analysis::rustc::{ use rustc_session::lint::builtin::{ BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS, }; +use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::DesugaringKind; use rustc_span::{Span, sym}; +use rustc_trait_selection::infer::InferCtxtExt; use tracing::instrument; use crate::errors::*; @@ -39,7 +42,8 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err tcx, thir: &*thir, typeck_results, - param_env: tcx.param_env(def_id), + // FIXME(#132279): We're in a body, should handle opaques. + typing_env: ty::TypingEnv::non_body_analysis(tcx, def_id), lint_level: tcx.local_def_id_to_hir_id(def_id), let_source: LetSource::None, pattern_arena: &pattern_arena, @@ -86,7 +90,7 @@ enum LetSource { struct MatchVisitor<'p, 'tcx> { tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, typeck_results: &'tcx ty::TypeckResults<'tcx>, thir: &'p Thir<'tcx>, lint_level: HirId, @@ -192,15 +196,6 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> { } impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { - fn typing_env(&self) -> ty::TypingEnv<'tcx> { - // FIXME(#132279): We're in a body, should handle opaques. - debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing); - ty::TypingEnv { - typing_mode: ty::TypingMode::non_body_analysis(), - param_env: self.param_env, - } - } - #[instrument(level = "trace", skip(self, f))] fn with_let_source(&mut self, let_source: LetSource, f: impl FnOnce(&mut Self)) { let old_let_source = self.let_source; @@ -391,7 +386,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { PatCtxt { tcx: self.tcx, typeck_results: self.typeck_results, - param_env: self.param_env, + typing_env: self.typing_env, module: self.tcx.parent_module(self.lint_level).to_def_id(), dropless_arena: self.dropless_arena, match_lint_level: self.lint_level, @@ -745,8 +740,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { .variant(*variant_index) .inhabited_predicate(self.tcx, *adt) .instantiate(self.tcx, args); - variant_inhabited.apply(self.tcx, cx.typing_env(), cx.module) - && !variant_inhabited.apply_ignore_module(self.tcx, cx.typing_env()) + variant_inhabited.apply(self.tcx, cx.typing_env, cx.module) + && !variant_inhabited.apply_ignore_module(self.tcx, cx.typing_env) } else { false }; @@ -785,7 +780,7 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat: return; }; - let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()); + let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env); let sess = cx.tcx.sess; @@ -969,6 +964,10 @@ fn report_unreachable_pattern<'p, 'tcx>( covered_by_one: None, covered_by_many: None, covered_by_many_n_more_count: 0, + wanted_constant: None, + accessible_constant: None, + inaccessible_constant: None, + pattern_let_binding: None, suggest_remove: None, }; match explanation.covered_by.as_slice() { @@ -991,7 +990,10 @@ fn report_unreachable_pattern<'p, 'tcx>( }); } [covering_pat] if pat_is_catchall(covering_pat) => { - lint.covered_by_catchall = Some(covering_pat.data().span); + // A binding pattern that matches all, a single binding name. + let pat = covering_pat.data(); + lint.covered_by_catchall = Some(pat.span); + find_fallback_pattern_typo(cx, hir_id, pat, &mut lint); } [covering_pat] => { lint.covered_by_one = Some(covering_pat.data().span); @@ -1024,6 +1026,153 @@ fn report_unreachable_pattern<'p, 'tcx>( cx.tcx.emit_node_span_lint(UNREACHABLE_PATTERNS, hir_id, pat_span, lint); } +/// Detect typos that were meant to be a `const` but were interpreted as a new pattern binding. +fn find_fallback_pattern_typo<'tcx>( + cx: &PatCtxt<'_, 'tcx>, + hir_id: HirId, + pat: &Pat<'tcx>, + lint: &mut UnreachablePattern<'_>, +) { + if let (Level::Allow, _) = cx.tcx.lint_level_at_node(UNREACHABLE_PATTERNS, hir_id) { + // This is because we use `with_no_trimmed_paths` later, so if we never emit the lint we'd + // ICE. At the same time, we don't really need to do all of this if we won't emit anything. + return; + } + if let PatKind::Binding { name, subpattern: None, ty, .. } = pat.kind { + // See if the binding might have been a `const` that was mistyped or out of scope. + let mut accessible = vec![]; + let mut accessible_path = vec![]; + let mut inaccessible = vec![]; + let mut imported = vec![]; + let mut imported_spans = vec![]; + let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env); + let parent = cx.tcx.hir().get_parent_item(hir_id); + + for item in cx.tcx.hir_crate_items(()).free_items() { + 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; + }; + for res in &path.res { + if let Res::Def(DefKind::Const, id) = res + && infcx.can_eq(param_env, ty, cx.tcx.type_of(id).instantiate_identity()) + { + if cx.tcx.visibility(id).is_accessible_from(parent, cx.tcx) { + // The original const is accessible, suggest using it directly. + let item_name = cx.tcx.item_name(*id); + accessible.push(item_name); + accessible_path.push(with_no_trimmed_paths!(cx.tcx.def_path_str(id))); + } else if cx + .tcx + .visibility(item.owner_id) + .is_accessible_from(parent, cx.tcx) + { + // The const is accessible only through the re-export, point at + // the `use`. + imported.push(use_name); + imported_spans.push(item.ident.span); + } + } + } + } + if let DefKind::Const = cx.tcx.def_kind(item.owner_id) + && infcx.can_eq(param_env, ty, cx.tcx.type_of(item.owner_id).instantiate_identity()) + { + // Look for local consts. + let item_name = cx.tcx.item_name(item.owner_id.into()); + let vis = cx.tcx.visibility(item.owner_id); + if vis.is_accessible_from(parent, cx.tcx) { + accessible.push(item_name); + let path = if item_name == name { + // We know that the const wasn't in scope because it has the exact + // same name, so we suggest the full path. + with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id)) + } else { + // The const is likely just typoed, and nothing else. + cx.tcx.def_path_str(item.owner_id) + }; + accessible_path.push(path); + } else if name == item_name { + // The const exists somewhere in this crate, but it can't be imported + // from this pattern's scope. We'll just point at its definition. + inaccessible.push(cx.tcx.def_span(item.owner_id)); + } + } + } + if let Some((i, &const_name)) = + accessible.iter().enumerate().find(|(_, &const_name)| const_name == name) + { + // The pattern name is an exact match, so the pattern needed to be imported. + lint.wanted_constant = Some(WantedConstant { + span: pat.span, + is_typo: false, + const_name: const_name.to_string(), + const_path: accessible_path[i].clone(), + }); + } else if let Some(name) = find_best_match_for_name(&accessible, name, None) { + // The pattern name is likely a typo. + lint.wanted_constant = Some(WantedConstant { + span: pat.span, + is_typo: true, + const_name: name.to_string(), + const_path: name.to_string(), + }); + } else if let Some(i) = + imported.iter().enumerate().find(|(_, &const_name)| const_name == name).map(|(i, _)| i) + { + // The const with the exact name wasn't re-exported from an import in this + // crate, we point at the import. + lint.accessible_constant = Some(imported_spans[i]); + } else if let Some(name) = find_best_match_for_name(&imported, name, None) { + // The typoed const wasn't re-exported by an import in this crate, we suggest + // the right name (which will likely require another follow up suggestion). + lint.wanted_constant = Some(WantedConstant { + span: pat.span, + is_typo: true, + const_path: name.to_string(), + const_name: name.to_string(), + }); + } else if !inaccessible.is_empty() { + for span in inaccessible { + // The const with the exact name match isn't accessible, we just point at it. + lint.inaccessible_constant = Some(span); + } + } else { + // Look for local bindings for people that might have gotten confused with how + // `let` and `const` works. + for (_, node) in cx.tcx.hir().parent_iter(hir_id) { + match node { + hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Let(let_stmt), .. }) => { + if let hir::PatKind::Binding(_, _, binding_name, _) = let_stmt.pat.kind { + if name == binding_name.name { + lint.pattern_let_binding = Some(binding_name.span); + } + } + } + hir::Node::Block(hir::Block { stmts, .. }) => { + for stmt in *stmts { + if let hir::StmtKind::Let(let_stmt) = stmt.kind { + if let hir::PatKind::Binding(_, _, binding_name, _) = + let_stmt.pat.kind + { + if name == binding_name.name { + lint.pattern_let_binding = Some(binding_name.span); + } + } + } + } + } + hir::Node::Item(_) => break, + _ => {} + } + } + } + } +} + /// Report unreachable arms, if any. fn report_arm_reachability<'p, 'tcx>( cx: &PatCtxt<'p, 'tcx>, @@ -1149,7 +1298,7 @@ fn report_non_exhaustive_match<'p, 'tcx>( } if let ty::Ref(_, sub_ty, _) = scrut_ty.kind() { - if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.typing_env()) { + if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.typing_env) { err.note("references are always considered inhabited"); } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index a40134e44e7de..5db08f01fdbdc 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -80,14 +80,14 @@ impl<'tcx> ConstToPat<'tcx> { let pat_from_kind = |kind| Box::new(Pat { span: self.span, ty, kind }); // It's not *technically* correct to be revealing opaque types here as borrowcheck has - // not run yet. However, CTFE itself uses `Reveal::All` unconditionally even during - // typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821). As a - // result we always use a revealed env when resolving the instance to evaluate. + // not run yet. However, CTFE itself uses `TypingMode::PostAnalysis` unconditionally even + // during typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821). + // As a result we always use a revealed env when resolving the instance to evaluate. // - // FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All` + // FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself // instead of having this logic here let typing_env = - self.tcx.erase_regions(self.typing_env).with_reveal_all_normalized(self.tcx); + self.tcx.erase_regions(self.typing_env).with_post_analysis_normalized(self.tcx); let uv = self.tcx.erase_regions(uv); // try to resolve e.g. associated constants to their definition on an impl, and then diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs index 5ebb343f4e195..11cf8c3e89848 100644 --- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs +++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs @@ -1,6 +1,7 @@ //! Random access inspection of the results of a dataflow analysis. use std::cmp::Ordering; +use std::ops::{Deref, DerefMut}; #[cfg(debug_assertions)] use rustc_index::bit_set::BitSet; @@ -8,18 +9,63 @@ use rustc_middle::mir::{self, BasicBlock, Location}; use super::{Analysis, Direction, Effect, EffectIndex, Results}; -/// Allows random access inspection of the results of a dataflow analysis. +/// Some `ResultsCursor`s want to own a `Results`, and some want to borrow a `Results`, either +/// mutable or immutably. This type allows all of the above. It's similar to `Cow`. +pub enum ResultsHandle<'a, 'tcx, A> +where + A: Analysis<'tcx>, +{ + Borrowed(&'a Results<'tcx, A>), + BorrowedMut(&'a mut Results<'tcx, A>), + Owned(Results<'tcx, A>), +} + +impl<'tcx, A> Deref for ResultsHandle<'_, 'tcx, A> +where + A: Analysis<'tcx>, +{ + type Target = Results<'tcx, A>; + + fn deref(&self) -> &Results<'tcx, A> { + match self { + ResultsHandle::Borrowed(borrowed) => borrowed, + ResultsHandle::BorrowedMut(borrowed) => borrowed, + ResultsHandle::Owned(owned) => owned, + } + } +} + +impl<'tcx, A> DerefMut for ResultsHandle<'_, 'tcx, A> +where + A: Analysis<'tcx>, +{ + fn deref_mut(&mut self) -> &mut Results<'tcx, A> { + match self { + ResultsHandle::Borrowed(_borrowed) => { + panic!("tried to deref_mut a `ResultsHandle::Borrowed") + } + ResultsHandle::BorrowedMut(borrowed) => borrowed, + ResultsHandle::Owned(owned) => owned, + } + } +} + +/// Allows random access inspection of the results of a dataflow analysis. Use this when you want +/// to inspect domain values only in certain locations; use `ResultsVisitor` if you want to inspect +/// domain values in many or all locations. /// -/// This cursor only has linear performance within a basic block when its statements are visited in -/// the same order as the `DIRECTION` of the analysis. In the worst case—when statements are -/// visited in *reverse* order—performance will be quadratic in the number of statements in the -/// block. The order in which basic blocks are inspected has no impact on performance. +/// Because `Results` only has domain values for the entry of each basic block, these inspections +/// involve some amount of domain value recomputations. This cursor only has linear performance +/// within a basic block when its statements are visited in the same order as the `DIRECTION` of +/// the analysis. In the worst case—when statements are visited in *reverse* order—performance will +/// be quadratic in the number of statements in the block. The order in which basic blocks are +/// inspected has no impact on performance. pub struct ResultsCursor<'mir, 'tcx, A> where A: Analysis<'tcx>, { body: &'mir mir::Body<'tcx>, - results: Results<'tcx, A>, + results: ResultsHandle<'mir, 'tcx, A>, state: A::Domain, pos: CursorPosition, @@ -47,13 +93,8 @@ where self.body } - /// Unwraps this cursor, returning the underlying `Results`. - pub fn into_results(self) -> Results<'tcx, A> { - self.results - } - /// Returns a new cursor that can inspect `results`. - pub fn new(body: &'mir mir::Body<'tcx>, results: Results<'tcx, A>) -> Self { + pub fn new(body: &'mir mir::Body<'tcx>, results: ResultsHandle<'mir, 'tcx, A>) -> Self { let bottom_value = results.analysis.bottom_value(body); ResultsCursor { body, diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index 9a5cf9d4e84ff..566a6b09b2b15 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -9,30 +9,35 @@ use super::{Analysis, Effect, EffectIndex, Results, SwitchIntTarget}; pub trait Direction { const IS_FORWARD: bool; - const IS_BACKWARD: bool = !Self::IS_FORWARD; - /// Applies all effects between the given `EffectIndex`s. - /// - /// `effects.start()` must precede or equal `effects.end()` in this direction. - fn apply_effects_in_range<'tcx, A>( + /// Called by `iterate_to_fixpoint` during initial analysis computation. + fn apply_effects_in_block<'mir, 'tcx, A>( analysis: &mut A, + body: &mir::Body<'tcx>, state: &mut A::Domain, block: BasicBlock, - block_data: &mir::BasicBlockData<'tcx>, - effects: RangeInclusive, + block_data: &'mir mir::BasicBlockData<'tcx>, + propagate: impl FnMut(BasicBlock, &A::Domain), ) where A: Analysis<'tcx>; - fn apply_effects_in_block<'mir, 'tcx, A>( + /// Called by `ResultsCursor` to recompute the domain value for a location + /// in a basic block. Applies all effects between the given `EffectIndex`s. + /// + /// `effects.start()` must precede or equal `effects.end()` in this direction. + fn apply_effects_in_range<'tcx, A>( analysis: &mut A, state: &mut A::Domain, block: BasicBlock, - block_data: &'mir mir::BasicBlockData<'tcx>, - ) -> TerminatorEdges<'mir, 'tcx> - where + block_data: &mir::BasicBlockData<'tcx>, + effects: RangeInclusive, + ) where A: Analysis<'tcx>; + /// Called by `ResultsVisitor` to recompute the analysis domain values for + /// all locations in a basic block (starting from the entry value stored + /// in `Results`) and to visit them with `vis`. fn visit_results_in_block<'mir, 'tcx, A>( state: &mut A::Domain, block: BasicBlock, @@ -41,16 +46,6 @@ pub trait Direction { vis: &mut impl ResultsVisitor<'mir, 'tcx, A>, ) where A: Analysis<'tcx>; - - fn join_state_into_successors_of<'tcx, A>( - analysis: &mut A, - body: &mir::Body<'tcx>, - exit_state: &mut A::Domain, - block: BasicBlock, - edges: TerminatorEdges<'_, 'tcx>, - propagate: impl FnMut(BasicBlock, &A::Domain), - ) where - A: Analysis<'tcx>; } /// Dataflow that runs from the exit of a block (terminator), to its entry (the first statement). @@ -61,23 +56,84 @@ impl Direction for Backward { fn apply_effects_in_block<'mir, 'tcx, A>( analysis: &mut A, + body: &mir::Body<'tcx>, state: &mut A::Domain, block: BasicBlock, block_data: &'mir mir::BasicBlockData<'tcx>, - ) -> TerminatorEdges<'mir, 'tcx> - where + mut propagate: impl FnMut(BasicBlock, &A::Domain), + ) where A: Analysis<'tcx>, { let terminator = block_data.terminator(); let location = Location { block, statement_index: block_data.statements.len() }; analysis.apply_before_terminator_effect(state, terminator, location); - let edges = analysis.apply_terminator_effect(state, terminator, location); + analysis.apply_terminator_effect(state, terminator, location); for (statement_index, statement) in block_data.statements.iter().enumerate().rev() { let location = Location { block, statement_index }; analysis.apply_before_statement_effect(state, statement, location); analysis.apply_statement_effect(state, statement, location); } - edges + + let exit_state = state; + for pred in body.basic_blocks.predecessors()[block].iter().copied() { + match body[pred].terminator().kind { + // Apply terminator-specific edge effects. + // + // FIXME(ecstaticmorse): Avoid cloning the exit state unconditionally. + mir::TerminatorKind::Call { destination, target: Some(dest), .. } + if dest == block => + { + let mut tmp = exit_state.clone(); + analysis.apply_call_return_effect( + &mut tmp, + pred, + CallReturnPlaces::Call(destination), + ); + propagate(pred, &tmp); + } + + mir::TerminatorKind::InlineAsm { ref targets, ref operands, .. } + if targets.contains(&block) => + { + let mut tmp = exit_state.clone(); + analysis.apply_call_return_effect( + &mut tmp, + pred, + CallReturnPlaces::InlineAsm(operands), + ); + propagate(pred, &tmp); + } + + mir::TerminatorKind::Yield { resume, resume_arg, .. } if resume == block => { + let mut tmp = exit_state.clone(); + analysis.apply_call_return_effect( + &mut tmp, + resume, + CallReturnPlaces::Yield(resume_arg), + ); + propagate(pred, &tmp); + } + + mir::TerminatorKind::SwitchInt { targets: _, ref discr } => { + let mut applier = BackwardSwitchIntEdgeEffectsApplier { + body, + pred, + exit_state, + block, + propagate: &mut propagate, + effects_applied: false, + }; + + analysis.apply_switch_int_edge_effects(pred, discr, &mut applier); + + if !applier.effects_applied { + propagate(pred, exit_state) + } + } + + _ => propagate(pred, exit_state), + } + } } fn apply_effects_in_range<'tcx, A>( @@ -170,7 +226,6 @@ impl Direction for Backward { vis.visit_block_end(state); - // Terminator let loc = Location { block, statement_index: block_data.statements.len() }; let term = block_data.terminator(); results.analysis.apply_before_terminator_effect(state, term, loc); @@ -188,82 +243,13 @@ impl Direction for Backward { vis.visit_block_start(state); } - - fn join_state_into_successors_of<'tcx, A>( - analysis: &mut A, - body: &mir::Body<'tcx>, - exit_state: &mut A::Domain, - bb: BasicBlock, - _edges: TerminatorEdges<'_, 'tcx>, - mut propagate: impl FnMut(BasicBlock, &A::Domain), - ) where - A: Analysis<'tcx>, - { - for pred in body.basic_blocks.predecessors()[bb].iter().copied() { - match body[pred].terminator().kind { - // Apply terminator-specific edge effects. - // - // FIXME(ecstaticmorse): Avoid cloning the exit state unconditionally. - mir::TerminatorKind::Call { destination, target: Some(dest), .. } if dest == bb => { - let mut tmp = exit_state.clone(); - analysis.apply_call_return_effect( - &mut tmp, - pred, - CallReturnPlaces::Call(destination), - ); - propagate(pred, &tmp); - } - - mir::TerminatorKind::InlineAsm { ref targets, ref operands, .. } - if targets.contains(&bb) => - { - let mut tmp = exit_state.clone(); - analysis.apply_call_return_effect( - &mut tmp, - pred, - CallReturnPlaces::InlineAsm(operands), - ); - propagate(pred, &tmp); - } - - mir::TerminatorKind::Yield { resume, resume_arg, .. } if resume == bb => { - let mut tmp = exit_state.clone(); - analysis.apply_call_return_effect( - &mut tmp, - resume, - CallReturnPlaces::Yield(resume_arg), - ); - propagate(pred, &tmp); - } - - mir::TerminatorKind::SwitchInt { targets: _, ref discr } => { - let mut applier = BackwardSwitchIntEdgeEffectsApplier { - body, - pred, - exit_state, - bb, - propagate: &mut propagate, - effects_applied: false, - }; - - analysis.apply_switch_int_edge_effects(pred, discr, &mut applier); - - if !applier.effects_applied { - propagate(pred, exit_state) - } - } - - _ => propagate(pred, exit_state), - } - } - } } struct BackwardSwitchIntEdgeEffectsApplier<'mir, 'tcx, D, F> { body: &'mir mir::Body<'tcx>, pred: BasicBlock, exit_state: &'mir mut D, - bb: BasicBlock, + block: BasicBlock, propagate: &'mir mut F, effects_applied: bool, } @@ -276,8 +262,8 @@ where fn apply(&mut self, mut apply_edge_effect: impl FnMut(&mut D, SwitchIntTarget)) { assert!(!self.effects_applied); - let values = &self.body.basic_blocks.switch_sources()[&(self.bb, self.pred)]; - let targets = values.iter().map(|&value| SwitchIntTarget { value, target: self.bb }); + let values = &self.body.basic_blocks.switch_sources()[&(self.block, self.pred)]; + let targets = values.iter().map(|&value| SwitchIntTarget { value, target: self.block }); let mut tmp = None; for target in targets { @@ -298,11 +284,12 @@ impl Direction for Forward { fn apply_effects_in_block<'mir, 'tcx, A>( analysis: &mut A, + _body: &mir::Body<'tcx>, state: &mut A::Domain, block: BasicBlock, block_data: &'mir mir::BasicBlockData<'tcx>, - ) -> TerminatorEdges<'mir, 'tcx> - where + mut propagate: impl FnMut(BasicBlock, &A::Domain), + ) where A: Analysis<'tcx>, { for (statement_index, statement) in block_data.statements.iter().enumerate() { @@ -313,7 +300,53 @@ impl Direction for Forward { let terminator = block_data.terminator(); let location = Location { block, statement_index: block_data.statements.len() }; analysis.apply_before_terminator_effect(state, terminator, location); - analysis.apply_terminator_effect(state, terminator, location) + let edges = analysis.apply_terminator_effect(state, terminator, location); + + let exit_state = state; + match edges { + TerminatorEdges::None => {} + TerminatorEdges::Single(target) => propagate(target, exit_state), + TerminatorEdges::Double(target, unwind) => { + propagate(target, exit_state); + propagate(unwind, exit_state); + } + TerminatorEdges::AssignOnReturn { return_, cleanup, place } => { + // This must be done *first*, otherwise the unwind path will see the assignments. + if let Some(cleanup) = cleanup { + propagate(cleanup, exit_state); + } + + if !return_.is_empty() { + analysis.apply_call_return_effect(exit_state, block, place); + for &target in return_ { + propagate(target, exit_state); + } + } + } + TerminatorEdges::SwitchInt { targets, discr } => { + let mut applier = ForwardSwitchIntEdgeEffectsApplier { + exit_state, + targets, + propagate, + effects_applied: false, + }; + + analysis.apply_switch_int_edge_effects(block, discr, &mut applier); + + let ForwardSwitchIntEdgeEffectsApplier { + exit_state, + mut propagate, + effects_applied, + .. + } = applier; + + if !effects_applied { + for target in targets.all_targets() { + propagate(*target, exit_state); + } + } + } + } } fn apply_effects_in_range<'tcx, A>( @@ -351,7 +384,8 @@ impl Direction for Forward { let statement = &block_data.statements[from.statement_index]; analysis.apply_statement_effect(state, statement, location); - // If we only needed to apply the after effect of the statement at `idx`, we are done. + // If we only needed to apply the after effect of the statement at `idx`, we are + // done. if from == to { return; } @@ -419,62 +453,6 @@ impl Direction for Forward { vis.visit_block_end(state); } - - fn join_state_into_successors_of<'tcx, A>( - analysis: &mut A, - _body: &mir::Body<'tcx>, - exit_state: &mut A::Domain, - bb: BasicBlock, - edges: TerminatorEdges<'_, 'tcx>, - mut propagate: impl FnMut(BasicBlock, &A::Domain), - ) where - A: Analysis<'tcx>, - { - match edges { - TerminatorEdges::None => {} - TerminatorEdges::Single(target) => propagate(target, exit_state), - TerminatorEdges::Double(target, unwind) => { - propagate(target, exit_state); - propagate(unwind, exit_state); - } - TerminatorEdges::AssignOnReturn { return_, cleanup, place } => { - // This must be done *first*, otherwise the unwind path will see the assignments. - if let Some(cleanup) = cleanup { - propagate(cleanup, exit_state); - } - - if !return_.is_empty() { - analysis.apply_call_return_effect(exit_state, bb, place); - for &target in return_ { - propagate(target, exit_state); - } - } - } - TerminatorEdges::SwitchInt { targets, discr } => { - let mut applier = ForwardSwitchIntEdgeEffectsApplier { - exit_state, - targets, - propagate, - effects_applied: false, - }; - - analysis.apply_switch_int_edge_effects(bb, discr, &mut applier); - - let ForwardSwitchIntEdgeEffectsApplier { - exit_state, - mut propagate, - effects_applied, - .. - } = applier; - - if !effects_applied { - for target in targets.all_targets() { - propagate(*target, exit_state); - } - } - } - } - } } struct ForwardSwitchIntEdgeEffectsApplier<'mir, D, F> { diff --git a/compiler/rustc_mir_dataflow/src/framework/fmt.rs b/compiler/rustc_mir_dataflow/src/framework/fmt.rs index ed540cd148c45..dc176ba2d03ea 100644 --- a/compiler/rustc_mir_dataflow/src/framework/fmt.rs +++ b/compiler/rustc_mir_dataflow/src/framework/fmt.rs @@ -4,7 +4,7 @@ use std::fmt; use rustc_index::Idx; -use rustc_index::bit_set::{BitSet, ChunkedBitSet, HybridBitSet}; +use rustc_index::bit_set::{BitSet, ChunkedBitSet}; use super::lattice::MaybeReachable; @@ -85,8 +85,8 @@ where let size = self.domain_size(); assert_eq!(size, old.domain_size()); - let mut set_in_self = HybridBitSet::new_empty(size); - let mut cleared_in_self = HybridBitSet::new_empty(size); + let mut set_in_self = ChunkedBitSet::new_empty(size); + let mut cleared_in_self = ChunkedBitSet::new_empty(size); for i in (0..size).map(T::new) { match (self.contains(i), old.contains(i)) { @@ -112,8 +112,8 @@ where let size = self.domain_size(); assert_eq!(size, old.domain_size()); - let mut set_in_self = HybridBitSet::new_empty(size); - let mut cleared_in_self = HybridBitSet::new_empty(size); + let mut set_in_self = ChunkedBitSet::new_empty(size); + let mut cleared_in_self = ChunkedBitSet::new_empty(size); for i in (0..size).map(T::new) { match (self.contains(i), old.contains(i)) { @@ -159,8 +159,8 @@ where } fn fmt_diff( - inserted: &HybridBitSet, - removed: &HybridBitSet, + inserted: &ChunkedBitSet, + removed: &ChunkedBitSet, ctxt: &C, f: &mut fmt::Formatter<'_>, ) -> fmt::Result @@ -230,16 +230,3 @@ where write!(f, "{}", ctxt.move_data().move_paths[*self]) } } - -impl DebugWithContext for crate::lattice::Dual -where - T: DebugWithContext, -{ - fn fmt_with(&self, ctxt: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (self.0).fmt_with(ctxt, f) - } - - fn fmt_diff_with(&self, old: &Self, ctxt: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (self.0).fmt_diff_with(&old.0, ctxt, f) - } -} diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index 98a4f58cb5dc3..6e4994af8b4e4 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -47,20 +47,16 @@ where { pub(crate) fn new( body: &'mir Body<'tcx>, - results: Results<'tcx, A>, + results: &'mir Results<'tcx, A>, style: OutputStyle, ) -> Self { let reachable = mir::traversal::reachable_as_bitset(body); - Formatter { cursor: results.into_results_cursor(body).into(), style, reachable } + Formatter { cursor: results.as_results_cursor(body).into(), style, reachable } } fn body(&self) -> &'mir Body<'tcx> { self.cursor.borrow().body() } - - pub(crate) fn into_results(self) -> Results<'tcx, A> { - self.cursor.into_inner().into_results() - } } /// A pair of a basic block and an index into that basic blocks `successors`. diff --git a/compiler/rustc_mir_dataflow/src/framework/lattice.rs b/compiler/rustc_mir_dataflow/src/framework/lattice.rs index 4d03ee53b7c00..e2b56aedca3ab 100644 --- a/compiler/rustc_mir_dataflow/src/framework/lattice.rs +++ b/compiler/rustc_mir_dataflow/src/framework/lattice.rs @@ -25,8 +25,8 @@ //! //! ## `PartialOrd` //! -//! Given that they represent partially ordered sets, you may be surprised that [`JoinSemiLattice`] -//! and [`MeetSemiLattice`] do not have [`PartialOrd`] as a supertrait. This +//! Given that it represents a partially ordered set, you may be surprised that [`JoinSemiLattice`] +//! does not have [`PartialOrd`] as a supertrait. This //! is because most standard library types use lexicographic ordering instead of set inclusion for //! their `PartialOrd` impl. Since we do not actually need to compare lattice elements to run a //! dataflow analysis, there's no need for a newtype wrapper with a custom `PartialOrd` impl. The @@ -40,7 +40,7 @@ use std::iter; -use rustc_index::bit_set::{BitSet, ChunkedBitSet, HybridBitSet}; +use rustc_index::bit_set::{BitSet, ChunkedBitSet}; use rustc_index::{Idx, IndexVec}; use crate::framework::BitSetExt; @@ -58,23 +58,6 @@ pub trait JoinSemiLattice: Eq { fn join(&mut self, other: &Self) -> bool; } -/// A [partially ordered set][poset] that has a [greatest lower bound][glb] for any pair of -/// elements in the set. -/// -/// Dataflow analyses only require that their domains implement [`JoinSemiLattice`], not -/// `MeetSemiLattice`. However, types that will be used as dataflow domains should implement both -/// so that they can be used with [`Dual`]. -/// -/// [glb]: https://en.wikipedia.org/wiki/Infimum_and_supremum -/// [poset]: https://en.wikipedia.org/wiki/Partially_ordered_set -pub trait MeetSemiLattice: Eq { - /// Computes the greatest lower bound of two elements, storing the result in `self` and - /// returning `true` if `self` has changed. - /// - /// The lattice meet operator is abbreviated as `∧`. - fn meet(&mut self, other: &Self) -> bool; -} - /// A set that has a "bottom" element, which is less than or equal to any other element. pub trait HasBottom { const BOTTOM: Self; @@ -105,17 +88,6 @@ impl JoinSemiLattice for bool { } } -impl MeetSemiLattice for bool { - fn meet(&mut self, other: &Self) -> bool { - if let (true, false) = (*self, *other) { - *self = false; - return true; - } - - false - } -} - impl HasBottom for bool { const BOTTOM: Self = false; @@ -145,18 +117,6 @@ impl JoinSemiLattice for IndexVec { } } -impl MeetSemiLattice for IndexVec { - fn meet(&mut self, other: &Self) -> bool { - assert_eq!(self.len(), other.len()); - - let mut changed = false; - for (a, b) in iter::zip(self, other) { - changed |= a.meet(b); - } - changed - } -} - /// A `BitSet` represents the lattice formed by the powerset of all possible values of /// the index type `T` ordered by inclusion. Equivalently, it is a tuple of "two-point" lattices, /// one for each possible value of `T`. @@ -166,60 +126,12 @@ impl JoinSemiLattice for BitSet { } } -impl MeetSemiLattice for BitSet { - fn meet(&mut self, other: &Self) -> bool { - self.intersect(other) - } -} - impl JoinSemiLattice for ChunkedBitSet { fn join(&mut self, other: &Self) -> bool { self.union(other) } } -impl MeetSemiLattice for ChunkedBitSet { - fn meet(&mut self, other: &Self) -> bool { - self.intersect(other) - } -} - -/// The counterpart of a given semilattice `T` using the [inverse order]. -/// -/// The dual of a join-semilattice is a meet-semilattice and vice versa. For example, the dual of a -/// powerset has the empty set as its top element and the full set as its bottom element and uses -/// set *intersection* as its join operator. -/// -/// [inverse order]: https://en.wikipedia.org/wiki/Duality_(order_theory) -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct Dual(pub T); - -impl BitSetExt for Dual> { - fn contains(&self, elem: T) -> bool { - self.0.contains(elem) - } - - fn union(&mut self, other: &HybridBitSet) { - self.0.union(other); - } - - fn subtract(&mut self, other: &HybridBitSet) { - self.0.subtract(other); - } -} - -impl JoinSemiLattice for Dual { - fn join(&mut self, other: &Self) -> bool { - self.0.meet(&other.0) - } -} - -impl MeetSemiLattice for Dual { - fn meet(&mut self, other: &Self) -> bool { - self.0.join(&other.0) - } -} - /// Extends a type `T` with top and bottom elements to make it a partially ordered set in which no /// value of `T` is comparable with any other. /// @@ -257,22 +169,6 @@ impl JoinSemiLattice for FlatSet { } } -impl MeetSemiLattice for FlatSet { - fn meet(&mut self, other: &Self) -> bool { - let result = match (&*self, other) { - (Self::Bottom, _) | (_, Self::Top) => return false, - (Self::Elem(ref a), Self::Elem(ref b)) if a == b => return false, - - (Self::Top, Self::Elem(ref x)) => Self::Elem(x.clone()), - - _ => Self::Bottom, - }; - - *self = result; - true - } -} - impl HasBottom for FlatSet { const BOTTOM: Self = Self::Bottom; @@ -331,20 +227,6 @@ impl> BitSetExt for MaybeReachable { fn contains(&self, elem: T) -> bool { self.contains(elem) } - - fn union(&mut self, other: &HybridBitSet) { - match self { - MaybeReachable::Unreachable => {} - MaybeReachable::Reachable(set) => set.union(other), - } - } - - fn subtract(&mut self, other: &HybridBitSet) { - match self { - MaybeReachable::Unreachable => {} - MaybeReachable::Reachable(set) => set.subtract(other), - } - } } impl Clone for MaybeReachable { diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index 244dfe26ad362..f1ea94e16893d 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -8,8 +8,9 @@ //! The `impls` module contains several examples of dataflow analyses. //! //! Then call `iterate_to_fixpoint` on your type that impls `Analysis` to get a `Results`. From -//! there, you can use a `ResultsCursor` to inspect the fixpoint solution to your dataflow problem, -//! or implement the `ResultsVisitor` interface and use `visit_results`. The following example uses +//! there, you can use a `ResultsCursor` to inspect the fixpoint solution to your dataflow problem +//! (good for inspecting a small number of locations), or implement the `ResultsVisitor` interface +//! and use `visit_results` (good for inspecting many or all locations). The following example uses //! the `ResultsCursor` approach. //! //! ```ignore (cross-crate-imports) @@ -34,7 +35,7 @@ use std::cmp::Ordering; use rustc_data_structures::work_queue::WorkQueue; -use rustc_index::bit_set::{BitSet, ChunkedBitSet, HybridBitSet}; +use rustc_index::bit_set::{BitSet, ChunkedBitSet}; use rustc_index::{Idx, IndexVec}; use rustc_middle::bug; use rustc_middle::mir::{self, BasicBlock, CallReturnPlaces, Location, TerminatorEdges, traversal}; @@ -62,36 +63,18 @@ pub use self::visitor::{ResultsVisitor, visit_results}; /// operations needed by all of them. pub trait BitSetExt { fn contains(&self, elem: T) -> bool; - fn union(&mut self, other: &HybridBitSet); - fn subtract(&mut self, other: &HybridBitSet); } impl BitSetExt for BitSet { fn contains(&self, elem: T) -> bool { self.contains(elem) } - - fn union(&mut self, other: &HybridBitSet) { - self.union(other); - } - - fn subtract(&mut self, other: &HybridBitSet) { - self.subtract(other); - } } impl BitSetExt for ChunkedBitSet { fn contains(&self, elem: T) -> bool { self.contains(elem) } - - fn union(&mut self, other: &HybridBitSet) { - self.union(other); - } - - fn subtract(&mut self, other: &HybridBitSet) { - self.subtract(other); - } } /// A dataflow problem with an arbitrarily complex transfer function. @@ -278,22 +261,17 @@ pub trait Analysis<'tcx> { // every iteration. let mut state = self.bottom_value(body); while let Some(bb) = dirty_queue.pop() { - let bb_data = &body[bb]; - // Set the state to the entry state of the block. // This is equivalent to `state = entry_sets[bb].clone()`, // but it saves an allocation, thus improving compile times. state.clone_from(&entry_sets[bb]); - // Apply the block transfer function, using the cached one if it exists. - let edges = Self::Direction::apply_effects_in_block(&mut self, &mut state, bb, bb_data); - - Self::Direction::join_state_into_successors_of( + Self::Direction::apply_effects_in_block( &mut self, body, &mut state, bb, - edges, + &body[bb], |target: BasicBlock, state: &Self::Domain| { let set_changed = entry_sets[target].join(state); if set_changed { @@ -306,14 +284,13 @@ pub trait Analysis<'tcx> { let results = Results { analysis: self, entry_sets }; if tcx.sess.opts.unstable_opts.dump_mir_dataflow { - let (res, results) = write_graphviz_results(tcx, body, results, pass_name); + let res = write_graphviz_results(tcx, body, &results, pass_name); if let Err(e) = res { error!("Failed to write graphviz dataflow results: {}", e); } - results - } else { - results } + + results } } @@ -378,16 +355,6 @@ impl> GenKill for MaybeReachable { } } -impl GenKill for lattice::Dual> { - fn gen_(&mut self, elem: T) { - self.0.insert(elem); - } - - fn kill(&mut self, elem: T) { - self.0.remove(elem); - } -} - // NOTE: DO NOT CHANGE VARIANT ORDER. The derived `Ord` impls rely on the current order. #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] enum Effect { diff --git a/compiler/rustc_mir_dataflow/src/framework/results.rs b/compiler/rustc_mir_dataflow/src/framework/results.rs index ff6cafbfbaee6..8493a7aa44bb1 100644 --- a/compiler/rustc_mir_dataflow/src/framework/results.rs +++ b/compiler/rustc_mir_dataflow/src/framework/results.rs @@ -17,10 +17,13 @@ use super::{Analysis, ResultsCursor, ResultsVisitor, graphviz, visit_results}; use crate::errors::{ DuplicateValuesFor, PathMustEndInFilename, RequiresAnArgument, UnknownFormatter, }; +use crate::framework::cursor::ResultsHandle; pub type EntrySets<'tcx, A> = IndexVec>::Domain>; -/// A dataflow analysis that has converged to fixpoint. +/// A dataflow analysis that has converged to fixpoint. It only holds the domain values at the +/// entry of each basic block. Domain values in other parts of the block are recomputed on the fly +/// by visitors (i.e. `ResultsCursor`, or `ResultsVisitor` impls). #[derive(Clone)] pub struct Results<'tcx, A> where @@ -34,12 +37,30 @@ impl<'tcx, A> Results<'tcx, A> where A: Analysis<'tcx>, { - /// Creates a `ResultsCursor` that can inspect these `Results`. + /// Creates a `ResultsCursor` that can inspect these `Results`. Immutably borrows the `Results`, + /// which is appropriate when the `Results` is used outside the cursor. + pub fn as_results_cursor<'mir>( + &'mir self, + body: &'mir mir::Body<'tcx>, + ) -> ResultsCursor<'mir, 'tcx, A> { + ResultsCursor::new(body, ResultsHandle::Borrowed(self)) + } + + /// Creates a `ResultsCursor` that can mutate these `Results`. Mutably borrows the `Results`, + /// which is appropriate when the `Results` is used outside the cursor. + pub fn as_results_cursor_mut<'mir>( + &'mir mut self, + body: &'mir mir::Body<'tcx>, + ) -> ResultsCursor<'mir, 'tcx, A> { + ResultsCursor::new(body, ResultsHandle::BorrowedMut(self)) + } + + /// Creates a `ResultsCursor` that takes ownership of the `Results`. pub fn into_results_cursor<'mir>( self, body: &'mir mir::Body<'tcx>, ) -> ResultsCursor<'mir, 'tcx, A> { - ResultsCursor::new(body, self) + ResultsCursor::new(body, ResultsHandle::Owned(self)) } /// Gets the dataflow state for the given block. @@ -74,9 +95,9 @@ where pub(super) fn write_graphviz_results<'tcx, A>( tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>, - results: Results<'tcx, A>, + results: &Results<'tcx, A>, pass_name: Option<&'static str>, -) -> (std::io::Result<()>, Results<'tcx, A>) +) -> std::io::Result<()> where A: Analysis<'tcx>, A::Domain: DebugWithContext, @@ -87,7 +108,7 @@ where let def_id = body.source.def_id(); let Ok(attrs) = RustcMirAttrs::parse(tcx, def_id) else { // Invalid `rustc_mir` attrs are reported in `RustcMirAttrs::parse` - return (Ok(()), results); + return Ok(()); }; let file = try { @@ -104,12 +125,12 @@ where create_dump_file(tcx, "dot", false, A::NAME, &pass_name.unwrap_or("-----"), body)? } - _ => return (Ok(()), results), + _ => return Ok(()), } }; let mut file = match file { Ok(f) => f, - Err(e) => return (Err(e), results), + Err(e) => return Err(e), }; let style = match attrs.formatter { @@ -132,7 +153,7 @@ where file.write_all(&buf)?; }; - (lhs, graphviz.into_results()) + lhs } #[derive(Default)] diff --git a/compiler/rustc_mir_dataflow/src/framework/visitor.rs b/compiler/rustc_mir_dataflow/src/framework/visitor.rs index 5c7539eed4d6a..bde41974d4727 100644 --- a/compiler/rustc_mir_dataflow/src/framework/visitor.rs +++ b/compiler/rustc_mir_dataflow/src/framework/visitor.rs @@ -26,7 +26,9 @@ pub fn visit_results<'mir, 'tcx, A>( } } -/// A visitor over the results of an `Analysis`. +/// A visitor over the results of an `Analysis`. Use this when you want to inspect domain values in +/// many or all locations; use `ResultsCursor` if you want to inspect domain values only in certain +/// locations. pub trait ResultsVisitor<'mir, 'tcx, A> where A: Analysis<'tcx>, diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs index 859019fd1f6ee..cec654cac7251 100644 --- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs +++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs @@ -15,7 +15,7 @@ use crate::{Analysis, GenKill}; pub struct MaybeBorrowedLocals; impl MaybeBorrowedLocals { - pub(super) fn transfer_function<'a, T>(&'a self, trans: &'a mut T) -> TransferFunction<'a, T> { + pub(super) fn transfer_function<'a, T>(trans: &'a mut T) -> TransferFunction<'a, T> { TransferFunction { trans } } } @@ -39,7 +39,7 @@ impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals { statement: &Statement<'tcx>, location: Location, ) { - self.transfer_function(trans).visit_statement(statement, location); + Self::transfer_function(trans).visit_statement(statement, location); } fn apply_terminator_effect<'mir>( @@ -48,7 +48,7 @@ impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals { terminator: &'mir Terminator<'tcx>, location: Location, ) -> TerminatorEdges<'mir, 'tcx> { - self.transfer_function(trans).visit_terminator(terminator, location); + Self::transfer_function(trans).visit_terminator(terminator, location); terminator.edges() } } diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index 9bb50d1e056bd..2c10d4b1cd352 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -12,7 +12,7 @@ use crate::framework::SwitchIntEdgeEffects; use crate::move_paths::{HasMoveData, InitIndex, InitKind, LookupResult, MoveData, MovePathIndex}; use crate::{ Analysis, GenKill, MaybeReachable, drop_flag_effects, drop_flag_effects_for_function_entry, - drop_flag_effects_for_location, lattice, on_all_children_bits, on_lookup_result_bits, + drop_flag_effects_for_location, on_all_children_bits, on_lookup_result_bits, }; /// `MaybeInitializedPlaces` tracks all places that might be @@ -42,10 +42,10 @@ use crate::{ /// } /// ``` /// -/// To determine whether a place *must* be initialized at a -/// particular control-flow point, one can take the set-difference -/// between this data and the data from `MaybeUninitializedPlaces` at the -/// corresponding control-flow point. +/// To determine whether a place is *definitely* initialized at a +/// particular control-flow point, one can take the set-complement +/// of the data from `MaybeUninitializedPlaces` at the corresponding +/// control-flow point. /// /// Similarly, at a given `drop` statement, the set-intersection /// between this data and `MaybeUninitializedPlaces` yields the set of @@ -117,10 +117,10 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> { /// } /// ``` /// -/// To determine whether a place *must* be uninitialized at a -/// particular control-flow point, one can take the set-difference -/// between this data and the data from `MaybeInitializedPlaces` at the -/// corresponding control-flow point. +/// To determine whether a place is *definitely* uninitialized at a +/// particular control-flow point, one can take the set-complement +/// of the data from `MaybeInitializedPlaces` at the corresponding +/// control-flow point. /// /// Similarly, at a given `drop` statement, the set-intersection /// between this data and `MaybeInitializedPlaces` yields the set of @@ -170,57 +170,6 @@ impl<'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { } } -/// `DefinitelyInitializedPlaces` tracks all places that are definitely -/// initialized upon reaching a particular point in the control flow -/// for a function. -/// -/// For example, in code like the following, we have corresponding -/// dataflow information shown in the right-hand comments. -/// -/// ```rust -/// struct S; -/// fn foo(pred: bool) { // definite-init: -/// // { } -/// let a = S; let mut b = S; let c; let d; // {a, b } -/// -/// if pred { -/// drop(a); // { b, } -/// b = S; // { b, } -/// -/// } else { -/// drop(b); // {a, } -/// d = S; // {a, d} -/// -/// } // { } -/// -/// c = S; // { c } -/// } -/// ``` -/// -/// To determine whether a place *may* be uninitialized at a -/// particular control-flow point, one can take the set-complement -/// of this data. -/// -/// Similarly, at a given `drop` statement, the set-difference between -/// this data and `MaybeInitializedPlaces` yields the set of places -/// that would require a dynamic drop-flag at that statement. -pub struct DefinitelyInitializedPlaces<'a, 'tcx> { - body: &'a Body<'tcx>, - move_data: &'a MoveData<'tcx>, -} - -impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> { - pub fn new(body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self { - DefinitelyInitializedPlaces { body, move_data } - } -} - -impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { - fn move_data(&self) -> &MoveData<'tcx> { - self.move_data - } -} - /// `EverInitializedPlaces` tracks all places that might have ever been /// initialized upon reaching a particular point in the control flow /// for a function, without an intervening `StorageDead`. @@ -293,19 +242,6 @@ impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> { } } -impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> { - fn update_bits( - trans: &mut >::Domain, - path: MovePathIndex, - state: DropFlagState, - ) { - match state { - DropFlagState::Absent => trans.kill(path), - DropFlagState::Present => trans.gen_(path), - } - } -} - impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { /// There can be many more `MovePathIndex` than there are locals in a MIR body. /// We use a chunked bitset to avoid paying too high a memory footprint. @@ -554,70 +490,6 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { } } -impl<'a, 'tcx> Analysis<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { - /// Use set intersection as the join operator. - type Domain = lattice::Dual>; - - const NAME: &'static str = "definite_init"; - - fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain { - // bottom = initialized (start_block_effect counters this at outset) - lattice::Dual(BitSet::new_filled(self.move_data().move_paths.len())) - } - - // sets on_entry bits for Arg places - fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain) { - state.0.clear(); - - drop_flag_effects_for_function_entry(self.body, self.move_data, |path, s| { - assert!(s == DropFlagState::Present); - state.0.insert(path); - }); - } - - fn apply_statement_effect( - &mut self, - trans: &mut Self::Domain, - _statement: &mir::Statement<'tcx>, - location: Location, - ) { - drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| { - Self::update_bits(trans, path, s) - }) - } - - fn apply_terminator_effect<'mir>( - &mut self, - trans: &mut Self::Domain, - terminator: &'mir mir::Terminator<'tcx>, - location: Location, - ) -> TerminatorEdges<'mir, 'tcx> { - drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| { - Self::update_bits(trans, path, s) - }); - terminator.edges() - } - - fn apply_call_return_effect( - &mut self, - trans: &mut Self::Domain, - _block: mir::BasicBlock, - return_places: CallReturnPlaces<'_, 'tcx>, - ) { - return_places.for_each(|place| { - // when a call returns successfully, that means we need to set - // the bits for that dest_place to 1 (initialized). - on_lookup_result_bits( - self.move_data(), - self.move_data().rev_lookup.find(place.as_ref()), - |mpi| { - trans.gen_(mpi); - }, - ); - }); - } -} - impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { /// There can be many more `InitIndex` than there are locals in a MIR body. /// We use a chunked bitset to avoid paying too high a memory footprint. diff --git a/compiler/rustc_mir_dataflow/src/impls/mod.rs b/compiler/rustc_mir_dataflow/src/impls/mod.rs index 9b5bfa9bfa00a..b9e194b00c54e 100644 --- a/compiler/rustc_mir_dataflow/src/impls/mod.rs +++ b/compiler/rustc_mir_dataflow/src/impls/mod.rs @@ -9,10 +9,11 @@ mod storage_liveness; pub use self::borrowed_locals::{MaybeBorrowedLocals, borrowed_locals}; pub use self::initialized::{ - DefinitelyInitializedPlaces, EverInitializedPlaces, MaybeInitializedPlaces, - MaybeUninitializedPlaces, + EverInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces, }; pub use self::liveness::{ MaybeLiveLocals, MaybeTransitiveLiveLocals, TransferFunction as LivenessTransferFunction, }; -pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageDead, MaybeStorageLive}; +pub use self::storage_liveness::{ + MaybeRequiresStorage, MaybeStorageDead, MaybeStorageLive, always_storage_live_locals, +}; diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index 576289e228ad0..1aae06d79d35f 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -7,6 +7,23 @@ use rustc_middle::mir::*; use super::MaybeBorrowedLocals; use crate::{Analysis, GenKill, ResultsCursor}; +/// The set of locals in a MIR body that do not have `StorageLive`/`StorageDead` annotations. +/// +/// These locals have fixed storage for the duration of the body. +pub fn always_storage_live_locals(body: &Body<'_>) -> BitSet { + let mut always_live_locals = BitSet::new_filled(body.local_decls.len()); + + for block in &*body.basic_blocks { + for statement in &block.statements { + if let StatementKind::StorageLive(l) | StatementKind::StorageDead(l) = statement.kind { + always_live_locals.remove(l); + } + } + } + + always_live_locals +} + pub struct MaybeStorageLive<'a> { always_live_locals: Cow<'a, BitSet>, } @@ -28,10 +45,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageLive<'a> { } fn initialize_start_block(&self, body: &Body<'tcx>, on_entry: &mut Self::Domain) { - assert_eq!(body.local_decls.len(), self.always_live_locals.domain_size()); - for local in self.always_live_locals.iter() { - on_entry.insert(local); - } + on_entry.union(&*self.always_live_locals); for arg in body.args_iter() { on_entry.insert(arg); @@ -135,7 +149,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { loc: Location, ) { // If a place is borrowed in a statement, it needs storage for that statement. - self.borrowed_locals.mut_analysis().apply_statement_effect(trans, stmt, loc); + MaybeBorrowedLocals::transfer_function(trans).visit_statement(stmt, loc); match &stmt.kind { StatementKind::StorageDead(l) => trans.kill(*l), @@ -180,10 +194,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { loc: Location, ) { // If a place is borrowed in a terminator, it needs storage for that terminator. - self.borrowed_locals - .mut_analysis() - .transfer_function(trans) - .visit_terminator(terminator, loc); + MaybeBorrowedLocals::transfer_function(trans).visit_terminator(terminator, loc); match &terminator.kind { TerminatorKind::Call { destination, .. } => { diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index ab1453f1ed091..2248972ceccb4 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -25,7 +25,7 @@ pub use self::framework::{ use self::move_paths::MoveData; pub mod debuginfo; -pub mod drop_flag_effects; +mod drop_flag_effects; pub mod elaborate_drops; mod errors; mod framework; @@ -33,13 +33,12 @@ pub mod impls; pub mod move_paths; pub mod points; pub mod rustc_peek; -pub mod storage; -pub mod un_derefer; +mod un_derefer; pub mod value_analysis; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } -pub struct MoveDataParamEnv<'tcx> { +pub struct MoveDataTypingEnv<'tcx> { pub move_data: MoveData<'tcx>, - pub param_env: ty::ParamEnv<'tcx>, + pub typing_env: ty::TypingEnv<'tcx>, } diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index 99d0ccde1052c..34ef8afdde322 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -12,9 +12,7 @@ use crate::errors::{ PeekMustBePlaceOrRefPlace, StopAfterDataFlowEndedCompilation, }; use crate::framework::BitSetExt; -use crate::impls::{ - DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeLiveLocals, MaybeUninitializedPlaces, -}; +use crate::impls::{MaybeInitializedPlaces, MaybeLiveLocals, MaybeUninitializedPlaces}; use crate::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex}; use crate::{Analysis, JoinSemiLattice, ResultsCursor}; @@ -56,13 +54,6 @@ pub fn sanity_check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { sanity_check_via_rustc_peek(tcx, flow_uninits.into_results_cursor(body)); } - if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_definite_init).is_some() { - let flow_def_inits = - DefinitelyInitializedPlaces::new(body, &move_data).iterate_to_fixpoint(tcx, body, None); - - sanity_check_via_rustc_peek(tcx, flow_def_inits.into_results_cursor(body)); - } - if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_liveness).is_some() { let flow_liveness = MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None); diff --git a/compiler/rustc_mir_dataflow/src/storage.rs b/compiler/rustc_mir_dataflow/src/storage.rs deleted file mode 100644 index e5a0e1d312eae..0000000000000 --- a/compiler/rustc_mir_dataflow/src/storage.rs +++ /dev/null @@ -1,20 +0,0 @@ -use rustc_index::bit_set::BitSet; -use rustc_middle::mir::{self, Local}; - -/// The set of locals in a MIR body that do not have `StorageLive`/`StorageDead` annotations. -/// -/// These locals have fixed storage for the duration of the body. -pub fn always_storage_live_locals(body: &mir::Body<'_>) -> BitSet { - let mut always_live_locals = BitSet::new_filled(body.local_decls.len()); - - for block in &*body.basic_blocks { - for statement in &block.statements { - use mir::StatementKind::{StorageDead, StorageLive}; - if let StorageLive(l) | StorageDead(l) = statement.kind { - always_live_locals.remove(l); - } - } - } - - always_live_locals -} diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 8295a806d7125..9b9aeccf8909c 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -70,8 +70,8 @@ use rustc_middle::ty::{ use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::impls::{ MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive, + always_storage_live_locals, }; -use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor}; use rustc_span::Span; use rustc_span::def_id::{DefId, LocalDefId}; @@ -676,12 +676,11 @@ fn locals_live_across_suspend_points<'tcx>( let mut borrowed_locals_cursor = borrowed_locals_results.clone().into_results_cursor(body); - // Calculate the MIR locals that we actually need to keep storage around - // for. - let mut requires_storage_cursor = + // Calculate the MIR locals that we need to keep storage around for. + let mut requires_storage_results = MaybeRequiresStorage::new(borrowed_locals_results.into_results_cursor(body)) - .iterate_to_fixpoint(tcx, body, None) - .into_results_cursor(body); + .iterate_to_fixpoint(tcx, body, None); + let mut requires_storage_cursor = requires_storage_results.as_results_cursor_mut(body); // Calculate the liveness of MIR locals ignoring borrows. let mut liveness = @@ -697,8 +696,7 @@ fn locals_live_across_suspend_points<'tcx>( let loc = Location { block, statement_index: data.statements.len() }; liveness.seek_to_block_end(block); - let mut live_locals: BitSet<_> = BitSet::new_empty(body.local_decls.len()); - live_locals.union(liveness.get()); + let mut live_locals = liveness.get().clone(); if !movable { // The `liveness` variable contains the liveness of MIR locals ignoring borrows. @@ -754,7 +752,7 @@ fn locals_live_across_suspend_points<'tcx>( body, &saved_locals, always_live_locals.clone(), - requires_storage_cursor.into_results(), + requires_storage_results, ); LivenessInfo { diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 9c74b2f083943..8f977d2979ec3 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -217,11 +217,6 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation { else { continue; }; - if !tcx.consider_optimizing(|| { - format!("{} round {}", tcx.def_path_str(def_id), round_count) - }) { - break; - } // Replace `src` by `dest` everywhere. merges.insert(*src, *dest); diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index 704ed508b22a8..17c8348140a3e 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -108,10 +108,6 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch { let parent = BasicBlock::from_usize(i); let Some(opt_data) = evaluate_candidate(tcx, body, parent) else { continue }; - if !tcx.consider_optimizing(|| format!("EarlyOtherwiseBranch {opt_data:?}")) { - break; - } - trace!("SUCCESS: found optimization possibility to apply: {opt_data:?}"); should_cleanup = true; diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index b0f041d8722ba..0c0f3b61977fe 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -3,7 +3,6 @@ use std::fmt; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_index::IndexVec; use rustc_index::bit_set::BitSet; -use rustc_infer::traits::Reveal; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; @@ -13,7 +12,7 @@ use rustc_mir_dataflow::elaborate_drops::{ use rustc_mir_dataflow::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex}; use rustc_mir_dataflow::{ - Analysis, MoveDataParamEnv, ResultsCursor, on_all_children_bits, on_lookup_result_bits, + Analysis, MoveDataTypingEnv, ResultsCursor, on_all_children_bits, on_lookup_result_bits, }; use rustc_span::Span; use tracing::{debug, instrument}; @@ -61,7 +60,7 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops { // init/uninit for types that do need dropping. let move_data = MoveData::gather_moves(body, tcx, |ty| ty.needs_drop(tcx, typing_env)); let elaborate_patch = { - let env = MoveDataParamEnv { move_data, param_env: typing_env.param_env }; + let env = MoveDataTypingEnv { move_data, typing_env }; let mut inits = MaybeInitializedPlaces::new(tcx, body, &env.move_data) .skipping_unreachable_unwind() @@ -149,7 +148,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for ElaborateDropsCtxt<'a, 'tcx> { } fn typing_env(&self) -> ty::TypingEnv<'tcx> { - self.typing_env() + self.env.typing_env } #[instrument(level = "debug", skip(self), ret)] @@ -230,7 +229,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for ElaborateDropsCtxt<'a, 'tcx> { struct ElaborateDropsCtxt<'a, 'tcx> { tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, - env: &'a MoveDataParamEnv<'tcx>, + env: &'a MoveDataTypingEnv<'tcx>, init_data: InitializationData<'a, 'tcx>, drop_flags: IndexVec>, patch: MirPatch<'tcx>, @@ -247,15 +246,6 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> { &self.env.move_data } - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.env.param_env - } - - fn typing_env(&self) -> ty::TypingEnv<'tcx> { - debug_assert_eq!(self.param_env().reveal(), Reveal::All); - ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: self.param_env() } - } - fn create_drop_flag(&mut self, index: MovePathIndex, span: Span) { let patch = &mut self.patch; debug!("create_drop_flag({:?})", self.body.span); diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 976f4a8e91958..d5a813ec8ec64 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -638,7 +638,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { let proj = match proj { ProjectionElem::Deref => { let ty = place.ty(self.local_decls, self.tcx).ty; - if let Some(Mutability::Not) = ty.ref_mutability() + // unsound: https://github.com/rust-lang/rust/issues/130853 + if self.tcx.sess.opts.unstable_opts.unsound_mir_opts + && let Some(Mutability::Not) = ty.ref_mutability() && let Some(pointee_ty) = ty.builtin_deref(true) && pointee_ty.is_freeze(self.tcx, self.typing_env()) { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 00f6c3845d41e..0878fa26a92c6 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -210,12 +210,6 @@ impl<'tcx> Inliner<'tcx> { let callee_body = try_instance_mir(self.tcx, callsite.callee.def)?; self.check_mir_body(callsite, callee_body, callee_attrs, cross_crate_inlinable)?; - if !self.tcx.consider_optimizing(|| { - format!("Inline {:?} into {:?}", callsite.callee, caller_body.source) - }) { - return Err("optimization fuel exhausted"); - } - let Ok(callee_body) = callsite.callee.try_instantiate_mir_and_normalize_erasing_regions( self.tcx, self.typing_env, diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 3352d583f2ce4..a6ba2f32d32d2 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -7,8 +7,8 @@ use rustc_middle::bug; use rustc_middle::mir::*; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, layout}; -use rustc_span::sym; use rustc_span::symbol::Symbol; +use rustc_span::{DUMMY_SP, sym}; use crate::simplify::simplify_duplicate_switch_targets; use crate::take_array; @@ -43,12 +43,12 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify { match statement.kind { StatementKind::Assign(box (_place, ref mut rvalue)) => { if !preserve_ub_checks { - ctx.simplify_ub_check(&statement.source_info, rvalue); + ctx.simplify_ub_check(rvalue); } - ctx.simplify_bool_cmp(&statement.source_info, rvalue); - ctx.simplify_ref_deref(&statement.source_info, rvalue); - ctx.simplify_len(&statement.source_info, rvalue); - ctx.simplify_ptr_aggregate(&statement.source_info, rvalue); + ctx.simplify_bool_cmp(rvalue); + ctx.simplify_ref_deref(rvalue); + ctx.simplify_len(rvalue); + ctx.simplify_ptr_aggregate(rvalue); ctx.simplify_cast(rvalue); } _ => {} @@ -70,23 +70,8 @@ struct InstSimplifyContext<'a, 'tcx> { } impl<'tcx> InstSimplifyContext<'_, 'tcx> { - fn should_simplify(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> bool { - self.should_simplify_custom(source_info, "Rvalue", rvalue) - } - - fn should_simplify_custom( - &self, - source_info: &SourceInfo, - label: &str, - value: impl std::fmt::Debug, - ) -> bool { - self.tcx.consider_optimizing(|| { - format!("InstSimplify - {label}: {value:?} SourceInfo: {source_info:?}") - }) - } - /// Transform boolean comparisons into logical operations. - fn simplify_bool_cmp(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { + fn simplify_bool_cmp(&self, rvalue: &mut Rvalue<'tcx>) { match rvalue { Rvalue::BinaryOp(op @ (BinOp::Eq | BinOp::Ne), box (a, b)) => { let new = match (op, self.try_eval_bool(a), self.try_eval_bool(b)) { @@ -117,9 +102,7 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { _ => None, }; - if let Some(new) = new - && self.should_simplify(source_info, rvalue) - { + if let Some(new) = new { *rvalue = new; } } @@ -134,17 +117,13 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { } /// Transform `&(*a)` ==> `a`. - fn simplify_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { + fn simplify_ref_deref(&self, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) = rvalue { if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() { if rvalue.ty(self.local_decls, self.tcx) != base.ty(self.local_decls, self.tcx).ty { return; } - if !self.should_simplify(source_info, rvalue) { - return; - } - *rvalue = Rvalue::Use(Operand::Copy(Place { local: base.local, projection: self.tcx.mk_place_elems(base.projection), @@ -154,36 +133,24 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { } /// Transform `Len([_; N])` ==> `N`. - fn simplify_len(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { + fn simplify_len(&self, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::Len(ref place) = *rvalue { let place_ty = place.ty(self.local_decls, self.tcx).ty; if let ty::Array(_, len) = *place_ty.kind() { - if !self.should_simplify(source_info, rvalue) { - return; - } - let const_ = Const::from_ty_const(len, self.tcx.types.usize, self.tcx); - let constant = ConstOperand { span: source_info.span, const_, user_ty: None }; + let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None }; *rvalue = Rvalue::Use(Operand::Constant(Box::new(constant))); } } } /// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`. - fn simplify_ptr_aggregate(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { + fn simplify_ptr_aggregate(&self, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue { let meta_ty = fields.raw[1].ty(self.local_decls, self.tcx); if meta_ty.is_unit() { // The mutable borrows we're holding prevent printing `rvalue` here - if !self.should_simplify_custom( - source_info, - "Aggregate::RawPtr", - (&pointee_ty, *mutability, &fields), - ) { - return; - } - let mut fields = std::mem::take(fields); let _meta = fields.pop().unwrap(); let data = fields.pop().unwrap(); @@ -193,10 +160,10 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { } } - fn simplify_ub_check(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { + fn simplify_ub_check(&self, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::NullaryOp(NullOp::UbChecks, _) = *rvalue { let const_ = Const::from_bool(self.tcx, self.tcx.sess.ub_checks()); - let constant = ConstOperand { span: source_info.span, const_, user_ty: None }; + let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None }; *rvalue = Rvalue::Use(Operand::Constant(Box::new(constant))); } } @@ -284,16 +251,6 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { return; } - if !self.tcx.consider_optimizing(|| { - format!( - "InstSimplify - Call: {:?} SourceInfo: {:?}", - (fn_def_id, fn_args), - terminator.source_info - ) - }) { - return; - } - let Ok([arg]) = take_array(args) else { return }; let Some(arg_place) = arg.node.place() else { return }; diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 53e282e9b4692..acf3eb2b62cea 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -258,7 +258,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // Normalization needed b/c known panics lint runs in // `mir_drops_elaborated_and_const_checked`, which happens before // optimized MIR. Only after optimizing the MIR can we guarantee - // that the `RevealAll` pass has happened and that the body's consts + // that the `PostAnalysisNormalize` pass has happened and that the body's consts // are normalized, so any call to resolve before that needs to be // manually normalized. let val = self.tcx.try_normalize_erasing_regions(self.typing_env, c.const_).ok()?; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index bfb842e448564..f0fcb44603b15 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -163,7 +163,7 @@ declare_passes! { mod remove_unneeded_drops : RemoveUnneededDrops; mod remove_zsts : RemoveZsts; mod required_consts : RequiredConstsVisitor; - mod reveal_all : RevealAll; + mod post_analysis_normalize : PostAnalysisNormalize; mod sanity_check : SanityCheck; // This pass is public to allow external drivers to perform MIR cleanup pub mod simplify : @@ -604,8 +604,8 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // These next passes must be executed together. &add_call_guards::CriticalCallEdges, // Must be done before drop elaboration because we need to drop opaque types, too. - &reveal_all::RevealAll, - // Calling this after reveal_all ensures that we don't deal with opaque types. + &post_analysis_normalize::PostAnalysisNormalize, + // Calling this after `PostAnalysisNormalize` ensures that we don't deal with opaque types. &add_subtyping_projections::Subtyper, &elaborate_drops::ElaborateDrops, // This will remove extraneous landing pads which are no longer diff --git a/compiler/rustc_mir_transform/src/lint.rs b/compiler/rustc_mir_transform/src/lint.rs index d8ff1cfc90b58..29e762af8de35 100644 --- a/compiler/rustc_mir_transform/src/lint.rs +++ b/compiler/rustc_mir_transform/src/lint.rs @@ -9,8 +9,7 @@ use rustc_index::bit_set::BitSet; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; -use rustc_mir_dataflow::impls::{MaybeStorageDead, MaybeStorageLive}; -use rustc_mir_dataflow::storage::always_storage_live_locals; +use rustc_mir_dataflow::impls::{MaybeStorageDead, MaybeStorageLive, always_storage_live_locals}; use rustc_mir_dataflow::{Analysis, ResultsCursor}; pub(super) fn lint_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, when: String) { diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index b8502fcbafb1b..732a9cd9890dc 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -216,22 +216,17 @@ fn true_significant_drop_ty<'tcx>( /// Returns the list of types with a "potentially sigificant" that may be dropped /// by dropping a value of type `ty`. -#[instrument(level = "debug", skip(tcx, param_env))] +#[instrument(level = "debug", skip(tcx, typing_env))] fn extract_component_raw<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, ty_seen: &mut UnordSet>, ) -> SmallVec<[Ty<'tcx>; 4]> { // Droppiness does not depend on regions, so let us erase them. - let ty = tcx - .try_normalize_erasing_regions( - ty::TypingEnv { param_env, typing_mode: ty::TypingMode::PostAnalysis }, - ty, - ) - .unwrap_or(ty); - - let tys = tcx.list_significant_drop_tys(param_env.and(ty)); + let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + + let tys = tcx.list_significant_drop_tys(typing_env.as_query_input(ty)); debug!(?ty, "components"); let mut out_tys = smallvec![]; for ty in tys { @@ -239,7 +234,7 @@ fn extract_component_raw<'tcx>( // Some types can be further opened up because the drop is simply delegated for ty in tys { if ty_seen.insert(ty) { - out_tys.extend(extract_component_raw(tcx, param_env, ty, ty_seen)); + out_tys.extend(extract_component_raw(tcx, typing_env, ty, ty_seen)); } } } else { @@ -251,13 +246,13 @@ fn extract_component_raw<'tcx>( out_tys } -#[instrument(level = "debug", skip(tcx, param_env))] +#[instrument(level = "debug", skip(tcx, typing_env))] fn extract_component_with_significant_dtor<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, ) -> SmallVec<[Ty<'tcx>; 4]> { - let mut tys = extract_component_raw(tcx, param_env, ty, &mut Default::default()); + let mut tys = extract_component_raw(tcx, typing_env, ty, &mut Default::default()); let mut deduplicate = FxHashSet::default(); tys.retain(|oty| deduplicate.insert(*oty)); tys.into_iter().collect() @@ -359,7 +354,7 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body< // We group them per-block because they tend to scheduled in the same drop ladder block. let mut bid_per_block = IndexMap::default(); let mut bid_places = UnordSet::new(); - let param_env = tcx.param_env(def_id).with_reveal_all_normalized(tcx); + let typing_env = ty::TypingEnv::post_analysis(tcx, def_id); let mut ty_dropped_components = UnordMap::default(); for (block, data) in body.basic_blocks.iter_enumerated() { for (statement_index, stmt) in data.statements.iter().enumerate() { @@ -367,7 +362,7 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body< let ty = place.ty(body, tcx).ty; if ty_dropped_components .entry(ty) - .or_insert_with(|| extract_component_with_significant_dtor(tcx, param_env, ty)) + .or_insert_with(|| extract_component_with_significant_dtor(tcx, typing_env, ty)) .is_empty() { continue; @@ -479,7 +474,7 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body< if ty_dropped_components .entry(observer_ty) .or_insert_with(|| { - extract_component_with_significant_dtor(tcx, param_env, observer_ty) + extract_component_with_significant_dtor(tcx, typing_env, observer_ty) }) .is_empty() { @@ -575,7 +570,7 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body< let name = name.as_str(); let mut seen_dyn = false; - let destructors = extract_component_with_significant_dtor(tcx, param_env, observer_ty) + let destructors = extract_component_with_significant_dtor(tcx, typing_env, observer_ty) .into_iter() .filter_map(|ty| { if let Some(span) = ty_dtor_span(tcx, ty) { diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs index ff027680c4922..20e2a65b311c5 100644 --- a/compiler/rustc_mir_transform/src/match_branches.rs +++ b/compiler/rustc_mir_transform/src/match_branches.rs @@ -18,16 +18,11 @@ impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification { } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let def_id = body.source.def_id(); let typing_env = body.typing_env(tcx); let mut should_cleanup = false; for i in 0..body.basic_blocks.len() { let bbs = &*body.basic_blocks; let bb_idx = BasicBlock::from_usize(i); - if !tcx.consider_optimizing(|| format!("MatchBranchSimplification {def_id:?} ")) { - continue; - } - match bbs[bb_idx].terminator().kind { TerminatorKind::SwitchInt { discr: ref _discr @ (Operand::Copy(_) | Operand::Move(_)), diff --git a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs index b6d6ef5de1da9..a9227524ce5e5 100644 --- a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs +++ b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs @@ -14,10 +14,9 @@ impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators { sess.mir_opt_level() >= 4 } - fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // find basic blocks with no statement and a return terminator let mut bbs_simple_returns = BitSet::new_empty(body.basic_blocks.len()); - let def_id = body.source.def_id(); let bbs = body.basic_blocks_mut(); for idx in bbs.indices() { if bbs[idx].statements.is_empty() @@ -28,10 +27,6 @@ impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators { } for bb in bbs { - if !tcx.consider_optimizing(|| format!("MultipleReturnTerminators {def_id:?} ")) { - break; - } - if let TerminatorKind::Goto { target } = bb.terminator().kind { if bbs_simple_returns.contains(target) { bb.terminator_mut().kind = TerminatorKind::Return; diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs index 98fa149e2bc71..cd026ed68069f 100644 --- a/compiler/rustc_mir_transform/src/nrvo.rs +++ b/compiler/rustc_mir_transform/src/nrvo.rs @@ -45,10 +45,6 @@ impl<'tcx> crate::MirPass<'tcx> for RenameReturnPlace { return; }; - if !tcx.consider_optimizing(|| format!("RenameReturnPlace {def_id:?}")) { - return; - } - debug!( "`{:?}` was eligible for NRVO, making {:?} the return place", def_id, returned_local diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/post_analysis_normalize.rs similarity index 79% rename from compiler/rustc_mir_transform/src/reveal_all.rs rename to compiler/rustc_mir_transform/src/post_analysis_normalize.rs index 587032ee72088..3eecf79a7eae7 100644 --- a/compiler/rustc_mir_transform/src/reveal_all.rs +++ b/compiler/rustc_mir_transform/src/post_analysis_normalize.rs @@ -1,26 +1,28 @@ -//! Normalizes MIR in RevealAll mode. +//! Normalizes MIR in `TypingMode::PostAnalysis` mode, most notably revealing +//! its opaques. We also only normalize specializable associated items once in +//! `PostAnalysis` mode. use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; -pub(super) struct RevealAll; +pub(super) struct PostAnalysisNormalize; -impl<'tcx> crate::MirPass<'tcx> for RevealAll { +impl<'tcx> crate::MirPass<'tcx> for PostAnalysisNormalize { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // FIXME(#132279): This is used during the phase transition from analysis // to runtime, so we have to manually specify the correct typing mode. let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id()); - RevealAllVisitor { tcx, typing_env }.visit_body_preserves_cfg(body); + PostAnalysisNormalizeVisitor { tcx, typing_env }.visit_body_preserves_cfg(body); } } -struct RevealAllVisitor<'tcx> { +struct PostAnalysisNormalizeVisitor<'tcx> { tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, } -impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { +impl<'tcx> MutVisitor<'tcx> for PostAnalysisNormalizeVisitor<'tcx> { #[inline] fn tcx(&self) -> TyCtxt<'tcx> { self.tcx @@ -38,7 +40,7 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { return; } // `OpaqueCast` projections are only needed if there are opaque types on which projections - // are performed. After the `RevealAll` pass, all opaque types are replaced with their + // are performed. After the `PostAnalysisNormalize` pass, all opaque types are replaced with their // hidden types, so we don't need these projections anymore. place.projection = self.tcx.mk_place_elems( &place diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index af438ac2177ed..96bcdfa6fac47 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -8,8 +8,7 @@ use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; use rustc_mir_dataflow::Analysis; -use rustc_mir_dataflow::impls::MaybeStorageDead; -use rustc_mir_dataflow::storage::always_storage_live_locals; +use rustc_mir_dataflow::impls::{MaybeStorageDead, always_storage_live_locals}; use tracing::{debug, instrument}; use crate::ssa::{SsaLocals, StorageLiveLocals}; diff --git a/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs b/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs index ad62b47a66d61..e335051d65644 100644 --- a/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs +++ b/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs @@ -2,7 +2,8 @@ //! //! When the MIR is built, we check `needs_drop` before emitting a `Drop` for a place. This pass is //! useful because (unlike MIR building) it runs after type checking, so it can make use of -//! `Reveal::All` to provide more precise type information. +//! `TypingMode::PostAnalysis` to provide more precise type information, especially about opaque +//! types. use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; @@ -25,11 +26,6 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveUnneededDrops { if ty.ty.needs_drop(tcx, typing_env) { continue; } - if !tcx.consider_optimizing(|| { - format!("RemoveUnneededDrops {:?}", body.source.def_id()) - }) { - continue; - } debug!("SUCCESS: replacing `drop` with goto({:?})", target); terminator.kind = TerminatorKind::Goto { target }; should_simplify = true; diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index 6fd70fbe9b04d..64e183bcbc010 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -17,10 +17,6 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveZsts { return; } - if !tcx.consider_optimizing(|| format!("RemoveZsts - {:?}", body.source.def_id())) { - return; - } - let typing_env = body.typing_env(tcx); let local_decls = &body.local_decls; let mut replacer = Replacer { tcx, typing_env, local_decls }; @@ -94,16 +90,12 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { } } - fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) { + fn visit_operand(&mut self, operand: &mut Operand<'tcx>, _: Location) { if let Operand::Constant(_) = operand { return; } let op_ty = operand.ty(self.local_decls, self.tcx); - if self.known_to_be_zst(op_ty) - && self.tcx.consider_optimizing(|| { - format!("RemoveZsts - Operand: {operand:?} Location: {loc:?}") - }) - { + if self.known_to_be_zst(op_ty) { *operand = Operand::Constant(Box::new(self.make_zst(op_ty))) } } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index f16cde7cd4eb6..809357ec11009 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -141,7 +141,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< debug!("make_shim({:?}) = untransformed {:?}", instance, result); // We don't validate MIR here because the shims may generate code that's - // only valid in a reveal-all param-env. However, since we do initial + // only valid in a `PostAnalysis` param-env. However, since we do initial // validation with the MirBuilt phase, which uses a user-facing param-env. // This causes validation errors when TAITs are involved. pm::run_passes_no_validate( diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs index 9cd32459c7b48..734703ec78b55 100644 --- a/compiler/rustc_mir_transform/src/unreachable_prop.rs +++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs @@ -43,12 +43,6 @@ impl crate::MirPass<'_> for UnreachablePropagation { } } - if !tcx - .consider_optimizing(|| format!("UnreachablePropagation {:?} ", body.source.def_id())) - { - return; - } - patch.apply(body); // We do want do keep some unreachable blocks, but make them empty. diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 1739fdcc9af21..51e5c49cea104 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -646,7 +646,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { { self.fail( location, - format!("explicit opaque type cast to `{ty}` after `RevealAll`"), + format!("explicit opaque type cast to `{ty}` after `PostAnalysisNormalize`"), ) } ProjectionElem::Index(index) => { diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index 6c881fd7e06ba..e18441ea7fc95 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start rustc_abi = { path = "../rustc_abi" } +rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 8ee9ac3df7205..5efe7ffc7b9bc 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1556,7 +1556,7 @@ fn create_mono_items_for_default_impls<'tcx>( // Unlike 'lazy' monomorphization that begins by collecting items transitively // called by `main` or other global items, when eagerly monomorphizing impl // items, we never actually check that the predicates of this impl are satisfied - // in a empty reveal-all param env (i.e. with no assumptions). + // in a empty param env (i.e. with no assumptions). // // Even though this impl has no type or const generic parameters, because we don't // consider higher-ranked predicates such as `for<'a> &'a mut [u8]: Copy` to diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 7240cfce0f7f1..7ea4ded2b052c 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -208,8 +208,8 @@ where // available to downstream crates. This depends on whether we are in // share-generics mode and whether the current crate can even have // downstream crates. - let export_generics = - cx.tcx.sess.opts.share_generics() && cx.tcx.local_crate_exports_generics(); + let can_export_generics = cx.tcx.local_crate_exports_generics(); + let always_export_generics = can_export_generics && cx.tcx.sess.opts.share_generics(); let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx); let cgu_name_cache = &mut UnordMap::default(); @@ -249,7 +249,8 @@ where cx.tcx, &mono_item, &mut can_be_internalized, - export_generics, + can_export_generics, + always_export_generics, ); if visibility == Visibility::Hidden && can_be_internalized { internalization_candidates.insert(mono_item); @@ -739,12 +740,19 @@ fn mono_item_linkage_and_visibility<'tcx>( tcx: TyCtxt<'tcx>, mono_item: &MonoItem<'tcx>, can_be_internalized: &mut bool, - export_generics: bool, + can_export_generics: bool, + always_export_generics: bool, ) -> (Linkage, Visibility) { if let Some(explicit_linkage) = mono_item.explicit_linkage(tcx) { return (explicit_linkage, Visibility::Default); } - let vis = mono_item_visibility(tcx, mono_item, can_be_internalized, export_generics); + let vis = mono_item_visibility( + tcx, + mono_item, + can_be_internalized, + can_export_generics, + always_export_generics, + ); (Linkage::External, vis) } @@ -767,7 +775,8 @@ fn mono_item_visibility<'tcx>( tcx: TyCtxt<'tcx>, mono_item: &MonoItem<'tcx>, can_be_internalized: &mut bool, - export_generics: bool, + can_export_generics: bool, + always_export_generics: bool, ) -> Visibility { let instance = match mono_item { // This is pretty complicated; see below. @@ -826,7 +835,11 @@ fn mono_item_visibility<'tcx>( // Upstream `DefId` instances get different handling than local ones. let Some(def_id) = def_id.as_local() else { - return if export_generics && is_generic { + return if is_generic + && (always_export_generics + || (can_export_generics + && tcx.codegen_fn_attrs(def_id).inline == rustc_attr::InlineAttr::Never)) + { // If it is an upstream monomorphization and we export generics, we must make // it available to downstream crates. *can_be_internalized = false; @@ -837,7 +850,10 @@ fn mono_item_visibility<'tcx>( }; if is_generic { - if export_generics { + if always_export_generics + || (can_export_generics + && tcx.codegen_fn_attrs(def_id).inline == rustc_attr::InlineAttr::Never) + { if tcx.is_unreachable_local_definition(def_id) { // This instance cannot be used from another crate. Visibility::Hidden diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 545ab15b94549..198ccb000f345 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -321,7 +321,7 @@ where let mut candidates = vec![]; - if let TypingMode::Coherence = self.typing_mode(goal.param_env) { + if let TypingMode::Coherence = self.typing_mode() { if let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal) { return vec![candidate]; } @@ -337,9 +337,11 @@ where self.assemble_param_env_candidates(goal, &mut candidates); - match self.typing_mode(goal.param_env) { + match self.typing_mode() { TypingMode::Coherence => {} - TypingMode::Analysis { .. } | TypingMode::PostAnalysis => { + TypingMode::Analysis { .. } + | TypingMode::PostBorrowckAnalysis { .. } + | TypingMode::PostAnalysis => { self.discard_impls_shadowed_by_env(goal, &mut candidates); } } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index a56febec48c45..05ce61bc0678f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -12,7 +12,7 @@ use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use tracing::instrument; use crate::delegate::SolverDelegate; -use crate::solve::{EvalCtxt, Goal, NoSolution}; +use crate::solve::{AdtDestructorKind, EvalCtxt, Goal, NoSolution}; // Calculates the constituent types of a type for `auto trait` purposes. #[instrument(level = "trace", skip(ecx), ret)] @@ -703,6 +703,78 @@ pub(in crate::solve) fn extract_fn_def_from_const_callable( } } +pub(in crate::solve) fn const_conditions_for_destruct( + cx: I, + self_ty: I::Ty, +) -> Result>, NoSolution> { + let destruct_def_id = cx.require_lang_item(TraitSolverLangItem::Destruct); + + match self_ty.kind() { + // An ADT is `~const Destruct` only if all of the fields are, + // *and* if there is a `Drop` impl, that `Drop` impl is also `~const`. + ty::Adt(adt_def, args) => { + let mut const_conditions: Vec<_> = adt_def + .all_field_tys(cx) + .iter_instantiated(cx, args) + .map(|field_ty| ty::TraitRef::new(cx, destruct_def_id, [field_ty])) + .collect(); + match adt_def.destructor(cx) { + // `Drop` impl exists, but it's not const. Type cannot be `~const Destruct`. + Some(AdtDestructorKind::NotConst) => return Err(NoSolution), + // `Drop` impl exists, and it's const. Require `Ty: ~const Drop` to hold. + Some(AdtDestructorKind::Const) => { + let drop_def_id = cx.require_lang_item(TraitSolverLangItem::Drop); + let drop_trait_ref = ty::TraitRef::new(cx, drop_def_id, [self_ty]); + const_conditions.push(drop_trait_ref); + } + // No `Drop` impl, no need to require anything else. + None => {} + } + Ok(const_conditions) + } + + ty::Array(ty, _) | ty::Pat(ty, _) | ty::Slice(ty) => { + Ok(vec![ty::TraitRef::new(cx, destruct_def_id, [ty])]) + } + + ty::Tuple(tys) => Ok(tys + .iter() + .map(|field_ty| ty::TraitRef::new(cx, destruct_def_id, [field_ty])) + .collect()), + + // Trivially implement `~const Destruct` + ty::Bool + | ty::Char + | ty::Int(..) + | ty::Uint(..) + | ty::Float(..) + | ty::Str + | ty::RawPtr(..) + | ty::Ref(..) + | ty::FnDef(..) + | ty::FnPtr(..) + | ty::Never + | ty::Infer(ty::InferTy::FloatVar(_) | ty::InferTy::IntVar(_)) + | ty::Error(_) => Ok(vec![]), + + // Coroutines and closures could implement `~const Drop`, + // but they don't really need to right now. + ty::Closure(_, _) + | ty::CoroutineClosure(_, _) + | ty::Coroutine(_, _) + | ty::CoroutineWitness(_, _) => Err(NoSolution), + + ty::Dynamic(..) | ty::Param(_) | ty::Alias(..) | ty::Placeholder(_) | ty::Foreign(_) => { + Err(NoSolution) + } + + ty::Bound(..) + | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { + panic!("unexpected type `{self_ty:?}`") + } + } +} + /// Assemble a list of predicates that would be present on a theoretical /// user impl for an object type. These predicates must be checked any time /// we assemble a built-in object candidate for an object type, since they diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 603a68eb890cb..81b5199002b23 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -84,6 +84,10 @@ where let cx = ecx.cx(); let mut candidates = vec![]; + if !ecx.cx().alias_has_const_conditions(alias_ty.def_id) { + return vec![]; + } + for clause in elaborate::elaborate( cx, cx.explicit_implied_const_bounds(alias_ty.def_id) @@ -338,10 +342,27 @@ where } fn consider_builtin_destruct_candidate( - _ecx: &mut EvalCtxt<'_, D>, - _goal: Goal, + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, ) -> Result, NoSolution> { - Err(NoSolution) + let cx = ecx.cx(); + + let self_ty = goal.predicate.self_ty(); + let const_conditions = structural_traits::const_conditions_for_destruct(cx, self_ty)?; + + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + ecx.add_goals( + GoalSource::Misc, + const_conditions.into_iter().map(|trait_ref| { + goal.with( + cx, + ty::Binder::dummy(trait_ref) + .to_host_effect_clause(cx, goal.predicate.constness), + ) + }), + ); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) } fn consider_builtin_transmute_candidate( diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index 2f50070d43883..a143af13688ba 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -55,7 +55,6 @@ where &self, goal: Goal, ) -> (Vec, CanonicalInput) { - let param_env_for_debug_assertion = goal.param_env; let opaque_types = self.delegate.clone_opaque_types_for_query_response(); let (goal, opaque_types) = (goal, opaque_types).fold_with(&mut EagerResolver::new(self.delegate)); @@ -72,10 +71,7 @@ where .mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }), }, ); - let query_input = ty::CanonicalQueryInput { - canonical, - typing_mode: self.typing_mode(param_env_for_debug_assertion), - }; + let query_input = ty::CanonicalQueryInput { canonical, typing_mode: self.typing_mode() }; (orig_values, query_input) } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 979a379474822..70ceb22bfea58 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -214,8 +214,8 @@ where D: SolverDelegate, I: Interner, { - pub(super) fn typing_mode(&self, param_env_for_debug_assertion: I::ParamEnv) -> TypingMode { - self.delegate.typing_mode(param_env_for_debug_assertion) + pub(super) fn typing_mode(&self) -> TypingMode { + self.delegate.typing_mode() } pub(super) fn set_is_normalizes_to_goal(&mut self) { @@ -644,6 +644,12 @@ where } } + pub(super) fn next_region_var(&mut self) -> I::Region { + let region = self.delegate.next_region_infer(); + self.inspect.add_var_value(region); + region + } + pub(super) fn next_ty_infer(&mut self) -> I::Ty { let ty = self.delegate.next_ty_infer(); self.inspect.add_var_value(ty); diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 5c54656cc59f5..ebf1013db1ecb 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -23,7 +23,7 @@ mod trait_goals; use rustc_type_ir::inherent::*; pub use rustc_type_ir::solve::*; -use rustc_type_ir::{self as ty, Interner}; +use rustc_type_ir::{self as ty, Interner, TypingMode}; use tracing::instrument; pub use self::eval_ctxt::{EvalCtxt, GenerateProofTree, SolverDelegateEvalExt}; @@ -321,6 +321,19 @@ where Ok(ct) } } + + fn opaque_type_is_rigid(&self, def_id: I::DefId) -> bool { + match self.typing_mode() { + // Opaques are never rigid outside of analysis mode. + TypingMode::Coherence | TypingMode::PostAnalysis => false, + // During analysis, opaques are rigid unless they may be defined by + // the current body. + TypingMode::Analysis { defining_opaque_types: non_rigid_opaques } + | TypingMode::PostBorrowckAnalysis { defined_opaque_types: non_rigid_opaques } => { + !def_id.as_local().is_some_and(|def_id| non_rigid_opaques.contains(&def_id)) + } + } + } } fn response_no_constraints_raw( diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 6b407640426b7..f5b1b23b8e973 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -6,7 +6,7 @@ mod weak_types; use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; -use rustc_type_ir::{self as ty, Interner, NormalizesTo, TypingMode, Upcast as _}; +use rustc_type_ir::{self as ty, Interner, NormalizesTo, Upcast as _}; use tracing::instrument; use crate::delegate::SolverDelegate; @@ -71,21 +71,10 @@ where Ok(()) } ty::AliasTermKind::OpaqueTy => { - match self.typing_mode(param_env) { - // Opaques are never rigid outside of analysis mode. - TypingMode::Coherence | TypingMode::PostAnalysis => Err(NoSolution), - // During analysis, opaques are only rigid if we may not define it. - TypingMode::Analysis { defining_opaque_types } => { - if rigid_alias - .def_id - .as_local() - .is_some_and(|def_id| defining_opaque_types.contains(&def_id)) - { - Err(NoSolution) - } else { - Ok(()) - } - } + if self.opaque_type_is_rigid(rigid_alias.def_id) { + Ok(()) + } else { + Err(NoSolution) } } // FIXME(generic_const_exprs): we would need to support generic consts here diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs index d1d701695ab83..26a8a22d77ebe 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs @@ -1,8 +1,8 @@ //! Computes a normalizes-to (projection) goal for opaque types. This goal -//! behaves differently depending on the param-env's reveal mode and whether -//! the opaque is in a defining scope. +//! behaves differently depending on the current `TypingMode`. use rustc_index::bit_set::GrowableBitSet; +use rustc_type_ir::fold::fold_regions; use rustc_type_ir::inherent::*; use rustc_type_ir::{self as ty, Interner, TypingMode}; @@ -22,7 +22,7 @@ where let opaque_ty = goal.predicate.alias; let expected = goal.predicate.term.as_type().expect("no such thing as an opaque const"); - match self.typing_mode(goal.param_env) { + match self.typing_mode() { TypingMode::Coherence => { // An impossible opaque type bound is the only way this goal will fail // e.g. assigning `impl Copy := NotCopy` @@ -96,6 +96,26 @@ where ); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } + TypingMode::PostBorrowckAnalysis { defined_opaque_types } => { + let Some(def_id) = opaque_ty.def_id.as_local() else { + return Err(NoSolution); + }; + + if !defined_opaque_types.contains(&def_id) { + return Err(NoSolution); + } + + let actual = cx.type_of(opaque_ty.def_id).instantiate(cx, opaque_ty.args); + // FIXME: Actually use a proper binder here instead of relying on `ReErased`. + // + // This is also probably unsound or sth :shrug: + let actual = fold_regions(cx, actual, |re, _dbi| match re.kind() { + ty::ReErased => self.next_region_var(), + _ => re, + }); + self.eq(goal.param_env, expected, actual)?; + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } TypingMode::PostAnalysis => { // FIXME: Add an assertion that opaque type storage is empty. let actual = cx.type_of(opaque_ty.def_id).instantiate(cx, opaque_ty.args); diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index ce16258d1806c..6641d2bf92492 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -67,9 +67,11 @@ where let maximal_certainty = match (impl_polarity, goal.predicate.polarity) { // In intercrate mode, this is ambiguous. But outside of intercrate, // it's not a real impl. - (ty::ImplPolarity::Reservation, _) => match ecx.typing_mode(goal.param_env) { + (ty::ImplPolarity::Reservation, _) => match ecx.typing_mode() { TypingMode::Coherence => Certainty::AMBIGUOUS, - TypingMode::Analysis { .. } | TypingMode::PostAnalysis => return Err(NoSolution), + TypingMode::Analysis { .. } + | TypingMode::PostBorrowckAnalysis { .. } + | TypingMode::PostAnalysis => return Err(NoSolution), }, // Impl matches polarity @@ -174,20 +176,7 @@ where // ideally we want to avoid, since we can make progress on this goal // via an alias bound or a locally-inferred hidden type instead. if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() { - match ecx.typing_mode(goal.param_env) { - TypingMode::Coherence | TypingMode::PostAnalysis => { - unreachable!("rigid opaque outside of analysis: {goal:?}"); - } - TypingMode::Analysis { defining_opaque_types } => { - if opaque_ty - .def_id - .as_local() - .is_some_and(|def_id| defining_opaque_types.contains(&def_id)) - { - return Err(NoSolution); - } - } - } + debug_assert!(ecx.opaque_type_is_rigid(opaque_ty.def_id)); } ecx.probe_and_evaluate_goal_for_constituent_tys( diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index cafd4b6dca28f..b9a325eddd800 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -716,6 +716,10 @@ parse_require_colon_after_labeled_expression = labeled expression must be follow .label = the label .suggestion = add `:` after the label +parse_reserved_multihash = reserved multi-hash token is forbidden + .note = sequences of two or more # are reserved for future use since Rust 2024 + .suggestion_whitespace = consider inserting whitespace here + parse_reserved_string = invalid string literal .note = unprefixed guarded string literals are reserved for future use since Rust 2024 .suggestion_whitespace = consider inserting whitespace here @@ -827,7 +831,7 @@ parse_unexpected_expr_in_pat = }, found an expression .label = not a pattern - .note = arbitrary expressions are not allowed in patterns: + .note = arbitrary expressions are not allowed in patterns: parse_unexpected_expr_in_pat_const_sugg = consider extracting the expression into a `const` diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 9bdb99dc00077..91e8ba2e1f996 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2151,6 +2151,15 @@ pub(crate) enum UnknownPrefixSugg { }, } +#[derive(Diagnostic)] +#[diag(parse_reserved_multihash)] +#[note] +pub(crate) struct ReservedMultihash { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub sugg: Option, +} #[derive(Diagnostic)] #[diag(parse_reserved_string)] #[note] @@ -2611,8 +2620,9 @@ pub(crate) enum InvalidMutInPattern { #[diag(parse_repeated_mut_in_pattern)] pub(crate) struct RepeatedMutInPattern { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] pub span: Span, + #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] + pub suggestion: Span, } #[derive(Diagnostic)] diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 5023e83bd67c7..8a42cf388f9b7 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -18,6 +18,7 @@ use rustc_span::symbol::Symbol; use rustc_span::{BytePos, Pos, Span}; use tracing::debug; +use crate::lexer::diagnostics::TokenTreeDiagInfo; use crate::lexer::unicode_chars::UNICODE_ARRAY; use crate::{errors, make_unclosed_delims_error}; @@ -56,7 +57,7 @@ pub(crate) fn lex_token_trees<'psess, 'src>( } let cursor = Cursor::new(src); - let string_reader = StringReader { + let mut lexer = Lexer { psess, start_pos, pos: start_pos, @@ -65,34 +66,31 @@ pub(crate) fn lex_token_trees<'psess, 'src>( override_span, nbsp_is_whitespace: false, last_lifetime: None, + token: Token::dummy(), + diag_info: TokenTreeDiagInfo::default(), }; - let (stream, res, unmatched_delims) = - tokentrees::TokenTreesReader::lex_all_token_trees(string_reader); - match res { - Ok(()) if unmatched_delims.is_empty() => Ok(stream), - _ => { - // Return error if there are unmatched delimiters or unclosed delimiters. - // We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch - // because the delimiter mismatch is more likely to be the root cause of error - - let mut buffer = Vec::with_capacity(1); - for unmatched in unmatched_delims { - if let Some(err) = make_unclosed_delims_error(unmatched, psess) { - buffer.push(err); - } - } - if let Err(errs) = res { - // Add unclosing delimiter or diff marker errors - for err in errs { - buffer.push(err); - } - } - Err(buffer) + let (_open_spacing, stream, res) = lexer.lex_token_trees(/* is_delimited */ false); + let unmatched_delims = lexer.diag_info.unmatched_delims; + + if res.is_ok() && unmatched_delims.is_empty() { + Ok(stream) + } else { + // Return error if there are unmatched delimiters or unclosed delimiters. + // We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch + // because the delimiter mismatch is more likely to be the root cause of error + let mut buffer: Vec<_> = unmatched_delims + .into_iter() + .filter_map(|unmatched_delim| make_unclosed_delims_error(unmatched_delim, psess)) + .collect(); + if let Err(errs) = res { + // Add unclosing delimiter or diff marker errors + buffer.extend(errs); } + Err(buffer) } } -struct StringReader<'psess, 'src> { +struct Lexer<'psess, 'src> { psess: &'psess ParseSess, /// Initial position, read-only. start_pos: BytePos, @@ -111,9 +109,14 @@ struct StringReader<'psess, 'src> { /// Track the `Span` for the leading `'` of the last lifetime. Used for /// diagnostics to detect possible typo where `"` was meant. last_lifetime: Option, + + /// The current token. + token: Token, + + diag_info: TokenTreeDiagInfo, } -impl<'psess, 'src> StringReader<'psess, 'src> { +impl<'psess, 'src> Lexer<'psess, 'src> { fn dcx(&self) -> DiagCtxtHandle<'psess> { self.psess.dcx() } @@ -124,7 +127,7 @@ impl<'psess, 'src> StringReader<'psess, 'src> { /// Returns the next token, paired with a bool indicating if the token was /// preceded by whitespace. - fn next_token(&mut self) -> (Token, bool) { + fn next_token_from_cursor(&mut self) -> (Token, bool) { let mut preceded_by_whitespace = false; let mut swallow_next_invalid = 0; // Skip trivial (whitespace & comments) tokens @@ -231,7 +234,8 @@ impl<'psess, 'src> StringReader<'psess, 'src> { .push(span); token::Ident(sym, IdentIsRaw::No) } - // split up (raw) c string literals to an ident and a string literal when edition < 2021. + // split up (raw) c string literals to an ident and a string literal when edition < + // 2021. rustc_lexer::TokenKind::Literal { kind: kind @ (LiteralKind::CStr { .. } | LiteralKind::RawCStr { .. }), suffix_start: _, @@ -252,7 +256,9 @@ impl<'psess, 'src> StringReader<'psess, 'src> { let prefix_span = self.mk_sp(start, lit_start); return (Token::new(self.ident(start), prefix_span), preceded_by_whitespace); } - rustc_lexer::TokenKind::GuardedStrPrefix => self.maybe_report_guarded_str(start, str_before), + rustc_lexer::TokenKind::GuardedStrPrefix => { + self.maybe_report_guarded_str(start, str_before) + } rustc_lexer::TokenKind::Literal { kind, suffix_start } => { let suffix_start = start + BytePos(suffix_start); let (kind, symbol) = self.cook_lexer_literal(start, suffix_start, kind); @@ -296,13 +302,20 @@ impl<'psess, 'src> StringReader<'psess, 'src> { if prefix_span.at_least_rust_2021() { let span = self.mk_sp(start, self.pos); - let lifetime_name_without_tick = Symbol::intern(&self.str_from(ident_start)); + let lifetime_name_without_tick = + Symbol::intern(&self.str_from(ident_start)); if !lifetime_name_without_tick.can_be_raw() { - self.dcx().emit_err(errors::CannotBeRawLifetime { span, ident: lifetime_name_without_tick }); + self.dcx().emit_err( + errors::CannotBeRawLifetime { + span, + ident: lifetime_name_without_tick + } + ); } // Put the `'` back onto the lifetime name. - let mut lifetime_name = String::with_capacity(lifetime_name_without_tick.as_str().len() + 1); + let mut lifetime_name = + String::with_capacity(lifetime_name_without_tick.as_str().len() + 1); lifetime_name.push('\''); lifetime_name += lifetime_name_without_tick.as_str(); let sym = Symbol::intern(&lifetime_name); @@ -803,7 +816,7 @@ impl<'psess, 'src> StringReader<'psess, 'src> { let mut cursor = Cursor::new(str_before); - let (span, unterminated) = match cursor.guarded_double_quoted_string() { + let (is_string, span, unterminated) = match cursor.guarded_double_quoted_string() { Some(rustc_lexer::GuardedStr { n_hashes, terminated, token_len }) => { let end = start + BytePos(token_len); let span = self.mk_sp(start, end); @@ -816,13 +829,13 @@ impl<'psess, 'src> StringReader<'psess, 'src> { let unterminated = if terminated { None } else { Some(str_start) }; - (span, unterminated) + (true, span, unterminated) } - _ => { + None => { // We should only get here in the `##+` case. debug_assert_eq!(self.str_from_to(start, start + BytePos(2)), "##"); - (span, None) + (false, span, None) } }; if edition2024 { @@ -844,7 +857,11 @@ impl<'psess, 'src> StringReader<'psess, 'src> { }; // In Edition 2024 and later, emit a hard error. - let err = self.dcx().emit_err(errors::ReservedString { span, sugg }); + let err = if is_string { + self.dcx().emit_err(errors::ReservedString { span, sugg }) + } else { + self.dcx().emit_err(errors::ReservedMultihash { span, sugg }) + }; token::Literal(token::Lit { kind: token::Err(err), @@ -857,7 +874,7 @@ impl<'psess, 'src> StringReader<'psess, 'src> { RUST_2024_GUARDED_STRING_INCOMPATIBLE_SYNTAX, span, ast::CRATE_NODE_ID, - BuiltinLintDiag::ReservedString(space_span), + BuiltinLintDiag::ReservedString { is_string, suggestion: space_span }, ); // For backwards compatibility, roll back to after just the first `#` diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index 7b21ffacc841d..c6c9eb3b0b263 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -4,41 +4,19 @@ use rustc_ast_pretty::pprust::token_to_string; use rustc_errors::{Applicability, PErr}; use rustc_span::symbol::kw; -use super::diagnostics::{ - TokenTreeDiagInfo, report_suspicious_mismatch_block, same_indentation_level, -}; -use super::{StringReader, UnmatchedDelim}; +use super::diagnostics::{report_suspicious_mismatch_block, same_indentation_level}; +use super::{Lexer, UnmatchedDelim}; use crate::Parser; -pub(super) struct TokenTreesReader<'psess, 'src> { - string_reader: StringReader<'psess, 'src>, - /// The "next" token, which has been obtained from the `StringReader` but - /// not yet handled by the `TokenTreesReader`. - token: Token, - diag_info: TokenTreeDiagInfo, -} - -impl<'psess, 'src> TokenTreesReader<'psess, 'src> { - pub(super) fn lex_all_token_trees( - string_reader: StringReader<'psess, 'src>, - ) -> (TokenStream, Result<(), Vec>>, Vec) { - let mut tt_reader = TokenTreesReader { - string_reader, - token: Token::dummy(), - diag_info: TokenTreeDiagInfo::default(), - }; - let (_open_spacing, stream, res) = tt_reader.lex_token_trees(/* is_delimited */ false); - (stream, res, tt_reader.diag_info.unmatched_delims) - } - +impl<'psess, 'src> Lexer<'psess, 'src> { // Lex into a token stream. The `Spacing` in the result is that of the // opening delimiter. - fn lex_token_trees( + pub(super) fn lex_token_trees( &mut self, is_delimited: bool, ) -> (Spacing, TokenStream, Result<(), Vec>>) { // Move past the opening delimiter. - let (_, open_spacing) = self.bump(false); + let open_spacing = self.bump_minimal(); let mut buf = Vec::new(); loop { @@ -71,7 +49,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> { } _ => { // Get the next normal token. - let (this_tok, this_spacing) = self.bump(true); + let (this_tok, this_spacing) = self.bump(); buf.push(TokenTree::Token(this_tok, this_spacing)); } } @@ -80,7 +58,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> { fn eof_err(&mut self) -> PErr<'psess> { let msg = "this file contains an unclosed delimiter"; - let mut err = self.string_reader.dcx().struct_span_err(self.token.span, msg); + let mut err = self.dcx().struct_span_err(self.token.span, msg); let unclosed_delimiter_show_limit = 5; let len = usize::min(unclosed_delimiter_show_limit, self.diag_info.open_braces.len()); @@ -110,7 +88,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> { report_suspicious_mismatch_block( &mut err, &self.diag_info, - self.string_reader.psess.source_map(), + self.psess.source_map(), *delim, ) } @@ -136,7 +114,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> { // Expand to cover the entire delimited token tree. let delim_span = DelimSpan::from_pair(pre_span, self.token.span); - let sm = self.string_reader.psess.source_map(); + let sm = self.psess.source_map(); let close_spacing = match self.token.kind { // Correct delimiter. @@ -160,7 +138,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> { } // Move past the closing delimiter. - self.bump(false).1 + self.bump_minimal() } // Incorrect delimiter. token::CloseDelim(close_delim) => { @@ -203,7 +181,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> { // bar(baz( // } // Incorrect delimiter but matches the earlier `{` if !self.diag_info.open_braces.iter().any(|&(b, _)| b == close_delim) { - self.bump(false).1 + self.bump_minimal() } else { // The choice of value here doesn't matter. Spacing::Alone @@ -225,14 +203,14 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> { } // Move on to the next token, returning the current token and its spacing. - // Will glue adjacent single-char tokens together if `glue` is set. - fn bump(&mut self, glue: bool) -> (Token, Spacing) { + // Will glue adjacent single-char tokens together. + fn bump(&mut self) -> (Token, Spacing) { let (this_spacing, next_tok) = loop { - let (next_tok, is_next_tok_preceded_by_whitespace) = self.string_reader.next_token(); + let (next_tok, is_next_tok_preceded_by_whitespace) = self.next_token_from_cursor(); if is_next_tok_preceded_by_whitespace { break (Spacing::Alone, next_tok); - } else if glue && let Some(glued) = self.token.glue(&next_tok) { + } else if let Some(glued) = self.token.glue(&next_tok) { self.token = glued; } else { let this_spacing = if next_tok.is_punct() { @@ -249,6 +227,26 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> { (this_tok, this_spacing) } + // Cut-down version of `bump` used when the token kind is known in advance. + fn bump_minimal(&mut self) -> Spacing { + let (next_tok, is_next_tok_preceded_by_whitespace) = self.next_token_from_cursor(); + + let this_spacing = if is_next_tok_preceded_by_whitespace { + Spacing::Alone + } else { + if next_tok.is_punct() { + Spacing::Joint + } else if next_tok == token::Eof { + Spacing::Alone + } else { + Spacing::JointHidden + } + }; + + self.token = next_tok; + this_spacing + } + fn unclosed_delim_err( &mut self, tts: TokenStream, @@ -256,7 +254,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> { ) -> Vec> { // If there are unclosed delims, see if there are diff markers and if so, point them // out instead of complaining about the unclosed delims. - let mut parser = Parser::new(self.string_reader.psess, tts, None); + let mut parser = Parser::new(self.psess, tts, None); let mut diff_errs = vec![]; // Suggest removing a `{` we think appears in an `if`/`while` condition. // We want to suggest removing a `{` only if we think we're in an `if`/`while` condition, @@ -314,14 +312,9 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> { // An unexpected closing delimiter (i.e., there is no matching opening delimiter). let token_str = token_to_string(&self.token); let msg = format!("unexpected closing delimiter: `{token_str}`"); - let mut err = self.string_reader.dcx().struct_span_err(self.token.span, msg); + let mut err = self.dcx().struct_span_err(self.token.span, msg); - report_suspicious_mismatch_block( - &mut err, - &self.diag_info, - self.string_reader.psess.source_map(), - delim, - ); + report_suspicious_mismatch_block(&mut err, &self.diag_info, self.psess.source_map(), delim); err.span_label(self.token.span, "unexpected closing delimiter"); err } diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs index d78b3664b1ee8..42eef27803eb5 100644 --- a/compiler/rustc_parse/src/lexer/unicode_chars.rs +++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs @@ -4,7 +4,7 @@ use rustc_span::symbol::kw; use rustc_span::{BytePos, Pos, Span}; -use super::StringReader; +use super::Lexer; use crate::errors::TokenSubstitution; use crate::token::{self, Delimiter}; @@ -338,7 +338,7 @@ const ASCII_ARRAY: &[(&str, &str, Option)] = &[ ]; pub(super) fn check_for_substitution( - reader: &StringReader<'_, '_>, + lexer: &Lexer<'_, '_>, pos: BytePos, ch: char, count: usize, @@ -351,11 +351,11 @@ pub(super) fn check_for_substitution( let Some((_, ascii_name, token)) = ASCII_ARRAY.iter().find(|&&(s, _, _)| s == ascii_str) else { let msg = format!("substitution character not found for '{ch}'"); - reader.dcx().span_bug(span, msg); + lexer.dcx().span_bug(span, msg); }; // special help suggestion for "directed" double quotes - let sugg = if let Some(s) = peek_delimited(&reader.src[reader.src_index(pos)..], '“', '”') { + let sugg = if let Some(s) = peek_delimited(&lexer.src[lexer.src_index(pos)..], '“', '”') { let span = Span::with_root_ctxt( pos, pos + Pos::from_usize('“'.len_utf8() + s.len() + '”'.len_utf8()), diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index a1fe550897073..34131e3af6e2c 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1990,7 +1990,6 @@ impl<'a> Parser<'a> { /// `await? `, `await()`, and `await { }`. pub(super) fn recover_incorrect_await_syntax( &mut self, - lo: Span, await_sp: Span, ) -> PResult<'a, P> { let (hi, expr, is_question) = if self.token == token::Not { @@ -1999,8 +1998,8 @@ impl<'a> Parser<'a> { } else { self.recover_await_prefix(await_sp)? }; - let (sp, guar) = self.error_on_incorrect_await(lo, hi, &expr, is_question); - let expr = self.mk_expr_err(lo.to(sp), guar); + let (sp, guar) = self.error_on_incorrect_await(await_sp, hi, &expr, is_question); + let expr = self.mk_expr_err(await_sp.to(sp), guar); self.maybe_recover_from_bad_qpath(expr) } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index aa5e9586daf96..4430d2d14313b 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1446,34 +1446,31 @@ impl<'a> Parser<'a> { this.parse_expr_closure() } else { assert!(this.eat_keyword(kw::For)); - this.parse_expr_for(None, this.prev_token.span) + this.parse_expr_for(None, lo) } } else if this.eat_keyword(kw::While) { - this.parse_expr_while(None, this.prev_token.span) + this.parse_expr_while(None, lo) } else if let Some(label) = this.eat_label() { this.parse_expr_labeled(label, true) } else if this.eat_keyword(kw::Loop) { - let sp = this.prev_token.span; - this.parse_expr_loop(None, this.prev_token.span).map_err(|mut err| { - err.span_label(sp, "while parsing this `loop` expression"); + this.parse_expr_loop(None, lo).map_err(|mut err| { + err.span_label(lo, "while parsing this `loop` expression"); err }) } else if this.eat_keyword(kw::Match) { - let match_sp = this.prev_token.span; this.parse_expr_match().map_err(|mut err| { - err.span_label(match_sp, "while parsing this `match` expression"); + err.span_label(lo, "while parsing this `match` expression"); err }) } else if this.eat_keyword(kw::Unsafe) { - let sp = this.prev_token.span; this.parse_expr_block(None, lo, BlockCheckMode::Unsafe(ast::UserProvided)).map_err( |mut err| { - err.span_label(sp, "while parsing this `unsafe` expression"); + err.span_label(lo, "while parsing this `unsafe` expression"); err }, ) } else if this.check_inline_const(0) { - this.parse_const_block(lo.to(this.token.span), false) + this.parse_const_block(lo, false) } else if this.may_recover() && this.is_do_catch_block() { this.recover_do_catch() } else if this.is_try_block() { @@ -1514,7 +1511,7 @@ impl<'a> Parser<'a> { this.parse_expr_closure() } } else if this.eat_keyword_noexpect(kw::Await) { - this.recover_incorrect_await_syntax(lo, this.prev_token.span) + this.recover_incorrect_await_syntax(lo) } else { this.parse_expr_lit() } diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 5aebe716b0a10..76ecb77d75062 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -1,6 +1,7 @@ use ast::token::Delimiter; use rustc_ast::{ - self as ast, AttrVec, GenericBounds, GenericParam, GenericParamKind, TyKind, WhereClause, token, + self as ast, AttrVec, DUMMY_NODE_ID, GenericBounds, GenericParam, GenericParamKind, TyKind, + WhereClause, token, }; use rustc_errors::{Applicability, PResult}; use rustc_span::Span; @@ -14,8 +15,8 @@ use crate::errors::{ WhereClauseBeforeTupleStructBodySugg, }; -enum PredicateOrStructBody { - Predicate(ast::WherePredicate), +enum PredicateKindOrStructBody { + PredicateKind(ast::WherePredicateKind), StructBody(ThinVec), } @@ -218,10 +219,11 @@ impl<'a> Parser<'a> { } else if this.token.can_begin_type() { // Trying to write an associated type bound? (#26271) let snapshot = this.create_snapshot_for_diagnostic(); - match this.parse_ty_where_predicate() { - Ok(where_predicate) => { + let lo = this.token.span; + match this.parse_ty_where_predicate_kind() { + Ok(_) => { this.dcx().emit_err(errors::BadAssocTypeBounds { - span: where_predicate.span(), + span: lo.to(this.prev_token.span), }); // FIXME - try to continue parsing other generics? } @@ -340,31 +342,33 @@ impl<'a> Parser<'a> { loop { let where_sp = where_lo.to(self.prev_token.span); let pred_lo = self.token.span; - if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { + let kind = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { let lifetime = self.expect_lifetime(); // Bounds starting with a colon are mandatory, but possibly empty. self.expect(&token::Colon)?; let bounds = self.parse_lt_param_bounds(); - where_clause.predicates.push(ast::WherePredicate::RegionPredicate( - ast::WhereRegionPredicate { - span: pred_lo.to(self.prev_token.span), - lifetime, - bounds, - }, - )); + ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate { + lifetime, + bounds, + }) } else if self.check_type() { - match self.parse_ty_where_predicate_or_recover_tuple_struct_body( + match self.parse_ty_where_predicate_kind_or_recover_tuple_struct_body( struct_, pred_lo, where_sp, )? { - PredicateOrStructBody::Predicate(pred) => where_clause.predicates.push(pred), - PredicateOrStructBody::StructBody(body) => { + PredicateKindOrStructBody::PredicateKind(kind) => kind, + PredicateKindOrStructBody::StructBody(body) => { tuple_struct_body = Some(body); break; } } } else { break; - } + }; + where_clause.predicates.push(ast::WherePredicate { + kind, + id: DUMMY_NODE_ID, + span: pred_lo.to(self.prev_token.span), + }); let prev_token = self.prev_token.span; let ate_comma = self.eat(&token::Comma); @@ -384,12 +388,12 @@ impl<'a> Parser<'a> { Ok((where_clause, tuple_struct_body)) } - fn parse_ty_where_predicate_or_recover_tuple_struct_body( + fn parse_ty_where_predicate_kind_or_recover_tuple_struct_body( &mut self, struct_: Option<(Ident, Span)>, pred_lo: Span, where_sp: Span, - ) -> PResult<'a, PredicateOrStructBody> { + ) -> PResult<'a, PredicateKindOrStructBody> { let mut snapshot = None; if let Some(struct_) = struct_ @@ -399,8 +403,8 @@ impl<'a> Parser<'a> { snapshot = Some((struct_, self.create_snapshot_for_diagnostic())); }; - match self.parse_ty_where_predicate() { - Ok(pred) => Ok(PredicateOrStructBody::Predicate(pred)), + match self.parse_ty_where_predicate_kind() { + Ok(pred) => Ok(PredicateKindOrStructBody::PredicateKind(pred)), Err(type_err) => { let Some(((struct_name, body_insertion_point), mut snapshot)) = snapshot else { return Err(type_err); @@ -436,7 +440,7 @@ impl<'a> Parser<'a> { }); self.restore_snapshot(snapshot); - Ok(PredicateOrStructBody::StructBody(body)) + Ok(PredicateKindOrStructBody::StructBody(body)) } Ok(_) => Err(type_err), Err(body_err) => { @@ -448,8 +452,7 @@ impl<'a> Parser<'a> { } } - fn parse_ty_where_predicate(&mut self) -> PResult<'a, ast::WherePredicate> { - let lo = self.token.span; + fn parse_ty_where_predicate_kind(&mut self) -> PResult<'a, ast::WherePredicateKind> { // Parse optional `for<'a, 'b>`. // This `for` is parsed greedily and applies to the whole predicate, // the bounded type can have its own `for` applying only to it. @@ -464,8 +467,7 @@ impl<'a> Parser<'a> { let ty = self.parse_ty_for_where_clause()?; if self.eat(&token::Colon) { let bounds = self.parse_generic_bounds()?; - Ok(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { - span: lo.to(self.prev_token.span), + Ok(ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { bound_generic_params: lifetime_defs, bounded_ty: ty, bounds, @@ -474,11 +476,7 @@ impl<'a> Parser<'a> { // FIXME: We are just dropping the binders in lifetime_defs on the floor here. } else if self.eat(&token::Eq) || self.eat(&token::EqEq) { let rhs_ty = self.parse_ty()?; - Ok(ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { - span: lo.to(self.prev_token.span), - lhs_ty: ty, - rhs_ty, - })) + Ok(ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate { lhs_ty: ty, rhs_ty })) } else { self.maybe_recover_bounds_doubled_colon(&ty)?; self.unexpected_any() diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index fddbf5896ad83..26e81b7676bb1 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1791,6 +1791,17 @@ impl<'a> Parser<'a> { Ok((fields, recovered)) } + fn parse_unsafe_field(&mut self) -> Safety { + // not using parse_safety as that also accepts `safe`. + if self.eat_keyword(kw::Unsafe) { + let span = self.prev_token.span; + self.psess.gated_spans.gate(sym::unsafe_fields, span); + Safety::Unsafe(span) + } else { + Safety::Default + } + } + pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec> { // This is the case where we find `struct Foo(T) where T: Copy;` // Unit like structs are handled in parse_item_struct function @@ -1814,6 +1825,8 @@ impl<'a> Parser<'a> { return Err(err); } }; + // Unsafe fields are not supported in tuple structs, as doing so would result in a + // parsing ambiguity for `struct X(unsafe fn())`. let ty = match p.parse_ty() { Ok(ty) => ty, Err(err) => { @@ -1828,6 +1841,7 @@ impl<'a> Parser<'a> { FieldDef { span: lo.to(ty.span), vis, + safety: Safety::Default, ident: None, id: DUMMY_NODE_ID, ty, @@ -1850,7 +1864,8 @@ impl<'a> Parser<'a> { self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| { let lo = this.token.span; let vis = this.parse_visibility(FollowedByType::No)?; - this.parse_single_struct_field(adt_ty, lo, vis, attrs) + let safety = this.parse_unsafe_field(); + this.parse_single_struct_field(adt_ty, lo, vis, safety, attrs) .map(|field| (field, Trailing::No, UsePreAttrPos::No)) }) } @@ -1861,10 +1876,11 @@ impl<'a> Parser<'a> { adt_ty: &str, lo: Span, vis: Visibility, + safety: Safety, attrs: AttrVec, ) -> PResult<'a, FieldDef> { let mut seen_comma: bool = false; - let a_var = self.parse_name_and_ty(adt_ty, lo, vis, attrs)?; + let a_var = self.parse_name_and_ty(adt_ty, lo, vis, safety, attrs)?; if self.token == token::Comma { seen_comma = true; } @@ -1992,6 +2008,7 @@ impl<'a> Parser<'a> { adt_ty: &str, lo: Span, vis: Visibility, + safety: Safety, attrs: AttrVec, ) -> PResult<'a, FieldDef> { let name = self.parse_field_ident(adt_ty, lo)?; @@ -2017,6 +2034,7 @@ impl<'a> Parser<'a> { span: lo.to(self.prev_token.span), ident: Some(name), vis, + safety, id: DUMMY_NODE_ID, ty, attrs, diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index c4326427f67b0..bb976e092bf4c 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -1,11 +1,12 @@ use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::ptr::P; use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token}; +use rustc_ast::util::parser::AssocOp; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{ - self as ast, Arm, AttrVec, BinOpKind, BindingMode, ByRef, Expr, ExprKind, ExprPrecedence, - LocalKind, MacCall, Mutability, Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, - RangeSyntax, Stmt, StmtKind, + self as ast, Arm, AttrVec, BinOpKind, BindingMode, ByRef, Expr, ExprKind, LocalKind, MacCall, + Mutability, Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax, Stmt, + StmtKind, }; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, Diag, DiagArgValue, PResult, StashKey}; @@ -458,7 +459,7 @@ impl<'a> Parser<'a> { .create_err(UnexpectedExpressionInPattern { span, is_bound, - expr_precedence: expr.precedence().order(), + expr_precedence: expr.precedence(), }) .stash(span, StashKey::ExprInPat) .unwrap(), @@ -545,7 +546,8 @@ impl<'a> Parser<'a> { let expr = match &err.args["expr_precedence"] { DiagArgValue::Number(expr_precedence) => { if *expr_precedence - <= ExprPrecedence::Binary(BinOpKind::Eq).order() as i32 + <= AssocOp::from_ast_binop(BinOpKind::Eq).precedence() + as i32 { format!("({expr})") } else { @@ -568,8 +570,9 @@ impl<'a> Parser<'a> { } Some(guard) => { // Are parentheses required around the old guard? - let wrap_guard = guard.precedence().order() - <= ExprPrecedence::Binary(BinOpKind::And).order(); + let wrap_guard = guard.precedence() + <= AssocOp::from_ast_binop(BinOpKind::And).precedence() + as i8; err.subdiagnostic( UnexpectedExpressionInPatternSugg::UpdateGuard { @@ -1086,7 +1089,9 @@ impl<'a> Parser<'a> { return; } - self.dcx().emit_err(RepeatedMutInPattern { span: lo.to(self.prev_token.span) }); + let span = lo.to(self.prev_token.span); + let suggestion = span.with_hi(self.token.span.lo()); + self.dcx().emit_err(RepeatedMutInPattern { span, suggestion }); } /// Parse macro invocation diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index c561ea3823d09..505586e74f11f 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -274,7 +274,6 @@ impl<'a> Parser<'a> { // Function pointer type self.parse_ty_bare_fn(lo, ThinVec::new(), None, recover_return_sign)? } else if self.check_keyword(kw::For) { - let for_span = self.token.span; // Function pointer type or bound list (trait object type) starting with a poly-trait. // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T` // `for<'lt> Trait1<'lt> + Trait2 + 'a` @@ -302,7 +301,7 @@ impl<'a> Parser<'a> { kw: kw.name.as_str(), sugg: errors::TransposeDynOrImplSugg { removal_span, - insertion_span: for_span.shrink_to_lo(), + insertion_span: lo.shrink_to_lo(), kw: kw.name.as_str(), }, }); @@ -345,16 +344,14 @@ impl<'a> Parser<'a> { // FIXME(c_variadic): Should we just allow `...` syntactically // anywhere in a type and use semantic restrictions instead? // NOTE: This may regress certain MBE calls if done incorrectly. - let guar = self - .dcx() - .emit_err(NestedCVariadicType { span: lo.to(self.prev_token.span) }); + let guar = self.dcx().emit_err(NestedCVariadicType { span: lo }); TyKind::Err(guar) } } } else { let msg = format!("expected type, found {}", super::token_descr(&self.token)); - let mut err = self.dcx().struct_span_err(self.token.span, msg); - err.span_label(self.token.span, "expected type"); + let mut err = self.dcx().struct_span_err(lo, msg); + err.span_label(lo, "expected type"); return Err(err); }; diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 08098ae7f6cbf..0712af422adf3 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -558,6 +558,10 @@ passes_no_mangle_foreign = passes_no_patterns = patterns not allowed in naked function parameters +passes_no_sanitize = + `#[no_sanitize({$attr_str})]` should be applied to {$accepted_kind} + .label = not {$accepted_kind} + passes_non_exported_macro_invalid_attrs = attribute should be applied to function or closure .label = not a function or closure diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 87069e0b0575d..074fe77324faf 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -126,9 +126,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::inline, ..] => self.check_inline(hir_id, attr, span, target), [sym::coverage, ..] => self.check_coverage(attr, span, target), [sym::optimize, ..] => self.check_optimize(hir_id, attr, span, target), - [sym::no_sanitize, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr, span, target) - } + [sym::no_sanitize, ..] => self.check_no_sanitize(attr, span, target), [sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target), [sym::marker, ..] => self.check_marker(hir_id, attr, span, target), [sym::target_feature, ..] => { @@ -450,6 +448,39 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } + fn check_no_sanitize(&self, attr: &Attribute, span: Span, target: Target) { + if let Some(list) = attr.meta_item_list() { + for item in list.iter() { + let sym = item.name_or_empty(); + match sym { + sym::address | sym::hwaddress => { + let is_valid = + matches!(target, Target::Fn | Target::Method(..) | Target::Static); + if !is_valid { + self.dcx().emit_err(errors::NoSanitize { + attr_span: item.span(), + defn_span: span, + accepted_kind: "a function or static", + attr_str: sym.as_str(), + }); + } + } + _ => { + let is_valid = matches!(target, Target::Fn | Target::Method(..)); + if !is_valid { + self.dcx().emit_err(errors::NoSanitize { + attr_span: item.span(), + defn_span: span, + accepted_kind: "a function", + attr_str: sym.as_str(), + }); + } + } + } + } + } + } + fn check_generic_attr( &self, hir_id: HirId, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 2d1734c031433..fbf25cb476aee 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1846,3 +1846,14 @@ pub(crate) struct AttrCrateLevelOnlySugg { #[primary_span] pub attr: Span, } + +#[derive(Diagnostic)] +#[diag(passes_no_sanitize)] +pub(crate) struct NoSanitize<'a> { + #[primary_span] + pub attr_span: Span, + #[label] + pub defn_span: Span, + pub accepted_kind: &'a str, + pub attr_str: &'a str, +} diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index db34189be2a93..b8f66a2b2ec34 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -360,11 +360,10 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { } fn visit_where_predicate(&mut self, p: &'v hir::WherePredicate<'v>) { - record_variants!((self, p, p, None, hir, WherePredicate, WherePredicate), [ - BoundPredicate, - RegionPredicate, - EqPredicate - ]); + record_variants!( + (self, p, p.kind, Some(p.hir_id), hir, WherePredicate, WherePredicateKind), + [BoundPredicate, RegionPredicate, EqPredicate] + ); hir_visit::walk_where_predicate(self, p) } @@ -611,7 +610,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { } fn visit_where_predicate(&mut self, p: &'v ast::WherePredicate) { - record_variants!((self, p, p, None, ast, WherePredicate, WherePredicate), [ + record_variants!((self, p, &p.kind, None, ast, WherePredicate, WherePredicateKind), [ BoundPredicate, RegionPredicate, EqPredicate diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 4a793f1875ec8..2809ad453ff4a 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -590,16 +590,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> { } fn check_missing_const_stability(&self, def_id: LocalDefId, span: Span) { - // if the const impl is derived using the `derive_const` attribute, - // then it would be "stable" at least for the impl. - // We gate usages of it using `feature(const_trait_impl)` anyways - // so there is no unstable leakage - if self.tcx.is_automatically_derived(def_id.to_def_id()) { - return; - } - - let is_const = self.tcx.is_const_fn(def_id.to_def_id()) - || self.tcx.is_const_trait_impl(def_id.to_def_id()); + let is_const = self.tcx.is_const_fn(def_id.to_def_id()); // Reachable const fn must have a stability attribute. if is_const diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index cc0763ac751d2..009d817a1a93b 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -9,7 +9,6 @@ use rustc_index::{Idx, IndexVec}; use rustc_middle::middle::stability::EvalResult; use rustc_middle::mir::{self, Const}; use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary}; -use rustc_middle::traits::Reveal; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{ self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef, @@ -86,7 +85,7 @@ pub struct RustcPatCtxt<'p, 'tcx: 'p> { /// not. E.g., `struct Foo { _private: ! }` cannot be seen to be empty /// outside its module and should not be matchable with an empty match statement. pub module: DefId, - pub param_env: ty::ParamEnv<'tcx>, + pub typing_env: ty::TypingEnv<'tcx>, /// To allocate the result of `self.ctor_sub_tys()` pub dropless_arena: &'p DroplessArena, /// Lint level at the match. @@ -109,20 +108,11 @@ impl<'p, 'tcx: 'p> fmt::Debug for RustcPatCtxt<'p, 'tcx> { } impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { - pub fn typing_mode(&self) -> ty::TypingMode<'tcx> { - debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing); - // FIXME(#132279): This is inside of a body. If we need to use the `param_env` - // and `typing_mode` we should reveal opaques defined by that body. - ty::TypingMode::non_body_analysis() - } - - pub fn typing_env(&self) -> ty::TypingEnv<'tcx> { - ty::TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env } - } - /// Type inference occasionally gives us opaque types in places where corresponding patterns /// have more specific types. To avoid inconsistencies as well as detect opaque uninhabited /// types, we use the corresponding concrete type if possible. + // FIXME(#132279): This will be unnecessary once we have a TypingMode which supports revealing + // opaque types defined in a body. #[inline] pub fn reveal_opaque_ty(&self, ty: Ty<'tcx>) -> RevealedTy<'tcx> { fn reveal_inner<'tcx>(cx: &RustcPatCtxt<'_, 'tcx>, ty: Ty<'tcx>) -> RevealedTy<'tcx> { @@ -151,7 +141,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { !ty.inhabited_predicate(self.tcx).apply_revealing_opaque( self.tcx, - self.typing_env(), + self.typing_env, self.module, &|key| self.reveal_opaque_key(key), ) @@ -191,7 +181,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { variant.fields.iter().map(move |field| { let ty = field.ty(self.tcx, args); // `field.ty()` doesn't normalize after instantiating. - let ty = self.tcx.normalize_erasing_regions(self.typing_env(), ty); + let ty = self.tcx.normalize_erasing_regions(self.typing_env, ty); let ty = self.reveal_opaque_ty(ty); (field, ty) }) @@ -381,7 +371,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let is_inhabited = v .inhabited_predicate(cx.tcx, *def) .instantiate(cx.tcx, args) - .apply_revealing_opaque(cx.tcx, cx.typing_env(), cx.module, &|key| { + .apply_revealing_opaque(cx.tcx, cx.typing_env, cx.module, &|key| { cx.reveal_opaque_key(key) }); // Variants that depend on a disabled unstable feature. @@ -442,7 +432,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { match bdy { PatRangeBoundary::NegInfinity => MaybeInfiniteInt::NegInfinity, PatRangeBoundary::Finite(value) => { - let bits = value.eval_bits(self.tcx, self.typing_env()); + let bits = value.eval_bits(self.tcx, self.typing_env); match *ty.kind() { ty::Int(ity) => { let size = Integer::from_int_ty(&self.tcx, ity).size().bits(); @@ -551,7 +541,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { PatKind::Constant { value } => { match ty.kind() { ty::Bool => { - ctor = match value.try_eval_bool(cx.tcx, cx.typing_env()) { + ctor = match value.try_eval_bool(cx.tcx, cx.typing_env) { Some(b) => Bool(b), None => Opaque(OpaqueId::new()), }; @@ -559,7 +549,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Char | ty::Int(_) | ty::Uint(_) => { - ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) { Some(bits) => { let x = match *ty.kind() { ty::Int(ity) => { @@ -576,7 +566,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Float(ty::FloatTy::F16) => { - ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) { Some(bits) => { use rustc_apfloat::Float; let value = rustc_apfloat::ieee::Half::from_bits(bits); @@ -588,7 +578,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Float(ty::FloatTy::F32) => { - ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) { Some(bits) => { use rustc_apfloat::Float; let value = rustc_apfloat::ieee::Single::from_bits(bits); @@ -600,7 +590,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Float(ty::FloatTy::F64) => { - ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) { Some(bits) => { use rustc_apfloat::Float; let value = rustc_apfloat::ieee::Double::from_bits(bits); @@ -612,7 +602,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Float(ty::FloatTy::F128) => { - ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) { Some(bits) => { use rustc_apfloat::Float; let value = rustc_apfloat::ieee::Quad::from_bits(bits); @@ -661,8 +651,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } ty::Float(fty) => { use rustc_apfloat::Float; - let lo = lo.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env())); - let hi = hi.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env())); + let lo = lo.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env)); + let hi = hi.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env)); match fty { ty::FloatTy::F16 => { use rustc_apfloat::ieee::Half; diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index df898e0587ff9..a1917fed4d9cf 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -222,3 +222,9 @@ pub fn query_system<'tcx>( } rustc_middle::rustc_query_append! { define_queries! } + +pub fn provide(providers: &mut rustc_middle::util::Providers) { + providers.hooks.alloc_self_profile_query_strings = + |tcx| alloc_self_profile_query_strings(tcx.tcx); + providers.hooks.query_key_hash_verify_all = |tcx| query_key_hash_verify_all(tcx.tcx); +} diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index 5f989b264aa63..7d80e54bf87e6 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -252,6 +252,8 @@ pub fn alloc_self_profile_query_strings(tcx: TyCtxt<'_>) { return; } + let _prof_timer = tcx.sess.prof.generic_activity("self_profile_alloc_query_strings"); + let mut string_cache = QueryKeyStringCache::new(); for alloc in super::ALLOC_SELF_PROFILE_QUERY_STRINGS.iter() { diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 6602c7889691f..b13de2875bc20 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -257,8 +257,14 @@ resolve_lowercase_self = attempt to use a non-constant value in a constant .suggestion = try using `Self` +resolve_macro_cannot_use_as_attr = + `{$ident}` exists, but a declarative macro cannot be used as an attribute macro + +resolve_macro_cannot_use_as_derive = + `{$ident}` exists, but a declarative macro cannot be used as a derive macro + resolve_macro_defined_later = - a macro with the same name exists, but it appears later at here + a macro with the same name exists, but it appears later resolve_macro_expanded_extern_crate_cannot_shadow_extern_arguments = macro-expanded `extern crate` items cannot shadow names passed with `--extern` diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index bf27b767a4972..6649284258121 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -12,23 +12,16 @@ use rustc_span::hygiene::LocalExpnId; use rustc_span::symbol::{Symbol, kw, sym}; use tracing::debug; -use crate::{ImplTraitContext, InvocationParent, PendingAnonConstInfo, Resolver}; +use crate::{ImplTraitContext, InvocationParent, Resolver}; pub(crate) fn collect_definitions( resolver: &mut Resolver<'_, '_>, fragment: &AstFragment, expansion: LocalExpnId, ) { - let InvocationParent { parent_def, pending_anon_const_info, impl_trait_context, in_attr } = + let InvocationParent { parent_def, impl_trait_context, in_attr } = resolver.invocation_parents[&expansion]; - let mut visitor = DefCollector { - resolver, - parent_def, - pending_anon_const_info, - expansion, - impl_trait_context, - in_attr, - }; + let mut visitor = DefCollector { resolver, parent_def, expansion, impl_trait_context, in_attr }; fragment.visit_with(&mut visitor); } @@ -36,13 +29,6 @@ pub(crate) fn collect_definitions( struct DefCollector<'a, 'ra, 'tcx> { resolver: &'a mut Resolver<'ra, 'tcx>, parent_def: LocalDefId, - /// If we have an anon const that consists of a macro invocation, e.g. `Foo<{ m!() }>`, - /// we need to wait until we know what the macro expands to before we create the def for - /// the anon const. That's because we lower some anon consts into `hir::ConstArgKind::Path`, - /// which don't have defs. - /// - /// See `Self::visit_anon_const()`. - pending_anon_const_info: Option, impl_trait_context: ImplTraitContext, in_attr: bool, expansion: LocalExpnId, @@ -110,61 +96,13 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { fn visit_macro_invoc(&mut self, id: NodeId) { let id = id.placeholder_to_expn_id(); - let pending_anon_const_info = self.pending_anon_const_info.take(); let old_parent = self.resolver.invocation_parents.insert(id, InvocationParent { parent_def: self.parent_def, - pending_anon_const_info, impl_trait_context: self.impl_trait_context, in_attr: self.in_attr, }); assert!(old_parent.is_none(), "parent `LocalDefId` is reset for an invocation"); } - - /// Determines whether the const argument `AnonConst` is a simple macro call, optionally - /// surrounded with braces. - /// - /// If this const argument *is* a trivial macro call then the id for the macro call is - /// returned along with the information required to build the anon const's def if - /// the macro call expands to a non-trivial expression. - fn is_const_arg_trivial_macro_expansion( - &self, - anon_const: &'a AnonConst, - ) -> Option<(PendingAnonConstInfo, NodeId)> { - anon_const.value.optionally_braced_mac_call(false).map(|(block_was_stripped, id)| { - ( - PendingAnonConstInfo { - id: anon_const.id, - span: anon_const.value.span, - block_was_stripped, - }, - id, - ) - }) - } - - /// Determines whether the expression `const_arg_sub_expr` is a simple macro call, sometimes - /// surrounded with braces if a set of braces has not already been entered. This is required - /// as `{ N }` is treated as equivalent to a bare parameter `N` whereas `{{ N }}` is treated as - /// a real block expression and is lowered to an anonymous constant which is not allowed to use - /// generic parameters. - /// - /// If this expression is a trivial macro call then the id for the macro call is - /// returned along with the information required to build the anon const's def if - /// the macro call expands to a non-trivial expression. - fn is_const_arg_sub_expr_trivial_macro_expansion( - &self, - const_arg_sub_expr: &'a Expr, - ) -> Option<(PendingAnonConstInfo, NodeId)> { - let pending_anon = self.pending_anon_const_info.unwrap_or_else(|| - panic!("Checking expr is trivial macro call without having entered anon const: `{const_arg_sub_expr:?}`"), - ); - - const_arg_sub_expr.optionally_braced_mac_call(pending_anon.block_was_stripped).map( - |(block_was_stripped, id)| { - (PendingAnonConstInfo { block_was_stripped, ..pending_anon }, id) - }, - ) - } } impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { @@ -191,7 +129,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { ItemKind::Const(..) => DefKind::Const, ItemKind::Fn(..) | ItemKind::Delegation(..) => DefKind::Fn, ItemKind::MacroDef(def) => { - let edition = self.resolver.tcx.sess.edition(); + let edition = i.span.edition(); let macro_data = self.resolver.compile_macro(def, i.ident, &i.attrs, i.span, i.id, edition); let macro_kind = macro_data.ext.macro_kind(); @@ -376,78 +314,34 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } fn visit_anon_const(&mut self, constant: &'a AnonConst) { - // HACK(min_generic_const_args): don't create defs for anon consts if we think they will - // later be turned into ConstArgKind::Path's. because this is before resolve is done, we - // may accidentally identify a construction of a unit struct as a param and not create a - // def. we'll then create a def later in ast lowering in this case. the parent of nested - // items will be messed up, but that's ok because there can't be any if we're just looking - // for bare idents. - - if let Some((pending_anon, macro_invoc)) = - self.is_const_arg_trivial_macro_expansion(constant) - { - self.pending_anon_const_info = Some(pending_anon); - return self.visit_macro_invoc(macro_invoc); - } else if constant.value.is_potential_trivial_const_arg(true) { - return visit::walk_anon_const(self, constant); - } - - let def = self.create_def(constant.id, kw::Empty, DefKind::AnonConst, constant.value.span); - self.with_parent(def, |this| visit::walk_anon_const(this, constant)); + let parent = + self.create_def(constant.id, kw::Empty, DefKind::AnonConst, constant.value.span); + self.with_parent(parent, |this| visit::walk_anon_const(this, constant)); } fn visit_expr(&mut self, expr: &'a Expr) { - // If we're visiting the expression of a const argument that was a macro call then - // check if it is *still* unknown whether it is a trivial const arg or not. If so - // recurse into the macro call and delay creating the anon const def until expansion. - if self.pending_anon_const_info.is_some() - && let Some((pending_anon, macro_invoc)) = - self.is_const_arg_sub_expr_trivial_macro_expansion(expr) - { - self.pending_anon_const_info = Some(pending_anon); - return self.visit_macro_invoc(macro_invoc); - } - - // See self.pending_anon_const_info for explanation - let parent_def = self - .pending_anon_const_info - .take() - // If we already stripped away a set of braces then do not do it again when determining - // if the macro expanded to a trivial const arg. This arises in cases such as: - // `Foo<{ bar!() }>` where `bar!()` expands to `{ N }`. This should not be considered a - // trivial const argument even though `{ N }` by itself *is*. - .filter(|pending_anon| { - !expr.is_potential_trivial_const_arg(!pending_anon.block_was_stripped) - }) - .map(|pending_anon| { - self.create_def(pending_anon.id, kw::Empty, DefKind::AnonConst, pending_anon.span) - }) - .unwrap_or(self.parent_def); - - self.with_parent(parent_def, |this| { - let parent_def = match expr.kind { - ExprKind::MacCall(..) => return this.visit_macro_invoc(expr.id), - ExprKind::Closure(..) | ExprKind::Gen(..) => { - this.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span) - } - ExprKind::ConstBlock(ref constant) => { - for attr in &expr.attrs { - visit::walk_attribute(this, attr); - } - let def = this.create_def( - constant.id, - kw::Empty, - DefKind::InlineConst, - constant.value.span, - ); - this.with_parent(def, |this| visit::walk_anon_const(this, constant)); - return; + let parent_def = match expr.kind { + ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id), + ExprKind::Closure(..) | ExprKind::Gen(..) => { + self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span) + } + ExprKind::ConstBlock(ref constant) => { + for attr in &expr.attrs { + visit::walk_attribute(self, attr); } - _ => this.parent_def, - }; + let def = self.create_def( + constant.id, + kw::Empty, + DefKind::InlineConst, + constant.value.span, + ); + self.with_parent(def, |this| visit::walk_anon_const(this, constant)); + return; + } + _ => self.parent_def, + }; - this.with_parent(parent_def, |this| visit::walk_expr(this, expr)) - }) + self.with_parent(parent_def, |this| visit::walk_expr(this, expr)) } fn visit_ty(&mut self, ty: &'a Ty) { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 5b78acd904a75..4c76617a3918d 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -35,7 +35,8 @@ use tracing::debug; use crate::errors::{ self, AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion, ConsiderAddingADerive, - ExplicitUnsafeTraits, MacroDefinedLater, MacroSuggMovePosition, MaybeMissingMacroRulesName, + ExplicitUnsafeTraits, MacroDefinedLater, MacroRulesNot, MacroSuggMovePosition, + MaybeMissingMacroRulesName, }; use crate::imports::{Import, ImportKind}; use crate::late::{PatternSource, Rib}; @@ -1473,8 +1474,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let scope = self.local_macro_def_scopes[&def_id]; let parent_nearest = parent_scope.module.nearest_parent_mod(); if Some(parent_nearest) == scope.opt_def_id() { - err.subdiagnostic(MacroDefinedLater { span: unused_ident.span }); - err.subdiagnostic(MacroSuggMovePosition { span: ident.span, ident }); + match macro_kind { + MacroKind::Bang => { + err.subdiagnostic(MacroDefinedLater { span: unused_ident.span }); + err.subdiagnostic(MacroSuggMovePosition { span: ident.span, ident }); + } + MacroKind::Attr => { + err.subdiagnostic(MacroRulesNot::Attr { span: unused_ident.span, ident }); + } + MacroKind::Derive => { + err.subdiagnostic(MacroRulesNot::Derive { span: unused_ident.span, ident }); + } + } + return; } } diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index f605b7096f0c2..24f5a812a82cd 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -665,6 +665,22 @@ pub(crate) struct MacroSuggMovePosition { pub(crate) ident: Ident, } +#[derive(Subdiagnostic)] +pub(crate) enum MacroRulesNot { + #[label(resolve_macro_cannot_use_as_attr)] + Attr { + #[primary_span] + span: Span, + ident: Ident, + }, + #[label(resolve_macro_cannot_use_as_derive)] + Derive { + #[primary_span] + span: Span, + ident: Ident, + }, +} + #[derive(Subdiagnostic)] #[note(resolve_missing_macro_rules_name)] pub(crate) struct MaybeMissingMacroRulesName { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 26b345f5941c4..fc92dc8b4ed71 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1268,15 +1268,14 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r debug!("visit_where_predicate {:?}", p); let previous_value = replace(&mut self.diag_metadata.current_where_predicate, Some(p)); self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| { - if let WherePredicate::BoundPredicate(WhereBoundPredicate { - ref bounded_ty, - ref bounds, - ref bound_generic_params, - span: predicate_span, + if let WherePredicateKind::BoundPredicate(WhereBoundPredicate { + bounded_ty, + bounds, + bound_generic_params, .. - }) = p + }) = &p.kind { - let span = predicate_span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo()); + let span = p.span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo()); this.with_generic_param_rib( bound_generic_params, RibKind::Normal, @@ -3940,12 +3939,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } Res::SelfCtor(_) => { // We resolve `Self` in pattern position as an ident sometimes during recovery, - // so delay a bug instead of ICEing. (Note: is this no longer true? We now ICE. If - // this triggers, please convert to a delayed bug and add a test.) - self.r.dcx().span_bug( + // so delay a bug instead of ICEing. + self.r.dcx().span_delayed_bug( ident.span, "unexpected `SelfCtor` in pattern, expected identifier" ); + None } _ => span_bug!( ident.span, @@ -4522,7 +4521,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ); self.resolve_anon_const_manual( - constant.value.is_potential_trivial_const_arg(true), + constant.value.is_potential_trivial_const_arg(), anon_const_kind, |this| this.resolve_expr(&constant.value, None), ) @@ -4686,7 +4685,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // that is how they will be later lowered to HIR. if const_args.contains(&idx) { self.resolve_anon_const_manual( - argument.is_potential_trivial_const_arg(true), + argument.is_potential_trivial_const_arg(), AnonConstKind::ConstArg(IsRepeatExpr::No), |this| this.resolve_expr(argument, None), ); @@ -4794,14 +4793,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let res = self.r.resolve_rustdoc_path(path.as_str(), *ns, self.parent_scope); if let Some(res) = res && let Some(def_id) = res.opt_def_id() - && !def_id.is_local() - && self.r.tcx.crate_types().contains(&CrateType::ProcMacro) - && matches!( - self.r.tcx.sess.opts.resolve_doc_links, - ResolveDocLinks::ExportedMetadata - ) + && self.is_invalid_proc_macro_item_for_doc(def_id) { - // Encoding foreign def ids in proc macro crate metadata will ICE. + // Encoding def ids in proc macro crate metadata will ICE, + // because it will only store proc macros for it. return None; } res @@ -4810,6 +4805,17 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { res } + fn is_invalid_proc_macro_item_for_doc(&self, did: DefId) -> bool { + if !matches!(self.r.tcx.sess.opts.resolve_doc_links, ResolveDocLinks::ExportedMetadata) + || !self.r.tcx.crate_types().contains(&CrateType::ProcMacro) + { + return false; + } + let Some(local_did) = did.as_local() else { return true }; + let Some(node_id) = self.r.def_id_to_node_id.get(local_did) else { return true }; + !self.r.proc_macros.contains(node_id) + } + fn resolve_doc_links(&mut self, attrs: &[Attribute], maybe_exported: MaybeExported<'_>) { match self.r.tcx.sess.opts.resolve_doc_links { ResolveDocLinks::None => return, @@ -4872,14 +4878,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .traits_in_scope(None, &self.parent_scope, SyntaxContext::root(), None) .into_iter() .filter_map(|tr| { - if !tr.def_id.is_local() - && self.r.tcx.crate_types().contains(&CrateType::ProcMacro) - && matches!( - self.r.tcx.sess.opts.resolve_doc_links, - ResolveDocLinks::ExportedMetadata - ) - { - // Encoding foreign def ids in proc macro crate metadata will ICE. + if self.is_invalid_proc_macro_item_for_doc(tr.def_id) { + // Encoding def ids in proc macro crate metadata will ICE. + // because it will only store proc macros for it. return None; } Some(tr.def_id) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 09f5a8e96d3de..663c3ac0045ab 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1206,7 +1206,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let PathSource::TupleStruct(_, _) = source else { return }; let Some(Res::Def(DefKind::Fn, _)) = res else { return }; err.primary_message("expected a pattern, found a function call"); - err.note("function calls are not allowed in patterns: "); + err.note("function calls are not allowed in patterns: "); } fn suggest_changing_type_to_const_param( @@ -1317,21 +1317,24 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { /// Given `where ::Baz: String`, suggest `where T: Bar`. fn restrict_assoc_type_in_where_clause(&mut self, span: Span, err: &mut Diag<'_>) -> bool { // Detect that we are actually in a `where` predicate. - let (bounded_ty, bounds, where_span) = - if let Some(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { - bounded_ty, - bound_generic_params, - bounds, - span, - })) = self.diag_metadata.current_where_predicate - { - if !bound_generic_params.is_empty() { - return false; - } - (bounded_ty, bounds, span) - } else { + let (bounded_ty, bounds, where_span) = if let Some(ast::WherePredicate { + kind: + ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { + bounded_ty, + bound_generic_params, + bounds, + }), + span, + .. + }) = self.diag_metadata.current_where_predicate + { + if !bound_generic_params.is_empty() { return false; - }; + } + (bounded_ty, bounds, span) + } else { + return false; + }; // Confirm that the target is an associated type. let (ty, _, path) = if let ast::TyKind::Path(Some(qself), path) = &bounded_ty.kind { @@ -2840,9 +2843,10 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // for<'a, 'b> T: Trait + 'b // ^^^^^^^^^^^ suggest outer binder `for<'a, 'b>` if let LifetimeBinderKind::WhereBound = kind - && let Some(ast::WherePredicate::BoundPredicate( + && let Some(predicate) = self.diag_metadata.current_where_predicate + && let ast::WherePredicateKind::BoundPredicate( ast::WhereBoundPredicate { bounded_ty, bounds, .. }, - )) = self.diag_metadata.current_where_predicate + ) = &predicate.kind && bounded_ty.id == binder { for bound in bounds { @@ -3473,7 +3477,6 @@ fn mk_where_bound_predicate( }; let new_where_bound_predicate = ast::WhereBoundPredicate { - span: DUMMY_SP, bound_generic_params: ThinVec::new(), bounded_ty: ast::ptr::P(ty.clone()), bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index e382295b8f6d8..094871ad26876 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -174,7 +174,6 @@ impl<'ra> ParentScope<'ra> { #[derive(Copy, Debug, Clone)] struct InvocationParent { parent_def: LocalDefId, - pending_anon_const_info: Option, impl_trait_context: ImplTraitContext, in_attr: bool, } @@ -182,23 +181,11 @@ struct InvocationParent { impl InvocationParent { const ROOT: Self = Self { parent_def: CRATE_DEF_ID, - pending_anon_const_info: None, impl_trait_context: ImplTraitContext::Existential, in_attr: false, }; } -#[derive(Copy, Debug, Clone)] -struct PendingAnonConstInfo { - // A const arg is only a "trivial" const arg if it has at *most* one set of braces - // around the argument. We track whether we have stripped an outter brace so that - // if a macro expands to a braced expression *and* the macro was itself inside of - // some braces then we can consider it to be a non-trivial const argument. - block_was_stripped: bool, - id: NodeId, - span: Span, -} - #[derive(Copy, Debug, Clone)] enum ImplTraitContext { Existential, diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index 893c532f1fbb1..8fd87893a98c2 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -84,8 +84,6 @@ session_not_supported = not supported session_octal_float_literal_not_supported = octal float literal is not supported -session_optimization_fuel_exhausted = optimization-fuel-exhausted: {$msg} - session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index d60c56fee756f..cb6d539cdf940 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1208,7 +1208,7 @@ impl Options { /// Returns `true` if there will be an output file generated. pub fn will_create_output_file(&self) -> bool { - !self.unstable_opts.parse_only && // The file is just being parsed + !self.unstable_opts.parse_crate_root_only && // The file is just being parsed self.unstable_opts.ls.is_empty() // The file is just being queried } @@ -1864,7 +1864,7 @@ fn parse_output_types( matches: &getopts::Matches, ) -> OutputTypes { let mut output_types = BTreeMap::new(); - if !unstable_opts.parse_only { + if !unstable_opts.parse_crate_root_only { for list in matches.opt_strs("emit") { for output_type in list.split(',') { let (shorthand, path) = split_out_file_name(output_type); @@ -2356,14 +2356,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M early_dcx.early_warn(format!("number of threads was capped at {}", parse::MAX_THREADS_CAP)); } - let fuel = unstable_opts.fuel.is_some() || unstable_opts.print_fuel.is_some(); - if fuel && unstable_opts.threads > 1 { - early_dcx.early_fatal("optimization fuel is incompatible with multiple threads"); - } - if fuel && cg.incremental.is_some() { - early_dcx.early_fatal("optimization fuel is incompatible with incremental compilation"); - } - let incremental = cg.incremental.as_ref().map(PathBuf::from); let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state); diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 33f84f104474d..736a5ce07049a 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -463,12 +463,6 @@ pub fn report_lit_error( } } -#[derive(Diagnostic)] -#[diag(session_optimization_fuel_exhausted)] -pub(crate) struct OptimisationFuelExhausted { - pub(crate) msg: String, -} - #[derive(Diagnostic)] #[diag(session_incompatible_linker_flavor)] #[note] diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index cbfe5d22f1dbc..25f75ae12e8e5 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -358,7 +358,7 @@ fn build_options( #[allow(non_upper_case_globals)] mod desc { - pub(crate) const parse_no_flag: &str = "no value"; + pub(crate) const parse_no_value: &str = "no value"; pub(crate) const parse_bool: &str = "one of: `y`, `yes`, `on`, `true`, `n`, `no`, `off` or `false`"; pub(crate) const parse_opt_bool: &str = parse_bool; @@ -394,7 +394,6 @@ mod desc { pub(crate) const parse_collapse_macro_debuginfo: &str = "one of `no`, `external`, or `yes`"; pub(crate) const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`"; pub(crate) const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of(); - pub(crate) const parse_optimization_fuel: &str = "crate=integer"; pub(crate) const parse_dump_mono_stats: &str = "`markdown` (default) or `json`"; pub(crate) const parse_instrument_coverage: &str = parse_bool; pub(crate) const parse_coverage_options: &str = @@ -462,14 +461,18 @@ pub mod parse { pub(crate) use super::*; pub(crate) const MAX_THREADS_CAP: usize = 256; - /// This is for boolean options that don't take a value and start with - /// `no-`. This style of option is deprecated. - pub(crate) fn parse_no_flag(slot: &mut bool, v: Option<&str>) -> bool { + /// This is for boolean options that don't take a value, and are true simply + /// by existing on the command-line. + /// + /// This style of option is deprecated, and is mainly used by old options + /// beginning with `no-`. + pub(crate) fn parse_no_value(slot: &mut bool, v: Option<&str>) -> bool { match v { None => { *slot = true; true } + // Trying to specify a value is always forbidden. Some(_) => false, } } @@ -944,21 +947,6 @@ pub mod parse { true } - pub(crate) fn parse_optimization_fuel( - slot: &mut Option<(String, u64)>, - v: Option<&str>, - ) -> bool { - match v { - None => false, - Some(s) => { - let [crate_name, fuel] = *s.split('=').collect::>() else { return false }; - let Ok(fuel) = fuel.parse::() else { return false }; - *slot = Some((crate_name.to_string(), fuel)); - true - } - } - } - pub(crate) fn parse_unpretty(slot: &mut Option, v: Option<&str>) -> bool { match v { None => false, @@ -1609,16 +1597,16 @@ options! { "perform LLVM link-time optimizations"), metadata: Vec = (Vec::new(), parse_list, [TRACKED], "metadata to mangle symbol names with"), - no_prepopulate_passes: bool = (false, parse_no_flag, [TRACKED], + no_prepopulate_passes: bool = (false, parse_no_value, [TRACKED], "give an empty list of passes to the pass manager"), no_redzone: Option = (None, parse_opt_bool, [TRACKED], "disable the use of the redzone"), #[rustc_lint_opt_deny_field_access("documented to do nothing")] - no_stack_check: bool = (false, parse_no_flag, [UNTRACKED], + no_stack_check: bool = (false, parse_no_value, [UNTRACKED], "this option is deprecated and does nothing"), - no_vectorize_loops: bool = (false, parse_no_flag, [TRACKED], + no_vectorize_loops: bool = (false, parse_no_value, [TRACKED], "disable loop vectorization optimization passes"), - no_vectorize_slp: bool = (false, parse_no_flag, [TRACKED], + no_vectorize_slp: bool = (false, parse_no_value, [TRACKED], "disable LLVM's SLP vectorization pass"), opt_level: String = ("0".to_string(), parse_string, [TRACKED], "optimization level (0-3, s, or z; default: 0)"), @@ -1790,8 +1778,6 @@ options! { `shallow` prints only type names, `none` prints nothing and disables `{:?}`. (default: `full`)"), force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED], "force all crates to be `rustc_private` unstable (default: no)"), - fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED], - "set the optimization fuel quota for a crate"), function_return: FunctionReturn = (FunctionReturn::default(), parse_function_return, [TRACKED], "replace returns with jumps to `__x86_return_thunk` (default: `keep`)"), function_sections: Option = (None, parse_opt_bool, [TRACKED], @@ -1915,25 +1901,25 @@ options! { "dump facts from NLL analysis into side files (default: no)"), nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED], "the directory the NLL facts are dumped into (default: `nll-facts`)"), - no_analysis: bool = (false, parse_no_flag, [UNTRACKED], + no_analysis: bool = (false, parse_no_value, [UNTRACKED], "parse and expand the source, but run no analysis"), - no_codegen: bool = (false, parse_no_flag, [TRACKED_NO_CRATE_HASH], + no_codegen: bool = (false, parse_no_value, [TRACKED_NO_CRATE_HASH], "run all passes except codegen; no output"), - no_generate_arange_section: bool = (false, parse_no_flag, [TRACKED], + no_generate_arange_section: bool = (false, parse_no_value, [TRACKED], "omit DWARF address ranges that give faster lookups"), no_implied_bounds_compat: bool = (false, parse_bool, [TRACKED], "disable the compatibility version of the `implied_bounds_ty` query"), - no_jump_tables: bool = (false, parse_no_flag, [TRACKED], + no_jump_tables: bool = (false, parse_no_value, [TRACKED], "disable the jump tables and lookup tables that can be generated from a switch case lowering"), - no_leak_check: bool = (false, parse_no_flag, [UNTRACKED], + no_leak_check: bool = (false, parse_no_value, [UNTRACKED], "disable the 'leak check' for subtyping; unsound, but useful for tests"), - no_link: bool = (false, parse_no_flag, [TRACKED], + no_link: bool = (false, parse_no_value, [TRACKED], "compile without linking"), - no_parallel_backend: bool = (false, parse_no_flag, [UNTRACKED], + no_parallel_backend: bool = (false, parse_no_value, [UNTRACKED], "run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"), - no_profiler_runtime: bool = (false, parse_no_flag, [TRACKED], + no_profiler_runtime: bool = (false, parse_no_value, [TRACKED], "prevent automatic injection of the profiler_builtins crate"), - no_trait_vptr: bool = (false, parse_no_flag, [TRACKED], + no_trait_vptr: bool = (false, parse_no_value, [TRACKED], "disable generation of trait vptr in vtable for upcasting"), no_unique_section_names: bool = (false, parse_bool, [TRACKED], "do not use unique names for text and data sections when -Z function-sections is used"), @@ -1951,8 +1937,9 @@ options! { "support compiling tests with panic=abort (default: no)"), panic_in_drop: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy, [TRACKED], "panic strategy for panics in drops"), - parse_only: bool = (false, parse_bool, [UNTRACKED], - "parse only; do not compile, assemble, or link (default: no)"), + parse_crate_root_only: bool = (false, parse_bool, [UNTRACKED], + "parse the crate root file only; do not parse other files, compile, assemble, or link \ + (default: no)"), patchable_function_entry: PatchableFunctionEntry = (PatchableFunctionEntry::default(), parse_patchable_function_entry, [TRACKED], "nop padding at function entry"), plt: Option = (None, parse_opt_bool, [TRACKED], @@ -1974,8 +1961,6 @@ options! { #[rustc_lint_opt_deny_field_access("use `Session::print_codegen_stats` instead of this field")] print_codegen_stats: bool = (false, parse_bool, [UNTRACKED], "print codegen statistics (default: no)"), - print_fuel: Option = (None, parse_opt_string, [TRACKED], - "make rustc print the total optimization fuel used by a crate"), print_llvm_passes: bool = (false, parse_bool, [UNTRACKED], "print the LLVM optimization passes being run (default: no)"), print_mono_items: Option = (None, parse_opt_string, [UNTRACKED], @@ -1991,7 +1976,7 @@ options! { proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread, parse_proc_macro_execution_strategy, [UNTRACKED], "how to run proc-macro code (default: same-thread)"), - profile_closures: bool = (false, parse_no_flag, [UNTRACKED], + profile_closures: bool = (false, parse_no_value, [UNTRACKED], "profile size of closures"), profile_sample_use: Option = (None, parse_opt_pathbuf, [TRACKED], "use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)"), @@ -2052,7 +2037,7 @@ written to standard error output)"), shell_argfiles: bool = (false, parse_bool, [UNTRACKED], "allow argument files to be specified with POSIX \"shell-style\" argument quoting"), show_span: Option = (None, parse_opt_string, [TRACKED], - "show spans for compiler debugging (expr|pat|ty)"), + "show spans in the crate root file, for compiler debugging (expr|pat|ty)"), simulate_remapped_rust_src_base: Option = (None, parse_opt_pathbuf, [TRACKED], "simulate the effect of remap-debuginfo = true at bootstrapping by remapping path \ to rust's source base directory. only meant for testing purposes"), @@ -2165,8 +2150,14 @@ written to standard error output)"), "enable unsound and buggy MIR optimizations (default: no)"), /// This name is kind of confusing: Most unstable options enable something themselves, while /// this just allows "normal" options to be feature-gated. + /// + /// The main check for `-Zunstable-options` takes place separately from the + /// usual parsing of `-Z` options (see [`crate::config::nightly_options`]), + /// so this boolean value is mostly used for enabling unstable _values_ of + /// stable options. That separate check doesn't handle boolean values, so + /// to avoid an inconsistent state we also forbid them here. #[rustc_lint_opt_deny_field_access("use `Session::unstable_options` instead of this field")] - unstable_options: bool = (false, parse_bool, [UNTRACKED], + unstable_options: bool = (false, parse_no_value, [UNTRACKED], "adds unstable command line options to rustc interface (default: no)"), use_ctors_section: Option = (None, parse_opt_bool, [TRACKED], "use legacy .ctors section for initializers rather than .init_array"), diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 29fabdd1deb8d..f585410adb97d 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -4,7 +4,6 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use std::sync::Arc; use std::sync::atomic::AtomicBool; -use std::sync::atomic::Ordering::SeqCst; use std::{env, fmt, io}; use rustc_data_structures::flock; @@ -12,7 +11,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::jobserver::{self, Client}; use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef}; use rustc_data_structures::sync::{ - AtomicU64, DynSend, DynSync, Lock, Lrc, MappedReadGuard, ReadGuard, RwLock, + DynSend, DynSync, Lock, Lrc, MappedReadGuard, ReadGuard, RwLock, }; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::codes::*; @@ -49,13 +48,6 @@ use crate::parse::{ParseSess, add_feature_diagnostics}; use crate::search_paths::SearchPath; use crate::{errors, filesearch, lint}; -struct OptimizationFuel { - /// If `-zfuel=crate=n` is specified, initially set to `n`, otherwise `0`. - remaining: u64, - /// We're rejecting all further optimizations. - out_of_fuel: bool, -} - /// The behavior of the CTFE engine when an error occurs with regards to backtraces. #[derive(Clone, Copy)] pub enum CtfeBacktrace { @@ -163,12 +155,6 @@ pub struct Session { /// Data about code being compiled, gathered during compilation. pub code_stats: CodeStats, - /// Tracks fuel info if `-zfuel=crate=n` is specified. - optimization_fuel: Lock, - - /// Always set to zero and incremented so that we can print fuel expended by a crate. - pub print_fuel: AtomicU64, - /// Loaded up early on in the initialization of this `Session` to avoid /// false positives about a job server in our environment. pub jobserver: Client, @@ -532,41 +518,6 @@ impl Session { self.opts.incremental.as_ref().map(|_| self.incr_comp_session_dir()) } - /// We want to know if we're allowed to do an optimization for crate foo from -z fuel=foo=n. - /// This expends fuel if applicable, and records fuel if applicable. - pub fn consider_optimizing( - &self, - get_crate_name: impl Fn() -> Symbol, - msg: impl Fn() -> String, - ) -> bool { - let mut ret = true; - if let Some((ref c, _)) = self.opts.unstable_opts.fuel { - if c == get_crate_name().as_str() { - assert_eq!(self.threads(), 1); - let mut fuel = self.optimization_fuel.lock(); - ret = fuel.remaining != 0; - if fuel.remaining == 0 && !fuel.out_of_fuel { - if self.dcx().can_emit_warnings() { - // We only call `msg` in case we can actually emit warnings. - // Otherwise, this could cause a `must_produce_diag` ICE - // (issue #79546). - self.dcx().emit_warn(errors::OptimisationFuelExhausted { msg: msg() }); - } - fuel.out_of_fuel = true; - } else if fuel.remaining > 0 { - fuel.remaining -= 1; - } - } - } - if let Some(ref c) = self.opts.unstable_opts.print_fuel { - if c == get_crate_name().as_str() { - assert_eq!(self.threads(), 1); - self.print_fuel.fetch_add(1, SeqCst); - } - } - ret - } - /// Is this edition 2015? pub fn is_rust_2015(&self) -> bool { self.edition().is_rust_2015() @@ -1097,12 +1048,6 @@ pub fn build_session( Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, target_triple)) }; - let optimization_fuel = Lock::new(OptimizationFuel { - remaining: sopts.unstable_opts.fuel.as_ref().map_or(0, |&(_, i)| i), - out_of_fuel: false, - }); - let print_fuel = AtomicU64::new(0); - let prof = SelfProfilerRef::new( self_profiler, sopts.unstable_opts.time_passes.then(|| sopts.unstable_opts.time_passes_format), @@ -1130,8 +1075,6 @@ pub fn build_session( incr_comp_session: RwLock::new(IncrCompSession::NotInitialized), prof, code_stats: Default::default(), - optimization_fuel, - print_fuel, jobserver: jobserver::client(), lint_store: None, registered_lints: false, diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index a326e8583ea2c..d4b034ea21908 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -313,6 +313,7 @@ macro_rules! optional { macro_rules! run_driver { ($args:expr, $callback:expr $(, $with_tcx:ident)?) => {{ use rustc_driver::{Callbacks, Compilation, RunCompiler}; + use rustc_middle::ty::TyCtxt; use rustc_interface::{interface, Queries}; use stable_mir::CompilerError; use std::ops::ControlFlow; @@ -373,23 +374,21 @@ macro_rules! run_driver { fn after_analysis<'tcx>( &mut self, _compiler: &interface::Compiler, - queries: &'tcx Queries<'tcx>, + tcx: TyCtxt<'tcx>, ) -> Compilation { - queries.global_ctxt().unwrap().enter(|tcx| { - if let Some(callback) = self.callback.take() { - rustc_internal::run(tcx, || { - self.result = Some(callback($(optional!($with_tcx tcx))?)); - }) - .unwrap(); - if self.result.as_ref().is_some_and(|val| val.is_continue()) { - Compilation::Continue - } else { - Compilation::Stop - } - } else { + if let Some(callback) = self.callback.take() { + rustc_internal::run(tcx, || { + self.result = Some(callback($(optional!($with_tcx tcx))?)); + }) + .unwrap(); + if self.result.as_ref().is_some_and(|val| val.is_continue()) { Compilation::Continue + } else { + Compilation::Stop } - }) + } else { + Compilation::Continue + } } } diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs index fe09daf522c1c..36f9b4cff60b0 100644 --- a/compiler/rustc_span/src/edition.rs +++ b/compiler/rustc_span/src/edition.rs @@ -33,7 +33,7 @@ pub const EDITION_NAME_LIST: &str = "2015|2018|2021|2024"; pub const DEFAULT_EDITION: Edition = Edition::Edition2015; -pub const LATEST_STABLE_EDITION: Edition = Edition::Edition2021; +pub const LATEST_STABLE_EDITION: Edition = Edition::Edition2024; impl fmt::Display for Edition { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -62,7 +62,7 @@ impl Edition { Edition::Edition2015 => true, Edition::Edition2018 => true, Edition::Edition2021 => true, - Edition::Edition2024 => false, + Edition::Edition2024 => true, } } diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index a9ca5dbe50941..a5826137181db 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -26,6 +26,7 @@ use std::cell::RefCell; use std::collections::hash_map::Entry; +use std::collections::hash_set::Entry as SetEntry; use std::fmt; use std::hash::Hash; @@ -1270,7 +1271,7 @@ pub struct HygieneDecodeContext { inner: Lock, /// A set of serialized `SyntaxContext` ids that are currently being decoded on each thread. - local_in_progress: WorkerLocal>>, + local_in_progress: WorkerLocal>>, } /// Register an expansion which has been decoded from the on-disk-cache for the local crate. @@ -1364,14 +1365,14 @@ pub fn decode_syntax_context SyntaxContext match inner.decoding.entry(raw_id) { Entry::Occupied(ctxt_entry) => { match context.local_in_progress.borrow_mut().entry(raw_id) { - Entry::Occupied(..) => { + SetEntry::Occupied(..) => { // We're decoding this already on the current thread. Return here // and let the function higher up the stack finish decoding to handle // recursive cases. return *ctxt_entry.get(); } - Entry::Vacant(entry) => { - entry.insert(()); + SetEntry::Vacant(entry) => { + entry.insert(); // Some other thread is current decoding this. Race with it. *ctxt_entry.get() @@ -1380,7 +1381,7 @@ pub fn decode_syntax_context SyntaxContext } Entry::Vacant(entry) => { // We are the first thread to start decoding. Mark the current thread as being progress. - context.local_in_progress.borrow_mut().insert(raw_id, ()); + context.local_in_progress.borrow_mut().insert(raw_id); // Allocate and store SyntaxContext id *before* calling the decoder function, // as the SyntaxContextData may reference itself. diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 8966cfc9171f6..57c645bfaba56 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -22,6 +22,7 @@ #![feature(array_windows)] #![feature(cfg_match)] #![feature(core_io_borrowed_buf)] +#![feature(hash_set_entry)] #![feature(if_let_guard)] #![feature(let_chains)] #![feature(min_specialization)] @@ -1829,6 +1830,8 @@ impl StableSourceFileId { } impl SourceFile { + const MAX_FILE_SIZE: u32 = u32::MAX - 1; + pub fn new( name: FileName, mut src: String, @@ -1849,6 +1852,9 @@ impl SourceFile { let stable_id = StableSourceFileId::from_filename_in_current_crate(&name); let source_len = src.len(); let source_len = u32::try_from(source_len).map_err(|_| OffsetOverflowError)?; + if source_len > Self::MAX_FILE_SIZE { + return Err(OffsetOverflowError); + } let (lines, multibyte_chars) = analyze_source_file::analyze_source_file(&src); diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index e74a5c2d8fe75..55e106b661b28 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -115,6 +115,12 @@ impl FileLoader for RealFileLoader { } fn read_file(&self, path: &Path) -> io::Result { + if path.metadata().is_ok_and(|metadata| metadata.len() > SourceFile::MAX_FILE_SIZE.into()) { + return Err(io::Error::other(format!( + "text files larger than {} bytes are unsupported", + SourceFile::MAX_FILE_SIZE + ))); + } fs::read_to_string(path) } @@ -297,7 +303,10 @@ impl SourceMap { /// unmodified. pub fn new_source_file(&self, filename: FileName, src: String) -> Lrc { self.try_new_source_file(filename, src).unwrap_or_else(|OffsetOverflowError| { - eprintln!("fatal error: rustc does not support files larger than 4GB"); + eprintln!( + "fatal error: rustc does not support text files larger than {} bytes", + SourceFile::MAX_FILE_SIZE + ); crate::fatal_error::FatalError.raise() }) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a2d9859645ff6..3a07c283e0ebb 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -416,7 +416,9 @@ symbols! { asm, asm_const, asm_experimental_arch, + asm_experimental_reg, asm_goto, + asm_goto_with_outputs, asm_sym, asm_unwind, assert, @@ -610,6 +612,7 @@ symbols! { const_compare_raw_pointers, const_constructor, const_deallocate, + const_destruct, const_eval_limit, const_eval_select, const_evaluatable_checked, @@ -1608,6 +1611,7 @@ symbols! { repr_simd, repr_transparent, require, + reserve_x18: "reserve-x18", residual, result, result_ffi_guarantees, @@ -1725,7 +1729,6 @@ symbols! { rustc_partition_reused, rustc_pass_by_value, rustc_peek, - rustc_peek_definite_init, rustc_peek_liveness, rustc_peek_maybe_init, rustc_peek_maybe_uninit, @@ -2086,6 +2089,7 @@ symbols! { unsafe_cell, unsafe_cell_raw_get, unsafe_extern_blocks, + unsafe_fields, unsafe_no_drop_flag, unsafe_pin_internals, unsize, @@ -2137,6 +2141,7 @@ symbols! { vec_pop, vec_with_capacity, vecdeque_iter, + vector, version, vfp2, vis, diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index b82d327a40911..cdccb3e5d728e 100644 --- a/compiler/rustc_target/src/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs @@ -1,7 +1,7 @@ use std::fmt; use rustc_data_structures::fx::FxIndexSet; -use rustc_span::Symbol; +use rustc_span::{Symbol, sym}; use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; use crate::spec::{RelocModel, Target}; @@ -71,18 +71,26 @@ impl AArch64InlineAsmRegClass { } } -pub(crate) fn target_reserves_x18(target: &Target) -> bool { - target.os == "android" || target.os == "fuchsia" || target.is_like_osx || target.is_like_windows +pub(crate) fn target_reserves_x18(target: &Target, target_features: &FxIndexSet) -> bool { + // See isX18ReservedByDefault in LLVM for targets reserve x18 by default: + // https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/TargetParser/AArch64TargetParser.cpp#L102-L105 + // Note that +reserve-x18 is currently not set for the above targets. + target.os == "android" + || target.os == "fuchsia" + || target.env == "ohos" + || target.is_like_osx + || target.is_like_windows + || target_features.contains(&sym::reserve_x18) } fn reserved_x18( _arch: InlineAsmArch, _reloc_model: RelocModel, - _target_features: &FxIndexSet, + target_features: &FxIndexSet, target: &Target, _is_clobber: bool, ) -> Result<(), &'static str> { - if target_reserves_x18(target) { + if target_reserves_x18(target, target_features) { Err("x18 is a reserved register on this target") } else { Ok(()) diff --git a/compiler/rustc_target/src/asm/avr.rs b/compiler/rustc_target/src/asm/avr.rs index 276f376b297e6..55d393c81d3ec 100644 --- a/compiler/rustc_target/src/asm/avr.rs +++ b/compiler/rustc_target/src/asm/avr.rs @@ -105,7 +105,12 @@ def_regs! { #error = ["SP", "SPL", "SPH"] => "the stack pointer cannot be used as an operand for inline asm", #error = ["r0", "r1", "r1r0"] => - "r0 and r1 are not available due to an issue in LLVM", + "LLVM reserves r0 (scratch register) and r1 (zero register)", + // If this changes within LLVM, the compiler might use the registers + // in the future. This must be reflected in the set of clobbered + // registers, else the clobber ABI implementation is *unsound*, as + // this generates invalid code (register is not marked as clobbered + // but may change the register content). } } diff --git a/compiler/rustc_target/src/asm/hexagon.rs b/compiler/rustc_target/src/asm/hexagon.rs index f7e726c33768d..aa14ca3f337b6 100644 --- a/compiler/rustc_target/src/asm/hexagon.rs +++ b/compiler/rustc_target/src/asm/hexagon.rs @@ -7,6 +7,7 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; def_reg_class! { Hexagon HexagonInlineAsmRegClass { reg, + preg, } } @@ -37,6 +38,7 @@ impl HexagonInlineAsmRegClass { ) -> &'static [(InlineAsmType, Option)] { match self { Self::reg => types! { _: I8, I16, I32, F32; }, + Self::preg => &[], } } } @@ -71,6 +73,10 @@ def_regs! { r26: reg = ["r26"], r27: reg = ["r27"], r28: reg = ["r28"], + p0: preg = ["p0"], + p1: preg = ["p1"], + p2: preg = ["p2"], + p3: preg = ["p3"], #error = ["r19"] => "r19 is used internally by LLVM and cannot be used as an operand for inline asm", #error = ["r29", "sp"] => diff --git a/compiler/rustc_target/src/asm/loongarch.rs b/compiler/rustc_target/src/asm/loongarch.rs index b1c01d27cadd6..b4ea6fc592a8c 100644 --- a/compiler/rustc_target/src/asm/loongarch.rs +++ b/compiler/rustc_target/src/asm/loongarch.rs @@ -38,7 +38,7 @@ impl LoongArchInlineAsmRegClass { ) -> &'static [(InlineAsmType, Option)] { match self { Self::reg => types! { _: I8, I16, I32, I64, F32, F64; }, - Self::freg => types! { _: F32, F64; }, + Self::freg => types! { f: F32; d: F64; }, } } } diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 10778e9acf1fd..204d5d5336102 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -604,9 +604,13 @@ impl InlineAsmRegClass { /// Returns a list of supported types for this register class, each with an /// options target feature required to use this type. + /// + /// At the codegen stage, it is fine to always pass true for `allow_experimental_reg`, + /// since all the stability checking will have been done in prior stages. pub fn supported_types( self, arch: InlineAsmArch, + allow_experimental_reg: bool, ) -> &'static [(InlineAsmType, Option)] { match self { Self::X86(r) => r.supported_types(arch), @@ -618,7 +622,7 @@ impl InlineAsmRegClass { Self::Hexagon(r) => r.supported_types(arch), Self::LoongArch(r) => r.supported_types(arch), Self::Mips(r) => r.supported_types(arch), - Self::S390x(r) => r.supported_types(arch), + Self::S390x(r) => r.supported_types(arch, allow_experimental_reg), Self::Sparc(r) => r.supported_types(arch), Self::SpirV(r) => r.supported_types(arch), Self::Wasm(r) => r.supported_types(arch), @@ -696,8 +700,11 @@ impl InlineAsmRegClass { /// Returns whether registers in this class can only be used as clobbers /// and not as inputs/outputs. - pub fn is_clobber_only(self, arch: InlineAsmArch) -> bool { - self.supported_types(arch).is_empty() + /// + /// At the codegen stage, it is fine to always pass true for `allow_experimental_reg`, + /// since all the stability checking will have been done in prior stages. + pub fn is_clobber_only(self, arch: InlineAsmArch, allow_experimental_reg: bool) -> bool { + self.supported_types(arch, allow_experimental_reg).is_empty() } } @@ -921,7 +928,9 @@ pub enum InlineAsmClobberAbi { AArch64, AArch64NoX18, Arm64EC, + Avr, RiscV, + RiscVE, LoongArch, PowerPC, S390x, @@ -934,6 +943,7 @@ impl InlineAsmClobberAbi { pub fn parse( arch: InlineAsmArch, target: &Target, + target_features: &FxIndexSet, name: Symbol, ) -> Result { let name = name.as_str(); @@ -956,11 +966,13 @@ impl InlineAsmClobberAbi { _ => Err(&["C", "system", "efiapi", "aapcs"]), }, InlineAsmArch::AArch64 => match name { - "C" | "system" | "efiapi" => Ok(if aarch64::target_reserves_x18(target) { - InlineAsmClobberAbi::AArch64NoX18 - } else { - InlineAsmClobberAbi::AArch64 - }), + "C" | "system" | "efiapi" => { + Ok(if aarch64::target_reserves_x18(target, target_features) { + InlineAsmClobberAbi::AArch64NoX18 + } else { + InlineAsmClobberAbi::AArch64 + }) + } _ => Err(&["C", "system", "efiapi"]), }, InlineAsmArch::Arm64EC => match name { @@ -968,9 +980,17 @@ impl InlineAsmClobberAbi { _ => Err(&["C", "system"]), }, InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name { - "C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::RiscV), + "C" | "system" | "efiapi" => Ok(if riscv::is_e(target_features) { + InlineAsmClobberAbi::RiscVE + } else { + InlineAsmClobberAbi::RiscV + }), _ => Err(&["C", "system", "efiapi"]), }, + InlineAsmArch::Avr => match name { + "C" | "system" => Ok(InlineAsmClobberAbi::Avr), + _ => Err(&["C", "system"]), + }, InlineAsmArch::LoongArch64 => match name { "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch), _ => Err(&["C", "system"]), @@ -1118,6 +1138,23 @@ impl InlineAsmClobberAbi { d24, d25, d26, d27, d28, d29, d30, d31, } }, + InlineAsmClobberAbi::Avr => clobbered_regs! { + Avr AvrInlineAsmReg { + // The list of "Call-Used Registers" according to + // https://gcc.gnu.org/wiki/avr-gcc#Call-Used_Registers + + // Clobbered registers available in inline assembly + r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r30, r31, + // As per the AVR-GCC-ABI documentation linked above, the R0 + // register is a clobbered register as well. Since we don't + // allow the usage of R0 in inline assembly, nothing has to + // be done here. + // Likewise, the T-flag in the SREG should be clobbered, but + // this is not necessary to be listed here, since the SREG + // is considered clobbered anyways unless `preserve_flags` + // is used. + } + }, InlineAsmClobberAbi::RiscV => clobbered_regs! { RiscV RiscVInlineAsmReg { // ra @@ -1141,6 +1178,31 @@ impl InlineAsmClobberAbi { v24, v25, v26, v27, v28, v29, v30, v31, } }, + InlineAsmClobberAbi::RiscVE => clobbered_regs! { + RiscV RiscVInlineAsmReg { + // Refs: + // - ILP32E https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/draft-20240829-13bfa9f54634cb60d86b9b333e109f077805b4b3/riscv-cc.adoc#ilp32e-calling-convention + // - LP64E https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/299 + + // ra + x1, + // t0-t2 + x5, x6, x7, + // a0-a5 + x10, x11, x12, x13, x14, x15, + // ft0-ft7 + f0, f1, f2, f3, f4, f5, f6, f7, + // fa0-fa7 + f10, f11, f12, f13, f14, f15, f16, f17, + // ft8-ft11 + f28, f29, f30, f31, + + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, + } + }, InlineAsmClobberAbi::LoongArch => clobbered_regs! { LoongArch LoongArchInlineAsmReg { // ra diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs index cfd573efbc1c9..d6b305253798c 100644 --- a/compiler/rustc_target/src/asm/riscv.rs +++ b/compiler/rustc_target/src/asm/riscv.rs @@ -54,6 +54,10 @@ impl RiscVInlineAsmRegClass { } } +pub(crate) fn is_e(target_features: &FxIndexSet) -> bool { + target_features.contains(&sym::e) +} + fn not_e( _arch: InlineAsmArch, _reloc_model: RelocModel, @@ -61,7 +65,7 @@ fn not_e( _target: &Target, _is_clobber: bool, ) -> Result<(), &'static str> { - if target_features.contains(&sym::e) { + if is_e(target_features) { Err("register can't be used with the `e` target feature") } else { Ok(()) diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs index 9b31190a72ba4..410590b722b14 100644 --- a/compiler/rustc_target/src/asm/s390x.rs +++ b/compiler/rustc_target/src/asm/s390x.rs @@ -38,11 +38,22 @@ impl S390xInlineAsmRegClass { pub fn supported_types( self, _arch: InlineAsmArch, + allow_experimental_reg: bool, ) -> &'static [(InlineAsmType, Option)] { match self { Self::reg | Self::reg_addr => types! { _: I8, I16, I32, I64; }, Self::freg => types! { _: F32, F64; }, - Self::vreg => &[], + Self::vreg => { + if allow_experimental_reg { + // non-clobber-only vector register support is unstable. + types! { + vector: I32, F32, I64, F64, I128, F128, + VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2); + } + } else { + &[] + } + } Self::areg => &[], } } diff --git a/compiler/rustc_target/src/callconv/aarch64.rs b/compiler/rustc_target/src/callconv/aarch64.rs index 55b65fb1caaaf..67345f0d47b71 100644 --- a/compiler/rustc_target/src/callconv/aarch64.rs +++ b/compiler/rustc_target/src/callconv/aarch64.rs @@ -1,5 +1,10 @@ +use std::iter; + +use rustc_abi::{BackendRepr, Primitive}; + use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform}; use crate::abi::{HasDataLayout, TyAbiInterface}; +use crate::spec::{HasTargetSpec, Target}; /// Indicates the variant of the AArch64 ABI we are compiling for. /// Used to accommodate Apple and Microsoft's deviations from the usual AAPCS ABI. @@ -15,7 +20,7 @@ pub(crate) enum AbiKind { fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option where Ty: TyAbiInterface<'a, C> + Copy, - C: HasDataLayout, + C: HasDataLayout + HasTargetSpec, { arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| { let size = arg.layout.size; @@ -27,7 +32,9 @@ where let valid_unit = match unit.kind { RegKind::Integer => false, - RegKind::Float => true, + // The softfloat ABI treats floats like integers, so they + // do not get homogeneous aggregate treatment. + RegKind::Float => cx.target_spec().abi != "softfloat", RegKind::Vector => size.bits() == 64 || size.bits() == 128, }; @@ -35,10 +42,42 @@ where }) } +fn softfloat_float_abi(target: &Target, arg: &mut ArgAbi<'_, Ty>) { + if target.abi != "softfloat" { + return; + } + // Do *not* use the float registers for passing arguments, as that would make LLVM pick the ABI + // and its choice depends on whether `neon` instructions are enabled. Instead, we follow the + // AAPCS "softfloat" ABI, which specifies that floats should be passed as equivalently-sized + // integers. Nominally this only exists for "R" profile chips, but sometimes people don't want + // to use hardfloats even if the hardware supports them, so we do this for all softfloat + // targets. + if let BackendRepr::Scalar(s) = arg.layout.backend_repr + && let Primitive::Float(f) = s.primitive() + { + arg.cast_to(Reg { kind: RegKind::Integer, size: f.size() }); + } else if let BackendRepr::ScalarPair(s1, s2) = arg.layout.backend_repr + && (matches!(s1.primitive(), Primitive::Float(_)) + || matches!(s2.primitive(), Primitive::Float(_))) + { + // This case can only be reached for the Rust ABI, so we can do whatever we want here as + // long as it does not depend on target features (i.e., as long as we do not use float + // registers). So we pass small things in integer registers and large things via pointer + // indirection. This means we lose the nice "pass it as two arguments" optimization, but we + // currently just have to way to combine a `PassMode::Cast` with that optimization (and we + // need a cast since we want to pass the float as an int). + if arg.layout.size.bits() <= target.pointer_width.into() { + arg.cast_to(Reg { kind: RegKind::Integer, size: arg.layout.size }); + } else { + arg.make_indirect(); + } + } +} + fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, kind: AbiKind) where Ty: TyAbiInterface<'a, C> + Copy, - C: HasDataLayout, + C: HasDataLayout + HasTargetSpec, { if !ret.layout.is_sized() { // Not touching this... @@ -51,6 +90,7 @@ where // See also: ret.extend_integer_width_to(32) } + softfloat_float_abi(cx.target_spec(), ret); return; } if let Some(uniform) = is_homogeneous_aggregate(cx, ret) { @@ -69,7 +109,7 @@ where fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, kind: AbiKind) where Ty: TyAbiInterface<'a, C> + Copy, - C: HasDataLayout, + C: HasDataLayout + HasTargetSpec, { if !arg.layout.is_sized() { // Not touching this... @@ -82,6 +122,8 @@ where // See also: arg.extend_integer_width_to(32); } + softfloat_float_abi(cx.target_spec(), arg); + return; } if let Some(uniform) = is_homogeneous_aggregate(cx, arg) { @@ -112,7 +154,7 @@ where pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, kind: AbiKind) where Ty: TyAbiInterface<'a, C> + Copy, - C: HasDataLayout, + C: HasDataLayout + HasTargetSpec, { if !fn_abi.ret.is_ignore() { classify_ret(cx, &mut fn_abi.ret, kind); @@ -125,3 +167,13 @@ where classify_arg(cx, arg, kind); } } + +pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout + HasTargetSpec, +{ + for arg in fn_abi.args.iter_mut().chain(iter::once(&mut fn_abi.ret)) { + softfloat_float_abi(cx.target_spec(), arg); + } +} diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index aa639f1624f42..fb0fe4029348e 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -738,6 +738,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { "x86" => x86::compute_rust_abi_info(cx, self, abi), "riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self, abi), "loongarch64" => loongarch::compute_rust_abi_info(cx, self, abi), + "aarch64" => aarch64::compute_rust_abi_info(cx, self), _ => {} }; diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs new file mode 100644 index 0000000000000..206766325aa16 --- /dev/null +++ b/compiler/rustc_target/src/spec/json.rs @@ -0,0 +1,798 @@ +use std::borrow::Cow; +use std::collections::BTreeMap; +use std::str::FromStr; + +use serde_json::Value; + +use super::{Target, TargetKind, TargetOptions, TargetWarnings}; +use crate::json::{Json, ToJson}; + +impl Target { + /// Loads a target descriptor from a JSON object. + pub fn from_json(obj: Json) -> Result<(Target, TargetWarnings), String> { + // While ugly, this code must remain this way to retain + // compatibility with existing JSON fields and the internal + // expected naming of the Target and TargetOptions structs. + // To ensure compatibility is retained, the built-in targets + // are round-tripped through this code to catch cases where + // the JSON parser is not updated to match the structs. + + let mut obj = match obj { + Value::Object(obj) => obj, + _ => return Err("Expected JSON object for target")?, + }; + + let mut get_req_field = |name: &str| { + obj.remove(name) + .and_then(|j| j.as_str().map(str::to_string)) + .ok_or_else(|| format!("Field {name} in target specification is required")) + }; + + let mut base = Target { + llvm_target: get_req_field("llvm-target")?.into(), + metadata: Default::default(), + pointer_width: get_req_field("target-pointer-width")? + .parse::() + .map_err(|_| "target-pointer-width must be an integer".to_string())?, + data_layout: get_req_field("data-layout")?.into(), + arch: get_req_field("arch")?.into(), + options: Default::default(), + }; + + // FIXME: This doesn't properly validate anything and just ignores the data if it's invalid. + // That's okay for now, the only use of this is when generating docs, which we don't do for + // custom targets. + if let Some(Json::Object(mut metadata)) = obj.remove("metadata") { + base.metadata.description = metadata + .remove("description") + .and_then(|desc| desc.as_str().map(|desc| desc.to_owned().into())); + base.metadata.tier = metadata + .remove("tier") + .and_then(|tier| tier.as_u64()) + .filter(|tier| (1..=3).contains(tier)); + base.metadata.host_tools = + metadata.remove("host_tools").and_then(|host| host.as_bool()); + base.metadata.std = metadata.remove("std").and_then(|host| host.as_bool()); + } + + let mut incorrect_type = vec![]; + + macro_rules! key { + ($key_name:ident) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(s) = obj.remove(&name).and_then(|s| s.as_str().map(str::to_string).map(Cow::from)) { + base.$key_name = s; + } + } ); + ($key_name:ident = $json_name:expr) => ( { + let name = $json_name; + if let Some(s) = obj.remove(name).and_then(|s| s.as_str().map(str::to_string).map(Cow::from)) { + base.$key_name = s; + } + } ); + ($key_name:ident, bool) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(s) = obj.remove(&name).and_then(|b| b.as_bool()) { + base.$key_name = s; + } + } ); + ($key_name:ident = $json_name:expr, bool) => ( { + let name = $json_name; + if let Some(s) = obj.remove(name).and_then(|b| b.as_bool()) { + base.$key_name = s; + } + } ); + ($key_name:ident, u32) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) { + if s < 1 || s > 5 { + return Err("Not a valid DWARF version number".into()); + } + base.$key_name = s as u32; + } + } ); + ($key_name:ident, Option) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(s) = obj.remove(&name).and_then(|b| b.as_bool()) { + base.$key_name = Some(s); + } + } ); + ($key_name:ident, Option) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) { + base.$key_name = Some(s); + } + } ); + ($key_name:ident, MergeFunctions) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { + match s.parse::() { + Ok(mergefunc) => base.$key_name = mergefunc, + _ => return Some(Err(format!("'{}' is not a valid value for \ + merge-functions. Use 'disabled', \ + 'trampolines', or 'aliases'.", + s))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident, RelocModel) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { + match s.parse::() { + Ok(relocation_model) => base.$key_name = relocation_model, + _ => return Some(Err(format!("'{}' is not a valid relocation model. \ + Run `rustc --print relocation-models` to \ + see the list of supported values.", s))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident, CodeModel) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { + match s.parse::() { + Ok(code_model) => base.$key_name = Some(code_model), + _ => return Some(Err(format!("'{}' is not a valid code model. \ + Run `rustc --print code-models` to \ + see the list of supported values.", s))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident, TlsModel) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { + match s.parse::() { + Ok(tls_model) => base.$key_name = tls_model, + _ => return Some(Err(format!("'{}' is not a valid TLS model. \ + Run `rustc --print tls-models` to \ + see the list of supported values.", s))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident, SmallDataThresholdSupport) => ( { + obj.remove("small-data-threshold-support").and_then(|o| o.as_str().and_then(|s| { + match s.parse::() { + Ok(support) => base.small_data_threshold_support = support, + _ => return Some(Err(format!("'{s}' is not a valid value for small-data-threshold-support."))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident, PanicStrategy) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { + match s { + "unwind" => base.$key_name = super::PanicStrategy::Unwind, + "abort" => base.$key_name = super::PanicStrategy::Abort, + _ => return Some(Err(format!("'{}' is not a valid value for \ + panic-strategy. Use 'unwind' or 'abort'.", + s))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident, RelroLevel) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { + match s.parse::() { + Ok(level) => base.$key_name = level, + _ => return Some(Err(format!("'{}' is not a valid value for \ + relro-level. Use 'full', 'partial, or 'off'.", + s))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident, Option) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { + match s.parse::() { + Ok(level) => base.$key_name = Some(level), + _ => return Some(Err(format!("'{}' is not a valid value for \ + symbol-visibility. Use 'hidden', 'protected, or 'interposable'.", + s))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident, DebuginfoKind) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { + match s.parse::() { + Ok(level) => base.$key_name = level, + _ => return Some(Err( + format!("'{s}' is not a valid value for debuginfo-kind. Use 'dwarf', \ + 'dwarf-dsym' or 'pdb'.") + )), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident, SplitDebuginfo) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { + match s.parse::() { + Ok(level) => base.$key_name = level, + _ => return Some(Err(format!("'{}' is not a valid value for \ + split-debuginfo. Use 'off' or 'dsymutil'.", + s))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident, list) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(j) = obj.remove(&name) { + if let Some(v) = j.as_array() { + base.$key_name = v.iter() + .map(|a| a.as_str().unwrap().to_string().into()) + .collect(); + } else { + incorrect_type.push(name) + } + } + } ); + ($key_name:ident, opt_list) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(j) = obj.remove(&name) { + if let Some(v) = j.as_array() { + base.$key_name = Some(v.iter() + .map(|a| a.as_str().unwrap().to_string().into()) + .collect()); + } else { + incorrect_type.push(name) + } + } + } ); + ($key_name:ident, fallible_list) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|j| { + if let Some(v) = j.as_array() { + match v.iter().map(|a| FromStr::from_str(a.as_str().unwrap())).collect() { + Ok(l) => { base.$key_name = l }, + // FIXME: `fallible_list` can't re-use the `key!` macro for list + // elements and the error messages from that macro, so it has a bad + // generic message instead + Err(_) => return Some(Err( + format!("`{:?}` is not a valid value for `{}`", j, name) + )), + } + } else { + incorrect_type.push(name) + } + Some(Ok(())) + }).unwrap_or(Ok(())) + } ); + ($key_name:ident, optional) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(o) = obj.remove(&name) { + base.$key_name = o + .as_str() + .map(|s| s.to_string().into()); + } + } ); + ($key_name:ident = $json_name:expr, LldFlavor) => ( { + let name = $json_name; + obj.remove(name).and_then(|o| o.as_str().and_then(|s| { + if let Some(flavor) = super::LldFlavor::from_str(&s) { + base.$key_name = flavor; + } else { + return Some(Err(format!( + "'{}' is not a valid value for lld-flavor. \ + Use 'darwin', 'gnu', 'link' or 'wasm'.", + s))) + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident = $json_name:expr, LinkerFlavorCli) => ( { + let name = $json_name; + obj.remove(name).and_then(|o| o.as_str().and_then(|s| { + match super::LinkerFlavorCli::from_str(s) { + Some(linker_flavor) => base.$key_name = linker_flavor, + _ => return Some(Err(format!("'{}' is not a valid value for linker-flavor. \ + Use {}", s, super::LinkerFlavorCli::one_of()))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident, StackProbeType) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|o| match super::StackProbeType::from_json(&o) { + Ok(v) => { + base.$key_name = v; + Some(Ok(())) + }, + Err(s) => Some(Err( + format!("`{:?}` is not a valid value for `{}`: {}", o, name, s) + )), + }).unwrap_or(Ok(())) + } ); + ($key_name:ident, SanitizerSet) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(o) = obj.remove(&name) { + if let Some(a) = o.as_array() { + for s in a { + use super::SanitizerSet; + base.$key_name |= match s.as_str() { + Some("address") => SanitizerSet::ADDRESS, + Some("cfi") => SanitizerSet::CFI, + Some("dataflow") => SanitizerSet::DATAFLOW, + Some("kcfi") => SanitizerSet::KCFI, + Some("kernel-address") => SanitizerSet::KERNELADDRESS, + Some("leak") => SanitizerSet::LEAK, + Some("memory") => SanitizerSet::MEMORY, + Some("memtag") => SanitizerSet::MEMTAG, + Some("safestack") => SanitizerSet::SAFESTACK, + Some("shadow-call-stack") => SanitizerSet::SHADOWCALLSTACK, + Some("thread") => SanitizerSet::THREAD, + Some("hwaddress") => SanitizerSet::HWADDRESS, + Some(s) => return Err(format!("unknown sanitizer {}", s)), + _ => return Err(format!("not a string: {:?}", s)), + }; + } + } else { + incorrect_type.push(name) + } + } + Ok::<(), String>(()) + } ); + ($key_name:ident, link_self_contained_components) => ( { + // Skeleton of what needs to be parsed: + // + // ``` + // $name: { + // "components": [ + // + // ] + // } + // ``` + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(o) = obj.remove(&name) { + if let Some(o) = o.as_object() { + let component_array = o.get("components") + .ok_or_else(|| format!("{name}: expected a \ + JSON object with a `components` field."))?; + let component_array = component_array.as_array() + .ok_or_else(|| format!("{name}.components: expected a JSON array"))?; + let mut components = super::LinkSelfContainedComponents::empty(); + for s in component_array { + components |= match s.as_str() { + Some(s) => { + super::LinkSelfContainedComponents::from_str(s) + .ok_or_else(|| format!("unknown \ + `-Clink-self-contained` component: {s}"))? + }, + _ => return Err(format!("not a string: {:?}", s)), + }; + } + base.$key_name = super::LinkSelfContainedDefault::WithComponents(components); + } else { + incorrect_type.push(name) + } + } + Ok::<(), String>(()) + } ); + ($key_name:ident = $json_name:expr, link_self_contained_backwards_compatible) => ( { + let name = $json_name; + obj.remove(name).and_then(|o| o.as_str().and_then(|s| { + match s.parse::() { + Ok(lsc_default) => base.$key_name = lsc_default, + _ => return Some(Err(format!("'{}' is not a valid `-Clink-self-contained` default. \ + Use 'false', 'true', 'musl' or 'mingw'", s))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident = $json_name:expr, link_objects) => ( { + let name = $json_name; + if let Some(val) = obj.remove(name) { + let obj = val.as_object().ok_or_else(|| format!("{}: expected a \ + JSON object with fields per CRT object kind.", name))?; + let mut args = super::CrtObjects::new(); + for (k, v) in obj { + let kind = super::LinkOutputKind::from_str(&k).ok_or_else(|| { + format!("{}: '{}' is not a valid value for CRT object kind. \ + Use '(dynamic,static)-(nopic,pic)-exe' or \ + '(dynamic,static)-dylib' or 'wasi-reactor-exe'", name, k) + })?; + + let v = v.as_array().ok_or_else(|| + format!("{}.{}: expected a JSON array", name, k) + )?.iter().enumerate() + .map(|(i,s)| { + let s = s.as_str().ok_or_else(|| + format!("{}.{}[{}]: expected a JSON string", name, k, i))?; + Ok(s.to_string().into()) + }) + .collect::, String>>()?; + + args.insert(kind, v); + } + base.$key_name = args; + } + } ); + ($key_name:ident = $json_name:expr, link_args) => ( { + let name = $json_name; + if let Some(val) = obj.remove(name) { + let obj = val.as_object().ok_or_else(|| format!("{}: expected a \ + JSON object with fields per linker-flavor.", name))?; + let mut args = super::LinkArgsCli::new(); + for (k, v) in obj { + let flavor = super::LinkerFlavorCli::from_str(&k).ok_or_else(|| { + format!("{}: '{}' is not a valid value for linker-flavor. \ + Use 'em', 'gcc', 'ld' or 'msvc'", name, k) + })?; + + let v = v.as_array().ok_or_else(|| + format!("{}.{}: expected a JSON array", name, k) + )?.iter().enumerate() + .map(|(i,s)| { + let s = s.as_str().ok_or_else(|| + format!("{}.{}[{}]: expected a JSON string", name, k, i))?; + Ok(s.to_string().into()) + }) + .collect::, String>>()?; + + args.insert(flavor, v); + } + base.$key_name = args; + } + } ); + ($key_name:ident, env) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(o) = obj.remove(&name) { + if let Some(a) = o.as_array() { + for o in a { + if let Some(s) = o.as_str() { + if let [k, v] = *s.split('=').collect::>() { + base.$key_name + .to_mut() + .push((k.to_string().into(), v.to_string().into())) + } + } + } + } else { + incorrect_type.push(name) + } + } + } ); + ($key_name:ident, target_families) => ( { + if let Some(value) = obj.remove("target-family") { + if let Some(v) = value.as_array() { + base.$key_name = v.iter() + .map(|a| a.as_str().unwrap().to_string().into()) + .collect(); + } else if let Some(v) = value.as_str() { + base.$key_name = vec![v.to_string().into()].into(); + } + } + } ); + ($key_name:ident, Conv) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { + match super::Conv::from_str(s) { + Ok(c) => { + base.$key_name = c; + Some(Ok(())) + } + Err(e) => Some(Err(e)) + } + })).unwrap_or(Ok(())) + } ); + } + + if let Some(j) = obj.remove("target-endian") { + if let Some(s) = j.as_str() { + base.endian = s.parse()?; + } else { + incorrect_type.push("target-endian".into()) + } + } + + if let Some(fp) = obj.remove("frame-pointer") { + if let Some(s) = fp.as_str() { + base.frame_pointer = s + .parse() + .map_err(|()| format!("'{s}' is not a valid value for frame-pointer"))?; + } else { + incorrect_type.push("frame-pointer".into()) + } + } + + key!(c_int_width = "target-c-int-width"); + key!(c_enum_min_bits, Option); // if None, matches c_int_width + key!(os); + key!(env); + key!(abi); + key!(vendor); + key!(linker, optional); + key!(linker_flavor_json = "linker-flavor", LinkerFlavorCli)?; + key!(lld_flavor_json = "lld-flavor", LldFlavor)?; + key!(linker_is_gnu_json = "linker-is-gnu", bool); + key!(pre_link_objects = "pre-link-objects", link_objects); + key!(post_link_objects = "post-link-objects", link_objects); + key!(pre_link_objects_self_contained = "pre-link-objects-fallback", link_objects); + key!(post_link_objects_self_contained = "post-link-objects-fallback", link_objects); + // Deserializes the backwards-compatible variants of `-Clink-self-contained` + key!( + link_self_contained = "crt-objects-fallback", + link_self_contained_backwards_compatible + )?; + // Deserializes the components variant of `-Clink-self-contained` + key!(link_self_contained, link_self_contained_components)?; + key!(pre_link_args_json = "pre-link-args", link_args); + key!(late_link_args_json = "late-link-args", link_args); + key!(late_link_args_dynamic_json = "late-link-args-dynamic", link_args); + key!(late_link_args_static_json = "late-link-args-static", link_args); + key!(post_link_args_json = "post-link-args", link_args); + key!(link_script, optional); + key!(link_env, env); + key!(link_env_remove, list); + key!(asm_args, list); + key!(cpu); + key!(features); + key!(dynamic_linking, bool); + key!(direct_access_external_data, Option); + key!(dll_tls_export, bool); + key!(only_cdylib, bool); + key!(executables, bool); + key!(relocation_model, RelocModel)?; + key!(code_model, CodeModel)?; + key!(tls_model, TlsModel)?; + key!(disable_redzone, bool); + key!(function_sections, bool); + key!(dll_prefix); + key!(dll_suffix); + key!(exe_suffix); + key!(staticlib_prefix); + key!(staticlib_suffix); + key!(families, target_families); + key!(abi_return_struct_as_int, bool); + key!(is_like_aix, bool); + key!(is_like_osx, bool); + key!(is_like_solaris, bool); + key!(is_like_windows, bool); + key!(is_like_msvc, bool); + key!(is_like_wasm, bool); + key!(is_like_android, bool); + key!(default_dwarf_version, u32); + key!(allows_weak_linkage, bool); + key!(has_rpath, bool); + key!(no_default_libraries, bool); + key!(position_independent_executables, bool); + key!(static_position_independent_executables, bool); + key!(plt_by_default, bool); + key!(relro_level, RelroLevel)?; + key!(archive_format); + key!(allow_asm, bool); + key!(main_needs_argc_argv, bool); + key!(has_thread_local, bool); + key!(obj_is_bitcode, bool); + key!(bitcode_llvm_cmdline); + key!(max_atomic_width, Option); + key!(min_atomic_width, Option); + key!(atomic_cas, bool); + key!(panic_strategy, PanicStrategy)?; + key!(crt_static_allows_dylibs, bool); + key!(crt_static_default, bool); + key!(crt_static_respected, bool); + key!(stack_probes, StackProbeType)?; + key!(min_global_align, Option); + key!(default_codegen_units, Option); + key!(trap_unreachable, bool); + key!(requires_lto, bool); + key!(singlethread, bool); + key!(no_builtins, bool); + key!(default_visibility, Option)?; + key!(emit_debug_gdb_scripts, bool); + key!(requires_uwtable, bool); + key!(default_uwtable, bool); + key!(simd_types_indirect, bool); + key!(limit_rdylib_exports, bool); + key!(override_export_symbols, opt_list); + key!(merge_functions, MergeFunctions)?; + key!(mcount = "target-mcount"); + key!(llvm_mcount_intrinsic, optional); + key!(llvm_abiname); + key!(relax_elf_relocations, bool); + key!(llvm_args, list); + key!(use_ctors_section, bool); + key!(eh_frame_header, bool); + key!(has_thumb_interworking, bool); + key!(debuginfo_kind, DebuginfoKind)?; + key!(split_debuginfo, SplitDebuginfo)?; + key!(supported_split_debuginfo, fallible_list)?; + key!(supported_sanitizers, SanitizerSet)?; + key!(generate_arange_section, bool); + key!(supports_stack_protector, bool); + key!(small_data_threshold_support, SmallDataThresholdSupport)?; + key!(entry_name); + key!(entry_abi, Conv)?; + key!(supports_xray, bool); + + base.update_from_cli(); + base.check_consistency(TargetKind::Json)?; + + // Each field should have been read using `Json::remove` so any keys remaining are unused. + let remaining_keys = obj.keys(); + Ok((base, TargetWarnings { + unused_fields: remaining_keys.cloned().collect(), + incorrect_type, + })) + } +} + +impl ToJson for Target { + fn to_json(&self) -> Json { + let mut d = serde_json::Map::new(); + let default: TargetOptions = Default::default(); + let mut target = self.clone(); + target.update_to_cli(); + + macro_rules! target_val { + ($attr:ident) => {{ + let name = (stringify!($attr)).replace("_", "-"); + d.insert(name, target.$attr.to_json()); + }}; + } + + macro_rules! target_option_val { + ($attr:ident) => {{ + let name = (stringify!($attr)).replace("_", "-"); + if default.$attr != target.$attr { + d.insert(name, target.$attr.to_json()); + } + }}; + ($attr:ident, $json_name:expr) => {{ + let name = $json_name; + if default.$attr != target.$attr { + d.insert(name.into(), target.$attr.to_json()); + } + }}; + (link_args - $attr:ident, $json_name:expr) => {{ + let name = $json_name; + if default.$attr != target.$attr { + let obj = target + .$attr + .iter() + .map(|(k, v)| (k.desc().to_string(), v.clone())) + .collect::>(); + d.insert(name.to_string(), obj.to_json()); + } + }}; + (env - $attr:ident) => {{ + let name = (stringify!($attr)).replace("_", "-"); + if default.$attr != target.$attr { + let obj = target + .$attr + .iter() + .map(|&(ref k, ref v)| format!("{k}={v}")) + .collect::>(); + d.insert(name, obj.to_json()); + } + }}; + } + + target_val!(llvm_target); + target_val!(metadata); + d.insert("target-pointer-width".to_string(), self.pointer_width.to_string().to_json()); + target_val!(arch); + target_val!(data_layout); + + target_option_val!(endian, "target-endian"); + target_option_val!(c_int_width, "target-c-int-width"); + target_option_val!(os); + target_option_val!(env); + target_option_val!(abi); + target_option_val!(vendor); + target_option_val!(linker); + target_option_val!(linker_flavor_json, "linker-flavor"); + target_option_val!(lld_flavor_json, "lld-flavor"); + target_option_val!(linker_is_gnu_json, "linker-is-gnu"); + target_option_val!(pre_link_objects); + target_option_val!(post_link_objects); + target_option_val!(pre_link_objects_self_contained, "pre-link-objects-fallback"); + target_option_val!(post_link_objects_self_contained, "post-link-objects-fallback"); + target_option_val!(link_args - pre_link_args_json, "pre-link-args"); + target_option_val!(link_args - late_link_args_json, "late-link-args"); + target_option_val!(link_args - late_link_args_dynamic_json, "late-link-args-dynamic"); + target_option_val!(link_args - late_link_args_static_json, "late-link-args-static"); + target_option_val!(link_args - post_link_args_json, "post-link-args"); + target_option_val!(link_script); + target_option_val!(env - link_env); + target_option_val!(link_env_remove); + target_option_val!(asm_args); + target_option_val!(cpu); + target_option_val!(features); + target_option_val!(dynamic_linking); + target_option_val!(direct_access_external_data); + target_option_val!(dll_tls_export); + target_option_val!(only_cdylib); + target_option_val!(executables); + target_option_val!(relocation_model); + target_option_val!(code_model); + target_option_val!(tls_model); + target_option_val!(disable_redzone); + target_option_val!(frame_pointer); + target_option_val!(function_sections); + target_option_val!(dll_prefix); + target_option_val!(dll_suffix); + target_option_val!(exe_suffix); + target_option_val!(staticlib_prefix); + target_option_val!(staticlib_suffix); + target_option_val!(families, "target-family"); + target_option_val!(abi_return_struct_as_int); + target_option_val!(is_like_aix); + target_option_val!(is_like_osx); + target_option_val!(is_like_solaris); + target_option_val!(is_like_windows); + target_option_val!(is_like_msvc); + target_option_val!(is_like_wasm); + target_option_val!(is_like_android); + target_option_val!(default_dwarf_version); + target_option_val!(allows_weak_linkage); + target_option_val!(has_rpath); + target_option_val!(no_default_libraries); + target_option_val!(position_independent_executables); + target_option_val!(static_position_independent_executables); + target_option_val!(plt_by_default); + target_option_val!(relro_level); + target_option_val!(archive_format); + target_option_val!(allow_asm); + target_option_val!(main_needs_argc_argv); + target_option_val!(has_thread_local); + target_option_val!(obj_is_bitcode); + target_option_val!(bitcode_llvm_cmdline); + target_option_val!(min_atomic_width); + target_option_val!(max_atomic_width); + target_option_val!(atomic_cas); + target_option_val!(panic_strategy); + target_option_val!(crt_static_allows_dylibs); + target_option_val!(crt_static_default); + target_option_val!(crt_static_respected); + target_option_val!(stack_probes); + target_option_val!(min_global_align); + target_option_val!(default_codegen_units); + target_option_val!(trap_unreachable); + target_option_val!(requires_lto); + target_option_val!(singlethread); + target_option_val!(no_builtins); + target_option_val!(default_visibility); + target_option_val!(emit_debug_gdb_scripts); + target_option_val!(requires_uwtable); + target_option_val!(default_uwtable); + target_option_val!(simd_types_indirect); + target_option_val!(limit_rdylib_exports); + target_option_val!(override_export_symbols); + target_option_val!(merge_functions); + target_option_val!(mcount, "target-mcount"); + target_option_val!(llvm_mcount_intrinsic); + target_option_val!(llvm_abiname); + target_option_val!(relax_elf_relocations); + target_option_val!(llvm_args); + target_option_val!(use_ctors_section); + target_option_val!(eh_frame_header); + target_option_val!(has_thumb_interworking); + target_option_val!(debuginfo_kind); + target_option_val!(split_debuginfo); + target_option_val!(supported_split_debuginfo); + target_option_val!(supported_sanitizers); + target_option_val!(c_enum_min_bits); + target_option_val!(generate_arange_section); + target_option_val!(supports_stack_protector); + target_option_val!(small_data_threshold_support); + target_option_val!(entry_name); + target_option_val!(entry_abi); + target_option_val!(supports_xray); + + // Serializing `-Clink-self-contained` needs a dynamic key to support the + // backwards-compatible variants. + d.insert(self.link_self_contained.json_key().into(), self.link_self_contained.to_json()); + + Json::Object(d) + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 321ab40403a37..a2e9430830a22 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -42,6 +42,7 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use std::{fmt, io}; +use rustc_data_structures::fx::FxHashSet; use rustc_fs_util::try_canonicalize; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -65,6 +66,8 @@ pub mod abi { } mod base; +mod json; + pub use base::avr_gnu::ef_avr_arch; /// Linker is called through a C/C++ compiler. @@ -1605,13 +1608,11 @@ macro_rules! supported_targets { #[cfg(test)] mod tests { - mod tests_impl; - // Cannot put this into a separate file without duplication, make an exception. $( #[test] // `#[test]` fn $module() { - tests_impl::test_target(crate::spec::targets::$module::target()); + crate::spec::targets::$module::target().test_target() } )+ } @@ -1998,6 +1999,14 @@ impl TargetWarnings { } } +/// For the [`Target::check_consistency`] function, determines whether the given target is a builtin or a JSON +/// target. +#[derive(Copy, Clone, Debug, PartialEq)] +enum TargetKind { + Json, + Builtin, +} + /// Everything `rustc` knows about how to compile for a specific target. /// /// Every field here must be specified, and has no default value. @@ -2327,8 +2336,6 @@ pub struct TargetOptions { /// If we give emcc .o files that are actually .bc files it /// will 'just work'. pub obj_is_bitcode: bool, - /// Whether the target requires that emitted object code includes bitcode. - pub forces_embed_bitcode: bool, /// Content of the LLVM cmdline section associated with embedded bitcode. pub bitcode_llvm_cmdline: StaticCow, @@ -2671,7 +2678,6 @@ impl Default for TargetOptions { allow_asm: true, has_thread_local: false, obj_is_bitcode: false, - forces_embed_bitcode: false, bitcode_llvm_cmdline: "".into(), min_atomic_width: None, max_atomic_width: None, @@ -2849,620 +2855,355 @@ impl Target { self.max_atomic_width.unwrap_or_else(|| self.pointer_width.into()) } - /// Loads a target descriptor from a JSON object. - pub fn from_json(obj: Json) -> Result<(Target, TargetWarnings), String> { - // While ugly, this code must remain this way to retain - // compatibility with existing JSON fields and the internal - // expected naming of the Target and TargetOptions structs. - // To ensure compatibility is retained, the built-in targets - // are round-tripped through this code to catch cases where - // the JSON parser is not updated to match the structs. - - let mut obj = match obj { - Value::Object(obj) => obj, - _ => return Err("Expected JSON object for target")?, - }; - - let mut get_req_field = |name: &str| { - obj.remove(name) - .and_then(|j| j.as_str().map(str::to_string)) - .ok_or_else(|| format!("Field {name} in target specification is required")) - }; - - let mut base = Target { - llvm_target: get_req_field("llvm-target")?.into(), - metadata: Default::default(), - pointer_width: get_req_field("target-pointer-width")? - .parse::() - .map_err(|_| "target-pointer-width must be an integer".to_string())?, - data_layout: get_req_field("data-layout")?.into(), - arch: get_req_field("arch")?.into(), - options: Default::default(), - }; - - // FIXME: This doesn't properly validate anything and just ignores the data if it's invalid. - // That's okay for now, the only use of this is when generating docs, which we don't do for - // custom targets. - if let Some(Json::Object(mut metadata)) = obj.remove("metadata") { - base.metadata.description = metadata - .remove("description") - .and_then(|desc| desc.as_str().map(|desc| desc.to_owned().into())); - base.metadata.tier = metadata - .remove("tier") - .and_then(|tier| tier.as_u64()) - .filter(|tier| (1..=3).contains(tier)); - base.metadata.host_tools = - metadata.remove("host_tools").and_then(|host| host.as_bool()); - base.metadata.std = metadata.remove("std").and_then(|host| host.as_bool()); - } - - let mut incorrect_type = vec![]; - - macro_rules! key { - ($key_name:ident) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - if let Some(s) = obj.remove(&name).and_then(|s| s.as_str().map(str::to_string).map(Cow::from)) { - base.$key_name = s; - } - } ); - ($key_name:ident = $json_name:expr) => ( { - let name = $json_name; - if let Some(s) = obj.remove(name).and_then(|s| s.as_str().map(str::to_string).map(Cow::from)) { - base.$key_name = s; - } - } ); - ($key_name:ident, bool) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - if let Some(s) = obj.remove(&name).and_then(|b| b.as_bool()) { - base.$key_name = s; - } - } ); - ($key_name:ident = $json_name:expr, bool) => ( { - let name = $json_name; - if let Some(s) = obj.remove(name).and_then(|b| b.as_bool()) { - base.$key_name = s; + /// Check some basic consistency of the current target. For JSON targets we are less strict; + /// some of these checks are more guidelines than strict rules. + fn check_consistency(&self, kind: TargetKind) -> Result<(), String> { + macro_rules! check { + ($b:expr, $($msg:tt)*) => { + if !$b { + return Err(format!($($msg)*)); } - } ); - ($key_name:ident, u32) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) { - if s < 1 || s > 5 { - return Err("Not a valid DWARF version number".into()); - } - base.$key_name = s as u32; - } - } ); - ($key_name:ident, Option) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - if let Some(s) = obj.remove(&name).and_then(|b| b.as_bool()) { - base.$key_name = Some(s); - } - } ); - ($key_name:ident, Option) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) { - base.$key_name = Some(s); - } - } ); - ($key_name:ident, MergeFunctions) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { - match s.parse::() { - Ok(mergefunc) => base.$key_name = mergefunc, - _ => return Some(Err(format!("'{}' is not a valid value for \ - merge-functions. Use 'disabled', \ - 'trampolines', or 'aliases'.", - s))), - } - Some(Ok(())) - })).unwrap_or(Ok(())) - } ); - ($key_name:ident, RelocModel) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { - match s.parse::() { - Ok(relocation_model) => base.$key_name = relocation_model, - _ => return Some(Err(format!("'{}' is not a valid relocation model. \ - Run `rustc --print relocation-models` to \ - see the list of supported values.", s))), - } - Some(Ok(())) - })).unwrap_or(Ok(())) - } ); - ($key_name:ident, CodeModel) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { - match s.parse::() { - Ok(code_model) => base.$key_name = Some(code_model), - _ => return Some(Err(format!("'{}' is not a valid code model. \ - Run `rustc --print code-models` to \ - see the list of supported values.", s))), - } - Some(Ok(())) - })).unwrap_or(Ok(())) - } ); - ($key_name:ident, TlsModel) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { - match s.parse::() { - Ok(tls_model) => base.$key_name = tls_model, - _ => return Some(Err(format!("'{}' is not a valid TLS model. \ - Run `rustc --print tls-models` to \ - see the list of supported values.", s))), - } - Some(Ok(())) - })).unwrap_or(Ok(())) - } ); - ($key_name:ident, SmallDataThresholdSupport) => ( { - obj.remove("small-data-threshold-support").and_then(|o| o.as_str().and_then(|s| { - match s.parse::() { - Ok(support) => base.small_data_threshold_support = support, - _ => return Some(Err(format!("'{s}' is not a valid value for small-data-threshold-support."))), - } - Some(Ok(())) - })).unwrap_or(Ok(())) - } ); - ($key_name:ident, PanicStrategy) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { - match s { - "unwind" => base.$key_name = PanicStrategy::Unwind, - "abort" => base.$key_name = PanicStrategy::Abort, - _ => return Some(Err(format!("'{}' is not a valid value for \ - panic-strategy. Use 'unwind' or 'abort'.", - s))), - } - Some(Ok(())) - })).unwrap_or(Ok(())) - } ); - ($key_name:ident, RelroLevel) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { - match s.parse::() { - Ok(level) => base.$key_name = level, - _ => return Some(Err(format!("'{}' is not a valid value for \ - relro-level. Use 'full', 'partial, or 'off'.", - s))), - } - Some(Ok(())) - })).unwrap_or(Ok(())) - } ); - ($key_name:ident, Option) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { - match s.parse::() { - Ok(level) => base.$key_name = Some(level), - _ => return Some(Err(format!("'{}' is not a valid value for \ - symbol-visibility. Use 'hidden', 'protected, or 'interposable'.", - s))), - } - Some(Ok(())) - })).unwrap_or(Ok(())) - } ); - ($key_name:ident, DebuginfoKind) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { - match s.parse::() { - Ok(level) => base.$key_name = level, - _ => return Some(Err( - format!("'{s}' is not a valid value for debuginfo-kind. Use 'dwarf', \ - 'dwarf-dsym' or 'pdb'.") - )), - } - Some(Ok(())) - })).unwrap_or(Ok(())) - } ); - ($key_name:ident, SplitDebuginfo) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { - match s.parse::() { - Ok(level) => base.$key_name = level, - _ => return Some(Err(format!("'{}' is not a valid value for \ - split-debuginfo. Use 'off' or 'dsymutil'.", - s))), - } - Some(Ok(())) - })).unwrap_or(Ok(())) - } ); - ($key_name:ident, list) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - if let Some(j) = obj.remove(&name) { - if let Some(v) = j.as_array() { - base.$key_name = v.iter() - .map(|a| a.as_str().unwrap().to_string().into()) - .collect(); - } else { - incorrect_type.push(name) - } + } + } + macro_rules! check_eq { + ($left:expr, $right:expr, $($msg:tt)*) => { + if ($left) != ($right) { + return Err(format!($($msg)*)); } - } ); - ($key_name:ident, opt_list) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - if let Some(j) = obj.remove(&name) { - if let Some(v) = j.as_array() { - base.$key_name = Some(v.iter() - .map(|a| a.as_str().unwrap().to_string().into()) - .collect()); - } else { - incorrect_type.push(name) - } + } + } + macro_rules! check_ne { + ($left:expr, $right:expr, $($msg:tt)*) => { + if ($left) == ($right) { + return Err(format!($($msg)*)); } - } ); - ($key_name:ident, fallible_list) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|j| { - if let Some(v) = j.as_array() { - match v.iter().map(|a| FromStr::from_str(a.as_str().unwrap())).collect() { - Ok(l) => { base.$key_name = l }, - // FIXME: `fallible_list` can't re-use the `key!` macro for list - // elements and the error messages from that macro, so it has a bad - // generic message instead - Err(_) => return Some(Err( - format!("`{:?}` is not a valid value for `{}`", j, name) - )), - } - } else { - incorrect_type.push(name) - } - Some(Ok(())) - }).unwrap_or(Ok(())) - } ); - ($key_name:ident, optional) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - if let Some(o) = obj.remove(&name) { - base.$key_name = o - .as_str() - .map(|s| s.to_string().into()); + } + } + macro_rules! check_matches { + ($left:expr, $right:pat, $($msg:tt)*) => { + if !matches!($left, $right) { + return Err(format!($($msg)*)); } - } ); - ($key_name:ident = $json_name:expr, LldFlavor) => ( { - let name = $json_name; - obj.remove(name).and_then(|o| o.as_str().and_then(|s| { - if let Some(flavor) = LldFlavor::from_str(&s) { - base.$key_name = flavor; - } else { - return Some(Err(format!( - "'{}' is not a valid value for lld-flavor. \ - Use 'darwin', 'gnu', 'link' or 'wasm'.", - s))) - } - Some(Ok(())) - })).unwrap_or(Ok(())) - } ); - ($key_name:ident = $json_name:expr, LinkerFlavor) => ( { - let name = $json_name; - obj.remove(name).and_then(|o| o.as_str().and_then(|s| { - match LinkerFlavorCli::from_str(s) { - Some(linker_flavor) => base.$key_name = linker_flavor, - _ => return Some(Err(format!("'{}' is not a valid value for linker-flavor. \ - Use {}", s, LinkerFlavorCli::one_of()))), + } + } + + check_eq!( + self.is_like_osx, + self.vendor == "apple", + "`is_like_osx` must be set if and only if `vendor` is `apple`" + ); + check_eq!( + self.is_like_solaris, + self.os == "solaris" || self.os == "illumos", + "`is_like_solaris` must be set if and only if `os` is `solaris` or `illumos`" + ); + check_eq!( + self.is_like_windows, + self.os == "windows" || self.os == "uefi", + "`is_like_windows` must be set if and only if `os` is `windows` or `uefi`" + ); + check_eq!( + self.is_like_wasm, + self.arch == "wasm32" || self.arch == "wasm64", + "`is_like_wasm` must be set if and only if `arch` is `wasm32` or `wasm64`" + ); + if self.is_like_msvc { + check!(self.is_like_windows, "if `is_like_msvc` is set, `is_like_windows` must be set"); + } + if self.os == "emscripten" { + check!(self.is_like_wasm, "the `emcscripten` os only makes sense on wasm-like targets"); + } + + // Check that default linker flavor is compatible with some other key properties. + check_eq!( + self.is_like_osx, + matches!(self.linker_flavor, LinkerFlavor::Darwin(..)), + "`linker_flavor` must be `darwin` if and only if `is_like_osx` is set" + ); + check_eq!( + self.is_like_msvc, + matches!(self.linker_flavor, LinkerFlavor::Msvc(..)), + "`linker_flavor` must be `msvc` if and only if `is_like_msvc` is set" + ); + check_eq!( + self.is_like_wasm && self.os != "emscripten", + matches!(self.linker_flavor, LinkerFlavor::WasmLld(..)), + "`linker_flavor` must be `wasm-lld` if and only if `is_like_wasm` is set and the `os` is not `emscripten`", + ); + check_eq!( + self.os == "emscripten", + matches!(self.linker_flavor, LinkerFlavor::EmCc), + "`linker_flavor` must be `em-cc` if and only if `os` is `emscripten`" + ); + check_eq!( + self.arch == "bpf", + matches!(self.linker_flavor, LinkerFlavor::Bpf), + "`linker_flavor` must be `bpf` if and only if `arch` is `bpf`" + ); + check_eq!( + self.arch == "nvptx64", + matches!(self.linker_flavor, LinkerFlavor::Ptx), + "`linker_flavor` must be `ptc` if and only if `arch` is `nvptx64`" + ); + + for args in [ + &self.pre_link_args, + &self.late_link_args, + &self.late_link_args_dynamic, + &self.late_link_args_static, + &self.post_link_args, + ] { + for (&flavor, flavor_args) in args { + check!(!flavor_args.is_empty(), "linker flavor args must not be empty"); + // Check that flavors mentioned in link args are compatible with the default flavor. + match self.linker_flavor { + LinkerFlavor::Gnu(..) => { + check_matches!( + flavor, + LinkerFlavor::Gnu(..), + "mixing GNU and non-GNU linker flavors" + ); } - Some(Ok(())) - })).unwrap_or(Ok(())) - } ); - ($key_name:ident, StackProbeType) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|o| match StackProbeType::from_json(&o) { - Ok(v) => { - base.$key_name = v; - Some(Ok(())) - }, - Err(s) => Some(Err( - format!("`{:?}` is not a valid value for `{}`: {}", o, name, s) - )), - }).unwrap_or(Ok(())) - } ); - ($key_name:ident, SanitizerSet) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - if let Some(o) = obj.remove(&name) { - if let Some(a) = o.as_array() { - for s in a { - base.$key_name |= match s.as_str() { - Some("address") => SanitizerSet::ADDRESS, - Some("cfi") => SanitizerSet::CFI, - Some("dataflow") => SanitizerSet::DATAFLOW, - Some("kcfi") => SanitizerSet::KCFI, - Some("kernel-address") => SanitizerSet::KERNELADDRESS, - Some("leak") => SanitizerSet::LEAK, - Some("memory") => SanitizerSet::MEMORY, - Some("memtag") => SanitizerSet::MEMTAG, - Some("safestack") => SanitizerSet::SAFESTACK, - Some("shadow-call-stack") => SanitizerSet::SHADOWCALLSTACK, - Some("thread") => SanitizerSet::THREAD, - Some("hwaddress") => SanitizerSet::HWADDRESS, - Some(s) => return Err(format!("unknown sanitizer {}", s)), - _ => return Err(format!("not a string: {:?}", s)), - }; - } - } else { - incorrect_type.push(name) + LinkerFlavor::Darwin(..) => { + check_matches!( + flavor, + LinkerFlavor::Darwin(..), + "mixing Darwin and non-Darwin linker flavors" + ) } - } - Ok::<(), String>(()) - } ); - ($key_name:ident, link_self_contained_components) => ( { - // Skeleton of what needs to be parsed: - // - // ``` - // $name: { - // "components": [ - // - // ] - // } - // ``` - let name = (stringify!($key_name)).replace("_", "-"); - if let Some(o) = obj.remove(&name) { - if let Some(o) = o.as_object() { - let component_array = o.get("components") - .ok_or_else(|| format!("{name}: expected a \ - JSON object with a `components` field."))?; - let component_array = component_array.as_array() - .ok_or_else(|| format!("{name}.components: expected a JSON array"))?; - let mut components = LinkSelfContainedComponents::empty(); - for s in component_array { - components |= match s.as_str() { - Some(s) => { - LinkSelfContainedComponents::from_str(s) - .ok_or_else(|| format!("unknown \ - `-Clink-self-contained` component: {s}"))? - }, - _ => return Err(format!("not a string: {:?}", s)), - }; - } - base.$key_name = LinkSelfContainedDefault::WithComponents(components); - } else { - incorrect_type.push(name) + LinkerFlavor::WasmLld(..) => { + check_matches!( + flavor, + LinkerFlavor::WasmLld(..), + "mixing wasm and non-wasm linker flavors" + ) } - } - Ok::<(), String>(()) - } ); - ($key_name:ident = $json_name:expr, link_self_contained_backwards_compatible) => ( { - let name = $json_name; - obj.remove(name).and_then(|o| o.as_str().and_then(|s| { - match s.parse::() { - Ok(lsc_default) => base.$key_name = lsc_default, - _ => return Some(Err(format!("'{}' is not a valid `-Clink-self-contained` default. \ - Use 'false', 'true', 'musl' or 'mingw'", s))), + LinkerFlavor::Unix(..) => { + check_matches!( + flavor, + LinkerFlavor::Unix(..), + "mixing unix and non-unix linker flavors" + ); } - Some(Ok(())) - })).unwrap_or(Ok(())) - } ); - ($key_name:ident = $json_name:expr, link_objects) => ( { - let name = $json_name; - if let Some(val) = obj.remove(name) { - let obj = val.as_object().ok_or_else(|| format!("{}: expected a \ - JSON object with fields per CRT object kind.", name))?; - let mut args = CrtObjects::new(); - for (k, v) in obj { - let kind = LinkOutputKind::from_str(&k).ok_or_else(|| { - format!("{}: '{}' is not a valid value for CRT object kind. \ - Use '(dynamic,static)-(nopic,pic)-exe' or \ - '(dynamic,static)-dylib' or 'wasi-reactor-exe'", name, k) - })?; - - let v = v.as_array().ok_or_else(|| - format!("{}.{}: expected a JSON array", name, k) - )?.iter().enumerate() - .map(|(i,s)| { - let s = s.as_str().ok_or_else(|| - format!("{}.{}[{}]: expected a JSON string", name, k, i))?; - Ok(s.to_string().into()) - }) - .collect::, String>>()?; - - args.insert(kind, v); + LinkerFlavor::Msvc(..) => { + check_matches!( + flavor, + LinkerFlavor::Msvc(..), + "mixing MSVC and non-MSVC linker flavors" + ); } - base.$key_name = args; - } - } ); - ($key_name:ident = $json_name:expr, link_args) => ( { - let name = $json_name; - if let Some(val) = obj.remove(name) { - let obj = val.as_object().ok_or_else(|| format!("{}: expected a \ - JSON object with fields per linker-flavor.", name))?; - let mut args = LinkArgsCli::new(); - for (k, v) in obj { - let flavor = LinkerFlavorCli::from_str(&k).ok_or_else(|| { - format!("{}: '{}' is not a valid value for linker-flavor. \ - Use 'em', 'gcc', 'ld' or 'msvc'", name, k) - })?; - - let v = v.as_array().ok_or_else(|| - format!("{}.{}: expected a JSON array", name, k) - )?.iter().enumerate() - .map(|(i,s)| { - let s = s.as_str().ok_or_else(|| - format!("{}.{}[{}]: expected a JSON string", name, k, i))?; - Ok(s.to_string().into()) - }) - .collect::, String>>()?; - - args.insert(flavor, v); + LinkerFlavor::EmCc + | LinkerFlavor::Bpf + | LinkerFlavor::Ptx + | LinkerFlavor::Llbc => { + check_eq!(flavor, self.linker_flavor, "mixing different linker flavors") } - base.$key_name = args; } - } ); - ($key_name:ident, env) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - if let Some(o) = obj.remove(&name) { - if let Some(a) = o.as_array() { - for o in a { - if let Some(s) = o.as_str() { - if let [k, v] = *s.split('=').collect::>() { - base.$key_name - .to_mut() - .push((k.to_string().into(), v.to_string().into())) - } + + // Check that link args for cc and non-cc versions of flavors are consistent. + let check_noncc = |noncc_flavor| -> Result<(), String> { + if let Some(noncc_args) = args.get(&noncc_flavor) { + for arg in flavor_args { + if let Some(suffix) = arg.strip_prefix("-Wl,") { + check!( + noncc_args.iter().any(|a| a == suffix), + " link args for cc and non-cc versions of flavors are not consistent" + ); } } - } else { - incorrect_type.push(name) - } - } - } ); - ($key_name:ident, TargetFamilies) => ( { - if let Some(value) = obj.remove("target-family") { - if let Some(v) = value.as_array() { - base.$key_name = v.iter() - .map(|a| a.as_str().unwrap().to_string().into()) - .collect(); - } else if let Some(v) = value.as_str() { - base.$key_name = vec![v.to_string().into()].into(); } + Ok(()) + }; + + match self.linker_flavor { + LinkerFlavor::Gnu(Cc::Yes, lld) => check_noncc(LinkerFlavor::Gnu(Cc::No, lld))?, + LinkerFlavor::WasmLld(Cc::Yes) => check_noncc(LinkerFlavor::WasmLld(Cc::No))?, + LinkerFlavor::Unix(Cc::Yes) => check_noncc(LinkerFlavor::Unix(Cc::No))?, + _ => {} } - } ); - ($key_name:ident, Conv) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { - match Conv::from_str(s) { - Ok(c) => { - base.$key_name = c; - Some(Ok(())) - } - Err(e) => Some(Err(e)) - } - })).unwrap_or(Ok(())) - } ); - } + } - if let Some(j) = obj.remove("target-endian") { - if let Some(s) = j.as_str() { - base.endian = s.parse()?; - } else { - incorrect_type.push("target-endian".into()) + // Check that link args for lld and non-lld versions of flavors are consistent. + for cc in [Cc::No, Cc::Yes] { + check_eq!( + args.get(&LinkerFlavor::Gnu(cc, Lld::No)), + args.get(&LinkerFlavor::Gnu(cc, Lld::Yes)), + "link args for lld and non-lld versions of flavors are not consistent", + ); + check_eq!( + args.get(&LinkerFlavor::Darwin(cc, Lld::No)), + args.get(&LinkerFlavor::Darwin(cc, Lld::Yes)), + "link args for lld and non-lld versions of flavors are not consistent", + ); + } + check_eq!( + args.get(&LinkerFlavor::Msvc(Lld::No)), + args.get(&LinkerFlavor::Msvc(Lld::Yes)), + "link args for lld and non-lld versions of flavors are not consistent", + ); + } + + if self.link_self_contained.is_disabled() { + check!( + self.pre_link_objects_self_contained.is_empty() + && self.post_link_objects_self_contained.is_empty(), + "if `link_self_contained` is disabled, then `pre_link_objects_self_contained` and `post_link_objects_self_contained` must be empty", + ); + } + + // If your target really needs to deviate from the rules below, + // except it and document the reasons. + // Keep the default "unknown" vendor instead. + check_ne!(self.vendor, "", "`vendor` cannot be empty"); + check_ne!(self.os, "", "`os` cannot be empty"); + if !self.can_use_os_unknown() { + // Keep the default "none" for bare metal targets instead. + check_ne!( + self.os, + "unknown", + "`unknown` os can only be used on particular targets; use `none` for bare-metal targets" + ); + } + + // Check dynamic linking stuff. + // We skip this for JSON targets since otherwise, our default values would fail this test. + // These checks are not critical for correctness, but more like default guidelines. + // FIXME (https://github.com/rust-lang/rust/issues/133459): do we want to change the JSON + // target defaults so that they pass these checks? + if kind == TargetKind::Builtin { + // BPF: when targeting user space vms (like rbpf), those can load dynamic libraries. + // hexagon: when targeting QuRT, that OS can load dynamic libraries. + // wasm{32,64}: dynamic linking is inherent in the definition of the VM. + if self.os == "none" + && (self.arch != "bpf" + && self.arch != "hexagon" + && self.arch != "wasm32" + && self.arch != "wasm64") + { + check!( + !self.dynamic_linking, + "dynamic linking is not supported on this OS/architecture" + ); + } + if self.only_cdylib + || self.crt_static_allows_dylibs + || !self.late_link_args_dynamic.is_empty() + { + check!( + self.dynamic_linking, + "dynamic linking must be allowed when `only_cdylib` or `crt_static_allows_dylibs` or `late_link_args_dynamic` are set" + ); + } + // Apparently PIC was slow on wasm at some point, see comments in wasm_base.rs + if self.dynamic_linking && !self.is_like_wasm { + check_eq!( + self.relocation_model, + RelocModel::Pic, + "targets that support dynamic linking must use the `pic` relocation model" + ); + } + if self.position_independent_executables { + check_eq!( + self.relocation_model, + RelocModel::Pic, + "targets that support position-independent executables must use the `pic` relocation model" + ); + } + // The UEFI targets do not support dynamic linking but still require PIC (#101377). + if self.relocation_model == RelocModel::Pic && (self.os != "uefi") { + check!( + self.dynamic_linking || self.position_independent_executables, + "when the relocation model is `pic`, the target must support dynamic linking or use position-independent executables. \ + Set the relocation model to `static` to avoid this requirement" + ); + } + if self.static_position_independent_executables { + check!( + self.position_independent_executables, + "if `static_position_independent_executables` is set, then `position_independent_executables` must be set" + ); } + if self.position_independent_executables { + check!( + self.executables, + "if `position_independent_executables` is set then `executables` must be set" + ); + } + } + + // Check crt static stuff + if self.crt_static_default || self.crt_static_allows_dylibs { + check!( + self.crt_static_respected, + "static CRT can be enabled but `crt_static_respected` is not set" + ); } - if let Some(fp) = obj.remove("frame-pointer") { - if let Some(s) = fp.as_str() { - base.frame_pointer = s - .parse() - .map_err(|()| format!("'{s}' is not a valid value for frame-pointer"))?; - } else { - incorrect_type.push("frame-pointer".into()) + // Check that RISC-V targets always specify which ABI they use. + match &*self.arch { + "riscv32" => { + check_matches!( + &*self.llvm_abiname, + "ilp32" | "ilp32f" | "ilp32d" | "ilp32e", + "invalid RISC-V ABI name" + ); + } + "riscv64" => { + // Note that the `lp64e` is still unstable as it's not (yet) part of the ELF psABI. + check_matches!( + &*self.llvm_abiname, + "lp64" | "lp64f" | "lp64d" | "lp64q" | "lp64e", + "invalid RISC-V ABI name" + ); + } + _ => {} + } + + // Check that the given target-features string makes some basic sense. + if !self.features.is_empty() { + let mut features_enabled = FxHashSet::default(); + let mut features_disabled = FxHashSet::default(); + for feat in self.features.split(',') { + if let Some(feat) = feat.strip_prefix("+") { + features_enabled.insert(feat); + if features_disabled.contains(feat) { + return Err(format!( + "target feature `{feat}` is both enabled and disabled" + )); + } + } else if let Some(feat) = feat.strip_prefix("-") { + features_disabled.insert(feat); + if features_enabled.contains(feat) { + return Err(format!( + "target feature `{feat}` is both enabled and disabled" + )); + } + } else { + return Err(format!( + "target feature `{feat}` is invalid, must start with `+` or `-`" + )); + } } } - key!(c_int_width = "target-c-int-width"); - key!(c_enum_min_bits, Option); // if None, matches c_int_width - key!(os); - key!(env); - key!(abi); - key!(vendor); - key!(linker, optional); - key!(linker_flavor_json = "linker-flavor", LinkerFlavor)?; - key!(lld_flavor_json = "lld-flavor", LldFlavor)?; - key!(linker_is_gnu_json = "linker-is-gnu", bool); - key!(pre_link_objects = "pre-link-objects", link_objects); - key!(post_link_objects = "post-link-objects", link_objects); - key!(pre_link_objects_self_contained = "pre-link-objects-fallback", link_objects); - key!(post_link_objects_self_contained = "post-link-objects-fallback", link_objects); - // Deserializes the backwards-compatible variants of `-Clink-self-contained` - key!( - link_self_contained = "crt-objects-fallback", - link_self_contained_backwards_compatible - )?; - // Deserializes the components variant of `-Clink-self-contained` - key!(link_self_contained, link_self_contained_components)?; - key!(pre_link_args_json = "pre-link-args", link_args); - key!(late_link_args_json = "late-link-args", link_args); - key!(late_link_args_dynamic_json = "late-link-args-dynamic", link_args); - key!(late_link_args_static_json = "late-link-args-static", link_args); - key!(post_link_args_json = "post-link-args", link_args); - key!(link_script, optional); - key!(link_env, env); - key!(link_env_remove, list); - key!(asm_args, list); - key!(cpu); - key!(features); - key!(dynamic_linking, bool); - key!(direct_access_external_data, Option); - key!(dll_tls_export, bool); - key!(only_cdylib, bool); - key!(executables, bool); - key!(relocation_model, RelocModel)?; - key!(code_model, CodeModel)?; - key!(tls_model, TlsModel)?; - key!(disable_redzone, bool); - key!(function_sections, bool); - key!(dll_prefix); - key!(dll_suffix); - key!(exe_suffix); - key!(staticlib_prefix); - key!(staticlib_suffix); - key!(families, TargetFamilies); - key!(abi_return_struct_as_int, bool); - key!(is_like_aix, bool); - key!(is_like_osx, bool); - key!(is_like_solaris, bool); - key!(is_like_windows, bool); - key!(is_like_msvc, bool); - key!(is_like_wasm, bool); - key!(is_like_android, bool); - key!(default_dwarf_version, u32); - key!(allows_weak_linkage, bool); - key!(has_rpath, bool); - key!(no_default_libraries, bool); - key!(position_independent_executables, bool); - key!(static_position_independent_executables, bool); - key!(plt_by_default, bool); - key!(relro_level, RelroLevel)?; - key!(archive_format); - key!(allow_asm, bool); - key!(main_needs_argc_argv, bool); - key!(has_thread_local, bool); - key!(obj_is_bitcode, bool); - key!(forces_embed_bitcode, bool); - key!(bitcode_llvm_cmdline); - key!(max_atomic_width, Option); - key!(min_atomic_width, Option); - key!(atomic_cas, bool); - key!(panic_strategy, PanicStrategy)?; - key!(crt_static_allows_dylibs, bool); - key!(crt_static_default, bool); - key!(crt_static_respected, bool); - key!(stack_probes, StackProbeType)?; - key!(min_global_align, Option); - key!(default_codegen_units, Option); - key!(trap_unreachable, bool); - key!(requires_lto, bool); - key!(singlethread, bool); - key!(no_builtins, bool); - key!(default_visibility, Option)?; - key!(emit_debug_gdb_scripts, bool); - key!(requires_uwtable, bool); - key!(default_uwtable, bool); - key!(simd_types_indirect, bool); - key!(limit_rdylib_exports, bool); - key!(override_export_symbols, opt_list); - key!(merge_functions, MergeFunctions)?; - key!(mcount = "target-mcount"); - key!(llvm_mcount_intrinsic, optional); - key!(llvm_abiname); - key!(relax_elf_relocations, bool); - key!(llvm_args, list); - key!(use_ctors_section, bool); - key!(eh_frame_header, bool); - key!(has_thumb_interworking, bool); - key!(debuginfo_kind, DebuginfoKind)?; - key!(split_debuginfo, SplitDebuginfo)?; - key!(supported_split_debuginfo, fallible_list)?; - key!(supported_sanitizers, SanitizerSet)?; - key!(generate_arange_section, bool); - key!(supports_stack_protector, bool); - key!(small_data_threshold_support, SmallDataThresholdSupport)?; - key!(entry_name); - key!(entry_abi, Conv)?; - key!(supports_xray, bool); - - base.update_from_cli(); - - // Each field should have been read using `Json::remove` so any keys remaining are unused. - let remaining_keys = obj.keys(); - Ok((base, TargetWarnings { - unused_fields: remaining_keys.cloned().collect(), - incorrect_type, - })) + Ok(()) + } + + /// Test target self-consistency and JSON encoding/decoding roundtrip. + #[cfg(test)] + fn test_target(mut self) { + let recycled_target = Target::from_json(self.to_json()).map(|(j, _)| j); + self.update_to_cli(); + self.check_consistency(TargetKind::Builtin).unwrap(); + assert_eq!(recycled_target, Ok(self)); + } + + // Add your target to the whitelist if it has `std` library + // and you certainly want "unknown" for the OS name. + fn can_use_os_unknown(&self) -> bool { + self.llvm_target == "wasm32-unknown-unknown" + || self.llvm_target == "wasm64-unknown-unknown" + || (self.env == "sgx" && self.vendor == "fortanix") } /// Load a built-in target @@ -3567,178 +3308,6 @@ impl Target { } } -impl ToJson for Target { - fn to_json(&self) -> Json { - let mut d = serde_json::Map::new(); - let default: TargetOptions = Default::default(); - let mut target = self.clone(); - target.update_to_cli(); - - macro_rules! target_val { - ($attr:ident) => {{ - let name = (stringify!($attr)).replace("_", "-"); - d.insert(name, target.$attr.to_json()); - }}; - } - - macro_rules! target_option_val { - ($attr:ident) => {{ - let name = (stringify!($attr)).replace("_", "-"); - if default.$attr != target.$attr { - d.insert(name, target.$attr.to_json()); - } - }}; - ($attr:ident, $json_name:expr) => {{ - let name = $json_name; - if default.$attr != target.$attr { - d.insert(name.into(), target.$attr.to_json()); - } - }}; - (link_args - $attr:ident, $json_name:expr) => {{ - let name = $json_name; - if default.$attr != target.$attr { - let obj = target - .$attr - .iter() - .map(|(k, v)| (k.desc().to_string(), v.clone())) - .collect::>(); - d.insert(name.to_string(), obj.to_json()); - } - }}; - (env - $attr:ident) => {{ - let name = (stringify!($attr)).replace("_", "-"); - if default.$attr != target.$attr { - let obj = target - .$attr - .iter() - .map(|&(ref k, ref v)| format!("{k}={v}")) - .collect::>(); - d.insert(name, obj.to_json()); - } - }}; - } - - target_val!(llvm_target); - target_val!(metadata); - d.insert("target-pointer-width".to_string(), self.pointer_width.to_string().to_json()); - target_val!(arch); - target_val!(data_layout); - - target_option_val!(endian, "target-endian"); - target_option_val!(c_int_width, "target-c-int-width"); - target_option_val!(os); - target_option_val!(env); - target_option_val!(abi); - target_option_val!(vendor); - target_option_val!(linker); - target_option_val!(linker_flavor_json, "linker-flavor"); - target_option_val!(lld_flavor_json, "lld-flavor"); - target_option_val!(linker_is_gnu_json, "linker-is-gnu"); - target_option_val!(pre_link_objects); - target_option_val!(post_link_objects); - target_option_val!(pre_link_objects_self_contained, "pre-link-objects-fallback"); - target_option_val!(post_link_objects_self_contained, "post-link-objects-fallback"); - target_option_val!(link_args - pre_link_args_json, "pre-link-args"); - target_option_val!(link_args - late_link_args_json, "late-link-args"); - target_option_val!(link_args - late_link_args_dynamic_json, "late-link-args-dynamic"); - target_option_val!(link_args - late_link_args_static_json, "late-link-args-static"); - target_option_val!(link_args - post_link_args_json, "post-link-args"); - target_option_val!(link_script); - target_option_val!(env - link_env); - target_option_val!(link_env_remove); - target_option_val!(asm_args); - target_option_val!(cpu); - target_option_val!(features); - target_option_val!(dynamic_linking); - target_option_val!(direct_access_external_data); - target_option_val!(dll_tls_export); - target_option_val!(only_cdylib); - target_option_val!(executables); - target_option_val!(relocation_model); - target_option_val!(code_model); - target_option_val!(tls_model); - target_option_val!(disable_redzone); - target_option_val!(frame_pointer); - target_option_val!(function_sections); - target_option_val!(dll_prefix); - target_option_val!(dll_suffix); - target_option_val!(exe_suffix); - target_option_val!(staticlib_prefix); - target_option_val!(staticlib_suffix); - target_option_val!(families, "target-family"); - target_option_val!(abi_return_struct_as_int); - target_option_val!(is_like_aix); - target_option_val!(is_like_osx); - target_option_val!(is_like_solaris); - target_option_val!(is_like_windows); - target_option_val!(is_like_msvc); - target_option_val!(is_like_wasm); - target_option_val!(is_like_android); - target_option_val!(default_dwarf_version); - target_option_val!(allows_weak_linkage); - target_option_val!(has_rpath); - target_option_val!(no_default_libraries); - target_option_val!(position_independent_executables); - target_option_val!(static_position_independent_executables); - target_option_val!(plt_by_default); - target_option_val!(relro_level); - target_option_val!(archive_format); - target_option_val!(allow_asm); - target_option_val!(main_needs_argc_argv); - target_option_val!(has_thread_local); - target_option_val!(obj_is_bitcode); - target_option_val!(forces_embed_bitcode); - target_option_val!(bitcode_llvm_cmdline); - target_option_val!(min_atomic_width); - target_option_val!(max_atomic_width); - target_option_val!(atomic_cas); - target_option_val!(panic_strategy); - target_option_val!(crt_static_allows_dylibs); - target_option_val!(crt_static_default); - target_option_val!(crt_static_respected); - target_option_val!(stack_probes); - target_option_val!(min_global_align); - target_option_val!(default_codegen_units); - target_option_val!(trap_unreachable); - target_option_val!(requires_lto); - target_option_val!(singlethread); - target_option_val!(no_builtins); - target_option_val!(default_visibility); - target_option_val!(emit_debug_gdb_scripts); - target_option_val!(requires_uwtable); - target_option_val!(default_uwtable); - target_option_val!(simd_types_indirect); - target_option_val!(limit_rdylib_exports); - target_option_val!(override_export_symbols); - target_option_val!(merge_functions); - target_option_val!(mcount, "target-mcount"); - target_option_val!(llvm_mcount_intrinsic); - target_option_val!(llvm_abiname); - target_option_val!(relax_elf_relocations); - target_option_val!(llvm_args); - target_option_val!(use_ctors_section); - target_option_val!(eh_frame_header); - target_option_val!(has_thumb_interworking); - target_option_val!(debuginfo_kind); - target_option_val!(split_debuginfo); - target_option_val!(supported_split_debuginfo); - target_option_val!(supported_sanitizers); - target_option_val!(c_enum_min_bits); - target_option_val!(generate_arange_section); - target_option_val!(supports_stack_protector); - target_option_val!(small_data_threshold_support); - target_option_val!(entry_name); - target_option_val!(entry_abi); - target_option_val!(supports_xray); - - // Serializing `-Clink-self-contained` needs a dynamic key to support the - // backwards-compatible variants. - d.insert(self.link_self_contained.json_key().into(), self.link_self_contained.to_json()); - - Json::Object(d) - } -} - /// Either a target tuple string or a path to a JSON file. #[derive(Clone, Debug)] pub enum TargetTuple { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs index 22b3a5f88426d..14a22988a0911 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs @@ -16,7 +16,6 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { - features: "+reserve-x18".into(), mcount: "\u{1}_mcount".into(), stack_probes: StackProbeType::Inline, supported_sanitizers: SanitizerSet::ADDRESS diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs index 34d8383a60476..ae7bfbd03940f 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs @@ -19,6 +19,7 @@ pub(crate) fn target() -> Target { cpu: "esp32-s2".into(), linker: Some("xtensa-esp32s2-elf-gcc".into()), max_atomic_width: Some(32), + features: "+forced-atomics".into(), ..xtensa::opts() }, } diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs deleted file mode 100644 index bd47d12ef9ff7..0000000000000 --- a/compiler/rustc_target/src/spec/tests/tests_impl.rs +++ /dev/null @@ -1,182 +0,0 @@ -use std::assert_matches::assert_matches; - -use super::super::*; - -// Test target self-consistency and JSON encoding/decoding roundtrip. -pub(super) fn test_target(mut target: Target) { - let recycled_target = Target::from_json(target.to_json()).map(|(j, _)| j); - target.update_to_cli(); - target.check_consistency(); - assert_eq!(recycled_target, Ok(target)); -} - -impl Target { - fn check_consistency(&self) { - assert_eq!(self.is_like_osx, self.vendor == "apple"); - assert_eq!(self.is_like_solaris, self.os == "solaris" || self.os == "illumos"); - assert_eq!(self.is_like_windows, self.os == "windows" || self.os == "uefi"); - assert_eq!(self.is_like_wasm, self.arch == "wasm32" || self.arch == "wasm64"); - if self.is_like_msvc { - assert!(self.is_like_windows); - } - - // Check that default linker flavor is compatible with some other key properties. - assert_eq!(self.is_like_osx, matches!(self.linker_flavor, LinkerFlavor::Darwin(..))); - assert_eq!(self.is_like_msvc, matches!(self.linker_flavor, LinkerFlavor::Msvc(..))); - assert_eq!( - self.is_like_wasm && self.os != "emscripten", - matches!(self.linker_flavor, LinkerFlavor::WasmLld(..)) - ); - assert_eq!(self.os == "emscripten", matches!(self.linker_flavor, LinkerFlavor::EmCc)); - assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::Bpf)); - assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::Ptx)); - - for args in [ - &self.pre_link_args, - &self.late_link_args, - &self.late_link_args_dynamic, - &self.late_link_args_static, - &self.post_link_args, - ] { - for (&flavor, flavor_args) in args { - assert!(!flavor_args.is_empty()); - // Check that flavors mentioned in link args are compatible with the default flavor. - match self.linker_flavor { - LinkerFlavor::Gnu(..) => { - assert_matches!(flavor, LinkerFlavor::Gnu(..)); - } - LinkerFlavor::Darwin(..) => { - assert_matches!(flavor, LinkerFlavor::Darwin(..)) - } - LinkerFlavor::WasmLld(..) => { - assert_matches!(flavor, LinkerFlavor::WasmLld(..)) - } - LinkerFlavor::Unix(..) => { - assert_matches!(flavor, LinkerFlavor::Unix(..)); - } - LinkerFlavor::Msvc(..) => { - assert_matches!(flavor, LinkerFlavor::Msvc(..)) - } - LinkerFlavor::EmCc - | LinkerFlavor::Bpf - | LinkerFlavor::Ptx - | LinkerFlavor::Llbc => { - assert_eq!(flavor, self.linker_flavor) - } - } - - // Check that link args for cc and non-cc versions of flavors are consistent. - let check_noncc = |noncc_flavor| { - if let Some(noncc_args) = args.get(&noncc_flavor) { - for arg in flavor_args { - if let Some(suffix) = arg.strip_prefix("-Wl,") { - assert!(noncc_args.iter().any(|a| a == suffix)); - } - } - } - }; - - match self.linker_flavor { - LinkerFlavor::Gnu(Cc::Yes, lld) => check_noncc(LinkerFlavor::Gnu(Cc::No, lld)), - LinkerFlavor::WasmLld(Cc::Yes) => check_noncc(LinkerFlavor::WasmLld(Cc::No)), - LinkerFlavor::Unix(Cc::Yes) => check_noncc(LinkerFlavor::Unix(Cc::No)), - _ => {} - } - } - - // Check that link args for lld and non-lld versions of flavors are consistent. - for cc in [Cc::No, Cc::Yes] { - assert_eq!( - args.get(&LinkerFlavor::Gnu(cc, Lld::No)), - args.get(&LinkerFlavor::Gnu(cc, Lld::Yes)), - ); - assert_eq!( - args.get(&LinkerFlavor::Darwin(cc, Lld::No)), - args.get(&LinkerFlavor::Darwin(cc, Lld::Yes)), - ); - } - assert_eq!( - args.get(&LinkerFlavor::Msvc(Lld::No)), - args.get(&LinkerFlavor::Msvc(Lld::Yes)), - ); - } - - if self.link_self_contained.is_disabled() { - assert!( - self.pre_link_objects_self_contained.is_empty() - && self.post_link_objects_self_contained.is_empty() - ); - } - - // If your target really needs to deviate from the rules below, - // except it and document the reasons. - // Keep the default "unknown" vendor instead. - assert_ne!(self.vendor, ""); - assert_ne!(self.os, ""); - if !self.can_use_os_unknown() { - // Keep the default "none" for bare metal targets instead. - assert_ne!(self.os, "unknown"); - } - - // Check dynamic linking stuff - // BPF: when targeting user space vms (like rbpf), those can load dynamic libraries. - // hexagon: when targeting QuRT, that OS can load dynamic libraries. - // wasm{32,64}: dynamic linking is inherent in the definition of the VM. - if self.os == "none" - && (self.arch != "bpf" - && self.arch != "hexagon" - && self.arch != "wasm32" - && self.arch != "wasm64") - { - assert!(!self.dynamic_linking); - } - if self.only_cdylib - || self.crt_static_allows_dylibs - || !self.late_link_args_dynamic.is_empty() - { - assert!(self.dynamic_linking); - } - // Apparently PIC was slow on wasm at some point, see comments in wasm_base.rs - if self.dynamic_linking && !(self.is_like_wasm && self.os != "emscripten") { - assert_eq!(self.relocation_model, RelocModel::Pic); - } - if self.position_independent_executables { - assert_eq!(self.relocation_model, RelocModel::Pic); - } - // The UEFI targets do not support dynamic linking but still require PIC (#101377). - if self.relocation_model == RelocModel::Pic && self.os != "uefi" { - assert!(self.dynamic_linking || self.position_independent_executables); - } - if self.static_position_independent_executables { - assert!(self.position_independent_executables); - } - if self.position_independent_executables { - assert!(self.executables); - } - - // Check crt static stuff - if self.crt_static_default || self.crt_static_allows_dylibs { - assert!(self.crt_static_respected); - } - - // Check that RISC-V targets always specify which ABI they use. - match &*self.arch { - "riscv32" => { - assert_matches!(&*self.llvm_abiname, "ilp32" | "ilp32f" | "ilp32d" | "ilp32e") - } - "riscv64" => { - // Note that the `lp64e` is still unstable as it's not (yet) part of the ELF psABI. - assert_matches!(&*self.llvm_abiname, "lp64" | "lp64f" | "lp64d" | "lp64q" | "lp64e") - } - _ => {} - } - } - - // Add your target to the whitelist if it has `std` library - // and you certainly want "unknown" for the OS name. - fn can_use_os_unknown(&self) -> bool { - self.llvm_target == "wasm32-unknown-unknown" - || self.llvm_target == "wasm64-unknown-unknown" - || (self.env == "sgx" && self.vendor == "fortanix") - } -} diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 112eb8626635a..67c047dddfcf4 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -228,6 +228,12 @@ const AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("rcpc3", Unstable(sym::aarch64_unstable_target_feature), &["rcpc2"]), // FEAT_RDM ("rdm", Stable, &["neon"]), + // This is needed for inline assembly, but shouldn't be stabilized as-is + // since it should be enabled globally using -Zfixed-x18, not + // #[target_feature]. + // Note that cfg(target_feature = "reserve-x18") is currently not set for + // targets that reserve x18 by default. + ("reserve-x18", Unstable(sym::aarch64_unstable_target_feature), &[]), // FEAT_SB ("sb", Stable, &[]), // FEAT_SHA1 & FEAT_SHA256 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 929fa559d750c..0f9d4cb1982d4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -152,7 +152,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err: TypeError<'tcx>, ) -> Diag<'a> { self.report_and_explain_type_error( - TypeTrace::types(cause, true, expected, actual), + TypeTrace::types(cause, expected, actual), param_env, err, ) @@ -167,7 +167,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err: TypeError<'tcx>, ) -> Diag<'a> { self.report_and_explain_type_error( - TypeTrace::consts(cause, true, expected, actual), + TypeTrace::consts(cause, expected, actual), param_env, err, ) @@ -1792,12 +1792,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn suggest_specify_actual_length( &self, - terr: TypeError<'_>, - trace: &TypeTrace<'_>, + terr: TypeError<'tcx>, + trace: &TypeTrace<'tcx>, span: Span, ) -> Option { let hir = self.tcx.hir(); - let TypeError::FixedArraySize(sz) = terr else { + let TypeError::ArraySize(sz) = terr else { return None; }; let tykind = match self.tcx.hir_node_by_def_id(trace.cause.body_id) { @@ -1838,9 +1838,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let Some(tykind) = tykind && let hir::TyKind::Array(_, length) = tykind && let hir::ArrayLen::Body(ct) = length + && let Some((scalar, ty)) = sz.found.try_to_scalar() + && ty == self.tcx.types.usize { let span = ct.span(); - Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength { span, length: sz.found }) + Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength { + span, + length: scalar.to_target_usize(&self.tcx).unwrap(), + }) } else { None } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs index 75054b2215336..218d2e753efd2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs @@ -3,6 +3,7 @@ use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::{self, Binder, Region, Ty, TyCtxt, TypeFoldable}; use rustc_span::Span; use tracing::instrument; @@ -83,7 +84,7 @@ pub fn find_param_with_region<'tcx>( // May return None; sometimes the tables are not yet populated. let ty = fn_sig.inputs()[index]; let mut found_anon_region = false; - let new_param_ty = tcx.fold_regions(ty, |r, _| { + let new_param_ty = fold_regions(tcx, ty, |r, _| { if r == anon_region { found_anon_region = true; replace_region diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 4e7d7b79ff4de..9b969dd3e43a6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -725,7 +725,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &obligation.cause, None, None, - TypeError::Sorts(ty::error::ExpectedFound::new(true, expected_ty, ct_ty)), + TypeError::Sorts(ty::error::ExpectedFound::new(expected_ty, ct_ty)), false, ); diag @@ -1449,7 +1449,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { secondary_span, values.map(|(_, normalized_ty, expected_ty)| { obligation.param_env.and(infer::ValuePairs::Terms(ExpectedFound::new( - true, expected_ty, normalized_ty, ))) @@ -1732,6 +1731,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span.push_span_label(self.tcx.def_span(trait_def_id), "this is the required trait"); for (sp, label) in [trait_def_id, other_trait_def_id] .iter() + // The current crate-version might depend on another version of the same crate + // (Think "semver-trick"). Do not call `extern_crate` in that case for the local + // crate as that doesn't make sense and ICEs (#133563). + .filter(|def_id| !def_id.is_local()) .filter_map(|def_id| self.tcx.extern_crate(def_id.krate)) .map(|data| { let dependency = if data.dependency_of == LOCAL_CRATE { @@ -1804,24 +1807,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { StringPart::highlighted("cargo tree".to_string()), StringPart::normal("` to explore your dependency tree".to_string()), ]); - - // FIXME: this is a giant hack for the benefit of this specific diagnostic. Because - // we're so nested in method calls before the error gets emitted, bubbling a single bit - // flag informing the top level caller to stop adding extra detail to the diagnostic, - // would actually be harder to follow. So we do something naughty here: we consume the - // diagnostic, emit it and leave in its place a "delayed bug" that will continue being - // modified but won't actually be printed to end users. This *is not ideal*, but allows - // us to reduce the verbosity of an error that is already quite verbose and increase its - // specificity. Below we modify the main message as well, in a way that *could* break if - // the implementation of Diagnostics change significantly, but that would be caught with - // a make test failure when this diagnostic is tested. - err.primary_message(format!( - "{} because the trait comes from a different crate version", - err.messages[0].0.as_str().unwrap(), - )); - let diag = err.clone(); - err.downgrade_to_delayed_bug(); - self.tcx.dcx().emit_diagnostic(diag); return true; } @@ -2755,7 +2740,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (obligation.cause.clone(), terr) }; self.report_and_explain_type_error( - TypeTrace::trait_refs(&cause, true, expected_trait_ref, found_trait_ref), + TypeTrace::trait_refs(&cause, expected_trait_ref, found_trait_ref), obligation.param_env, terr, ) @@ -2846,7 +2831,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if Some(expected_trait_ref.def_id) != self.tcx.lang_items().coroutine_trait() && not_tupled { return Ok(self.report_and_explain_type_error( - TypeTrace::trait_refs(&obligation.cause, true, expected_trait_ref, found_trait_ref), + TypeTrace::trait_refs(&obligation.cause, expected_trait_ref, found_trait_ref), obligation.param_env, ty::error::TypeError::Mismatch, )); 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 5ad15feadffc9..27b45f7094645 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -5312,9 +5312,10 @@ fn point_at_assoc_type_restriction( }; let name = tcx.item_name(proj.projection_term.def_id); let mut predicates = generics.predicates.iter().peekable(); - let mut prev: Option<&hir::WhereBoundPredicate<'_>> = None; + let mut prev: Option<(&hir::WhereBoundPredicate<'_>, Span)> = None; while let Some(pred) = predicates.next() { - let hir::WherePredicate::BoundPredicate(pred) = pred else { + let curr_span = pred.span; + let hir::WherePredicateKind::BoundPredicate(pred) = pred.kind else { continue; }; let mut bounds = pred.bounds.iter(); @@ -5340,8 +5341,8 @@ fn point_at_assoc_type_restriction( .iter() .filter(|p| { matches!( - p, - hir::WherePredicate::BoundPredicate(p) + p.kind, + hir::WherePredicateKind::BoundPredicate(p) if hir::PredicateOrigin::WhereClause == p.origin ) }) @@ -5351,20 +5352,21 @@ fn point_at_assoc_type_restriction( // There's only one `where` bound, that needs to be removed. Remove the whole // `where` clause. generics.where_clause_span - } else if let Some(hir::WherePredicate::BoundPredicate(next)) = predicates.peek() + } else if let Some(next_pred) = predicates.peek() + && let hir::WherePredicateKind::BoundPredicate(next) = next_pred.kind && pred.origin == next.origin { // There's another bound, include the comma for the current one. - pred.span.until(next.span) - } else if let Some(prev) = prev + curr_span.until(next_pred.span) + } else if let Some((prev, prev_span)) = prev && pred.origin == prev.origin { // Last bound, try to remove the previous comma. - prev.span.shrink_to_hi().to(pred.span) + prev_span.shrink_to_hi().to(curr_span) } else if pred.origin == hir::PredicateOrigin::WhereClause { - pred.span.with_hi(generics.where_clause_span.hi()) + curr_span.with_hi(generics.where_clause_span.hi()) } else { - pred.span + curr_span }; err.span_suggestion_verbose( @@ -5417,7 +5419,7 @@ fn point_at_assoc_type_restriction( ); } } - prev = Some(pred); + prev = Some((pred, curr_span)); } } diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 2cc787c8bc577..97cde67799c2c 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -204,8 +204,10 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< // and the obligation is monomorphic, otherwise passes such as // transmute checking and polymorphic MIR optimizations could // get a result which isn't correct for all monomorphizations. - match self.typing_mode_unchecked() { - TypingMode::Coherence | TypingMode::Analysis { .. } => false, + match self.typing_mode() { + TypingMode::Coherence + | TypingMode::Analysis { .. } + | TypingMode::PostBorrowckAnalysis { .. } => false, TypingMode::PostAnalysis => { let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref); !poly_trait_ref.still_further_specializable() diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 53e5420d27a5d..0f90c45d0320c 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -264,14 +264,14 @@ fn fulfillment_error_for_no_solution<'tcx>( let (a, b) = infcx.enter_forall_and_leak_universe( obligation.predicate.kind().rebind((pred.a, pred.b)), ); - let expected_found = ExpectedFound::new(true, a, b); + let expected_found = ExpectedFound::new(a, b); FulfillmentErrorCode::Subtype(expected_found, TypeError::Sorts(expected_found)) } ty::PredicateKind::Coerce(pred) => { let (a, b) = infcx.enter_forall_and_leak_universe( obligation.predicate.kind().rebind((pred.a, pred.b)), ); - let expected_found = ExpectedFound::new(false, a, b); + let expected_found = ExpectedFound::new(b, a); FulfillmentErrorCode::Subtype(expected_found, TypeError::Sorts(expected_found)) } ty::PredicateKind::Clause(_) @@ -346,12 +346,21 @@ fn find_best_leaf_obligation<'tcx>( consider_ambiguities: bool, ) -> PredicateObligation<'tcx> { let obligation = infcx.resolve_vars_if_possible(obligation.clone()); + // FIXME: we use a probe here as the `BestObligation` visitor does not + // check whether it uses candidates which get shadowed by where-bounds. + // + // We should probably fix the visitor to not do so instead, as this also + // means the leaf obligation may be incorrect. infcx - .visit_proof_tree(obligation.clone().into(), &mut BestObligation { - obligation: obligation.clone(), - consider_ambiguities, + .fudge_inference_if_ok(|| { + infcx + .visit_proof_tree(obligation.clone().into(), &mut BestObligation { + obligation: obligation.clone(), + consider_ambiguities, + }) + .break_value() + .ok_or(()) }) - .break_value() .unwrap_or(obligation) } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index fac0414d7145b..6730f28893d1c 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -318,13 +318,11 @@ impl<'tcx> AutoTraitFinder<'tcx> { elaborate(tcx, computed_preds.clone().chain(user_computed_preds.iter().cloned())); new_env = ty::ParamEnv::new( tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())), - param_env.reveal(), ); } let final_user_env = ty::ParamEnv::new( tcx.mk_clauses_from_iter(user_computed_preds.into_iter().filter_map(|p| p.as_clause())), - user_env.reveal(), ); debug!( "evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \ diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index cf63f14fb937d..e0a9ddf1876e6 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -150,8 +150,8 @@ fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> .predicates .iter() .filter_map(|pred| { - match pred { - hir::WherePredicate::BoundPredicate(pred) + match pred.kind { + hir::WherePredicateKind::BoundPredicate(pred) if pred.bounded_ty.hir_id.owner.to_def_id() == trait_def_id => { // Fetch spans for trait bounds that are Sized: @@ -707,7 +707,7 @@ fn receiver_is_dispatchable<'tcx>( let caller_bounds = param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]); - ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds), param_env.reveal()) + ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds)) }; // Receiver: DispatchFromDyn U]> diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index cb36f1a62dbfd..07fb2efb7fed3 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -20,13 +20,18 @@ pub fn evaluate_host_effect_obligation<'tcx>( selcx: &mut SelectionContext<'_, 'tcx>, obligation: &HostEffectObligation<'tcx>, ) -> Result>, EvaluationFailure> { - if matches!(selcx.infcx.typing_mode(obligation.param_env), TypingMode::Coherence) { + if matches!(selcx.infcx.typing_mode(), TypingMode::Coherence) { span_bug!( obligation.cause.span, "should not select host obligation in old solver in intercrate mode" ); } + // Force ambiguity for infer self ty. + if obligation.predicate.self_ty().is_ty_var() { + return Err(EvaluationFailure::Ambiguous); + } + match evaluate_host_effect_from_bounds(selcx, obligation) { Ok(result) => return Ok(result), Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous), diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 2ec5f0d22496d..03e483f555d8e 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -557,8 +557,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ProcessResult::Changed(mk_pending(ok.obligations)) } Ok(Err(err)) => { - let expected_found = - ExpectedFound::new(subtype.a_is_expected, subtype.a, subtype.b); + let expected_found = if subtype.a_is_expected { + ExpectedFound::new(subtype.a, subtype.b) + } else { + ExpectedFound::new(subtype.b, subtype.a) + }; ProcessResult::Error(FulfillmentErrorCode::Subtype(expected_found, err)) } } @@ -578,7 +581,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } Ok(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)), Ok(Err(err)) => { - let expected_found = ExpectedFound::new(false, coerce.a, coerce.b); + let expected_found = ExpectedFound::new(coerce.b, coerce.a); ProcessResult::Error(FulfillmentErrorCode::Subtype(expected_found, err)) } } @@ -703,7 +706,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } Err(err) => { ProcessResult::Error(FulfillmentErrorCode::ConstEquate( - ExpectedFound::new(true, c1, c2), + ExpectedFound::new(c1, c2), err, )) } @@ -727,7 +730,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ProcessResult::Unchanged } else { // Two different constants using generic parameters ~> error. - let expected_found = ExpectedFound::new(true, c1, c2); + let expected_found = ExpectedFound::new(c1, c2); ProcessResult::Error(FulfillmentErrorCode::ConstEquate( expected_found, TypeError::ConstMismatch(expected_found), @@ -768,8 +771,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { stalled_on: &mut Vec, ) -> ProcessResult, FulfillmentErrorCode<'tcx>> { let infcx = self.selcx.infcx; - if obligation.predicate.is_global() - && !matches!(infcx.typing_mode(obligation.param_env), TypingMode::Coherence) + if obligation.predicate.is_global() && !matches!(infcx.typing_mode(), TypingMode::Coherence) { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. @@ -824,8 +826,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { ) -> ProcessResult, FulfillmentErrorCode<'tcx>> { let tcx = self.selcx.tcx(); let infcx = self.selcx.infcx; - if obligation.predicate.is_global() - && !matches!(infcx.typing_mode(obligation.param_env), TypingMode::Coherence) + if obligation.predicate.is_global() && !matches!(infcx.typing_mode(), TypingMode::Coherence) { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 80cef69002897..069fab6a6e6b9 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -423,7 +423,7 @@ pub fn normalize_param_env_or_error<'tcx>( debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates); - let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal()); + let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates)); if !elaborated_env.has_aliases() { return elaborated_env; } @@ -470,8 +470,7 @@ pub fn normalize_param_env_or_error<'tcx>( // here. I believe they should not matter, because we are ignoring TypeOutlives param-env // predicates here anyway. Keeping them here anyway because it seems safer. let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned(); - let outlives_env = - ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env), unnormalized_env.reveal()); + let outlives_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env)); let Ok(outlives_predicates) = do_normalize_predicates(tcx, cause, outlives_env, outlives_predicates) else { @@ -484,7 +483,7 @@ pub fn normalize_param_env_or_error<'tcx>( let mut predicates = non_outlives_predicates; predicates.extend(outlives_predicates); debug!("normalize_param_env_or_error: final predicates={:?}", predicates); - ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal()) + ty::ParamEnv::new(tcx.mk_clauses(&predicates)) } #[derive(Debug)] @@ -552,8 +551,18 @@ pub fn try_evaluate_const<'tcx>( | ty::ConstKind::Placeholder(_) | ty::ConstKind::Expr(_) => Err(EvaluateConstErr::HasGenericsOrInfers), ty::ConstKind::Unevaluated(uv) => { - // Postpone evaluation of constants that depend on generic parameters or inference variables. - let (args, param_env) = if tcx.features().generic_const_exprs() + // Postpone evaluation of constants that depend on generic parameters or + // inference variables. + // + // We use `TypingMode::PostAnalysis` here which is not *technically* correct + // to be revealing opaque types here as borrowcheck has not run yet. However, + // CTFE itself uses `TypingMode::PostAnalysis` unconditionally even during + // typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821). + // As a result we always use a revealed env when resolving the instance to evaluate. + // + // FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself + // instead of having this logic here + let (args, typing_env) = if tcx.features().generic_const_exprs() && uv.has_non_region_infer() { // `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause @@ -569,13 +578,17 @@ pub fn try_evaluate_const<'tcx>( // the generic arguments provided for it, then we should *not* attempt to evaluate it. return Err(EvaluateConstErr::HasGenericsOrInfers); } else { - (replace_param_and_infer_args_with_placeholder(tcx, uv.args), param_env) + let args = replace_param_and_infer_args_with_placeholder(tcx, uv.args); + let typing_env = infcx + .typing_env(tcx.erase_regions(param_env)) + .with_post_analysis_normalized(tcx); + (args, typing_env) } } Err(_) | Ok(None) => { let args = GenericArgs::identity_for_item(tcx, uv.def); - let param_env = tcx.param_env(uv.def); - (args, param_env) + let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def); + (args, typing_env) } } } else if tcx.def_kind(uv.def) == DefKind::AnonConst && uv.has_non_region_infer() { @@ -594,27 +607,20 @@ pub fn try_evaluate_const<'tcx>( ); let args = GenericArgs::identity_for_item(tcx, uv.def); - let param_env = tcx.param_env(uv.def); - (args, param_env) + let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def); + (args, typing_env) } else { // FIXME: This codepath is reachable under `associated_const_equality` and in the // future will be reachable by `min_generic_const_args`. We should handle inference // variables and generic parameters properly instead of doing nothing. - (uv.args, param_env) + let typing_env = infcx + .typing_env(tcx.erase_regions(param_env)) + .with_post_analysis_normalized(tcx); + (uv.args, typing_env) }; let uv = ty::UnevaluatedConst::new(uv.def, args); - // It's not *technically* correct to be revealing opaque types here as we could still be - // before borrowchecking. However, CTFE itself uses `Reveal::All` unconditionally even during - // typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821). As a result we - // always use a revealed env when resolving the instance to evaluate. - // - // FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All` - // instead of having this logic here - let typing_env = - tcx.erase_regions(infcx.typing_env(param_env)).with_reveal_all_normalized(tcx); let erased_uv = tcx.erase_regions(uv); - use rustc_middle::mir::interpret::ErrorHandled; match tcx.const_eval_resolve_for_typeck(typing_env, erased_uv, DUMMY_SP) { Ok(Ok(val)) => Ok(ty::Const::new_value( diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 5c38d162712e6..e99c5eacbd8e0 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -111,17 +111,17 @@ where pub(super) fn needs_normalization<'tcx, T: TypeVisitable>>( infcx: &InferCtxt<'tcx>, - param_env_for_debug_assertion: ty::ParamEnv<'tcx>, value: &T, ) -> bool { let mut flags = ty::TypeFlags::HAS_ALIAS; - // Opaques are treated as rigid with `Reveal::UserFacing`, + // Opaques are treated as rigid outside of `TypingMode::PostAnalysis`, // so we can ignore those. - match infcx.typing_mode(param_env_for_debug_assertion) { - TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => { - flags.remove(ty::TypeFlags::HAS_TY_OPAQUE) - } + match infcx.typing_mode() { + // FIXME(#132279): We likely want to reveal opaques during post borrowck analysis + TypingMode::Coherence + | TypingMode::Analysis { .. } + | TypingMode::PostBorrowckAnalysis { .. } => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE), TypingMode::PostAnalysis => {} } @@ -158,11 +158,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { "Normalizing {value:?} without wrapping in a `Binder`" ); - if !needs_normalization(self.selcx.infcx, self.param_env, &value) { - value - } else { - value.fold_with(self) - } + if !needs_normalization(self.selcx.infcx, &value) { value } else { value.fold_with(self) } } } @@ -182,7 +178,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if !needs_normalization(self.selcx.infcx, self.param_env, &ty) { + if !needs_normalization(self.selcx.infcx, &ty) { return ty; } @@ -217,10 +213,11 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx match kind { ty::Opaque => { // Only normalize `impl Trait` outside of type inference, usually in codegen. - match self.selcx.infcx.typing_mode(self.param_env) { - TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => { - ty.super_fold_with(self) - } + match self.selcx.infcx.typing_mode() { + // FIXME(#132279): We likely want to reveal opaques during post borrowck analysis + TypingMode::Coherence + | TypingMode::Analysis { .. } + | TypingMode::PostBorrowckAnalysis { .. } => ty.super_fold_with(self), TypingMode::PostAnalysis => { let recursion_limit = self.cx().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { @@ -407,8 +404,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx #[instrument(skip(self), level = "debug")] fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> { let tcx = self.selcx.tcx(); - if tcx.features().generic_const_exprs() - || !needs_normalization(self.selcx.infcx, self.param_env, &constant) + if tcx.features().generic_const_exprs() || !needs_normalization(self.selcx.infcx, &constant) { constant } else { @@ -426,7 +422,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx #[inline] fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { - if p.allow_normalization() && needs_normalization(self.selcx.infcx, self.param_env, &p) { + if p.allow_normalization() && needs_normalization(self.selcx.infcx, &p) { p.super_fold_with(self) } else { p diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index aab854e9caf91..01f6cccb375ad 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -10,7 +10,6 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; -pub use rustc_middle::traits::Reveal; use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; @@ -975,8 +974,10 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // and the obligation is monomorphic, otherwise passes such as // transmute checking and polymorphic MIR optimizations could // get a result which isn't correct for all monomorphizations. - match selcx.infcx.typing_mode(obligation.param_env) { - TypingMode::Coherence | TypingMode::Analysis { .. } => { + match selcx.infcx.typing_mode() { + TypingMode::Coherence + | TypingMode::Analysis { .. } + | TypingMode::PostBorrowckAnalysis { .. } => { debug!( assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id), ?obligation.predicate, diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 5f89894fb82ed..2ef9d5421ba6c 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -89,7 +89,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { } } - if !needs_normalization(self.infcx, self.param_env, &value) { + if !needs_normalization(self.infcx, &value) { return Ok(Normalized { value, obligations: PredicateObligations::new() }); } @@ -191,7 +191,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { - if !needs_normalization(self.infcx, self.param_env, &ty) { + if !needs_normalization(self.infcx, &ty) { return Ok(ty); } @@ -215,10 +215,10 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { let res = match kind { ty::Opaque => { // Only normalize `impl Trait` outside of type inference, usually in codegen. - match self.infcx.typing_mode(self.param_env) { - TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => { - ty.try_super_fold_with(self)? - } + match self.infcx.typing_mode() { + TypingMode::Coherence + | TypingMode::Analysis { .. } + | TypingMode::PostBorrowckAnalysis { .. } => ty.try_super_fold_with(self)?, TypingMode::PostAnalysis => { let args = data.args.try_fold_with(self)?; @@ -334,7 +334,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { &mut self, constant: ty::Const<'tcx>, ) -> Result, Self::Error> { - if !needs_normalization(self.infcx, self.param_env, &constant) { + if !needs_normalization(self.infcx, &constant) { return Ok(constant); } @@ -353,7 +353,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { &mut self, p: ty::Predicate<'tcx>, ) -> Result, Self::Error> { - if p.allow_normalization() && needs_normalization(self.infcx, self.param_env, &p) { + if p.allow_normalization() && needs_normalization(self.infcx, &p) { p.try_super_fold_with(self) } else { Ok(p) diff --git a/compiler/rustc_trait_selection/src/traits/select/_match.rs b/compiler/rustc_trait_selection/src/traits/select/_match.rs index 3980d672a11bc..7c19c35a4f784 100644 --- a/compiler/rustc_trait_selection/src/traits/select/_match.rs +++ b/compiler/rustc_trait_selection/src/traits/select/_match.rs @@ -70,7 +70,7 @@ impl<'tcx> TypeRelation> for MatchAgainstFreshVars<'tcx> { ) => Ok(a), (&ty::Infer(_), _) | (_, &ty::Infer(_)) => { - Err(TypeError::Sorts(ExpectedFound::new(true, a, b))) + Err(TypeError::Sorts(ExpectedFound::new(a, b))) } (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(Ty::new_error(self.cx(), guar)), @@ -95,7 +95,7 @@ impl<'tcx> TypeRelation> for MatchAgainstFreshVars<'tcx> { } (ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => { - return Err(TypeError::ConstMismatch(ExpectedFound::new(true, a, b))); + return Err(TypeError::ConstMismatch(ExpectedFound::new(a, b))); } _ => {} 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 345e1cc31f32b..32b4567aba4f0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -91,14 +91,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } else if tcx.is_lang_item(def_id, LangItem::Sized) { // Sized is never implementable by end-users, it is // always automatically computed. - - // FIXME: Consider moving this check to the top level as it - // may also be useful for predicates other than `Sized` - // Error type cannot possibly implement `Sized` (fixes #123154) - if let Err(e) = obligation.predicate.skip_binder().self_ty().error_reported() { - return Err(SelectionError::Overflow(e.into())); - } - let sized_conditions = self.sized_conditions(obligation); self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates); } else if tcx.is_lang_item(def_id, LangItem::Unsize) { @@ -230,13 +222,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result<(), SelectionError<'tcx>> { debug!(?stack.obligation); - // An error type will unify with anything. So, avoid - // matching an error type with `ParamCandidate`. - // This helps us avoid spurious errors like issue #121941. - if stack.obligation.predicate.references_error() { - return Ok(()); - } - let bounds = stack .obligation .param_env @@ -563,19 +548,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - // Essentially any user-written impl will match with an error type, - // so creating `ImplCandidates` isn't useful. However, we might - // end up finding a candidate elsewhere (e.g. a `BuiltinCandidate` for `Sized`) - // This helps us avoid overflow: see issue #72839 - // Since compilation is already guaranteed to fail, this is just - // to try to show the 'nicest' possible errors to the user. - // We don't check for errors in the `ParamEnv` - in practice, - // it seems to cause us to be overly aggressive in deciding - // to give up searching for candidates, leading to spurious errors. - if obligation.predicate.references_error() { - return; - } - let drcx = DeepRejectCtxt::relate_rigid_infer(self.tcx()); let obligation_args = obligation.predicate.skip_binder().trait_ref.args; self.tcx().for_each_relevant_impl( @@ -788,9 +760,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // // Note that this is only sound as projection candidates of opaque types // are always applicable for auto traits. - } else if let TypingMode::Coherence = - self.infcx.typing_mode(obligation.param_env) - { + } else if let TypingMode::Coherence = self.infcx.typing_mode() { // We do not emit auto trait candidates for opaque types in coherence. // Doing so can result in weird dependency cycles. candidates.ambiguous = true; @@ -933,7 +903,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // // FIXME(@lcnr): This should probably only trigger during analysis, // disabling candidates during codegen is also questionable. - if let TypingMode::Coherence = self.infcx.typing_mode(param_env) { + if let TypingMode::Coherence = self.infcx.typing_mode() { return None; } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 5b4e895189b0e..50c4f9eff6ff8 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -25,6 +25,7 @@ use rustc_middle::dep_graph::{DepNodeIndex, dep_kinds}; pub use rustc_middle::traits::select::*; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::TypeErrorToStringExt; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; use rustc_middle::ty::{ self, GenericArgsRef, PolyProjectionPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, @@ -222,7 +223,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Enables tracking of intercrate ambiguity causes. See /// the documentation of [`Self::intercrate_ambiguity_causes`] for more. pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) { - assert_matches!(self.infcx.typing_mode_unchecked(), TypingMode::Coherence); + assert_matches!(self.infcx.typing_mode(), TypingMode::Coherence); assert!(self.intercrate_ambiguity_causes.is_none()); self.intercrate_ambiguity_causes = Some(FxIndexSet::default()); debug!("selcx: enable_tracking_intercrate_ambiguity_causes"); @@ -234,7 +235,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { pub fn take_intercrate_ambiguity_causes( &mut self, ) -> FxIndexSet> { - assert_matches!(self.infcx.typing_mode_unchecked(), TypingMode::Coherence); + assert_matches!(self.infcx.typing_mode(), TypingMode::Coherence); self.intercrate_ambiguity_causes.take().unwrap_or_default() } @@ -1027,7 +1028,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { previous_stack: TraitObligationStackList<'o, 'tcx>, mut obligation: PolyTraitObligation<'tcx>, ) -> Result { - if !matches!(self.infcx.typing_mode(obligation.param_env), TypingMode::Coherence) + if !matches!(self.infcx.typing_mode(), TypingMode::Coherence) && obligation.is_global() && obligation.param_env.caller_bounds().iter().all(|bound| bound.has_param()) { @@ -1310,13 +1311,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { param_env: ty::ParamEnv<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> Option { - let tcx = self.tcx(); + let infcx = self.infcx; + let tcx = infcx.tcx; if self.can_use_global_caches(param_env, trait_pred) { - if let Some(res) = tcx.evaluation_cache.get(&(param_env, trait_pred), tcx) { - return Some(res); + let key = (infcx.typing_env(param_env), trait_pred); + if let Some(res) = tcx.evaluation_cache.get(&key, tcx) { + Some(res) + } else { + debug_assert_eq!(infcx.evaluation_cache.get(&(param_env, trait_pred), tcx), None); + None } + } else { + self.infcx.evaluation_cache.get(&(param_env, trait_pred), tcx) } - self.infcx.evaluation_cache.get(&(param_env, trait_pred), tcx) } fn insert_evaluation_cache( @@ -1332,18 +1339,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return; } - if self.can_use_global_caches(param_env, trait_pred) && !trait_pred.has_infer() { + let infcx = self.infcx; + let tcx = infcx.tcx; + if self.can_use_global_caches(param_env, trait_pred) { debug!(?trait_pred, ?result, "insert_evaluation_cache global"); // This may overwrite the cache with the same value - // FIXME: Due to #50507 this overwrites the different values - // This should be changed to use HashMapExt::insert_same - // when that is fixed - self.tcx().evaluation_cache.insert((param_env, trait_pred), dep_node, result); + tcx.evaluation_cache.insert( + (infcx.typing_env(param_env), trait_pred), + dep_node, + result, + ); return; + } else { + debug!(?trait_pred, ?result, "insert_evaluation_cache local"); + self.infcx.evaluation_cache.insert((param_env, trait_pred), dep_node, result); } - - debug!(?trait_pred, ?result, "insert_evaluation_cache"); - self.infcx.evaluation_cache.insert((param_env, trait_pred), dep_node, result); } fn check_recursion_depth( @@ -1459,9 +1469,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> { let obligation = &stack.obligation; - match self.infcx.typing_mode(obligation.param_env) { + match self.infcx.typing_mode() { TypingMode::Coherence => {} - TypingMode::Analysis { .. } | TypingMode::PostAnalysis => return Ok(()), + TypingMode::Analysis { .. } + | TypingMode::PostBorrowckAnalysis { .. } + | TypingMode::PostAnalysis => return Ok(()), } debug!("is_knowable()"); @@ -1485,11 +1497,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // If there are any inference variables in the `ParamEnv`, then we // always use a cache local to this particular scope. Otherwise, we // switch to a global cache. - if param_env.has_infer() { + if param_env.has_infer() || pred.has_infer() { return false; } - match self.infcx.typing_mode(param_env) { + match self.infcx.typing_mode() { // Avoid using the global cache during coherence and just rely // on the local cache. It is really just a simplification to // avoid us having to fear that coherence results "pollute" @@ -1508,6 +1520,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { TypingMode::Analysis { defining_opaque_types } => { defining_opaque_types.is_empty() || !pred.has_opaque_types() } + // The hidden types of `defined_opaque_types` is not local to the current + // inference context, so we can freely move this to the global cache. + TypingMode::PostBorrowckAnalysis { .. } => true, // The global cache is only used if there are no opaque types in // the defining scope or we're outside of analysis. // @@ -1522,15 +1537,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { param_env: ty::ParamEnv<'tcx>, cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> Option>> { - let tcx = self.tcx(); + let infcx = self.infcx; + let tcx = infcx.tcx; let pred = cache_fresh_trait_pred.skip_binder(); if self.can_use_global_caches(param_env, cache_fresh_trait_pred) { - if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) { - return Some(res); + if let Some(res) = tcx.selection_cache.get(&(infcx.typing_env(param_env), pred), tcx) { + Some(res) + } else { + debug_assert_eq!(infcx.selection_cache.get(&(param_env, pred), tcx), None); + None } + } else { + infcx.selection_cache.get(&(param_env, pred), tcx) } - self.infcx.selection_cache.get(&(param_env, pred), tcx) } /// Determines whether can we safely cache the result @@ -1567,7 +1587,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { dep_node: DepNodeIndex, candidate: SelectionResult<'tcx, SelectionCandidate<'tcx>>, ) { - let tcx = self.tcx(); + let infcx = self.infcx; + let tcx = infcx.tcx; let pred = cache_fresh_trait_pred.skip_binder(); if !self.can_cache_candidate(&candidate) { @@ -1578,10 +1599,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if self.can_use_global_caches(param_env, cache_fresh_trait_pred) { if let Err(Overflow(OverflowError::Canonical)) = candidate { // Don't cache overflow globally; we only produce this in certain modes. - } else if !pred.has_infer() && !candidate.has_infer() { + } else { debug!(?pred, ?candidate, "insert_candidate_cache global"); + debug_assert!(!candidate.has_infer()); + // This may overwrite the cache with the same value. - tcx.selection_cache.insert((param_env, pred), dep_node, candidate); + tcx.selection_cache.insert( + (infcx.typing_env(param_env), pred), + dep_node, + candidate, + ); return; } } @@ -2487,10 +2514,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let impl_args = self.infcx.fresh_args_for_item(obligation.cause.span, impl_def_id); let trait_ref = impl_trait_header.trait_ref.instantiate(self.tcx(), impl_args); - if trait_ref.references_error() { - return Err(()); - } - debug!(?impl_trait_header); let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } = @@ -2522,7 +2545,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { nested_obligations.extend(obligations); if impl_trait_header.polarity == ty::ImplPolarity::Reservation - && !matches!(self.infcx.typing_mode(obligation.param_env), TypingMode::Coherence) + && !matches!(self.infcx.typing_mode(), TypingMode::Coherence) { debug!("reservation impls only apply in intercrate mode"); return Err(()); @@ -3192,7 +3215,7 @@ fn bind_coroutine_hidden_types_above<'tcx>( // Only remap erased regions if we use them. if considering_regions { bty = bty.map_bound(|ty| { - tcx.fold_regions(ty, |r, current_depth| match r.kind() { + fold_regions(tcx, ty, |r, current_depth| match r.kind() { ty::ReErased => { let br = ty::BoundRegion { var: ty::BoundVar::from_u32(counter), diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 5bf3dbcbc3273..a9cd705465e3a 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -15,24 +15,24 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::codes::*; use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_infer::infer::DefineOpaqueTypes; use rustc_middle::bug; use rustc_middle::query::LocalCrate; use rustc_middle::ty::print::PrintTraitRefExt as _; -use rustc_middle::ty::{ - self, GenericArgsRef, ImplSubject, Ty, TyCtxt, TypeVisitableExt, TypingMode, -}; +use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode}; use rustc_session::lint::builtin::{COHERENCE_LEAK_CHECK, ORDER_DEPENDENT_TRAIT_OBJECTS}; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, sym}; +use rustc_type_ir::solve::NoSolution; use specialization_graph::GraphExt; use tracing::{debug, instrument}; -use super::{SelectionContext, util}; use crate::error_reporting::traits::to_pretty_impl_header; use crate::errors::NegativePositiveConflict; -use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt}; +use crate::infer::{InferCtxt, TyCtxtInferExt}; use crate::traits::select::IntercrateAmbiguityCause; -use crate::traits::{FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt, coherence}; +use crate::traits::{ + FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt, coherence, + predicates_for_generics, +}; /// Information pertinent to an overlapping impl error. #[derive(Debug)] @@ -87,9 +87,14 @@ pub fn translate_args<'tcx>( source_args: GenericArgsRef<'tcx>, target_node: specialization_graph::Node, ) -> GenericArgsRef<'tcx> { - translate_args_with_cause(infcx, param_env, source_impl, source_args, target_node, |_, _| { - ObligationCause::dummy() - }) + translate_args_with_cause( + infcx, + param_env, + source_impl, + source_args, + target_node, + &ObligationCause::dummy(), + ) } /// Like [translate_args], but obligations from the parent implementation @@ -104,7 +109,7 @@ pub fn translate_args_with_cause<'tcx>( source_impl: DefId, source_args: GenericArgsRef<'tcx>, target_node: specialization_graph::Node, - cause: impl Fn(usize, Span) -> ObligationCause<'tcx>, + cause: &ObligationCause<'tcx>, ) -> GenericArgsRef<'tcx> { debug!( "translate_args({:?}, {:?}, {:?}, {:?})", @@ -123,7 +128,7 @@ pub fn translate_args_with_cause<'tcx>( } fulfill_implication(infcx, param_env, source_trait_ref, source_impl, target_impl, cause) - .unwrap_or_else(|()| { + .unwrap_or_else(|_| { bug!( "When translating generic parameters from {source_impl:?} to \ {target_impl:?}, the expected specialization failed to hold" @@ -137,6 +142,84 @@ pub fn translate_args_with_cause<'tcx>( source_args.rebase_onto(infcx.tcx, source_impl, target_args) } +/// Attempt to fulfill all obligations of `target_impl` after unification with +/// `source_trait_ref`. If successful, returns the generic parameters for *all* the +/// generics of `target_impl`, including both those needed to unify with +/// `source_trait_ref` and those whose identity is determined via a where +/// clause in the impl. +fn fulfill_implication<'tcx>( + infcx: &InferCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + source_trait_ref: ty::TraitRef<'tcx>, + source_impl: DefId, + target_impl: DefId, + cause: &ObligationCause<'tcx>, +) -> Result, NoSolution> { + debug!( + "fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)", + param_env, source_trait_ref, target_impl + ); + + let ocx = ObligationCtxt::new(infcx); + let source_trait_ref = ocx.normalize(cause, param_env, source_trait_ref); + + if !ocx.select_all_or_error().is_empty() { + infcx.dcx().span_delayed_bug( + infcx.tcx.def_span(source_impl), + format!("failed to fully normalize {source_trait_ref}"), + ); + return Err(NoSolution); + } + + let target_args = infcx.fresh_args_for_item(DUMMY_SP, target_impl); + let target_trait_ref = ocx.normalize( + cause, + param_env, + infcx + .tcx + .impl_trait_ref(target_impl) + .expect("expected source impl to be a trait impl") + .instantiate(infcx.tcx, target_args), + ); + + // do the impls unify? If not, no specialization. + ocx.eq(cause, param_env, source_trait_ref, target_trait_ref)?; + + // Now check that the source trait ref satisfies all the where clauses of the target impl. + // This is not just for correctness; we also need this to constrain any params that may + // only be referenced via projection predicates. + let predicates = ocx.normalize( + cause, + param_env, + infcx.tcx.predicates_of(target_impl).instantiate(infcx.tcx, target_args), + ); + let obligations = predicates_for_generics(|_, _| cause.clone(), param_env, predicates); + ocx.register_obligations(obligations); + + let errors = ocx.select_all_or_error(); + if !errors.is_empty() { + // no dice! + debug!( + "fulfill_implication: for impls on {:?} and {:?}, \ + could not fulfill: {:?} given {:?}", + source_trait_ref, + target_trait_ref, + errors, + param_env.caller_bounds() + ); + return Err(NoSolution); + } + + debug!( + "fulfill_implication: an impl for {:?} specializes {:?}", + source_trait_ref, target_trait_ref + ); + + // Now resolve the *generic parameters* we built for the target earlier, replacing + // the inference variables inside with whatever we got from fulfillment. + Ok(infcx.resolve_vars_if_possible(target_args)) +} + pub(super) fn specialization_enabled_in(tcx: TyCtxt<'_>, _: LocalCrate) -> bool { tcx.features().specialization() || tcx.features().min_specialization() } @@ -182,8 +265,9 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, return false; } - // create a parameter environment corresponding to a (placeholder) instantiation of impl1 - let penv = tcx.param_env(impl1_def_id); + // create a parameter environment corresponding to an identity instantiation of impl1, + // i.e. the most generic instantiation of impl1. + let param_env = tcx.param_env(impl1_def_id); // Create an infcx, taking the predicates of impl1 as assumptions: let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); @@ -191,90 +275,15 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, // Attempt to prove that impl2 applies, given all of the above. fulfill_implication( &infcx, - penv, + param_env, impl1_trait_header.trait_ref.instantiate_identity(), impl1_def_id, impl2_def_id, - |_, _| ObligationCause::dummy(), + &ObligationCause::dummy(), ) .is_ok() } -/// Attempt to fulfill all obligations of `target_impl` after unification with -/// `source_trait_ref`. If successful, returns the generic parameters for *all* the -/// generics of `target_impl`, including both those needed to unify with -/// `source_trait_ref` and those whose identity is determined via a where -/// clause in the impl. -fn fulfill_implication<'tcx>( - infcx: &InferCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - source_trait_ref: ty::TraitRef<'tcx>, - source_impl: DefId, - target_impl: DefId, - error_cause: impl Fn(usize, Span) -> ObligationCause<'tcx>, -) -> Result, ()> { - debug!( - "fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)", - param_env, source_trait_ref, target_impl - ); - - let ocx = ObligationCtxt::new(infcx); - let source_trait_ref = ocx.normalize(&ObligationCause::dummy(), param_env, source_trait_ref); - - if !ocx.select_all_or_error().is_empty() { - infcx.dcx().span_delayed_bug( - infcx.tcx.def_span(source_impl), - format!("failed to fully normalize {source_trait_ref}"), - ); - } - - let source_trait_ref = infcx.resolve_vars_if_possible(source_trait_ref); - let source_trait = ImplSubject::Trait(source_trait_ref); - - let selcx = SelectionContext::new(infcx); - let target_args = infcx.fresh_args_for_item(DUMMY_SP, target_impl); - let (target_trait, obligations) = - util::impl_subject_and_oblig(&selcx, param_env, target_impl, target_args, error_cause); - - // do the impls unify? If not, no specialization. - let Ok(InferOk { obligations: more_obligations, .. }) = infcx - .at(&ObligationCause::dummy(), param_env) - // Ok to use `Yes`, as all the generic params are already replaced by inference variables, - // which will match the opaque type no matter if it is defining or not. - // Any concrete type that would match the opaque would already be handled by coherence rules, - // and thus either be ok to match here and already have errored, or it won't match, in which - // case there is no issue anyway. - .eq(DefineOpaqueTypes::Yes, source_trait, target_trait) - else { - debug!("fulfill_implication: {:?} does not unify with {:?}", source_trait, target_trait); - return Err(()); - }; - - // attempt to prove all of the predicates for impl2 given those for impl1 - // (which are packed up in penv) - ocx.register_obligations(obligations.chain(more_obligations)); - - let errors = ocx.select_all_or_error(); - if !errors.is_empty() { - // no dice! - debug!( - "fulfill_implication: for impls on {:?} and {:?}, \ - could not fulfill: {:?} given {:?}", - source_trait, - target_trait, - errors, - param_env.caller_bounds() - ); - return Err(()); - } - - debug!("fulfill_implication: an impl for {:?} specializes {:?}", source_trait, target_trait); - - // Now resolve the *generic parameters* we built for the target earlier, replacing - // the inference variables inside with whatever we got from fulfillment. - Ok(infcx.resolve_vars_if_possible(target_args)) -} - /// Query provider for `specialization_graph_of`. pub(super) fn specialization_graph_provider( tcx: TyCtxt<'_>, diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index b7a2f20b769d2..da1045b664afc 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -3,19 +3,16 @@ use std::collections::BTreeMap; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Diag; use rustc_hir::def_id::DefId; -use rustc_infer::infer::{InferCtxt, InferOk}; +use rustc_infer::infer::InferCtxt; pub use rustc_infer::traits::util::*; use rustc_middle::bug; use rustc_middle::ty::{ - self, GenericArgsRef, ImplSubject, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeVisitableExt, Upcast, + self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, Upcast, }; use rustc_span::Span; use smallvec::{SmallVec, smallvec}; use tracing::debug; -use super::{NormalizeExt, ObligationCause, PredicateObligation, SelectionContext}; - /////////////////////////////////////////////////////////////////////////// // `TraitAliasExpander` iterator /////////////////////////////////////////////////////////////////////////// @@ -166,34 +163,6 @@ impl<'tcx> Iterator for TraitAliasExpander<'tcx> { // Other /////////////////////////////////////////////////////////////////////////// -/// Instantiate all bound parameters of the impl subject with the given args, -/// returning the resulting subject and all obligations that arise. -/// The obligations are closed under normalization. -pub(crate) fn impl_subject_and_oblig<'a, 'tcx>( - selcx: &SelectionContext<'a, 'tcx>, - param_env: ty::ParamEnv<'tcx>, - impl_def_id: DefId, - impl_args: GenericArgsRef<'tcx>, - cause: impl Fn(usize, Span) -> ObligationCause<'tcx>, -) -> (ImplSubject<'tcx>, impl Iterator>) { - let subject = selcx.tcx().impl_subject(impl_def_id); - let subject = subject.instantiate(selcx.tcx(), impl_args); - - let InferOk { value: subject, obligations: normalization_obligations1 } = - selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(subject); - - let predicates = selcx.tcx().predicates_of(impl_def_id); - let predicates = predicates.instantiate(selcx.tcx(), impl_args); - let InferOk { value: predicates, obligations: normalization_obligations2 } = - selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(predicates); - let impl_obligations = super::predicates_for_generics(cause, param_env, predicates); - - let impl_obligations = - impl_obligations.chain(normalization_obligations1).chain(normalization_obligations2); - - (subject, impl_obligations) -} - /// Casts a trait reference into a reference to one of its super /// traits; returns `None` if `target_trait_def_id` is not a /// supertrait. diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 437343b569c4f..c95b1641d1ffe 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -963,30 +963,7 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { /// bounds that must hold on the elided self type. These are derived /// from the declarations of `SomeTrait`, `Send`, and friends -- if /// they declare `trait SomeTrait : 'static`, for example, then -/// `'static` would appear in the list. The hard work is done by -/// `infer::required_region_bounds`, see that for more information. -pub fn object_region_bounds<'tcx>( - tcx: TyCtxt<'tcx>, - existential_predicates: &'tcx ty::List>, -) -> Vec> { - let predicates = existential_predicates.iter().filter_map(|predicate| { - if let ty::ExistentialPredicate::Projection(_) = predicate.skip_binder() { - None - } else { - Some(predicate.with_self_ty(tcx, tcx.types.trait_object_dummy_self)) - } - }); - - required_region_bounds(tcx, tcx.types.trait_object_dummy_self, predicates) -} - -/// Given a set of predicates that apply to an object type, returns -/// the region bounds that the (erased) `Self` type must -/// outlive. Precisely *because* the `Self` type is erased, the -/// parameter `erased_self_ty` must be supplied to indicate what type -/// has been used to represent `Self` in the predicates -/// themselves. This should really be a unique type; `FreshTy(0)` is a -/// popular choice. +/// `'static` would appear in the list. /// /// N.B., in some cases, particularly around higher-ranked bounds, /// this function returns a kind of conservative approximation. @@ -996,13 +973,14 @@ pub fn object_region_bounds<'tcx>( /// /// Requires that trait definitions have been processed so that we can /// elaborate predicates and walk supertraits. -#[instrument(skip(tcx, predicates), level = "debug", ret)] -pub(crate) fn required_region_bounds<'tcx>( +pub fn object_region_bounds<'tcx>( tcx: TyCtxt<'tcx>, - erased_self_ty: Ty<'tcx>, - predicates: impl Iterator>, + existential_predicates: &'tcx ty::List>, ) -> Vec> { - assert!(!erased_self_ty.has_escaping_bound_vars()); + let erased_self_ty = tcx.types.trait_object_dummy_self; + + let predicates = + existential_predicates.iter().map(|predicate| predicate.with_self_ty(tcx, erased_self_ty)); traits::elaborate(tcx, predicates) .filter_map(|pred| { diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 57225df0819d8..e5276e6d51585 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -74,12 +74,21 @@ pub(crate) fn codegen_select_candidate<'tcx>( } let impl_source = infcx.resolve_vars_if_possible(impl_source); - let impl_source = infcx.tcx.erase_regions(impl_source); - if impl_source.has_infer() { - // Unused lifetimes on an impl get replaced with inference vars, but never resolved, - // causing the return value of a query to contain inference vars. We do not have a concept - // for this and will in fact ICE in stable hashing of the return value. So bail out instead. - infcx.tcx.dcx().has_errors().unwrap(); + let impl_source = tcx.erase_regions(impl_source); + if impl_source.has_non_region_infer() { + // Unused generic types or consts on an impl get replaced with inference vars, + // but never resolved, causing the return value of a query to contain inference + // vars. We do not have a concept for this and will in fact ICE in stable hashing + // of the return value. So bail out instead. + match impl_source { + ImplSource::UserDefined(impl_) => { + tcx.dcx().span_delayed_bug( + tcx.def_span(impl_.impl_def_id), + "this impl has unconstrained generic parameters", + ); + } + _ => unreachable!(), + } return Err(CodegenObligationError::FulfillmentError); } diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 5cd10e9053872..c4637f1293cb7 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -6,6 +6,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::bug; use rustc_middle::query::Providers; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; @@ -86,7 +87,8 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' } } // FIXME: This could use a real folder, I guess. - let remapped_wf_tys = tcx.fold_regions( + let remapped_wf_tys = fold_regions( + tcx, tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(), |region, _| { // If `region` is a `ReLateParam` that is captured by the diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 29fc92e1f2f92..1a98c85bee9fb 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -133,8 +133,10 @@ fn resolve_associated_item<'tcx>( bug!("{:?} not found in {:?}", trait_item_id, impl_data.impl_def_id); }); - // Since this is a trait item, we need to see if the item is either a trait default item - // or a specialization because we can't resolve those unless we can `Reveal::All`. + // Since this is a trait item, we need to see if the item is either a trait + // default item or a specialization because we can't resolve those until we're + // in `TypingMode::PostAnalysis`. + // // NOTE: This should be kept in sync with the similar code in // `rustc_trait_selection::traits::project::assemble_candidates_from_impls()`. let eligible = if leaf_def.is_final() { @@ -147,7 +149,8 @@ fn resolve_associated_item<'tcx>( // get a result which isn't correct for all monomorphizations. match typing_env.typing_mode { ty::TypingMode::Coherence - | ty::TypingMode::Analysis { defining_opaque_types: _ } => false, + | ty::TypingMode::Analysis { .. } + | ty::TypingMode::PostBorrowckAnalysis { .. } => false, ty::TypingMode::PostAnalysis => !trait_ref.still_further_specializable(), } }; @@ -155,7 +158,7 @@ fn resolve_associated_item<'tcx>( return Ok(None); } - let typing_env = typing_env.with_reveal_all_normalized(tcx); + let typing_env = typing_env.with_post_analysis_normalized(tcx); let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); let args = rcvr_args.rebase_onto(tcx, trait_def_id, impl_data.args); let args = translate_args( diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 092e140a60098..66134b81b2a2c 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -46,10 +46,10 @@ fn layout_of<'tcx>( let PseudoCanonicalInput { typing_env, value: ty } = query; debug!(?ty); - // Optimization: We convert to RevealAll and convert opaque types in the where bounds - // to their hidden types. This reduces overall uncached invocations of `layout_of` and - // is thus a small performance improvement. - let typing_env = typing_env.with_reveal_all_normalized(tcx); + // Optimization: We convert to TypingMode::PostAnalysis and convert opaque types in + // the where bounds to their hidden types. This reduces overall uncached invocations + // of `layout_of` and is thus a small performance improvement. + let typing_env = typing_env.with_post_analysis_normalized(tcx); let unnormalized_ty = ty; // FIXME: We might want to have two different versions of `layout_of`: diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 469a4ac3e414d..d85da7d355e6f 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -431,13 +431,13 @@ fn adt_significant_drop_tys( #[instrument(level = "debug", skip(tcx), ret)] fn list_significant_drop_tys<'tcx>( tcx: TyCtxt<'tcx>, - ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, + key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>, ) -> &'tcx ty::List> { tcx.mk_type_list( &drop_tys_helper( tcx, - ty.value, - ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: ty.param_env }, + key.value, + key.typing_env, adt_consider_insignificant_dtor(tcx), true, true, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 2127ba8a42321..774f066025882 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -5,9 +5,9 @@ use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; use rustc_middle::bug; use rustc_middle::query::Providers; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::{ - self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, - TypeVisitor, Upcast, + self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, }; use rustc_span::DUMMY_SP; use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; @@ -95,9 +95,6 @@ fn adt_sized_constraint<'tcx>( let tail_ty = tcx.type_of(tail_def.did).instantiate_identity(); let constraint_ty = sized_constraint_for_ty(tcx, tail_ty)?; - if let Err(guar) = constraint_ty.error_reported() { - return Some(ty::EarlyBinder::bind(Ty::new_error(tcx, guar))); - } // perf hack: if there is a `constraint_ty: Sized` bound, then we know // that the type is sized and do not need to check it on the impl. @@ -162,8 +159,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { let local_did = def_id.as_local(); - let unnormalized_env = - ty::ParamEnv::new(tcx.mk_clauses(&predicates), traits::Reveal::UserFacing); + let unnormalized_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates)); let body_id = local_did.unwrap_or(CRATE_DEF_ID); let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); @@ -202,7 +198,7 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { // We have entered some binders as we've walked into the // bounds of the RPITIT. Shift these binders back out when // constructing the top-level projection predicate. - let shifted_alias_ty = self.tcx.fold_regions(unshifted_alias_ty, |re, depth| { + let shifted_alias_ty = fold_regions(self.tcx, unshifted_alias_ty, |re, depth| { if let ty::ReBound(index, bv) = re.kind() { if depth != ty::INNERMOST { return ty::Region::new_error_with_message( @@ -253,8 +249,10 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { } } -fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { - tcx.param_env(def_id).with_reveal_all_normalized(tcx) +fn param_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { + // This is a bit ugly but the easiest way to avoid code duplication. + let typing_env = ty::TypingEnv::non_body_analysis(tcx, def_id); + typing_env.with_post_analysis_normalized(tcx).param_env } /// If the given trait impl enables exploiting the former order dependence of trait objects, @@ -366,7 +364,7 @@ pub(crate) fn provide(providers: &mut Providers) { asyncness, adt_sized_constraint, param_env, - param_env_reveal_all_normalized, + param_env_normalized_for_post_analysis, self_ty_of_trait_impl_enabling_order_dep_trait_object_hack, defaultness, unsizing_params_for_adt, diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs index 2c1ad9de9aa8b..0d574445df80d 100644 --- a/compiler/rustc_type_ir/src/elaborate.rs +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -45,14 +45,12 @@ pub trait Elaboratable { pub struct ClauseWithSupertraitSpan { pub pred: I::Predicate, - // Span of the original elaborated predicate. - pub original_span: I::Span, // Span of the supertrait predicatae that lead to this clause. pub supertrait_span: I::Span, } impl ClauseWithSupertraitSpan { pub fn new(pred: I::Predicate, span: I::Span) -> Self { - ClauseWithSupertraitSpan { pred, original_span: span, supertrait_span: span } + ClauseWithSupertraitSpan { pred, supertrait_span: span } } } impl Elaboratable for ClauseWithSupertraitSpan { @@ -63,7 +61,6 @@ impl Elaboratable for ClauseWithSupertraitSpan { fn child(&self, clause: ::Clause) -> Self { ClauseWithSupertraitSpan { pred: clause.as_predicate(), - original_span: self.original_span, supertrait_span: self.supertrait_span, } } @@ -75,11 +72,7 @@ impl Elaboratable for ClauseWithSupertraitSpan { _parent_trait_pred: crate::Binder>, _index: usize, ) -> Self { - ClauseWithSupertraitSpan { - pred: clause.as_predicate(), - original_span: self.original_span, - supertrait_span: supertrait_span, - } + ClauseWithSupertraitSpan { pred: clause.as_predicate(), supertrait_span: supertrait_span } } } diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs index cdff77f742d0a..55671b84dbc4f 100644 --- a/compiler/rustc_type_ir/src/error.rs +++ b/compiler/rustc_type_ir/src/error.rs @@ -12,12 +12,8 @@ pub struct ExpectedFound { } impl ExpectedFound { - pub fn new(a_is_expected: bool, a: T, b: T) -> Self { - if a_is_expected { - ExpectedFound { expected: a, found: b } - } else { - ExpectedFound { expected: b, found: a } - } + pub fn new(expected: T, found: T) -> Self { + ExpectedFound { expected, found } } } @@ -33,7 +29,7 @@ pub enum TypeError { Mutability, ArgumentMutability(usize), TupleSize(ExpectedFound), - FixedArraySize(ExpectedFound), + ArraySize(ExpectedFound), ArgCount, RegionsDoesNotOutlive(I::Region, I::Region), @@ -73,7 +69,7 @@ impl TypeError { use self::TypeError::*; match self { CyclicTy(_) | CyclicConst(_) | SafetyMismatch(_) | PolarityMismatch(_) | Mismatch - | AbiMismatch(_) | FixedArraySize(_) | ArgumentSorts(..) | Sorts(_) + | AbiMismatch(_) | ArraySize(_) | ArgumentSorts(..) | Sorts(_) | VariadicMismatch(_) | TargetFeatureCast(_) => false, Mutability diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 8209d6f5fe3b1..d337a1a8ad9b7 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -49,7 +49,7 @@ use std::mem; use rustc_index::{Idx, IndexVec}; use thin_vec::ThinVec; -use tracing::instrument; +use tracing::{debug, instrument}; use crate::data_structures::Lrc; use crate::inherent::*; @@ -431,3 +431,75 @@ where value.fold_with(&mut Shifter::new(cx, amount)) } } + +/////////////////////////////////////////////////////////////////////////// +// Region folder + +pub fn fold_regions( + cx: I, + value: T, + mut f: impl FnMut(I::Region, ty::DebruijnIndex) -> I::Region, +) -> T +where + T: TypeFoldable, +{ + value.fold_with(&mut RegionFolder::new(cx, &mut f)) +} + +/// Folds over the substructure of a type, visiting its component +/// types and all regions that occur *free* within it. +/// +/// That is, function pointer types and trait object can introduce +/// new bound regions which are not visited by this visitors as +/// they are not free; only regions that occur free will be +/// visited by `fld_r`. +pub struct RegionFolder<'a, I: Interner> { + cx: I, + + /// Stores the index of a binder *just outside* the stuff we have + /// visited. So this begins as INNERMOST; when we pass through a + /// binder, it is incremented (via `shift_in`). + current_index: ty::DebruijnIndex, + + /// Callback invokes for each free region. The `DebruijnIndex` + /// points to the binder *just outside* the ones we have passed + /// through. + fold_region_fn: &'a mut (dyn FnMut(I::Region, ty::DebruijnIndex) -> I::Region + 'a), +} + +impl<'a, I: Interner> RegionFolder<'a, I> { + #[inline] + pub fn new( + cx: I, + fold_region_fn: &'a mut dyn FnMut(I::Region, ty::DebruijnIndex) -> I::Region, + ) -> RegionFolder<'a, I> { + RegionFolder { cx, current_index: ty::INNERMOST, fold_region_fn } + } +} + +impl<'a, I: Interner> TypeFolder for RegionFolder<'a, I> { + fn cx(&self) -> I { + self.cx + } + + fn fold_binder>(&mut self, t: ty::Binder) -> ty::Binder { + self.current_index.shift_in(1); + let t = t.super_fold_with(self); + self.current_index.shift_out(1); + t + } + + #[instrument(skip(self), level = "debug", ret)] + fn fold_region(&mut self, r: I::Region) -> I::Region { + match r.kind() { + ty::ReBound(debruijn, _) if debruijn < self.current_index => { + debug!(?self.current_index, "skipped bound region"); + r + } + _ => { + debug!(?self.current_index, "folding free region"); + (self.fold_region_fn)(r, self.current_index) + } + } + } +} diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index b01d3dc5269f5..a892b88c2c636 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -39,9 +39,44 @@ pub enum TypingMode { /// /// We only normalize opaque types which may get defined by the current body, /// which are stored in `defining_opaque_types`. + /// + /// We also refuse to project any associated type that is marked `default`. + /// Non-`default` ("final") types are always projected. This is necessary in + /// general for soundness of specialization. However, we *could* allow projections + /// in fully-monomorphic cases. We choose not to, because we prefer for `default type` + /// to force the type definition to be treated abstractly by any consumers of the + /// impl. Concretely, that means that the following example will + /// fail to compile: + /// + /// ```compile_fail,E0308 + /// #![feature(specialization)] + /// trait Assoc { + /// type Output; + /// } + /// + /// impl Assoc for T { + /// default type Output = bool; + /// } + /// + /// fn main() { + /// let x: <() as Assoc>::Output = true; + /// } + /// ``` Analysis { defining_opaque_types: I::DefiningOpaqueTypes }, + /// Any analysis after borrowck for a given body should be able to use all the + /// hidden types defined by borrowck, without being able to define any new ones. + /// + /// This is currently only used by the new solver, but should be implemented in + /// the old solver as well. + PostBorrowckAnalysis { defined_opaque_types: I::DefiningOpaqueTypes }, /// After analysis, mostly during codegen and MIR optimizations, we're able to - /// reveal all opaque types. + /// reveal all opaque types. As the concrete type should *never* be observable + /// directly by the user, this should not be used by checks which may expose + /// such details to the user. + /// + /// There are some exceptions to this as for example `layout_of` and const-evaluation + /// always run in `PostAnalysis` mode, even when used during analysis. This exposes + /// some information about the underlying type to users, but not the type itself. PostAnalysis, } @@ -56,6 +91,12 @@ impl TypingMode { pub fn analysis_in_body(cx: I, body_def_id: I::LocalDefId) -> TypingMode { TypingMode::Analysis { defining_opaque_types: cx.opaque_types_defined_by(body_def_id) } } + + pub fn post_borrowck_analysis(cx: I, body_def_id: I::LocalDefId) -> TypingMode { + TypingMode::PostBorrowckAnalysis { + defined_opaque_types: cx.opaque_types_defined_by(body_def_id), + } + } } pub trait InferCtxtLike: Sized { @@ -70,10 +111,7 @@ pub trait InferCtxtLike: Sized { true } - fn typing_mode( - &self, - param_env_for_debug_assertion: ::ParamEnv, - ) -> TypingMode; + fn typing_mode(&self) -> TypingMode; fn universe(&self) -> ty::UniverseIndex; fn create_next_universe(&self) -> ty::UniverseIndex; @@ -100,6 +138,7 @@ pub trait InferCtxtLike: Sized { vid: ty::RegionVid, ) -> ::Region; + fn next_region_infer(&self) -> ::Region; fn next_ty_infer(&self) -> ::Ty; fn next_const_infer(&self) -> ::Const; fn fresh_args_for_item( diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 5af1aa2f8faa9..a201f2b1c11f1 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -11,7 +11,7 @@ use rustc_ast_ir::Mutability; use crate::elaborate::Elaboratable; use crate::fold::{TypeFoldable, TypeSuperFoldable}; use crate::relate::Relate; -use crate::solve::Reveal; +use crate::solve::AdtDestructorKind; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; use crate::{self as ty, CollectAndApply, Interner, UpcastFrom}; @@ -257,8 +257,6 @@ pub trait Const>: + Relate + Flags { - fn try_to_target_usize(self, interner: I) -> Option; - fn new_infer(interner: I, var: ty::InferConst) -> Self; fn new_var(interner: I, var: ty::ConstVid) -> Self; @@ -537,11 +535,11 @@ pub trait AdtDef: Copy + Debug + Hash + Eq { fn sized_constraint(self, interner: I) -> Option>; fn is_fundamental(self) -> bool; + + fn destructor(self, interner: I) -> Option; } pub trait ParamEnv: Copy + Debug + Hash + Eq + TypeFoldable { - fn reveal(self) -> Reveal; - fn caller_bounds(self) -> impl IntoIterator; } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 93b9c2e289249..0ae688848ebfc 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -225,6 +225,7 @@ pub trait Interner: fn impl_is_const(self, def_id: Self::DefId) -> bool; fn fn_is_const(self, def_id: Self::DefId) -> bool; + fn alias_has_const_conditions(self, def_id: Self::DefId) -> bool; fn const_conditions( self, def_id: Self::DefId, diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index df43346065d40..eeb80bc3ab420 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -19,6 +19,7 @@ pub enum TraitSolverLangItem { CoroutineYield, Destruct, DiscriminantKind, + Drop, DynMetadata, Fn, FnMut, diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 8a8e624e72a2d..4213ef4803be2 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -444,7 +444,7 @@ pub enum AliasTermKind { /// An associated type in an inherent `impl` InherentTy, /// An opaque type (usually from `impl Trait` in type aliases or function return types) - /// Can only be normalized away in RevealAll mode + /// Can only be normalized away in PostAnalysis mode or its defining scope. OpaqueTy, /// A type alias that actually checks its trait bounds. /// Currently only used if the type alias references opaque types. @@ -684,19 +684,6 @@ impl ty::Binder> { self.skip_binder().projection_term.trait_def_id(cx) } - /// Get the trait ref required for this projection to be well formed. - /// Note that for generic associated types the predicates of the associated - /// type also need to be checked. - #[inline] - pub fn required_poly_trait_ref(&self, cx: I) -> ty::Binder> { - // Note: unlike with `TraitRef::to_poly_trait_ref()`, - // `self.0.trait_ref` is permitted to have escaping regions. - // This is because here `self` has a `Binder` and so does our - // return value, so we are preserving the number of binding - // levels. - self.map_bound(|predicate| predicate.projection_term.trait_ref(cx)) - } - pub fn term(&self) -> ty::Binder { self.map_bound(|predicate| predicate.term) } diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index ad17911830b3d..0b013b2017f12 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -171,16 +171,16 @@ impl Relate for ty::FnSig { return Err(TypeError::VariadicMismatch({ let a = a.c_variadic; let b = b.c_variadic; - ExpectedFound::new(true, a, b) + ExpectedFound::new(a, b) })); } if a.safety != b.safety { - return Err(TypeError::SafetyMismatch(ExpectedFound::new(true, a.safety, b.safety))); + return Err(TypeError::SafetyMismatch(ExpectedFound::new(a.safety, b.safety))); } if a.abi != b.abi { - return Err(TypeError::AbiMismatch(ExpectedFound::new(true, a.abi, b.abi))); + return Err(TypeError::AbiMismatch(ExpectedFound::new(a.abi, b.abi))); }; let a_inputs = a.inputs(); @@ -233,7 +233,7 @@ impl Relate for ty::AliasTy { Err(TypeError::ProjectionMismatched({ let a = a.def_id; let b = b.def_id; - ExpectedFound::new(true, a, b) + ExpectedFound::new(a, b) })) } else { let args = match a.kind(relation.cx()) { @@ -274,7 +274,7 @@ impl Relate for ty::AliasTerm { Err(TypeError::ProjectionMismatched({ let a = a.def_id; let b = b.def_id; - ExpectedFound::new(true, a, b) + ExpectedFound::new(a, b) })) } else { let args = match a.kind(relation.cx()) { @@ -309,7 +309,7 @@ impl Relate for ty::ExistentialProjection { Err(TypeError::ProjectionMismatched({ let a = a.def_id; let b = b.def_id; - ExpectedFound::new(true, a, b) + ExpectedFound::new(a, b) })) } else { let term = relation.relate_with_variance( @@ -340,7 +340,7 @@ impl Relate for ty::TraitRef { Err(TypeError::Traits({ let a = a.def_id; let b = b.def_id; - ExpectedFound::new(true, a, b) + ExpectedFound::new(a, b) })) } else { let args = relate_args_invariantly(relation, a.args, b.args)?; @@ -360,7 +360,7 @@ impl Relate for ty::ExistentialTraitRef { Err(TypeError::Traits({ let a = a.def_id; let b = b.def_id; - ExpectedFound::new(true, a, b) + ExpectedFound::new(a, b) })) } else { let args = relate_args_invariantly(relation, a.args, b.args)?; @@ -501,19 +501,10 @@ pub fn structurally_relate_tys>( let t = relation.relate(a_t, b_t)?; match relation.relate(sz_a, sz_b) { Ok(sz) => Ok(Ty::new_array_with_const_len(cx, t, sz)), - Err(err) => { - // Check whether the lengths are both concrete/known values, - // but are unequal, for better diagnostics. - let sz_a = sz_a.try_to_target_usize(cx); - let sz_b = sz_b.try_to_target_usize(cx); - - match (sz_a, sz_b) { - (Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => Err( - TypeError::FixedArraySize(ExpectedFound::new(true, sz_a_val, sz_b_val)), - ), - _ => Err(err), - } + Err(TypeError::ConstMismatch(_)) => { + Err(TypeError::ArraySize(ExpectedFound::new(sz_a, sz_b))) } + Err(e) => Err(e), } } @@ -529,9 +520,9 @@ pub fn structurally_relate_tys>( iter::zip(as_.iter(), bs.iter()).map(|(a, b)| relation.relate(a, b)), )?) } else if !(as_.is_empty() || bs.is_empty()) { - Err(TypeError::TupleSize(ExpectedFound::new(true, as_.len(), bs.len()))) + Err(TypeError::TupleSize(ExpectedFound::new(as_.len(), bs.len()))) } else { - Err(TypeError::Sorts(ExpectedFound::new(true, a, b))) + Err(TypeError::Sorts(ExpectedFound::new(a, b))) } } @@ -558,7 +549,7 @@ pub fn structurally_relate_tys>( Ok(Ty::new_pat(cx, ty, pat)) } - _ => Err(TypeError::Sorts(ExpectedFound::new(true, a, b))), + _ => Err(TypeError::Sorts(ExpectedFound::new(a, b))), } } @@ -637,7 +628,7 @@ pub fn structurally_relate_consts>( } _ => false, }; - if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(ExpectedFound::new(true, a, b))) } + if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(ExpectedFound::new(a, b))) } } impl> Relate for ty::Binder { @@ -658,9 +649,7 @@ impl Relate for ty::TraitPredicate { ) -> RelateResult> { let trait_ref = relation.relate(a.trait_ref, b.trait_ref)?; if a.polarity != b.polarity { - return Err(TypeError::PolarityMismatch(ExpectedFound::new( - true, a.polarity, b.polarity, - ))); + return Err(TypeError::PolarityMismatch(ExpectedFound::new(a.polarity, b.polarity))); } Ok(ty::TraitPredicate { trait_ref, polarity: a.polarity }) } diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index 53751f7711a71..d49f8d3093db7 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs @@ -123,13 +123,11 @@ where } // All other cases of inference are errors - (ty::Infer(_), _) | (_, ty::Infer(_)) => { - Err(TypeError::Sorts(ExpectedFound::new(true, a, b))) - } + (ty::Infer(_), _) | (_, ty::Infer(_)) => Err(TypeError::Sorts(ExpectedFound::new(a, b))), (ty::Alias(ty::Opaque, _), _) | (_, ty::Alias(ty::Opaque, _)) => { assert!(!infcx.next_trait_solver()); - match infcx.typing_mode(relation.param_env()) { + match infcx.typing_mode() { // During coherence, opaque types should be treated as *possibly* // equal to any other type. This is an // extremely heavy hammer, but can be relaxed in a forwards-compatible @@ -138,9 +136,9 @@ where relation.register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]); Ok(a) } - TypingMode::Analysis { .. } | TypingMode::PostAnalysis => { - structurally_relate_tys(relation, a, b) - } + TypingMode::Analysis { .. } + | TypingMode::PostBorrowckAnalysis { .. } + | TypingMode::PostAnalysis => structurally_relate_tys(relation, a, b), } } diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index fe4558730513a..8fe512026e5d9 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -10,54 +10,6 @@ use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Gen use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast}; -/// Depending on the stage of compilation, we want projection to be -/// more or less conservative. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] -pub enum Reveal { - /// At type-checking time, we refuse to project any associated - /// type that is marked `default`. Non-`default` ("final") types - /// are always projected. This is necessary in general for - /// soundness of specialization. However, we *could* allow - /// projections in fully-monomorphic cases. We choose not to, - /// because we prefer for `default type` to force the type - /// definition to be treated abstractly by any consumers of the - /// impl. Concretely, that means that the following example will - /// fail to compile: - /// - /// ```compile_fail,E0308 - /// #![feature(specialization)] - /// trait Assoc { - /// type Output; - /// } - /// - /// impl Assoc for T { - /// default type Output = bool; - /// } - /// - /// fn main() { - /// let x: <() as Assoc>::Output = true; - /// } - /// ``` - /// - /// We also do not reveal the hidden type of opaque types during - /// type-checking. - UserFacing, - - /// At codegen time, all monomorphic projections will succeed. - /// Also, `impl Trait` is normalized to the concrete type, - /// which has to be already collected by type-checking. - /// - /// NOTE: as `impl Trait`'s concrete type should *never* - /// be observable directly by the user, `Reveal::All` - /// should not be used by checks which may expose - /// type equality or type contents to the user. - /// There are some exceptions, e.g., around auto traits and - /// transmute-checking, which expose some details, but - /// not the whole concrete type of the `impl Trait`. - All, -} - pub type CanonicalInput::Predicate> = ty::CanonicalQueryInput>; pub type CanonicalResponse = Canonical>; @@ -326,3 +278,10 @@ impl MaybeCause { } } } + +/// Indicates that a `impl Drop for Adt` is `const` or not. +#[derive(Debug)] +pub enum AdtDestructorKind { + NotConst, + Const, +} diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 499e6d3dd37d1..033fcdb6c0339 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -41,7 +41,7 @@ pub enum AliasTyKind { /// An associated type in an inherent `impl` Inherent, /// An opaque type (usually from `impl Trait` in type aliases or function return types) - /// Can only be normalized away in RevealAll mode + /// Can only be normalized away in PostAnalysis mode or its defining scope. Opaque, /// A type alias that actually checks its trait bounds. /// Currently only used if the type alias references opaque types. diff --git a/config.example.toml b/config.example.toml index d3233ad17b511..9ec0d77e79b36 100644 --- a/config.example.toml +++ b/config.example.toml @@ -496,15 +496,18 @@ # #debug = false -# Whether to download the stage 1 and 2 compilers from CI. -# This is useful if you are working on tools, doc-comments, or library (you will be able to build -# the standard library without needing to build the compiler). +# Whether to download the stage 1 and 2 compilers from CI. This is useful if you +# are working on tools, doc-comments, or library (you will be able to build the +# standard library without needing to build the compiler). # -# Set this to "if-unchanged" if you are working on `src/tools`, `tests` or `library` (on CI, `library` -# changes triggers in-tree compiler build) to speed up the build process. +# Set this to "if-unchanged" if you are working on `src/tools`, `tests` or +# `library` (on CI, `library` changes triggers in-tree compiler build) to speed +# up the build process if you don't need to build a compiler from the latest +# commit from `master`. # -# Set this to `true` to always download or `false` to always use the in-tree compiler. -#download-rustc = "if-unchanged" +# Set this to `true` to always download or `false` to always use the in-tree +# compiler. +#download-rustc = false # Number of codegen units to use for each compiler invocation. A value of 0 # means "the number of cores on this machine", and 1+ is passed through to the @@ -770,6 +773,7 @@ #validate-mir-opts = 3 # Configure `std` features used during bootstrap. +# # Default features will be expanded in the following cases: # - If `rust.llvm-libunwind` or `target.llvm-libunwind` is enabled: # - "llvm-libunwind" will be added for in-tree LLVM builds. @@ -777,6 +781,9 @@ # - If `rust.backtrace` is enabled, "backtrace" will be added. # - If `rust.profiler` or `target.profiler` is enabled, "profiler" will be added. # - If building for a zkvm target, "compiler-builtins-mem" will be added. +# +# Since libstd also builds libcore and liballoc as dependencies and all their features are mirrored +# as libstd features, this option can also be used to configure features such as optimize_for_size. #std-features = ["panic_unwind"] # ============================================================================= diff --git a/library/Cargo.lock b/library/Cargo.lock index 97996d5f0b258..197e0a8fedb8c 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -42,9 +42,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "cc" -version = "1.1.22" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0" +checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" dependencies = [ "shlex", ] @@ -235,8 +235,6 @@ name = "profiler_builtins" version = "0.0.0" dependencies = [ "cc", - "compiler_builtins", - "core", ] [[package]] diff --git a/library/alloc/benches/lib.rs b/library/alloc/benches/lib.rs index c1907361f93e1..2633154318c13 100644 --- a/library/alloc/benches/lib.rs +++ b/library/alloc/benches/lib.rs @@ -4,8 +4,7 @@ #![feature(iter_next_chunk)] #![feature(repr_simd)] #![feature(slice_partition_dedup)] -#![cfg_attr(bootstrap, feature(strict_provenance))] -#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))] +#![feature(strict_provenance_lints)] #![feature(test)] #![deny(fuzzy_provenance_casts)] diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 98402a4620158..04b7315e650a2 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -61,7 +61,7 @@ pub use std::alloc::Global; /// of the allocator registered with the `#[global_allocator]` attribute /// if there is one, or the `std` crate’s default. /// -/// This function is expected to be deprecated in favor of the `alloc` method +/// This function is expected to be deprecated in favor of the `allocate` method /// of the [`Global`] type when it and the [`Allocator`] trait become stable. /// /// # Safety @@ -106,7 +106,7 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { /// of the allocator registered with the `#[global_allocator]` attribute /// if there is one, or the `std` crate’s default. /// -/// This function is expected to be deprecated in favor of the `dealloc` method +/// This function is expected to be deprecated in favor of the `deallocate` method /// of the [`Global`] type when it and the [`Allocator`] trait become stable. /// /// # Safety @@ -125,7 +125,7 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { /// of the allocator registered with the `#[global_allocator]` attribute /// if there is one, or the `std` crate’s default. /// -/// This function is expected to be deprecated in favor of the `realloc` method +/// This function is expected to be deprecated in favor of the `grow` and `shrink` methods /// of the [`Global`] type when it and the [`Allocator`] trait become stable. /// /// # Safety @@ -145,7 +145,7 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 /// of the allocator registered with the `#[global_allocator]` attribute /// if there is one, or the `std` crate’s default. /// -/// This function is expected to be deprecated in favor of the `alloc_zeroed` method +/// This function is expected to be deprecated in favor of the `allocate_zeroed` method /// of the [`Global`] type when it and the [`Allocator`] trait become stable. /// /// # Safety diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index ee60ec0fbacbe..e0f94428cfa65 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -191,9 +191,7 @@ use core::error::{self, Error}; use core::fmt; use core::future::Future; use core::hash::{Hash, Hasher}; -#[cfg(not(bootstrap))] -use core::marker::PointerLike; -use core::marker::{Tuple, Unsize}; +use core::marker::{PointerLike, Tuple, Unsize}; use core::mem::{self, SizedTypeProperties}; use core::ops::{ AsyncFn, AsyncFnMut, AsyncFnOnce, CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, @@ -227,7 +225,7 @@ pub use thin::ThinBox; #[fundamental] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] -#[cfg_attr(not(bootstrap), doc(search_unbox))] +#[doc(search_unbox)] // The declaration of the `Box` struct must be kept in sync with the // compiler or ICEs will happen. pub struct Box< @@ -1502,7 +1500,7 @@ impl Box { /// [`as_ptr`]: Self::as_ptr #[unstable(feature = "box_as_ptr", issue = "129090")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline] pub fn as_mut_ptr(b: &mut Self) -> *mut T { // This is a primitive deref, not going through `DerefMut`, and therefore not materializing @@ -1551,7 +1549,7 @@ impl Box { /// [`as_ptr`]: Self::as_ptr #[unstable(feature = "box_as_ptr", issue = "129090")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline] pub fn as_ptr(b: &Self) -> *const T { // This is a primitive deref, not going through `DerefMut`, and therefore not materializing @@ -2134,6 +2132,5 @@ impl Error for Box { } } -#[cfg(not(bootstrap))] #[unstable(feature = "pointer_like_trait", issue = "none")] impl PointerLike for Box {} diff --git a/library/alloc/src/boxed/convert.rs b/library/alloc/src/boxed/convert.rs index 4430fff66775c..255cefb1e78fb 100644 --- a/library/alloc/src/boxed/convert.rs +++ b/library/alloc/src/boxed/convert.rs @@ -110,7 +110,7 @@ impl From<&[T]> for Box<[T]> { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "box_from_mut_slice", since = "1.84.0")] impl From<&mut [T]> for Box<[T]> { /// Converts a `&mut [T]` into a `Box<[T]>` /// @@ -171,7 +171,7 @@ impl From<&str> for Box { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "box_from_mut_slice", since = "1.84.0")] impl From<&mut str> for Box { /// Converts a `&mut str` into a `Box` /// diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 59f10b09c73fd..0bc65cdbc55a3 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -452,7 +452,7 @@ impl BinaryHeap { /// /// The binary heap will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the binary heap will not allocate. + /// `capacity`. If `capacity` is zero, the binary heap will not allocate. /// /// # Examples /// @@ -496,7 +496,7 @@ impl BinaryHeap { /// /// The binary heap will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the binary heap will not allocate. + /// `capacity`. If `capacity` is zero, the binary heap will not allocate. /// /// # Examples /// diff --git a/library/alloc/src/collections/btree/map/entry.rs b/library/alloc/src/collections/btree/map/entry.rs index 75bb86916a887..0da6af54bc22b 100644 --- a/library/alloc/src/collections/btree/map/entry.rs +++ b/library/alloc/src/collections/btree/map/entry.rs @@ -269,6 +269,31 @@ impl<'a, K: Ord, V, A: Allocator + Clone> Entry<'a, K, V, A> { Vacant(entry) => Vacant(entry), } } + + /// Sets the value of the entry, and returns an `OccupiedEntry`. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_entry_insert)] + /// use std::collections::BTreeMap; + /// + /// let mut map: BTreeMap<&str, String> = BTreeMap::new(); + /// let entry = map.entry("poneyland").insert_entry("hoho".to_string()); + /// + /// assert_eq!(entry.key(), &"poneyland"); + /// ``` + #[inline] + #[unstable(feature = "btree_entry_insert", issue = "65225")] + pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, A> { + match self { + Occupied(mut entry) => { + entry.insert(value); + entry + } + Vacant(entry) => entry.insert_entry(value), + } + } } impl<'a, K: Ord, V: Default, A: Allocator + Clone> Entry<'a, K, V, A> { @@ -348,41 +373,61 @@ impl<'a, K: Ord, V, A: Allocator + Clone> VacantEntry<'a, K, V, A> { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_confusables("push", "put")] - pub fn insert(mut self, value: V) -> &'a mut V { - let out_ptr = match self.handle { + pub fn insert(self, value: V) -> &'a mut V { + self.insert_entry(value).into_mut() + } + + /// Sets the value of the entry with the `VacantEntry`'s key, + /// and returns an `OccupiedEntry`. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_entry_insert)] + /// use std::collections::BTreeMap; + /// use std::collections::btree_map::Entry; + /// + /// let mut map: BTreeMap<&str, u32> = BTreeMap::new(); + /// + /// if let Entry::Vacant(o) = map.entry("poneyland") { + /// let entry = o.insert_entry(37); + /// assert_eq!(entry.get(), &37); + /// } + /// assert_eq!(map["poneyland"], 37); + /// ``` + #[unstable(feature = "btree_entry_insert", issue = "65225")] + pub fn insert_entry(mut self, value: V) -> OccupiedEntry<'a, K, V, A> { + let handle = match self.handle { None => { // SAFETY: There is no tree yet so no reference to it exists. - let map = unsafe { self.dormant_map.awaken() }; - let mut root = NodeRef::new_leaf(self.alloc.clone()); - let val_ptr = root.borrow_mut().push(self.key, value); - map.root = Some(root.forget_type()); - map.length = 1; - val_ptr - } - Some(handle) => { - let new_handle = - handle.insert_recursing(self.key, value, self.alloc.clone(), |ins| { - drop(ins.left); - // SAFETY: Pushing a new root node doesn't invalidate - // handles to existing nodes. - let map = unsafe { self.dormant_map.reborrow() }; - let root = map.root.as_mut().unwrap(); // same as ins.left - root.push_internal_level(self.alloc).push(ins.kv.0, ins.kv.1, ins.right) - }); - - // Get the pointer to the value - let val_ptr = new_handle.into_val_mut(); - - // SAFETY: We have consumed self.handle. - let map = unsafe { self.dormant_map.awaken() }; - map.length += 1; - val_ptr + let map = unsafe { self.dormant_map.reborrow() }; + let root = map.root.insert(NodeRef::new_leaf(self.alloc.clone()).forget_type()); + // SAFETY: We *just* created the root as a leaf, and we're + // stacking the new handle on the original borrow lifetime. + unsafe { + let mut leaf = root.borrow_mut().cast_to_leaf_unchecked(); + leaf.push_with_handle(self.key, value) + } } + Some(handle) => handle.insert_recursing(self.key, value, self.alloc.clone(), |ins| { + drop(ins.left); + // SAFETY: Pushing a new root node doesn't invalidate + // handles to existing nodes. + let map = unsafe { self.dormant_map.reborrow() }; + let root = map.root.as_mut().unwrap(); // same as ins.left + root.push_internal_level(self.alloc.clone()).push(ins.kv.0, ins.kv.1, ins.right) + }), }; - // Now that we have finished growing the tree using borrowed references, - // dereference the pointer to a part of it, that we picked up along the way. - unsafe { &mut *out_ptr } + // SAFETY: modifying the length doesn't invalidate handles to existing nodes. + unsafe { self.dormant_map.reborrow().length += 1 }; + + OccupiedEntry { + handle: handle.forget_node_type(), + dormant_map: self.dormant_map, + alloc: self.alloc, + _marker: PhantomData, + } } } diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index db16d82be7dcc..5975134382e7d 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -2270,6 +2270,54 @@ fn test_into_iter_drop_leak_height_0() { assert_eq!(e.dropped(), 1); } +#[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn test_into_iter_drop_leak_kv_panic_in_key() { + let a_k = CrashTestDummy::new(0); + let a_v = CrashTestDummy::new(1); + let b_k = CrashTestDummy::new(2); + let b_v = CrashTestDummy::new(3); + let c_k = CrashTestDummy::new(4); + let c_v = CrashTestDummy::new(5); + let mut map = BTreeMap::new(); + map.insert(a_k.spawn(Panic::Never), a_v.spawn(Panic::Never)); + map.insert(b_k.spawn(Panic::InDrop), b_v.spawn(Panic::Never)); + map.insert(c_k.spawn(Panic::Never), c_v.spawn(Panic::Never)); + + catch_unwind(move || drop(map.into_iter())).unwrap_err(); + + assert_eq!(a_k.dropped(), 1); + assert_eq!(a_v.dropped(), 1); + assert_eq!(b_k.dropped(), 1); + assert_eq!(b_v.dropped(), 1); + assert_eq!(c_k.dropped(), 1); + assert_eq!(c_v.dropped(), 1); +} + +#[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn test_into_iter_drop_leak_kv_panic_in_val() { + let a_k = CrashTestDummy::new(0); + let a_v = CrashTestDummy::new(1); + let b_k = CrashTestDummy::new(2); + let b_v = CrashTestDummy::new(3); + let c_k = CrashTestDummy::new(4); + let c_v = CrashTestDummy::new(5); + let mut map = BTreeMap::new(); + map.insert(a_k.spawn(Panic::Never), a_v.spawn(Panic::Never)); + map.insert(b_k.spawn(Panic::Never), b_v.spawn(Panic::InDrop)); + map.insert(c_k.spawn(Panic::Never), c_v.spawn(Panic::Never)); + + catch_unwind(move || drop(map.into_iter())).unwrap_err(); + + assert_eq!(a_k.dropped(), 1); + assert_eq!(a_v.dropped(), 1); + assert_eq!(b_k.dropped(), 1); + assert_eq!(b_v.dropped(), 1); + assert_eq!(c_k.dropped(), 1); + assert_eq!(c_v.dropped(), 1); +} + #[test] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_into_iter_drop_leak_height_1() { diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index 2a853ef421629..0c93eff0d20fa 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -739,7 +739,7 @@ impl NodeRef { impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { /// Unsafely asserts to the compiler the static information that this node is a `Leaf`. - unsafe fn cast_to_leaf_unchecked(self) -> NodeRef, K, V, marker::Leaf> { + pub unsafe fn cast_to_leaf_unchecked(self) -> NodeRef, K, V, marker::Leaf> { debug_assert!(self.height == 0); NodeRef { height: self.height, node: self.node, _marker: PhantomData } } @@ -1173,11 +1173,25 @@ impl Handle, marker::KV> /// The node that the handle refers to must not yet have been deallocated. #[inline] pub unsafe fn drop_key_val(mut self) { + // Run the destructor of the value even if the destructor of the key panics. + struct Dropper<'a, T>(&'a mut MaybeUninit); + impl Drop for Dropper<'_, T> { + #[inline] + fn drop(&mut self) { + unsafe { + self.0.assume_init_drop(); + } + } + } + debug_assert!(self.idx < self.node.len()); let leaf = self.node.as_leaf_dying(); unsafe { - leaf.keys.get_unchecked_mut(self.idx).assume_init_drop(); - leaf.vals.get_unchecked_mut(self.idx).assume_init_drop(); + let key = leaf.keys.get_unchecked_mut(self.idx); + let val = leaf.vals.get_unchecked_mut(self.idx); + let _guard = Dropper(val); + key.assume_init_drop(); + // dropping the guard will drop the value } } } diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index d91682b796e4f..c739832bc7843 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -773,7 +773,7 @@ impl From<&CStr> for Box { } #[cfg(not(test))] -#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "box_from_mut_slice", since = "1.84.0")] impl From<&mut CStr> for Box { /// Converts a `&mut CStr` into a `Box`, /// by copying the contents into a newly allocated [`Box`]. @@ -921,7 +921,7 @@ impl From<&CStr> for Arc { } #[cfg(target_has_atomic = "ptr")] -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut CStr> for Arc { /// Converts a `&mut CStr` into a `Arc`, /// by copying the contents into a newly allocated [`Arc`]. @@ -953,7 +953,7 @@ impl From<&CStr> for Rc { } } -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut CStr> for Rc { /// Converts a `&mut CStr` into a `Rc`, /// by copying the contents into a newly allocated [`Rc`]. diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 041ff37897f05..108224b27fa80 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -163,8 +163,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(strict_provenance))] -#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))] #![cfg_attr(not(test), feature(coroutine_trait))] #![cfg_attr(test, feature(panic_update_hook))] #![cfg_attr(test, feature(test))] @@ -188,6 +186,7 @@ #![feature(slice_internals)] #![feature(staged_api)] #![feature(stmt_expr_attributes)] +#![feature(strict_provenance_lints)] #![feature(unboxed_closures)] #![feature(unsized_fn_params)] #![feature(with_negative_coherence)] diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 85a9120c7e255..2c7cdcf0cfb4e 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -103,7 +103,6 @@ impl RawVec { /// `RawVec` with capacity `usize::MAX`. Useful for implementing /// delayed allocation. #[must_use] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "raw_vec_internals_const", since = "1.81"))] pub const fn new() -> Self { Self::new_in(Global) } @@ -179,7 +178,6 @@ impl RawVec { /// Like `new`, but parameterized over the choice of allocator for /// the returned `RawVec`. #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "raw_vec_internals_const", since = "1.81"))] pub const fn new_in(alloc: A) -> Self { Self { inner: RawVecInner::new_in(alloc, align_of::()), _marker: PhantomData } } @@ -409,7 +407,6 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec { impl RawVecInner { #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "raw_vec_internals_const", since = "1.81"))] const fn new_in(alloc: A, align: usize) -> Self { let ptr = unsafe { core::mem::transmute(align) }; // `cap: 0` means "unallocated". zero-sized types are ignored. @@ -757,7 +754,9 @@ impl RawVecInner { } } -#[inline(never)] +// not marked inline(never) since we want optimizers to be able to observe the specifics of this +// function, see tests/codegen/vec-reserve-extend.rs. +#[cold] fn finish_grow( new_layout: Layout, current_memory: Option<(NonNull, Layout)>, diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 3a9bd1b5bf119..7aa1457b1df54 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -307,7 +307,7 @@ fn rc_inner_layout_for_value_layout(layout: Layout) -> Layout { /// `value.get_mut()`. This avoids conflicts with methods of the inner type `T`. /// /// [get_mut]: Rc::get_mut -#[cfg_attr(not(bootstrap), doc(search_unbox))] +#[doc(search_unbox)] #[cfg_attr(not(test), rustc_diagnostic_item = "Rc")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] @@ -2659,7 +2659,7 @@ impl From<&[T]> for Rc<[T]> { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut [T]> for Rc<[T]> { /// Allocates a reference-counted slice and fills it by cloning `v`'s items. /// @@ -2698,7 +2698,7 @@ impl From<&str> for Rc { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut str> for Rc { /// Allocates a reference-counted string slice and copies `v` into it. /// diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index da2d6bb3bce24..b8bdd298c27ab 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -235,7 +235,7 @@ macro_rules! acquire { /// counting in general. /// /// [rc_examples]: crate::rc#examples -#[cfg_attr(not(bootstrap), doc(search_unbox))] +#[doc(search_unbox)] #[cfg_attr(not(test), rustc_diagnostic_item = "Arc")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] @@ -3618,7 +3618,7 @@ impl From<&[T]> for Arc<[T]> { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut [T]> for Arc<[T]> { /// Allocates a reference-counted slice and fills it by cloning `v`'s items. /// @@ -3657,7 +3657,7 @@ impl From<&str> for Arc { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut str> for Arc { /// Allocates a reference-counted `str` and copies `v` into it. /// diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 990b7e8f76127..4b706086e0770 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -427,7 +427,7 @@ impl Vec { /// /// The vector will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the vector will not allocate. + /// `capacity`. If `capacity` is zero, the vector will not allocate. /// /// It is important to note that although the returned vector has the /// minimum *capacity* specified, the vector will have a zero *length*. For @@ -487,7 +487,7 @@ impl Vec { /// /// The vector will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the vector will not allocate. + /// `capacity`. If `capacity` is zero, the vector will not allocate. /// /// # Errors /// @@ -745,7 +745,7 @@ impl Vec { /// /// The vector will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the vector will not allocate. + /// `capacity`. If `capacity` is zero, the vector will not allocate. /// /// It is important to note that although the returned vector has the /// minimum *capacity* specified, the vector will have a zero *length*. For @@ -808,7 +808,7 @@ impl Vec { /// /// The vector will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the vector will not allocate. + /// `capacity`. If `capacity` is zero, the vector will not allocate. /// /// # Errors /// @@ -1662,7 +1662,7 @@ impl Vec { #[stable(feature = "vec_as_ptr", since = "1.37.0")] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline] pub const fn as_ptr(&self) -> *const T { // We shadow the slice method of the same name to avoid going through @@ -1725,7 +1725,7 @@ impl Vec { #[stable(feature = "vec_as_ptr", since = "1.37.0")] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline] pub const fn as_mut_ptr(&mut self) -> *mut T { // We shadow the slice method of the same name to avoid going through diff --git a/library/alloc/tests/boxed.rs b/library/alloc/tests/boxed.rs index 6a8ba5c92fb30..94389cf2de933 100644 --- a/library/alloc/tests/boxed.rs +++ b/library/alloc/tests/boxed.rs @@ -4,7 +4,7 @@ use core::mem::MaybeUninit; use core::ptr::NonNull; #[test] -#[cfg_attr(not(bootstrap), expect(dangling_pointers_from_temporaries))] +#[expect(dangling_pointers_from_temporaries)] fn uninitialized_zero_size_box() { assert_eq!( &*Box::<()>::new_uninit() as *const _, diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 699a8e6776e6d..02bbb40ef81d2 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -32,10 +32,9 @@ #![feature(panic_update_hook)] #![feature(pointer_is_aligned_to)] #![feature(thin_box)] -#![cfg_attr(bootstrap, feature(strict_provenance))] -#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))] #![feature(drain_keep_rest)] #![feature(local_waker)] +#![feature(strict_provenance_lints)] #![feature(vec_pop_if)] #![feature(unique_rc_arc)] #![feature(macro_metavar_expr_concat)] diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index 94f343d06705e..cace4582b489a 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -43,8 +43,6 @@ check-cfg = [ 'cfg(bootstrap)', 'cfg(no_fp_fmt_parse)', 'cfg(stdarch_intel_sde)', - # #[cfg(bootstrap)] rtems - 'cfg(target_os, values("rtems"))', # core use #[path] imports to portable-simd `core_simd` crate # and to stdarch `core_arch` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index f412ca1716338..60936da2e0b0d 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -157,7 +157,6 @@ impl Layout { #[must_use = "this returns the minimum alignment, \ without modifying the layout"] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(ptr_alignment_type))] pub const fn align(&self) -> usize { self.align.as_usize() } @@ -255,7 +254,7 @@ impl Layout { /// `align` violates the conditions listed in [`Layout::from_size_align`]. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] + #[rustc_const_stable_indirect] #[inline] pub const fn align_to(&self, align: usize) -> Result { if let Some(align) = Alignment::new(align) { @@ -331,7 +330,7 @@ impl Layout { /// to the layout's current size. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] + #[rustc_const_stable_indirect] #[must_use = "this returns a new `Layout`, \ without modifying the original"] #[inline] @@ -431,7 +430,7 @@ impl Layout { /// ``` #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] + #[rustc_const_stable_indirect] #[inline] pub const fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> { let new_align = Alignment::max(self.align, next.align); @@ -495,7 +494,7 @@ impl Layout { /// `isize::MAX`, returns `LayoutError`. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] + #[rustc_const_stable_indirect] #[inline] pub const fn array(n: usize) -> Result { // Reduce the amount of code we need to monomorphize per `T`. diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 4764d7f0b0fe0..95c1eb460cd94 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -10,11 +10,13 @@ use crate::convert::Infallible; use crate::error::Error; use crate::fmt; use crate::hash::{self, Hash}; +use crate::intrinsics::transmute_unchecked; use crate::iter::{UncheckedIterator, repeat_n}; use crate::mem::{self, MaybeUninit}; use crate::ops::{ ChangeOutputType, ControlFlow, FromResidual, Index, IndexMut, NeverShortCircuit, Residual, Try, }; +use crate::ptr::{null, null_mut}; use crate::slice::{Iter, IterMut}; mod ascii; @@ -212,8 +214,8 @@ impl BorrowMut<[T]> for [T; N] { } } -/// Tries to create an array `[T; N]` by copying from a slice `&[T]`. Succeeds if -/// `slice.len() == N`. +/// Tries to create an array `[T; N]` by copying from a slice `&[T]`. +/// Succeeds if `slice.len() == N`. /// /// ``` /// let bytes: [u8; 3] = [1, 0, 2]; @@ -280,13 +282,7 @@ impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N] { #[inline] fn try_from(slice: &'a [T]) -> Result<&'a [T; N], TryFromSliceError> { - if slice.len() == N { - let ptr = slice.as_ptr() as *const [T; N]; - // SAFETY: ok because we just checked that the length fits - unsafe { Ok(&*ptr) } - } else { - Err(TryFromSliceError(())) - } + slice.as_array().ok_or(TryFromSliceError(())) } } @@ -308,13 +304,7 @@ impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N] { #[inline] fn try_from(slice: &'a mut [T]) -> Result<&'a mut [T; N], TryFromSliceError> { - if slice.len() == N { - let ptr = slice.as_mut_ptr() as *mut [T; N]; - // SAFETY: ok because we just checked that the length fits - unsafe { Ok(&mut *ptr) } - } else { - Err(TryFromSliceError(())) - } + slice.as_mut_array().ok_or(TryFromSliceError(())) } } @@ -577,7 +567,8 @@ impl [T; N] { /// Returns a mutable slice containing the entire array. Equivalent to /// `&mut s[..]`. #[stable(feature = "array_as_slice", since = "1.57.0")] - pub fn as_mut_slice(&mut self) -> &mut [T] { + #[rustc_const_unstable(feature = "const_array_as_mut_slice", issue = "133333")] + pub const fn as_mut_slice(&mut self) -> &mut [T] { self } @@ -606,8 +597,20 @@ impl [T; N] { /// assert_eq!(strings.len(), 3); /// ``` #[stable(feature = "array_methods", since = "1.77.0")] - pub fn each_ref(&self) -> [&T; N] { - from_trusted_iterator(self.iter()) + #[rustc_const_unstable(feature = "const_array_each_ref", issue = "133289")] + pub const fn each_ref(&self) -> [&T; N] { + let mut buf = [null::(); N]; + + // FIXME(const-hack): We would like to simply use iterators for this (as in the original implementation), but this is not allowed in constant expressions. + let mut i = 0; + while i < N { + buf[i] = &raw const self[i]; + + i += 1; + } + + // SAFETY: `*const T` has the same layout as `&T`, and we've also initialised each pointer as a valid reference. + unsafe { transmute_unchecked(buf) } } /// Borrows each element mutably and returns an array of mutable references @@ -625,8 +628,20 @@ impl [T; N] { /// assert_eq!(floats, [0.0, 2.7, -1.0]); /// ``` #[stable(feature = "array_methods", since = "1.77.0")] - pub fn each_mut(&mut self) -> [&mut T; N] { - from_trusted_iterator(self.iter_mut()) + #[rustc_const_unstable(feature = "const_array_each_ref", issue = "133289")] + pub const fn each_mut(&mut self) -> [&mut T; N] { + let mut buf = [null_mut::(); N]; + + // FIXME(const-hack): We would like to simply use iterators for this (as in the original implementation), but this is not allowed in constant expressions. + let mut i = 0; + while i < N { + buf[i] = &raw mut self[i]; + + i += 1; + } + + // SAFETY: `*mut T` has the same layout as `&mut T`, and we've also initialised each pointer as a valid reference. + unsafe { transmute_unchecked(buf) } } /// Divides one array reference into two at an index. diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index bfd2a71f97b2c..c553979032777 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -587,7 +587,7 @@ impl Cell { #[inline] #[stable(feature = "cell_as_ptr", since = "1.12.0")] #[rustc_const_stable(feature = "const_cell_as_ptr", since = "1.32.0")] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[rustc_never_returns_null_ptr] pub const fn as_ptr(&self) -> *mut T { self.value.get() @@ -1150,7 +1150,7 @@ impl RefCell { /// ``` #[inline] #[stable(feature = "cell_as_ptr", since = "1.12.0")] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[rustc_never_returns_null_ptr] pub fn as_ptr(&self) -> *mut T { self.value.get() @@ -2133,9 +2133,8 @@ impl UnsafeCell { /// assert_eq!(*uc.get_mut(), 41); /// ``` #[inline(always)] - #[stable(feature = "unsafe_cell_from_mut", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unsafe_cell_from_mut", since = "CURRENT_RUSTC_VERSION")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] + #[stable(feature = "unsafe_cell_from_mut", since = "1.84.0")] + #[rustc_const_stable(feature = "unsafe_cell_from_mut", since = "1.84.0")] pub const fn from_mut(value: &mut T) -> &mut UnsafeCell { // SAFETY: `UnsafeCell` has the same memory layout as `T` due to #[repr(transparent)]. unsafe { &mut *(value as *mut T as *mut UnsafeCell) } @@ -2160,7 +2159,7 @@ impl UnsafeCell { #[inline(always)] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_unsafecell_get", since = "1.32.0")] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[rustc_never_returns_null_ptr] pub const fn get(&self) -> *mut T { // We can just cast the pointer from `UnsafeCell` to `T` because of @@ -2308,7 +2307,7 @@ impl SyncUnsafeCell { /// when casting to `&mut T`, and ensure that there are no mutations /// or mutable aliases going on when casting to `&T` #[inline] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[rustc_never_returns_null_ptr] pub const fn get(&self) -> *mut T { self.value.get() diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 974e7baccf7bc..7d33765879f2f 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -729,7 +729,7 @@ impl char { /// '𝕊'.encode_utf16(&mut b); /// ``` #[stable(feature = "unicode_encode_char", since = "1.15.0")] - #[rustc_const_stable(feature = "const_char_encode_utf16", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_char_encode_utf16", since = "1.84.0")] #[inline] pub const fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] { encode_utf16_raw(self as u32, dst) @@ -1299,7 +1299,7 @@ impl char { /// /// [`to_ascii_uppercase()`]: #method.to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); @@ -1325,7 +1325,7 @@ impl char { /// /// [`to_ascii_lowercase()`]: #method.to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); @@ -1787,7 +1787,6 @@ const fn len_utf16(code: u32) -> usize { /// Panics if the buffer is not large enough. /// A buffer of length four is large enough to encode any `char`. #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_char_encode_utf8", since = "1.83.0"))] #[doc(hidden)] #[inline] pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] { @@ -1836,10 +1835,6 @@ pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] { /// Panics if the buffer is not large enough. /// A buffer of length 2 is large enough to encode any `char`. #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")] -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_char_encode_utf16", since = "CURRENT_RUSTC_VERSION") -)] #[doc(hidden)] #[inline] pub const fn encode_utf16_raw(mut code: u32, dst: &mut [u16]) -> &mut [u16] { diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 9e32f74227cf9..8831443a10f17 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -138,11 +138,9 @@ enum FromBytesWithNulErrorKind { // FIXME: const stability attributes should not be required here, I think impl FromBytesWithNulError { - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0"))] const fn interior_nul(pos: usize) -> FromBytesWithNulError { FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) } } - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0"))] const fn not_nul_terminated() -> FromBytesWithNulError { FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated } } @@ -464,8 +462,7 @@ impl CStr { /// /// ```no_run /// # #![allow(unused_must_use)] - /// # #![cfg_attr(bootstrap, expect(temporary_cstring_as_ptr))] - /// # #![cfg_attr(not(bootstrap), expect(dangling_pointers_from_temporaries))] + /// # #![expect(dangling_pointers_from_temporaries)] /// use std::ffi::CString; /// /// // Do not do this: @@ -500,7 +497,7 @@ impl CStr { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0")] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[rustc_never_returns_null_ptr] pub const fn as_ptr(&self) -> *const c_char { self.inner.as_ptr() @@ -732,7 +729,6 @@ impl AsRef for CStr { /// located within `isize::MAX` from `ptr`. #[inline] #[unstable(feature = "cstr_internals", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cstr_from_ptr", since = "1.81.0"))] #[rustc_allow_const_fn_unstable(const_eval_select)] const unsafe fn strlen(ptr: *const c_char) -> usize { const_eval_select!( diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 2b1692a195e50..7fc9dd21fdd81 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -333,10 +333,6 @@ pub struct Arguments<'a> { #[unstable(feature = "fmt_internals", issue = "none")] impl<'a> Arguments<'a> { #[inline] - #[cfg_attr( - bootstrap, - rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none") - )] pub const fn new_const(pieces: &'a [&'static str; N]) -> Self { const { assert!(N <= 1) }; Arguments { pieces, fmt: None, args: &[] } @@ -438,7 +434,7 @@ impl<'a> Arguments<'a> { /// assert_eq!(format_args!("{:?}", std::env::current_dir()).as_str(), None); /// ``` #[stable(feature = "fmt_as_str", since = "1.52.0")] - #[rustc_const_stable(feature = "const_arguments_as_str", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_arguments_as_str", since = "1.84.0")] #[must_use] #[inline] pub const fn as_str(&self) -> Option<&'static str> { diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index f2d7e0f481e76..683e45b35f70a 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -199,32 +199,12 @@ static DEC_DIGITS_LUT: &[u8; 200] = b"0001020304050607080910111213141516171819\ 8081828384858687888990919293949596979899"; macro_rules! impl_Display { - ($($t:ident $(as $positive:ident)? named $name:ident,)* ; as $u:ident via $conv_fn:ident named $gen_name:ident) => { + ($($signed:ident, $unsigned:ident,)* ; as $u:ident via $conv_fn:ident named $gen_name:ident) => { $( #[stable(feature = "rust1", since = "1.0.0")] - impl fmt::Display for $t { + impl fmt::Display for $unsigned { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // If it's a signed integer. - $( - let is_nonnegative = *self >= 0; - - #[cfg(not(feature = "optimize_for_size"))] - { - if !is_nonnegative { - // convert the negative num to positive by summing 1 to its 2s complement - return (!self as $positive).wrapping_add(1)._fmt(false, f); - } - } - #[cfg(feature = "optimize_for_size")] - { - if !is_nonnegative { - // convert the negative num to positive by summing 1 to its 2s complement - return $gen_name((!self.$conv_fn()).wrapping_add(1), false, f); - } - } - )? - // If it's a positive integer. #[cfg(not(feature = "optimize_for_size"))] { self._fmt(true, f) @@ -236,10 +216,24 @@ macro_rules! impl_Display { } } + #[stable(feature = "rust1", since = "1.0.0")] + impl fmt::Display for $signed { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + #[cfg(not(feature = "optimize_for_size"))] + { + return self.unsigned_abs()._fmt(*self >= 0, f); + } + #[cfg(feature = "optimize_for_size")] + { + return $gen_name(self.unsigned_abs().$conv_fn(), *self >= 0, f); + } + } + } + #[cfg(not(feature = "optimize_for_size"))] - impl $t { - fn _fmt(mut self: $t, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result { - const SIZE: usize = $t::MAX.ilog(10) as usize + 1; + impl $unsigned { + fn _fmt(mut self, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result { + const SIZE: usize = $unsigned::MAX.ilog(10) as usize + 1; let mut buf = [MaybeUninit::::uninit(); SIZE]; let mut curr = SIZE; let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf); @@ -258,7 +252,7 @@ macro_rules! impl_Display { #[allow(unused_comparisons)] // This block will be removed for smaller types at compile time and in the worst // case, it will prevent to have the `10000` literal to overflow for `i8` and `u8`. - if core::mem::size_of::<$t>() >= 2 { + if core::mem::size_of::<$unsigned>() >= 2 { // eagerly decode 4 characters at a time while self >= 10000 { let rem = (self % 10000) as usize; @@ -312,8 +306,8 @@ macro_rules! impl_Display { #[cfg(feature = "optimize_for_size")] fn $gen_name(mut n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // 2^128 is about 3*10^38, so 39 gives an extra byte of space - let mut buf = [MaybeUninit::::uninit(); 39]; + const SIZE: usize = $u::MAX.ilog(10) as usize + 1; + let mut buf = [MaybeUninit::::uninit(); SIZE]; let mut curr = buf.len(); let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf); @@ -523,16 +517,11 @@ impl_Debug! { mod imp { use super::*; impl_Display!( - i8 as u8 named fmt_i8, - u8 named fmt_u8, - i16 as u16 named fmt_i16, - u16 named fmt_u16, - i32 as u32 named fmt_i32, - u32 named fmt_u32, - i64 as u64 named fmt_i64, - u64 named fmt_u64, - isize as usize named fmt_isize, - usize named fmt_usize, + i8, u8, + i16, u16, + i32, u32, + i64, u64, + isize, usize, ; as u64 via to_u64 named fmt_u64 ); impl_Exp!( @@ -545,18 +534,13 @@ mod imp { mod imp { use super::*; impl_Display!( - i8 as u8 named fmt_i8, - u8 named fmt_u8, - i16 as u16 named fmt_i16, - u16 named fmt_u16, - i32 as u32 named fmt_i32, - u32 named fmt_u32, - isize as usize named fmt_isize, - usize named fmt_usize, + i8, u8, + i16, u16, + i32, u32, + isize, usize, ; as u32 via to_u32 named fmt_u32); impl_Display!( - i64 as u64 named fmt_i64, - u64 named fmt_u64, + i64, u64, ; as u64 via to_u64 named fmt_u64); impl_Exp!(i8, u8, i16, u16, i32, u32, isize, usize as u32 via to_u32 named exp_u32); diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs index 234914c20fc31..cfbd88bbe7998 100644 --- a/library/core/src/future/future.rs +++ b/library/core/src/future/future.rs @@ -25,7 +25,7 @@ use crate::task::{Context, Poll}; /// [`async`]: ../../std/keyword.async.html /// [`Waker`]: crate::task::Waker #[doc(notable_trait)] -#[cfg_attr(not(bootstrap), doc(search_unbox))] +#[doc(search_unbox)] #[must_use = "futures do nothing unless you `.await` or poll them"] #[stable(feature = "futures_api", since = "1.36.0")] #[lang = "future_trait"] diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 78df51f2bc47d..c59e4414d3726 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -506,7 +506,6 @@ pub const fn black_box(dummy: T) -> T { /// # } /// ``` #[unstable(feature = "hint_must_use", issue = "94745")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "hint_must_use", issue = "94745"))] #[must_use] // <-- :) #[inline(always)] pub const fn must_use(value: T) -> T { diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index 6539964bc0956..55dcf7cd47e97 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -249,6 +249,39 @@ //! `Call(ret_val = function(arg1, arg2, ...), ReturnTo(next_block), UnwindContinue())`. //! - [`TailCall`] does not have a return destination or next block, so its syntax is just //! `TailCall(function(arg1, arg2, ...))`. +//! +//! #### Debuginfo +//! +//! Debuginfo associates source code variable names (of variables that may not exist any more) with +//! MIR expressions that indicate where the value of that variable is stored. The syntax to do so +//! is: +//! ```text +//! debug source_var_name => expression; +//! ``` +//! Both places and constants are supported in the `expression`. +//! +//! ```rust +//! #![allow(internal_features)] +//! #![feature(core_intrinsics, custom_mir)] +//! +//! use core::intrinsics::mir::*; +//! +//! #[custom_mir(dialect = "built")] +//! fn debuginfo(arg: Option<&i32>) { +//! mir!( +//! // Debuginfo for a source variable `plain_local` that just duplicates `arg`. +//! debug plain_local => arg; +//! // Debuginfo for a source variable `projection` that can be computed by dereferencing +//! // a field of `arg`. +//! debug projection => *Field::<&i32>(Variant(arg, 1), 0); +//! // Debuginfo for a source variable `constant` that always holds the value `5`. +//! debug constant => 5_usize; +//! { +//! Return() +//! } +//! ) +//! } +//! ``` #![unstable( feature = "custom_mir", diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index e9859a58696d9..6b9011adf3d3d 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1431,11 +1431,7 @@ pub fn abort() -> ! { /// reach code marked with this function. /// /// The stabilized version of this intrinsic is [`core::hint::unreachable_unchecked`]. -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0") -)] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1453,8 +1449,7 @@ pub const unsafe fn unreachable() -> ! { /// own, or if it does not enable any significant optimizations. /// /// The stabilized version of this intrinsic is [`core::hint::assert_unchecked`]. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assume", since = "1.77.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] @@ -1474,8 +1469,7 @@ pub const unsafe fn assume(b: bool) { /// /// This intrinsic does not have a stable counterpart. #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(not(bootstrap), rustc_intrinsic)] -#[cfg(not(bootstrap))] +#[rustc_intrinsic] #[rustc_nounwind] #[miri::intrinsic_fallback_is_spec] #[cold] @@ -1492,19 +1486,10 @@ pub const fn cold_path() {} /// any safety invariants. /// /// This intrinsic does not have a stable counterpart. -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_likely", since = "CURRENT_RUSTC_VERSION") -)] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_nounwind] #[inline(always)] pub const fn likely(b: bool) -> bool { - #[cfg(bootstrap)] - { - b - } - #[cfg(not(bootstrap))] if b { true } else { @@ -1524,19 +1509,10 @@ pub const fn likely(b: bool) -> bool { /// any safety invariants. /// /// This intrinsic does not have a stable counterpart. -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_likely", since = "CURRENT_RUSTC_VERSION") -)] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_nounwind] #[inline(always)] pub const fn unlikely(b: bool) -> bool { - #[cfg(bootstrap)] - { - b - } - #[cfg(not(bootstrap))] if b { cold_path(); true @@ -1570,8 +1546,7 @@ pub fn select_unpredictable(b: bool, true_val: T, false_val: T) -> T { /// This will statically either panic, or do nothing. /// /// This intrinsic does not have a stable counterpart. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type", since = "1.59.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1583,8 +1558,7 @@ pub const fn assert_inhabited() { /// zero-initialization: This will statically either panic, or do nothing. /// /// This intrinsic does not have a stable counterpart. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type2", since = "1.75.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1595,8 +1569,7 @@ pub const fn assert_zero_valid() { /// A guard for `std::mem::uninitialized`. This will statically either panic, or do nothing. /// /// This intrinsic does not have a stable counterpart. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type2", since = "1.75.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1612,8 +1585,7 @@ pub const fn assert_mem_uninitialized_valid() { /// any safety invariants. /// /// Consider using [`core::panic::Location::caller`] instead. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_caller_location", since = "1.79.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1630,8 +1602,7 @@ pub const fn caller_location() -> &'static crate::panic::Location<'static> { /// it does not require an `unsafe` block. /// Therefore, implementations must not require the user to uphold /// any safety invariants. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_intrinsic_forget", since = "1.83.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1944,8 +1915,7 @@ pub const unsafe fn transmute(_src: Src) -> Dst { /// /// This is not expected to ever be exposed directly to users, rather it /// may eventually be exposed through some more-constrained API. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_transmute", since = "1.56.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1966,8 +1936,7 @@ pub const unsafe fn transmute_unchecked(_src: Src) -> Dst { /// any safety invariants. /// /// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop). -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_needs_drop", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1992,8 +1961,7 @@ pub const fn needs_drop() -> bool { /// /// The stabilized version of this intrinsic is [`pointer::offset`]. #[must_use = "returns a new pointer rather than modifying its argument"] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2015,8 +1983,7 @@ pub const unsafe fn offset(_dst: Ptr, _offset: Delta) -> Ptr { /// /// The stabilized version of this intrinsic is [`pointer::wrapping_offset`]. #[must_use = "returns a new pointer rather than modifying its argument"] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2723,8 +2690,7 @@ pub fn frem_algebraic(_a: T, _b: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `count_ones` method. For example, /// [`u32::count_ones`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ctpop", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2768,8 +2734,7 @@ pub const fn ctpop(_x: T) -> u32 { /// let num_leading = ctlz(x); /// assert_eq!(num_leading, 16); /// ``` -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ctlz", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2794,8 +2759,7 @@ pub const fn ctlz(_x: T) -> u32 { /// let num_leading = unsafe { ctlz_nonzero(x) }; /// assert_eq!(num_leading, 3); /// ``` -#[cfg_attr(bootstrap, rustc_const_stable(feature = "constctlz", since = "1.50.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2839,8 +2803,7 @@ pub const unsafe fn ctlz_nonzero(_x: T) -> u32 { /// let num_trailing = cttz(x); /// assert_eq!(num_trailing, 16); /// ``` -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cttz", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2865,8 +2828,7 @@ pub const fn cttz(_x: T) -> u32 { /// let num_trailing = unsafe { cttz_nonzero(x) }; /// assert_eq!(num_trailing, 3); /// ``` -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2884,8 +2846,7 @@ pub const unsafe fn cttz_nonzero(_x: T) -> u32 { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `swap_bytes` method. For example, /// [`u32::swap_bytes`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_bswap", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2903,8 +2864,7 @@ pub const fn bswap(_x: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `reverse_bits` method. For example, /// [`u32::reverse_bits`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_bitreverse", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2919,7 +2879,6 @@ pub const fn bitreverse(_x: T) -> T { /// large and difficult to optimize. /// /// The stabilized version of this intrinsic is [`Ord::cmp`]. -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_three_way_compare", issue = "none"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn three_way_compare(_lhs: T, _rhss: T) -> crate::cmp::Ordering { @@ -2936,8 +2895,7 @@ pub const fn three_way_compare(_lhs: T, _rhss: T) -> crate::cmp::Orderi /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `overflowing_add` method. For example, /// [`u32::overflowing_add`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2955,8 +2913,7 @@ pub const fn add_with_overflow(_x: T, _y: T) -> (T, bool) { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `overflowing_sub` method. For example, /// [`u32::overflowing_sub`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2974,8 +2931,7 @@ pub const fn sub_with_overflow(_x: T, _y: T) -> (T, bool) { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `overflowing_mul` method. For example, /// [`u32::overflowing_mul`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2987,7 +2943,6 @@ pub const fn mul_with_overflow(_x: T, _y: T) -> (T, bool) { /// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1` /// /// This intrinsic does not have a stable counterpart. -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_exact_div", issue = "none"))] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3001,8 +2956,7 @@ pub const unsafe fn exact_div(_x: T, _y: T) -> T { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_div` method. For example, /// [`u32::checked_div`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked_div", since = "1.52.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3015,8 +2969,7 @@ pub const unsafe fn unchecked_div(_x: T, _y: T) -> T { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_rem` method. For example, /// [`u32::checked_rem`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked_rem", since = "1.52.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3030,8 +2983,7 @@ pub const unsafe fn unchecked_rem(_x: T, _y: T) -> T { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_shl` method. For example, /// [`u32::checked_shl`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3044,8 +2996,7 @@ pub const unsafe fn unchecked_shl(_x: T, _y: U) -> T { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_shr` method. For example, /// [`u32::checked_shr`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3058,8 +3009,7 @@ pub const unsafe fn unchecked_shr(_x: T, _y: U) -> T { /// /// The stable counterpart of this intrinsic is `unchecked_add` on the various /// integer types, such as [`u16::unchecked_add`] and [`i64::unchecked_add`]. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3072,8 +3022,7 @@ pub const unsafe fn unchecked_add(_x: T, _y: T) -> T { /// /// The stable counterpart of this intrinsic is `unchecked_sub` on the various /// integer types, such as [`u16::unchecked_sub`] and [`i64::unchecked_sub`]. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3086,8 +3035,7 @@ pub const unsafe fn unchecked_sub(_x: T, _y: T) -> T { /// /// The stable counterpart of this intrinsic is `unchecked_mul` on the various /// integer types, such as [`u16::unchecked_mul`] and [`i64::unchecked_mul`]. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3105,8 +3053,7 @@ pub const unsafe fn unchecked_mul(_x: T, _y: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `rotate_left` method. For example, /// [`u32::rotate_left`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_rotate", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3124,8 +3071,7 @@ pub const fn rotate_left(_x: T, _shift: u32) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `rotate_right` method. For example, /// [`u32::rotate_right`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_rotate", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3143,8 +3089,7 @@ pub const fn rotate_right(_x: T, _shift: u32) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `wrapping_add` method. For example, /// [`u32::wrapping_add`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3161,8 +3106,7 @@ pub const fn wrapping_add(_a: T, _b: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `wrapping_sub` method. For example, /// [`u32::wrapping_sub`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3179,8 +3123,7 @@ pub const fn wrapping_sub(_a: T, _b: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `wrapping_mul` method. For example, /// [`u32::wrapping_mul`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3198,8 +3141,7 @@ pub const fn wrapping_mul(_a: T, _b: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `saturating_add` method. For example, /// [`u32::saturating_add`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_saturating", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3216,8 +3158,7 @@ pub const fn saturating_add(_a: T, _b: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `saturating_sub` method. For example, /// [`u32::saturating_sub`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_saturating", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3231,8 +3172,7 @@ pub const fn saturating_sub(_a: T, _b: T) -> T { /// This intrinsic can *only* be called where the pointer is a local without /// projections (`read_via_copy(ptr)`, not `read_via_copy(*ptr)`) so that it /// trivially obeys runtime-MIR rules about derefs in operands. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_read", since = "1.71.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3246,8 +3186,7 @@ pub const unsafe fn read_via_copy(_ptr: *const T) -> T { /// This intrinsic can *only* be called where the pointer is a local without /// projections (`write_via_move(ptr, x)`, not `write_via_move(*ptr, x)`) so /// that it trivially obeys runtime-MIR rules about derefs in operands. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_write", since = "1.83.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3264,8 +3203,7 @@ pub const unsafe fn write_via_move(_ptr: *mut T, _value: T) { /// any safety invariants. /// /// The stabilized version of this intrinsic is [`core::mem::discriminant`]. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_discriminant", since = "1.75.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3304,8 +3242,7 @@ extern "rust-intrinsic" { } /// See documentation of `<*const T>::offset_from` for details. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3314,7 +3251,6 @@ pub const unsafe fn ptr_offset_from(_ptr: *const T, _base: *const T) -> isize } /// See documentation of `<*const T>::sub_ptr` for details. -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892"))] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3326,7 +3262,6 @@ pub const unsafe fn ptr_offset_from_unsigned(_ptr: *const T, _base: *const T) /// Returns `2` if the result is unknown. /// Returns `1` if the pointers are guaranteed equal. /// Returns `0` if the pointers are guaranteed inequal. -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020"))] #[rustc_intrinsic] #[rustc_nounwind] #[rustc_do_not_const_check] @@ -3359,7 +3294,6 @@ pub const fn ptr_guaranteed_cmp(ptr: *const T, other: *const T) -> u8 { /// /// (The implementation is allowed to branch on the results of comparisons, /// which is UB if any of their inputs are `undef`.) -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_intrinsic_raw_eq", issue = "none"))] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3381,10 +3315,6 @@ pub const unsafe fn raw_eq(_a: &T, _b: &T) -> bool { /// that differs. That allows optimizations that can read in large chunks. /// /// [valid]: crate::ptr#safety -#[cfg_attr( - bootstrap, - rustc_const_unstable(feature = "const_intrinsic_compare_bytes", issue = "none") -)] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3395,7 +3325,6 @@ pub const unsafe fn compare_bytes(_left: *const u8, _right: *const u8, _bytes: u /// See documentation of [`std::hint::black_box`] for details. /// /// [`std::hint::black_box`]: crate::hint::black_box -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_black_box", issue = "none"))] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3627,11 +3556,7 @@ pub(crate) macro const_eval_select { /// # _ = foo(&5_i32); /// # _ = bar(&5_i32); /// ``` -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_is_val_statically_known", since = "CURRENT_RUSTC_VERSION") -)] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] +#[rustc_const_stable_indirect] #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] @@ -3673,8 +3598,7 @@ pub const unsafe fn typed_swap(x: *mut T, y: *mut T) { /// assertions are enabled whenever the *user crate* has UB checks enabled. However, if the /// user has UB checks disabled, the checks will still get optimized out. This intrinsic is /// primarily used by [`ub_checks::assert_unsafe_precondition`]. -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ub_checks", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] // just for UB checks +#[rustc_intrinsic_const_stable_indirect] // just for UB checks #[inline(always)] #[rustc_intrinsic] pub const fn ub_checks() -> bool { @@ -3757,8 +3681,7 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize { /// The stabilized version of this intrinsic is [`core::mem::size_of`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_size_of", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn size_of() -> usize { @@ -3775,8 +3698,7 @@ pub const fn size_of() -> usize { /// The stabilized version of this intrinsic is [`core::mem::align_of`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_min_align_of", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn min_align_of() -> usize { @@ -3789,7 +3711,6 @@ pub const fn min_align_of() -> usize { /// It's "tracking issue" is [#91971](https://github.com/rust-lang/rust/issues/91971). #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_pref_align_of", issue = "91971"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn pref_align_of() -> usize { @@ -3807,7 +3728,6 @@ pub const unsafe fn pref_align_of() -> usize { /// The to-be-stabilized version of this intrinsic is [`crate::mem::variant_count`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "variant_count", issue = "73662"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn variant_count() -> usize { @@ -3823,7 +3743,6 @@ pub const fn variant_count() -> usize { /// See [`crate::mem::size_of_val_raw`] for safety conditions. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_size_of_val", issue = "46571"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn size_of_val(_ptr: *const T) -> usize { @@ -3839,7 +3758,6 @@ pub const unsafe fn size_of_val(_ptr: *const T) -> usize { /// See [`crate::mem::align_of_val_raw`] for safety conditions. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_align_of_val", issue = "46571"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn min_align_of_val(_ptr: *const T) -> usize { @@ -3856,7 +3774,6 @@ pub const unsafe fn min_align_of_val(_ptr: *const T) -> usize { /// The stabilized version of this intrinsic is [`core::any::type_name`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_type_name", issue = "63084"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn type_name() -> &'static str { @@ -3875,7 +3792,6 @@ pub const fn type_name() -> &'static str { /// The stabilized version of this intrinsic is [`core::any::TypeId::of`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_type_id", issue = "77125"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn type_id() -> u128 { @@ -3889,8 +3805,7 @@ pub const fn type_id() -> u128 { /// change the possible layouts of pointers. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn aggregate_raw_ptr, D, M>(_data: D, _meta: M) -> P { @@ -3915,11 +3830,7 @@ impl AggregateRawPtr<*mut T> for *mut P { /// This is used to implement functions like `ptr::metadata`. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr( - bootstrap, - cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")) -)] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn ptr_metadata + ?Sized, M>(_ptr: *const P) -> M { @@ -4025,8 +3936,7 @@ pub const fn ptr_metadata + ?Sized, M>(_ptr: *cons #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_diagnostic_item = "ptr_copy_nonoverlapping"] pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize) { - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0"))] - #[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] + #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -4132,8 +4042,7 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_diagnostic_item = "ptr_copy"] pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0"))] - #[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] + #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -4216,8 +4125,7 @@ pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_diagnostic_item = "ptr_write_bytes"] pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_write", since = "1.83.0"))] - #[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] + #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -4250,7 +4158,6 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { /// The stabilized version of this intrinsic is /// [`f16::min`] #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f16", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn minnumf16(_x: f16, _y: f16) -> f16 { @@ -4267,7 +4174,7 @@ pub const fn minnumf16(_x: f16, _y: f16) -> f16 { /// The stabilized version of this intrinsic is /// [`f32::min`] #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn minnumf32(_x: f32, _y: f32) -> f32 { @@ -4284,7 +4191,7 @@ pub const fn minnumf32(_x: f32, _y: f32) -> f32 { /// The stabilized version of this intrinsic is /// [`f64::min`] #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn minnumf64(_x: f64, _y: f64) -> f64 { @@ -4301,7 +4208,6 @@ pub const fn minnumf64(_x: f64, _y: f64) -> f64 { /// The stabilized version of this intrinsic is /// [`f128::min`] #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f128", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn minnumf128(_x: f128, _y: f128) -> f128 { @@ -4318,7 +4224,6 @@ pub const fn minnumf128(_x: f128, _y: f128) -> f128 { /// The stabilized version of this intrinsic is /// [`f16::max`] #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f16", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn maxnumf16(_x: f16, _y: f16) -> f16 { @@ -4335,7 +4240,7 @@ pub const fn maxnumf16(_x: f16, _y: f16) -> f16 { /// The stabilized version of this intrinsic is /// [`f32::max`] #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn maxnumf32(_x: f32, _y: f32) -> f32 { @@ -4352,7 +4257,7 @@ pub const fn maxnumf32(_x: f32, _y: f32) -> f32 { /// The stabilized version of this intrinsic is /// [`f64::max`] #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn maxnumf64(_x: f64, _y: f64) -> f64 { @@ -4369,7 +4274,6 @@ pub const fn maxnumf64(_x: f64, _y: f64) -> f64 { /// The stabilized version of this intrinsic is /// [`f128::max`] #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f128", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn maxnumf128(_x: f128, _y: f128) -> f128 { @@ -4381,7 +4285,6 @@ pub const fn maxnumf128(_x: f128, _y: f128) -> f128 { /// The stabilized version of this intrinsic is /// [`f16::abs`](../../std/primitive.f16.html#method.abs) #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f16", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn fabsf16(_x: f16) -> f16 { @@ -4393,7 +4296,7 @@ pub const unsafe fn fabsf16(_x: f16) -> f16 { /// The stabilized version of this intrinsic is /// [`f32::abs`](../../std/primitive.f32.html#method.abs) #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn fabsf32(_x: f32) -> f32 { @@ -4405,7 +4308,7 @@ pub const unsafe fn fabsf32(_x: f32) -> f32 { /// The stabilized version of this intrinsic is /// [`f64::abs`](../../std/primitive.f64.html#method.abs) #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn fabsf64(_x: f64) -> f64 { @@ -4417,7 +4320,6 @@ pub const unsafe fn fabsf64(_x: f64) -> f64 { /// The stabilized version of this intrinsic is /// [`f128::abs`](../../std/primitive.f128.html#method.abs) #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f128", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn fabsf128(_x: f128) -> f128 { @@ -4429,7 +4331,6 @@ pub const unsafe fn fabsf128(_x: f128) -> f128 { /// The stabilized version of this intrinsic is /// [`f16::copysign`](../../std/primitive.f16.html#method.copysign) #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f16", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16 { @@ -4441,7 +4342,7 @@ pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16 { /// The stabilized version of this intrinsic is /// [`f32::copysign`](../../std/primitive.f32.html#method.copysign) #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32 { @@ -4452,7 +4353,7 @@ pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32 { /// The stabilized version of this intrinsic is /// [`f64::copysign`](../../std/primitive.f64.html#method.copysign) #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64 { @@ -4464,7 +4365,6 @@ pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64 { /// The stabilized version of this intrinsic is /// [`f128::copysign`](../../std/primitive.f128.html#method.copysign) #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f128", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn copysignf128(_x: f128, _y: f128) -> f128 { diff --git a/library/core/src/io/borrowed_buf.rs b/library/core/src/io/borrowed_buf.rs index dbc60aa8154c6..4227e503ba7ba 100644 --- a/library/core/src/io/borrowed_buf.rs +++ b/library/core/src/io/borrowed_buf.rs @@ -108,6 +108,26 @@ impl<'data> BorrowedBuf<'data> { } } + /// Returns a shared reference to the filled portion of the buffer with its original lifetime. + #[inline] + pub fn into_filled(self) -> &'data [u8] { + // SAFETY: We only slice the filled part of the buffer, which is always valid + unsafe { + let buf = self.buf.get_unchecked(..self.filled); + MaybeUninit::slice_assume_init_ref(buf) + } + } + + /// Returns a mutable reference to the filled portion of the buffer with its original lifetime. + #[inline] + pub fn into_filled_mut(self) -> &'data mut [u8] { + // SAFETY: We only slice the filled part of the buffer, which is always valid + unsafe { + let buf = self.buf.get_unchecked_mut(..self.filled); + MaybeUninit::slice_assume_init_mut(buf) + } + } + /// Returns a cursor over the unfilled part of the buffer. #[inline] pub fn unfilled<'this>(&'this mut self) -> BorrowedCursor<'this> { diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index ffaf1bc56e942..38dfbbef39323 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -1553,7 +1553,7 @@ pub trait Iterator { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a + /// Panics if `N` is zero. This check will most probably get changed to a /// compile time error before this method gets stabilized. /// /// ```should_panic @@ -3454,7 +3454,7 @@ pub trait Iterator { /// /// # Panics /// - /// Panics if `N` is 0. + /// Panics if `N` is zero. /// /// # Examples /// diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index d30bf96cfd436..1b9a9ea3ecffc 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -107,9 +107,6 @@ // // Library features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(const_exact_div))] -#![cfg_attr(bootstrap, feature(const_fmt_arguments_new))] -#![cfg_attr(bootstrap, feature(const_ub_checks))] #![feature(array_ptr_get)] #![feature(asm_experimental_arch)] #![feature(const_align_of_val)] @@ -118,7 +115,6 @@ #![feature(const_black_box)] #![feature(const_eq_ignore_ascii_case)] #![feature(const_eval_select)] -#![feature(const_float_methods)] #![feature(const_heap)] #![feature(const_nonnull_new)] #![feature(const_ptr_sub_ptr)] @@ -145,6 +141,7 @@ #![feature(ptr_alignment_type)] #![feature(ptr_metadata)] #![feature(set_ptr_value)] +#![feature(slice_as_array)] #![feature(slice_as_chunks)] #![feature(slice_ptr_get)] #![feature(str_internals)] @@ -159,8 +156,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(strict_provenance))] -#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] @@ -174,6 +169,7 @@ #![feature(const_is_char_boundary)] #![feature(const_precise_live_drops)] #![feature(const_str_split_at)] +#![feature(const_trait_impl)] #![feature(decl_macro)] #![feature(deprecated_suggestion)] #![feature(doc_cfg)] @@ -209,6 +205,7 @@ #![feature(simd_ffi)] #![feature(staged_api)] #![feature(stmt_expr_attributes)] +#![feature(strict_provenance_lints)] #![feature(target_feature_11)] #![feature(trait_alias)] #![feature(transparent_unions)] @@ -258,7 +255,6 @@ pub mod assert_matches { } // We don't export this through #[macro_export] for now, to avoid breakage. -#[cfg(not(bootstrap))] #[unstable(feature = "autodiff", issue = "124509")] /// Unstable module containing the unstable `autodiff` macro. pub mod autodiff { diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 771c2d31b60e0..ab674b58902b5 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1554,7 +1554,6 @@ pub(crate) mod builtin { #[unstable(feature = "autodiff", issue = "124509")] #[allow_internal_unstable(rustc_attrs)] #[rustc_builtin_macro] - #[cfg(not(bootstrap))] pub macro autodiff($item:item) { /* compiler built-in */ } diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index c8ea52a1fb0b4..1620b949590d0 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -953,10 +953,11 @@ marker_impls! { /// /// This should be used for `~const` bounds, /// as non-const bounds will always hold for every type. -#[unstable(feature = "const_trait_impl", issue = "67792")] +#[unstable(feature = "const_destruct", issue = "133214")] #[lang = "destruct"] #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)] #[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(not(bootstrap), const_trait)] pub trait Destruct {} /// A marker for tuple types. diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 58315cb74f0a1..3c1a098374ef9 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -255,7 +255,11 @@ impl Clone for MaybeUninit { #[stable(feature = "maybe_uninit_debug", since = "1.41.0")] impl fmt::Debug for MaybeUninit { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad(type_name::()) + // NB: there is no `.pad_fmt` so we can't use a simpler `format_args!("MaybeUninit<{..}>"). + // This needs to be adjusted if `MaybeUninit` moves modules. + let full_name = type_name::(); + let short_name = full_name.split_once("mem::maybe_uninit::").unwrap().1; + f.pad(short_name) } } @@ -525,7 +529,7 @@ impl MaybeUninit { /// until they are, it is advisable to avoid them.) #[stable(feature = "maybe_uninit", since = "1.36.0")] #[rustc_const_stable(feature = "const_maybe_uninit_as_ptr", since = "1.59.0")] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline(always)] pub const fn as_ptr(&self) -> *const T { // `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer. @@ -567,7 +571,7 @@ impl MaybeUninit { /// until they are, it is advisable to avoid them.) #[stable(feature = "maybe_uninit", since = "1.36.0")] #[rustc_const_stable(feature = "const_maybe_uninit_as_mut_ptr", since = "1.83.0")] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline(always)] pub const fn as_mut_ptr(&mut self) -> *mut T { // `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer. @@ -907,10 +911,7 @@ impl MaybeUninit { /// }; /// ``` #[stable(feature = "maybe_uninit_ref", since = "1.55.0")] - #[rustc_const_stable( - feature = "const_maybe_uninit_assume_init", - since = "CURRENT_RUSTC_VERSION" - )] + #[rustc_const_stable(feature = "const_maybe_uninit_assume_init", since = "1.84.0")] #[inline(always)] pub const unsafe fn assume_init_mut(&mut self) -> &mut T { // SAFETY: the caller must guarantee that `self` is initialized. diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index 6746f0b2b316b..82f11f0eaac3c 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -1601,8 +1601,8 @@ impl Ipv6Addr { /// ``` #[must_use] #[inline] - #[stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "ipv6_is_unique_local", since = "1.84.0")] + #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "1.84.0")] pub const fn is_unique_local(&self) -> bool { (self.segments()[0] & 0xfe00) == 0xfc00 } @@ -1679,8 +1679,8 @@ impl Ipv6Addr { /// ``` #[must_use] #[inline] - #[stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "ipv6_is_unique_local", since = "1.84.0")] + #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "1.84.0")] pub const fn is_unicast_link_local(&self) -> bool { (self.segments()[0] & 0xffc0) == 0xfe80 } diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 3fac1ef099f35..abeccb7eea248 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -334,7 +334,7 @@ impl f128 { #[inline] #[must_use] #[unstable(feature = "f128", issue = "116909")] - #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs` + #[rustc_const_unstable(feature = "f128", issue = "116909")] pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. @@ -612,7 +612,6 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn recip(self) -> Self { 1.0 / self @@ -633,7 +632,6 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn to_degrees(self) -> Self { // Use a literal for better precision. @@ -657,7 +655,6 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn to_radians(self) -> f128 { // Use a literal for better precision. @@ -686,7 +683,7 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "this returns the result of the comparison, without modifying either input"] pub const fn max(self, other: f128) -> f128 { intrinsics::maxnumf128(self, other) @@ -712,7 +709,7 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "this returns the result of the comparison, without modifying either input"] pub const fn min(self, other: f128) -> f128 { intrinsics::minnumf128(self, other) @@ -1251,7 +1248,6 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn clamp(mut self, min: f128, max: f128) -> f128 { const_assert!( @@ -1292,7 +1288,7 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn abs(self) -> Self { // FIXME(f16_f128): replace with `intrinsics::fabsf128` when available @@ -1322,7 +1318,7 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn signum(self) -> f128 { if self.is_nan() { Self::NAN } else { 1.0_f128.copysign(self) } @@ -1360,7 +1356,7 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn copysign(self, sign: f128) -> f128 { // SAFETY: this is actually a safe intrinsic diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index eaac19f22f751..0d3e92695707c 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -326,7 +326,7 @@ impl f16 { #[inline] #[must_use] #[unstable(feature = "f16", issue = "116909")] - #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs` + #[rustc_const_unstable(feature = "f16", issue = "116909")] pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. @@ -605,7 +605,6 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn recip(self) -> Self { 1.0 / self @@ -626,7 +625,6 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn to_degrees(self) -> Self { // Use a literal for better precision. @@ -650,7 +648,6 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn to_radians(self) -> f16 { // Use a literal for better precision. @@ -677,7 +674,7 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "this returns the result of the comparison, without modifying either input"] pub const fn max(self, other: f16) -> f16 { intrinsics::maxnumf16(self, other) @@ -702,7 +699,7 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "this returns the result of the comparison, without modifying either input"] pub const fn min(self, other: f16) -> f16 { intrinsics::minnumf16(self, other) @@ -1228,7 +1225,6 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn clamp(mut self, min: f16, max: f16) -> f16 { const_assert!( @@ -1269,7 +1265,7 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn abs(self) -> Self { // FIXME(f16_f128): replace with `intrinsics::fabsf16` when available @@ -1298,7 +1294,7 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn signum(self) -> f16 { if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) } @@ -1336,7 +1332,7 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn copysign(self, sign: f16) -> f16 { // SAFETY: this is actually a safe intrinsic diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index ae9e69f56fba5..47dfce7530fb7 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -569,7 +569,6 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] - #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs` pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. @@ -819,7 +818,7 @@ impl f32 { /// ``` #[must_use = "this returns the result of the operation, without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn recip(self) -> f32 { 1.0 / self @@ -837,7 +836,7 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn to_degrees(self) -> f32 { // Use a constant for better precision. @@ -857,7 +856,7 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn to_radians(self) -> f32 { const RADS_PER_DEG: f32 = consts::PI / 180.0; @@ -879,7 +878,7 @@ impl f32 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn max(self, other: f32) -> f32 { intrinsics::maxnumf32(self, other) @@ -900,7 +899,7 @@ impl f32 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn min(self, other: f32) -> f32 { intrinsics::minnumf32(self, other) @@ -1397,7 +1396,7 @@ impl f32 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "clamp", since = "1.50.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn clamp(mut self, min: f32, max: f32) -> f32 { const_assert!( @@ -1434,7 +1433,7 @@ impl f32 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn abs(self) -> f32 { // SAFETY: this is actually a safe intrinsic @@ -1459,7 +1458,7 @@ impl f32 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn signum(self) -> f32 { if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) } @@ -1494,7 +1493,7 @@ impl f32 { #[must_use = "method returns a new number and does not mutate the original value"] #[inline] #[stable(feature = "copysign", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] pub const fn copysign(self, sign: f32) -> f32 { // SAFETY: this is actually a safe intrinsic unsafe { intrinsics::copysignf32(self, sign) } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 98dcbffd3b49e..c89023c1ae490 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -568,7 +568,6 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] - #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs` pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. @@ -836,7 +835,7 @@ impl f64 { /// ``` #[must_use = "this returns the result of the operation, without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn recip(self) -> f64 { 1.0 / self @@ -854,7 +853,7 @@ impl f64 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn to_degrees(self) -> f64 { // The division here is correctly rounded with respect to the true @@ -875,7 +874,7 @@ impl f64 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn to_radians(self) -> f64 { const RADS_PER_DEG: f64 = consts::PI / 180.0; @@ -897,7 +896,7 @@ impl f64 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn max(self, other: f64) -> f64 { intrinsics::maxnumf64(self, other) @@ -918,7 +917,7 @@ impl f64 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn min(self, other: f64) -> f64 { intrinsics::minnumf64(self, other) @@ -1397,7 +1396,7 @@ impl f64 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "clamp", since = "1.50.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn clamp(mut self, min: f64, max: f64) -> f64 { const_assert!( @@ -1434,7 +1433,7 @@ impl f64 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn abs(self) -> f64 { // SAFETY: this is actually a safe intrinsic @@ -1459,7 +1458,7 @@ impl f64 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn signum(self) -> f64 { if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) } @@ -1493,7 +1492,7 @@ impl f64 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "copysign", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn copysign(self, sign: f64) -> f64 { // SAFETY: this is actually a safe intrinsic diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 318bb8ee4cda2..9a202600988c4 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1152,7 +1152,6 @@ macro_rules! int_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_neg", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_neg(self) -> Self { @@ -1217,7 +1216,6 @@ macro_rules! int_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1282,7 +1280,6 @@ macro_rules! int_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { @@ -1340,7 +1337,6 @@ macro_rules! int_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1405,7 +1401,6 @@ macro_rules! int_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { @@ -1613,8 +1608,8 @@ macro_rules! int_impl { /// ``` #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_isqrt(), Some(3));")] /// ``` - #[stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "isqrt", since = "1.84.0")] + #[rustc_const_stable(feature = "isqrt", since = "1.84.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1828,7 +1823,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -1986,7 +1981,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2014,7 +2009,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2042,7 +2037,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2069,7 +2064,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2101,6 +2096,7 @@ macro_rules! int_impl { /// /// ``` #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_neg(), -100);")] + #[doc = concat!("assert_eq!((-100", stringify!($SelfT), ").wrapping_neg(), 100);")] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.wrapping_neg(), ", stringify!($SelfT), "::MIN);")] /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] @@ -2133,7 +2129,6 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shl(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds @@ -2163,7 +2158,6 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shr(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds @@ -2525,7 +2519,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2556,7 +2550,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2587,7 +2581,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2618,7 +2612,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2859,8 +2853,8 @@ macro_rules! int_impl { /// ``` #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")] /// ``` - #[stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "isqrt", since = "1.84.0")] + #[rustc_const_stable(feature = "isqrt", since = "1.84.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2886,7 +2880,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN` + /// This function will panic if `rhs` is zero or if `self` is `Self::MIN` /// and `rhs` is -1. This behavior is not affected by the `overflow-checks` flag. /// /// # Examples @@ -2925,7 +2919,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN` and + /// This function will panic if `rhs` is zero or if `self` is `Self::MIN` and /// `rhs` is -1. This behavior is not affected by the `overflow-checks` flag. /// /// # Examples @@ -2974,7 +2968,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN` + /// This function will panic if `rhs` is zero or if `self` is `Self::MIN` /// and `rhs` is -1. This behavior is not affected by the `overflow-checks` flag. /// /// # Examples @@ -3018,7 +3012,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN` + /// This function will panic if `rhs` is zero or if `self` is `Self::MIN` /// and `rhs` is -1. This behavior is not affected by the `overflow-checks` flag. /// /// # Examples diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 9d9897b9cf05e..995ed6eac3015 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -677,7 +677,7 @@ impl u8 { /// /// [`to_ascii_uppercase`]: Self::to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); @@ -703,7 +703,7 @@ impl u8 { /// /// [`to_ascii_lowercase`]: Self::to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); @@ -1449,7 +1449,6 @@ from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 } #[doc(hidden)] #[inline(always)] #[unstable(issue = "none", feature = "std_internals")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_from_str", since = "1.82.0"))] pub const fn can_not_overflow(radix: u32, is_signed_ty: bool, digits: &[u8]) -> bool { radix <= 16 && digits.len() <= mem::size_of::() * 2 - is_signed_ty as usize } diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index b883a0c2ec7f9..dba64d5dc8e34 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -139,9 +139,9 @@ impl_nonzero_fmt! { LowerHex #[stable(feature = "nonzero", since = "1.28.0")] UpperHex - #[stable(feature = "nonzero_fmt_exp", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "nonzero_fmt_exp", since = "1.84.0")] LowerExp - #[stable(feature = "nonzero_fmt_exp", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "nonzero_fmt_exp", since = "1.84.0")] UpperExp } @@ -1587,8 +1587,8 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Some(()) /// # } /// ``` - #[stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "isqrt", since = "1.84.0")] + #[rustc_const_stable(feature = "isqrt", since = "1.84.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 0383c13fa082d..90b986f4998db 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1434,7 +1434,6 @@ macro_rules! uint_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1499,7 +1498,6 @@ macro_rules! uint_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { @@ -1557,7 +1555,6 @@ macro_rules! uint_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1622,7 +1619,6 @@ macro_rules! uint_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { @@ -1877,7 +1873,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2034,7 +2030,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2063,7 +2059,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2091,7 +2087,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2121,7 +2117,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2193,7 +2189,6 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shl(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds @@ -2226,7 +2221,6 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shr(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds @@ -2545,7 +2539,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2576,7 +2570,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2604,7 +2598,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2635,7 +2629,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2838,8 +2832,8 @@ macro_rules! uint_impl { /// ``` #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")] /// ``` - #[stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "isqrt", since = "1.84.0")] + #[rustc_const_stable(feature = "isqrt", since = "1.84.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2872,7 +2866,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2900,7 +2894,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -3091,7 +3085,6 @@ macro_rules! uint_impl { // overflow cases it instead ends up returning the maximum value // of the type, and can return 0 for 0. #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_pow", since = "1.50.0"))] const fn one_less_than_next_power_of_two(self) -> Self { if self <= 1 { return 0; } diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs index 133ae04f02618..565bccf589826 100644 --- a/library/core/src/ops/arith.rs +++ b/library/core/src/ops/arith.rs @@ -73,6 +73,7 @@ append_const_msg )] #[doc(alias = "+")] +#[cfg_attr(not(bootstrap), const_trait)] pub trait Add { /// The resulting type after applying the `+` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -94,6 +95,7 @@ pub trait Add { macro_rules! add_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(bootstrap)] impl Add for $t { type Output = $t; @@ -103,6 +105,17 @@ macro_rules! add_impl { fn add(self, other: $t) -> $t { self + other } } + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(bootstrap))] + impl const Add for $t { + type Output = $t; + + #[inline] + #[track_caller] + #[rustc_inherit_overflow_checks] + fn add(self, other: $t) -> $t { self + other } + } + forward_ref_binop! { impl Add, add for $t, $t } )*) } diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index 45688727c9b36..c36d55fe2a8c1 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -133,6 +133,7 @@ #[doc(alias = "&*")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Deref"] +#[cfg_attr(not(bootstrap), const_trait)] pub trait Deref { /// The resulting type after dereferencing. #[stable(feature = "rust1", since = "1.0.0")] @@ -147,6 +148,7 @@ pub trait Deref { fn deref(&self) -> &Self::Target; } +#[cfg(bootstrap)] #[stable(feature = "rust1", since = "1.0.0")] impl Deref for &T { type Target = T; @@ -157,9 +159,21 @@ impl Deref for &T { } } +#[cfg(not(bootstrap))] +#[stable(feature = "rust1", since = "1.0.0")] +impl const Deref for &T { + type Target = T; + + #[rustc_diagnostic_item = "noop_method_deref"] + fn deref(&self) -> &T { + *self + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl !DerefMut for &T {} +#[cfg(bootstrap)] #[stable(feature = "rust1", since = "1.0.0")] impl Deref for &mut T { type Target = T; @@ -169,6 +183,16 @@ impl Deref for &mut T { } } +#[cfg(not(bootstrap))] +#[stable(feature = "rust1", since = "1.0.0")] +impl const Deref for &mut T { + type Target = T; + + fn deref(&self) -> &T { + *self + } +} + /// Used for mutable dereferencing operations, like in `*v = 1;`. /// /// In addition to being used for explicit dereferencing operations with the @@ -258,9 +282,23 @@ impl Deref for &mut T { /// *x = 'b'; /// assert_eq!('b', x.value); /// ``` +#[cfg(not(bootstrap))] +#[lang = "deref_mut"] +#[doc(alias = "*")] +#[stable(feature = "rust1", since = "1.0.0")] +#[const_trait] +pub trait DerefMut: ~const Deref { + /// Mutably dereferences the value. + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_diagnostic_item = "deref_mut_method"] + fn deref_mut(&mut self) -> &mut Self::Target; +} + +/// Bootstrap #[lang = "deref_mut"] #[doc(alias = "*")] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg(bootstrap)] pub trait DerefMut: Deref { /// Mutably dereferences the value. #[stable(feature = "rust1", since = "1.0.0")] @@ -268,6 +306,7 @@ pub trait DerefMut: Deref { fn deref_mut(&mut self) -> &mut Self::Target; } +#[cfg(bootstrap)] #[stable(feature = "rust1", since = "1.0.0")] impl DerefMut for &mut T { fn deref_mut(&mut self) -> &mut T { @@ -275,6 +314,14 @@ impl DerefMut for &mut T { } } +#[cfg(not(bootstrap))] +#[stable(feature = "rust1", since = "1.0.0")] +impl const DerefMut for &mut T { + fn deref_mut(&mut self) -> &mut T { + *self + } +} + /// Perma-unstable marker trait. Indicates that the type has a well-behaved [`Deref`] /// (and, if applicable, [`DerefMut`]) implementation. This is relied on for soundness /// of deref patterns. @@ -358,18 +405,15 @@ unsafe impl DerefPure for &mut T {} /// } /// ``` #[lang = "receiver"] -#[cfg(not(bootstrap))] #[unstable(feature = "arbitrary_self_types", issue = "44874")] pub trait Receiver { /// The target type on which the method may be called. - #[cfg(not(bootstrap))] #[rustc_diagnostic_item = "receiver_target"] #[lang = "receiver_target"] #[unstable(feature = "arbitrary_self_types", issue = "44874")] type Target: ?Sized; } -#[cfg(not(bootstrap))] #[unstable(feature = "arbitrary_self_types", issue = "44874")] impl Receiver for P where @@ -386,8 +430,7 @@ where /// facility based around the current "arbitrary self types" unstable feature. /// That new facility will use the replacement trait above called `Receiver` /// which is why this is now named `LegacyReceiver`. -#[cfg_attr(bootstrap, lang = "receiver")] -#[cfg_attr(not(bootstrap), lang = "legacy_receiver")] +#[lang = "legacy_receiver"] #[unstable(feature = "legacy_receiver_trait", issue = "none")] #[doc(hidden)] pub trait LegacyReceiver { diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs index a6f63ad68d695..f3314364e5428 100644 --- a/library/core/src/ops/drop.rs +++ b/library/core/src/ops/drop.rs @@ -203,7 +203,7 @@ /// [nomicon]: ../../nomicon/phantom-data.html#an-exception-the-special-case-of-the-standard-library-and-its-unstable-may_dangle #[lang = "drop"] #[stable(feature = "rust1", since = "1.0.0")] -// FIXME(const_trait_impl) #[const_trait] +#[cfg_attr(not(bootstrap), const_trait)] pub trait Drop { /// Executes the destructor for this type. /// diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs index cea1f84f3fd60..40526f9583e64 100644 --- a/library/core/src/ops/mod.rs +++ b/library/core/src/ops/mod.rs @@ -171,7 +171,6 @@ pub use self::deref::DerefPure; #[unstable(feature = "legacy_receiver_trait", issue = "none")] pub use self::deref::LegacyReceiver; #[unstable(feature = "arbitrary_self_types", issue = "44874")] -#[cfg(not(bootstrap))] pub use self::deref::Receiver; #[stable(feature = "rust1", since = "1.0.0")] pub use self::deref::{Deref, DerefMut}; diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 29d1956af9559..f4ac7af63961b 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -563,7 +563,7 @@ use crate::pin::Pin; use crate::{cmp, convert, hint, mem, slice}; /// The `Option` type. See [the module level documentation](self) for more. -#[cfg_attr(not(bootstrap), doc(search_unbox))] +#[doc(search_unbox)] #[derive(Copy, Eq, Debug, Hash)] #[rustc_diagnostic_item = "Option"] #[lang = "Option"] @@ -738,7 +738,7 @@ impl Option { #[inline] #[must_use] #[stable(feature = "pin", since = "1.33.0")] - #[rustc_const_stable(feature = "const_option_ext", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option_ext", since = "1.84.0")] pub const fn as_pin_ref(self: Pin<&Self>) -> Option> { // FIXME(const-hack): use `map` once that is possible match Pin::get_ref(self).as_ref() { @@ -755,7 +755,7 @@ impl Option { #[inline] #[must_use] #[stable(feature = "pin", since = "1.33.0")] - #[rustc_const_stable(feature = "const_option_ext", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option_ext", since = "1.84.0")] pub const fn as_pin_mut(self: Pin<&mut Self>) -> Option> { // SAFETY: `get_unchecked_mut` is never used to move the `Option` inside `self`. // `x` is guaranteed to be pinned because it comes from `self` which is pinned. @@ -802,7 +802,7 @@ impl Option { #[inline] #[must_use] #[stable(feature = "option_as_slice", since = "1.75.0")] - #[rustc_const_stable(feature = "const_option_ext", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option_ext", since = "1.84.0")] pub const fn as_slice(&self) -> &[T] { // SAFETY: When the `Option` is `Some`, we're using the actual pointer // to the payload, with a length of 1, so this is equivalent to @@ -857,7 +857,7 @@ impl Option { #[inline] #[must_use] #[stable(feature = "option_as_slice", since = "1.75.0")] - #[rustc_const_stable(feature = "const_option_ext", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option_ext", since = "1.84.0")] pub const fn as_mut_slice(&mut self) -> &mut [T] { // SAFETY: When the `Option` is `Some`, we're using the actual pointer // to the payload, with a length of 1, so this is equivalent to diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index 179aadf0c286c..5fa340a6147f6 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -208,14 +208,13 @@ pub macro const_panic { #[rustc_allow_const_fn_unstable(const_eval_select)] #[inline(always)] // inline the wrapper #[track_caller] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_panic", since = "CURRENT_RUSTC_VERSION"))] const fn do_panic($($arg: $ty),*) -> ! { $crate::intrinsics::const_eval_select!( @capture { $($arg: $ty = $arg),* } -> !: #[noinline] if const #[track_caller] #[inline] { // Inline this, to prevent codegen $crate::panic!($const_msg) - } else #[track_caller] #[cfg_attr(bootstrap, inline)] { // Do not inline this, it makes perf worse + } else #[track_caller] { // Do not inline this, it makes perf worse $crate::panic!($runtime_msg) } ) diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 230a9918dbf3e..9d53567a26fd9 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -165,7 +165,7 @@ impl<'a> PanicMessage<'a> { /// /// See [`fmt::Arguments::as_str`] for details. #[stable(feature = "panic_info_message", since = "1.81.0")] - #[rustc_const_stable(feature = "const_arguments_as_str", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_arguments_as_str", since = "1.84.0")] #[must_use] #[inline] pub const fn as_str(&self) -> Option<&'static str> { diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index f603eb2971f6d..53e2b238bae69 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -51,8 +51,7 @@ const _: () = assert!(cfg!(panic = "abort"), "panic_immediate_abort requires -C #[track_caller] #[lang = "panic_fmt"] // needed for const-evaluated panics #[rustc_do_not_const_check] // hooked by const-eval -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { if cfg!(feature = "panic_immediate_abort") { super::intrinsics::abort() @@ -86,8 +85,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { // and unwinds anyway, we will hit the "unwinding out of nounwind function" guard, // which causes a "panic in a function that cannot unwind". #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable #[rustc_allow_const_fn_unstable(const_eval_select)] pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! { const_eval_select!( @@ -130,8 +128,7 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable #[lang = "panic"] // used by lints and miri for panics pub const fn panic(expr: &'static str) -> ! { // Use Arguments::new_const instead of format_args!("{expr}") to potentially @@ -169,8 +166,7 @@ macro_rules! panic_const { #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable + #[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable #[lang = stringify!($lang)] pub const fn $lang() -> ! { // Use Arguments::new_const instead of format_args!("{expr}") to potentially @@ -217,8 +213,7 @@ panic_const! { #[cfg_attr(feature = "panic_immediate_abort", inline)] #[lang = "panic_nounwind"] // needed by codegen for non-unwinding panics #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable pub const fn panic_nounwind(expr: &'static str) -> ! { panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ false); } @@ -234,8 +229,7 @@ pub fn panic_nounwind_nobacktrace(expr: &'static str) -> ! { #[track_caller] #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable pub const fn panic_explicit() -> ! { panic_display(&"explicit panic"); } @@ -252,8 +246,7 @@ pub fn unreachable_display(x: &T) -> ! { #[inline] #[track_caller] #[rustc_diagnostic_item = "panic_str_2015"] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable pub const fn panic_str_2015(expr: &str) -> ! { panic_display(&expr); } @@ -263,8 +256,7 @@ pub const fn panic_str_2015(expr: &str) -> ! { #[rustc_do_not_const_check] // hooked by const-eval // enforce a &&str argument in const-check and hook this by const-eval #[rustc_const_panic_str] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable pub const fn panic_display(x: &T) -> ! { panic_fmt(format_args!("{}", *x)); } @@ -333,8 +325,7 @@ fn panic_in_cleanup() -> ! { /// This function is used instead of panic_fmt in const eval. #[lang = "const_panic_fmt"] // needed by const-eval machine to replace calls to `panic_fmt` lang item -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable pub const fn const_panic_fmt(fmt: fmt::Arguments<'_>) -> ! { if let Some(msg) = fmt.as_str() { // The panic_display function is hooked by const eval. diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index c14c49a0d92f9..f18a45083ff7e 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -373,9 +373,9 @@ //! exactly what we did with our `AddrTracker` example above. Without doing this, you *must not* //! rely on pinning-related guarantees to apply to your type! //! -//! If need to truly pin a value of a foreign or built-in type that implements [`Unpin`], you'll -//! need to create your own wrapper type around the [`Unpin`] type you want to pin and then -//! opts-out of [`Unpin`] using [`PhantomPinned`]. +//! If you really need to pin a value of a foreign or built-in type that implements [`Unpin`], +//! you'll need to create your own wrapper type around the [`Unpin`] type you want to pin and then +//! opt-out of [`Unpin`] using [`PhantomPinned`]. //! //! Exposing access to the inner field which you want to remain pinned must then be carefully //! considered as well! Remember, exposing a method that gives access to a @@ -1186,7 +1186,7 @@ impl> Pin { /// let mut pinned: Pin<&mut u8> = Pin::new(&mut val); /// ``` #[inline(always)] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin", since = "1.33.0")] pub const fn new(pointer: Ptr) -> Pin { // SAFETY: the value pointed to is `Unpin`, and so has no requirements @@ -1215,7 +1215,7 @@ impl> Pin { /// ``` #[inline(always)] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin_into_inner", since = "1.39.0")] pub const fn into_inner(pin: Pin) -> Ptr { pin.__pointer @@ -1352,7 +1352,7 @@ impl Pin { /// [`pin` module docs]: self #[lang = "new_unchecked"] #[inline(always)] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin", since = "1.33.0")] pub const unsafe fn new_unchecked(pointer: Ptr) -> Pin { Pin { __pointer: pointer } @@ -1423,7 +1423,7 @@ impl Pin { /// move in the future, and this method does not enable the pointee to move. "Malicious" /// implementations of `Ptr::DerefMut` are likewise ruled out by the contract of /// `Pin::new_unchecked`. - #[stable(feature = "pin_deref_mut", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "pin_deref_mut", since = "1.84.0")] #[must_use = "`self` will be dropped if the result is not used"] #[inline(always)] pub fn as_deref_mut(self: Pin<&mut Pin>) -> Pin<&mut Ptr::Target> { @@ -1505,7 +1505,7 @@ impl Pin { /// instead. #[inline(always)] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin_into_inner", since = "1.39.0")] pub const unsafe fn into_inner_unchecked(pin: Pin) -> Ptr { pin.__pointer @@ -1561,7 +1561,7 @@ impl<'a, T: ?Sized> Pin<&'a T> { /// ["pinning projections"]: self#projections-and-structural-pinning #[inline(always)] #[must_use] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin", since = "1.33.0")] pub const fn get_ref(self) -> &'a T { self.__pointer @@ -1572,7 +1572,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { /// Converts this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime. #[inline(always)] #[must_use = "`self` will be dropped if the result is not used"] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin", since = "1.33.0")] pub const fn into_ref(self) -> Pin<&'a T> { Pin { __pointer: self.__pointer } @@ -1590,7 +1590,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { #[inline(always)] #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "pin", since = "1.33.0")] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] pub const fn get_mut(self) -> &'a mut T where T: Unpin, @@ -1611,7 +1611,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { #[inline(always)] #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "pin", since = "1.33.0")] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] pub const unsafe fn get_unchecked_mut(self) -> &'a mut T { self.__pointer } @@ -1654,7 +1654,7 @@ impl Pin<&'static T> { /// This is safe because `T` is borrowed immutably for the `'static` lifetime, which /// never ends. #[stable(feature = "pin_static_ref", since = "1.61.0")] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] pub const fn static_ref(r: &'static T) -> Pin<&'static T> { // SAFETY: The 'static borrow guarantees the data will not be // moved/invalidated until it gets dropped (which is never). @@ -1668,7 +1668,7 @@ impl Pin<&'static mut T> { /// This is safe because `T` is borrowed for the `'static` lifetime, which /// never ends. #[stable(feature = "pin_static_ref", since = "1.61.0")] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] pub const fn static_mut(r: &'static mut T) -> Pin<&'static mut T> { // SAFETY: The 'static borrow guarantees the data will not be // moved/invalidated until it gets dropped (which is never). diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index 2538d60a8eee9..74a1d40f4e734 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -41,7 +41,6 @@ impl Alignment { /// This provides the same numerical value as [`mem::align_of`], /// but in an `Alignment` instead of a `usize`. #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const fn of() -> Self { // SAFETY: rustc ensures that type alignment is always a power of two. @@ -53,7 +52,6 @@ impl Alignment { /// /// Note that `0` is not a power of two, nor a valid alignment. #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const fn new(align: usize) -> Option { if align.is_power_of_two() { @@ -73,7 +71,6 @@ impl Alignment { /// Equivalently, it must be `1 << exp` for some `exp` in `0..usize::BITS`. /// It must *not* be zero. #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const unsafe fn new_unchecked(align: usize) -> Self { assert_unsafe_precondition!( @@ -89,7 +86,6 @@ impl Alignment { /// Returns the alignment as a [`usize`]. #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const fn as_usize(self) -> usize { self.0 as usize @@ -97,7 +93,6 @@ impl Alignment { /// Returns the alignment as a [NonZero]<[usize]>. #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const fn as_nonzero(self) -> NonZero { // SAFETY: All the discriminants are non-zero. @@ -118,7 +113,6 @@ impl Alignment { /// assert_eq!(Alignment::new(1024).unwrap().log2(), 10); /// ``` #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const fn log2(self) -> u32 { self.as_nonzero().trailing_zeros() @@ -148,7 +142,6 @@ impl Alignment { /// assert_ne!(one.mask(Alignment::of::().mask()), one); /// ``` #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const fn mask(self) -> usize { // SAFETY: The alignment is always nonzero, and therefore decrementing won't overflow. diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 0dbe819acb1b9..6f6815f49cd29 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -29,7 +29,7 @@ impl *const T { /// assert!(!ptr.is_null()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")] #[rustc_diagnostic_item = "ptr_const_is_null"] #[inline] #[rustc_allow_const_fn_unstable(const_eval_select)] @@ -113,7 +113,6 @@ impl *const T { /// println!("{:?}", unsafe { &*bad }); /// ``` #[unstable(feature = "set_ptr_value", issue = "75091")] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))] #[must_use = "returns a new pointer rather than modifying its argument"] #[inline] pub const fn with_metadata_of(self, meta: *const U) -> *const U @@ -159,7 +158,7 @@ impl *const T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline(always)] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn addr(self) -> usize { // A pointer-to-integer transmute currently has exactly the right semantics: it returns the // address without exposing the provenance. Note that this is *not* a stable guarantee about @@ -193,7 +192,7 @@ impl *const T { /// [`with_exposed_provenance`]: with_exposed_provenance #[must_use] #[inline(always)] - #[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "exposed_provenance", since = "1.84.0")] pub fn expose_provenance(self) -> usize { self.cast::<()>() as usize } @@ -211,7 +210,7 @@ impl *const T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn with_addr(self, addr: usize) -> Self { // This should probably be an intrinsic to avoid doing any sort of arithmetic, but // meanwhile, we can implement it with `wrapping_offset`, which preserves the pointer's @@ -230,7 +229,7 @@ impl *const T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self { self.with_addr(f(self.addr())) } @@ -282,7 +281,7 @@ impl *const T { /// } /// ``` #[stable(feature = "ptr_as_ref", since = "1.9.0")] - #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")] #[inline] pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> { // SAFETY: the caller must guarantee that `self` is valid @@ -1018,7 +1017,6 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self @@ -1526,6 +1524,22 @@ impl *const [T] { self as *const T } + /// Gets a raw pointer to the underlying array. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[rustc_const_unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub const fn as_array(self) -> Option<*const [T; N]> { + if self.len() == N { + let me = self.as_ptr() as *const [T; N]; + Some(me) + } else { + None + } + } + /// Returns a raw pointer to an element or subslice, without doing bounds /// checking. /// diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 5f20cb2ee7206..ae9810e558aa1 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -92,7 +92,6 @@ pub trait Thin = Pointee; /// /// assert_eq!(std::ptr::metadata("foo"), 3_usize); /// ``` -#[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))] #[inline] pub const fn metadata(ptr: *const T) -> ::Metadata { ptr_metadata(ptr) @@ -106,7 +105,6 @@ pub const fn metadata(ptr: *const T) -> ::Metadata { /// /// [`slice::from_raw_parts`]: crate::slice::from_raw_parts #[unstable(feature = "ptr_metadata", issue = "81513")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))] #[inline] pub const fn from_raw_parts( data_pointer: *const impl Thin, @@ -120,7 +118,6 @@ pub const fn from_raw_parts( /// /// See the documentation of [`from_raw_parts`] for more details. #[unstable(feature = "ptr_metadata", issue = "81513")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))] #[inline] pub const fn from_raw_parts_mut( data_pointer: *mut impl Thin, diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 805edddfe6312..6147e9f5e6190 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -591,8 +591,8 @@ pub const fn null_mut() -> *mut T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[inline(always)] #[must_use] -#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] -#[rustc_const_stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "strict_provenance", since = "1.84.0")] +#[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")] pub const fn without_provenance(addr: usize) -> *const T { // An int-to-pointer transmute currently has exactly the intended semantics: it creates a // pointer without provenance. Note that this is *not* a stable guarantee about transmute @@ -613,8 +613,8 @@ pub const fn without_provenance(addr: usize) -> *const T { /// some other means. #[inline(always)] #[must_use] -#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] -#[rustc_const_stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "strict_provenance", since = "1.84.0")] +#[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")] pub const fn dangling() -> *const T { without_provenance(mem::align_of::()) } @@ -634,8 +634,8 @@ pub const fn dangling() -> *const T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[inline(always)] #[must_use] -#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] -#[rustc_const_stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "strict_provenance", since = "1.84.0")] +#[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")] pub const fn without_provenance_mut(addr: usize) -> *mut T { // An int-to-pointer transmute currently has exactly the intended semantics: it creates a // pointer without provenance. Note that this is *not* a stable guarantee about transmute @@ -656,8 +656,8 @@ pub const fn without_provenance_mut(addr: usize) -> *mut T { /// some other means. #[inline(always)] #[must_use] -#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] -#[rustc_const_stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "strict_provenance", since = "1.84.0")] +#[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")] pub const fn dangling_mut() -> *mut T { without_provenance_mut(mem::align_of::()) } @@ -695,7 +695,7 @@ pub const fn dangling_mut() -> *mut T { /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API. #[must_use] #[inline(always)] -#[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "exposed_provenance", since = "1.84.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead pub fn with_exposed_provenance(addr: usize) -> *const T { @@ -735,7 +735,7 @@ pub fn with_exposed_provenance(addr: usize) -> *const T { /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API. #[must_use] #[inline(always)] -#[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "exposed_provenance", since = "1.84.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead pub fn with_exposed_provenance_mut(addr: usize) -> *mut T { diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index f0204bd0f773d..678c6029158b5 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -29,7 +29,7 @@ impl *mut T { /// assert!(!ptr.is_null()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")] #[rustc_diagnostic_item = "ptr_is_null"] #[inline] pub const fn is_null(self) -> bool { @@ -94,7 +94,6 @@ impl *mut T { /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`. /// println!("{:?}", unsafe { &*bad }); #[unstable(feature = "set_ptr_value", issue = "75091")] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))] #[must_use = "returns a new pointer rather than modifying its argument"] #[inline] pub const fn with_metadata_of(self, meta: *const U) -> *mut U @@ -146,7 +145,7 @@ impl *mut T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline(always)] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn addr(self) -> usize { // A pointer-to-integer transmute currently has exactly the right semantics: it returns the // address without exposing the provenance. Note that this is *not* a stable guarantee about @@ -179,7 +178,7 @@ impl *mut T { /// /// [`with_exposed_provenance_mut`]: with_exposed_provenance_mut #[inline(always)] - #[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "exposed_provenance", since = "1.84.0")] pub fn expose_provenance(self) -> usize { self.cast::<()>() as usize } @@ -197,7 +196,7 @@ impl *mut T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn with_addr(self, addr: usize) -> Self { // This should probably be an intrinsic to avoid doing any sort of arithmetic, but // meanwhile, we can implement it with `wrapping_offset`, which preserves the pointer's @@ -216,7 +215,7 @@ impl *mut T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self { self.with_addr(f(self.addr())) } @@ -271,7 +270,7 @@ impl *mut T { /// } /// ``` #[stable(feature = "ptr_as_ref", since = "1.9.0")] - #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")] #[inline] pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> { // SAFETY: the caller must guarantee that `self` is valid for a @@ -619,7 +618,7 @@ impl *mut T { /// println!("{s:?}"); // It'll print: "[4, 2, 3]". /// ``` #[stable(feature = "ptr_as_ref", since = "1.9.0")] - #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")] #[inline] pub const unsafe fn as_mut<'a>(self) -> Option<&'a mut T> { // SAFETY: the caller must guarantee that `self` is be valid for @@ -1097,7 +1096,6 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self @@ -1760,6 +1758,22 @@ impl *mut [T] { self.len() == 0 } + /// Gets a raw, mutable pointer to the underlying array. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[rustc_const_unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub const fn as_mut_array(self) -> Option<*mut [T; N]> { + if self.len() == N { + let me = self.as_mut_ptr() as *mut [T; N]; + Some(me) + } else { + None + } + } + /// Divides one mutable raw slice into two at an index. /// /// The first will contain all indices from `[0, mid)` (excluding diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index b69f8a4b9d3ea..d37b7eedfcbdb 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -278,7 +278,7 @@ impl NonNull { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn addr(self) -> NonZero { // SAFETY: The pointer is guaranteed by the type to be non-null, // meaning that the address will be non-zero. @@ -293,7 +293,7 @@ impl NonNull { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn with_addr(self, addr: NonZero) -> Self { // SAFETY: The result of `ptr::from::with_addr` is non-null because `addr` is guaranteed to be non-zero. unsafe { NonNull::new_unchecked(self.pointer.with_addr(addr.get()) as *mut _) } @@ -307,7 +307,7 @@ impl NonNull { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn map_addr(self, f: impl FnOnce(NonZero) -> NonZero) -> Self { self.with_addr(f(self.addr())) } @@ -629,7 +629,6 @@ impl NonNull { #[must_use = "returns a new pointer rather than modifying its argument"] #[stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))] pub const unsafe fn sub(self, count: usize) -> Self where T: Sized, diff --git a/library/core/src/result.rs b/library/core/src/result.rs index b450123c5aa90..9c7be618bc773 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -520,7 +520,7 @@ use crate::{convert, fmt, hint}; /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]). /// /// See the [module documentation](self) for details. -#[cfg_attr(not(bootstrap), doc(search_unbox))] +#[doc(search_unbox)] #[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] #[must_use = "this `Result` may be an `Err` variant, which should be handled"] #[rustc_diagnostic_item = "Result"] diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 17ad4fd8f677f..7cdb896586f13 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -88,7 +88,7 @@ impl [u8] { /// /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_uppercase(&mut self) { // FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions. @@ -110,7 +110,7 @@ impl [u8] { /// /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_lowercase(&mut self) { // FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions. diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 339adad1b17bf..98db7aaf53321 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -16,7 +16,6 @@ const USIZE_BYTES: usize = mem::size_of::(); /// bytes where the borrow propagated all the way to the most significant /// bit." #[inline] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_memchr", since = "1.65.0"))] const fn contains_zero_byte(x: usize) -> bool { x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0 } @@ -24,7 +23,6 @@ const fn contains_zero_byte(x: usize) -> bool { /// Returns the first index matching the byte `x` in `text`. #[inline] #[must_use] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_memchr", since = "1.65.0"))] pub const fn memchr(x: u8, text: &[u8]) -> Option { // Fast path for small slices. if text.len() < 2 * USIZE_BYTES { @@ -35,7 +33,6 @@ pub const fn memchr(x: u8, text: &[u8]) -> Option { } #[inline] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_memchr", since = "1.65.0"))] const fn memchr_naive(x: u8, text: &[u8]) -> Option { let mut i = 0; @@ -52,7 +49,6 @@ const fn memchr_naive(x: u8, text: &[u8]) -> Option { } #[rustc_allow_const_fn_unstable(const_eval_select)] // fallback impl has same behavior -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_memchr", since = "1.65.0"))] const fn memchr_aligned(x: u8, text: &[u8]) -> Option { // The runtime version behaves the same as the compiletime version, it's // just more optimized. diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index c855f963771ed..a24417dba8cc2 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -10,10 +10,10 @@ use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::intrinsics::{exact_div, select_unpredictable, unchecked_sub}; use crate::mem::{self, SizedTypeProperties}; use crate::num::NonZero; -use crate::ops::{Bound, OneSidedRange, Range, RangeBounds}; +use crate::ops::{Bound, OneSidedRange, Range, RangeBounds, RangeInclusive}; use crate::simd::{self, Simd}; use crate::ub_checks::assert_unsafe_precondition; -use crate::{fmt, hint, ptr, slice}; +use crate::{fmt, hint, ptr, range, slice}; #[unstable( feature = "slice_internals", @@ -735,7 +735,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline(always)] #[must_use] pub const fn as_ptr(&self) -> *const T { @@ -766,7 +766,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline(always)] #[must_use] pub const fn as_mut_ptr(&mut self) -> *mut T { @@ -855,6 +855,44 @@ impl [T] { start..end } + /// Gets a reference to the underlying array. + /// + /// If `N` is not exactly equal to slice's the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[rustc_const_unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub const fn as_array(&self) -> Option<&[T; N]> { + if self.len() == N { + let ptr = self.as_ptr() as *const [T; N]; + + // SAFETY: The underlying array of a slice can be reinterpreted as an actual array `[T; N]` if `N` is not greater than the slice's length. + let me = unsafe { &*ptr }; + Some(me) + } else { + None + } + } + + /// Gets a mutable reference to the slice's underlying array. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[rustc_const_unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub const fn as_mut_array(&mut self) -> Option<&mut [T; N]> { + if self.len() == N { + let ptr = self.as_mut_ptr() as *mut [T; N]; + + // SAFETY: The underlying array of a slice can be reinterpreted as an actual array `[T; N]` if `N` is not greater than the slice's length. + let me = unsafe { &mut *ptr }; + Some(me) + } else { + None + } + } + /// Swaps two elements in the slice. /// /// If `a` equals to `b`, it's guaranteed that elements won't change value. @@ -1039,7 +1077,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `size` is 0. + /// Panics if `size` is zero. /// /// # Examples /// @@ -1095,7 +1133,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1130,7 +1168,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1172,7 +1210,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1211,7 +1249,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1288,7 +1326,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1334,7 +1372,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1372,7 +1410,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1448,7 +1486,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1489,7 +1527,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1533,7 +1571,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1568,7 +1606,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1604,7 +1642,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1639,7 +1677,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1682,7 +1720,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1722,7 +1760,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -4469,6 +4507,12 @@ impl [T] { /// Returns mutable references to many indices at once, without doing any checks. /// + /// An index can be either a `usize`, a [`Range`] or a [`RangeInclusive`]. Note + /// that this method takes an array, so all indices must be of the same type. + /// If passed an array of `usize`s this method gives back an array of mutable references + /// to single elements, while if passed an array of ranges it gives back an array of + /// mutable references to slices. + /// /// For a safe alternative see [`get_many_mut`]. /// /// # Safety @@ -4489,30 +4533,49 @@ impl [T] { /// *b *= 100; /// } /// assert_eq!(x, &[10, 2, 400]); + /// + /// unsafe { + /// let [a, b] = x.get_many_unchecked_mut([0..1, 1..3]); + /// a[0] = 8; + /// b[0] = 88; + /// b[1] = 888; + /// } + /// assert_eq!(x, &[8, 88, 888]); + /// + /// unsafe { + /// let [a, b] = x.get_many_unchecked_mut([1..=2, 0..=0]); + /// a[0] = 11; + /// a[1] = 111; + /// b[0] = 1; + /// } + /// assert_eq!(x, &[1, 11, 111]); /// ``` /// /// [`get_many_mut`]: slice::get_many_mut /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html #[unstable(feature = "get_many_mut", issue = "104642")] #[inline] - pub unsafe fn get_many_unchecked_mut( + pub unsafe fn get_many_unchecked_mut( &mut self, - indices: [usize; N], - ) -> [&mut T; N] { + indices: [I; N], + ) -> [&mut I::Output; N] + where + I: GetManyMutIndex + SliceIndex, + { // NB: This implementation is written as it is because any variation of // `indices.map(|i| self.get_unchecked_mut(i))` would make miri unhappy, // or generate worse code otherwise. This is also why we need to go // through a raw pointer here. let slice: *mut [T] = self; - let mut arr: mem::MaybeUninit<[&mut T; N]> = mem::MaybeUninit::uninit(); + let mut arr: mem::MaybeUninit<[&mut I::Output; N]> = mem::MaybeUninit::uninit(); let arr_ptr = arr.as_mut_ptr(); // SAFETY: We expect `indices` to contain disjunct values that are // in bounds of `self`. unsafe { for i in 0..N { - let idx = *indices.get_unchecked(i); - *(*arr_ptr).get_unchecked_mut(i) = &mut *slice.get_unchecked_mut(idx); + let idx = indices.get_unchecked(i).clone(); + arr_ptr.cast::<&mut I::Output>().add(i).write(&mut *slice.get_unchecked_mut(idx)); } arr.assume_init() } @@ -4520,8 +4583,18 @@ impl [T] { /// Returns mutable references to many indices at once. /// - /// Returns an error if any index is out-of-bounds, or if the same index was - /// passed more than once. + /// An index can be either a `usize`, a [`Range`] or a [`RangeInclusive`]. Note + /// that this method takes an array, so all indices must be of the same type. + /// If passed an array of `usize`s this method gives back an array of mutable references + /// to single elements, while if passed an array of ranges it gives back an array of + /// mutable references to slices. + /// + /// Returns an error if any index is out-of-bounds, or if there are overlapping indices. + /// An empty range is not considered to overlap if it is located at the beginning or at + /// the end of another range, but is considered to overlap if it is located in the middle. + /// + /// This method does a O(n^2) check to check that there are no overlapping indices, so be careful + /// when passing many indices. /// /// # Examples /// @@ -4534,13 +4607,30 @@ impl [T] { /// *b = 612; /// } /// assert_eq!(v, &[413, 2, 612]); + /// + /// if let Ok([a, b]) = v.get_many_mut([0..1, 1..3]) { + /// a[0] = 8; + /// b[0] = 88; + /// b[1] = 888; + /// } + /// assert_eq!(v, &[8, 88, 888]); + /// + /// if let Ok([a, b]) = v.get_many_mut([1..=2, 0..=0]) { + /// a[0] = 11; + /// a[1] = 111; + /// b[0] = 1; + /// } + /// assert_eq!(v, &[1, 11, 111]); /// ``` #[unstable(feature = "get_many_mut", issue = "104642")] #[inline] - pub fn get_many_mut( + pub fn get_many_mut( &mut self, - indices: [usize; N], - ) -> Result<[&mut T; N], GetManyMutError> { + indices: [I; N], + ) -> Result<[&mut I::Output; N], GetManyMutError> + where + I: GetManyMutIndex + SliceIndex, + { if !get_many_check_valid(&indices, self.len()) { return Err(GetManyMutError { _private: () }); } @@ -4885,14 +4975,15 @@ impl SlicePattern for [T; N] { /// /// This will do `binomial(N + 1, 2) = N * (N + 1) / 2 = 0, 1, 3, 6, 10, ..` /// comparison operations. -fn get_many_check_valid(indices: &[usize; N], len: usize) -> bool { +#[inline] +fn get_many_check_valid(indices: &[I; N], len: usize) -> bool { // NB: The optimizer should inline the loops into a sequence // of instructions without additional branching. let mut valid = true; - for (i, &idx) in indices.iter().enumerate() { - valid &= idx < len; - for &idx2 in &indices[..i] { - valid &= idx != idx2; + for (i, idx) in indices.iter().enumerate() { + valid &= idx.is_in_bounds(len); + for idx2 in &indices[..i] { + valid &= !idx.is_overlapping(idx2); } } valid @@ -4916,6 +5007,7 @@ fn get_many_check_valid(indices: &[usize; N], len: usize) -> boo #[unstable(feature = "get_many_mut", issue = "104642")] // NB: The N here is there to be forward-compatible with adding more details // to the error type at a later point +#[derive(Clone, PartialEq, Eq)] pub struct GetManyMutError { _private: (), } @@ -4933,3 +5025,111 @@ impl fmt::Display for GetManyMutError { fmt::Display::fmt("an index is out of bounds or appeared multiple times in the array", f) } } + +mod private_get_many_mut_index { + use super::{Range, RangeInclusive, range}; + + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + pub trait Sealed {} + + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + impl Sealed for usize {} + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + impl Sealed for Range {} + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + impl Sealed for RangeInclusive {} + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + impl Sealed for range::Range {} + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + impl Sealed for range::RangeInclusive {} +} + +/// A helper trait for `<[T]>::get_many_mut()`. +/// +/// # Safety +/// +/// If `is_in_bounds()` returns `true` and `is_overlapping()` returns `false`, +/// it must be safe to index the slice with the indices. +#[unstable(feature = "get_many_mut_helpers", issue = "none")] +pub unsafe trait GetManyMutIndex: Clone + private_get_many_mut_index::Sealed { + /// Returns `true` if `self` is in bounds for `len` slice elements. + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + fn is_in_bounds(&self, len: usize) -> bool; + + /// Returns `true` if `self` overlaps with `other`. + /// + /// Note that we don't consider zero-length ranges to overlap at the beginning or the end, + /// but do consider them to overlap in the middle. + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + fn is_overlapping(&self, other: &Self) -> bool; +} + +#[unstable(feature = "get_many_mut_helpers", issue = "none")] +// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. +unsafe impl GetManyMutIndex for usize { + #[inline] + fn is_in_bounds(&self, len: usize) -> bool { + *self < len + } + + #[inline] + fn is_overlapping(&self, other: &Self) -> bool { + *self == *other + } +} + +#[unstable(feature = "get_many_mut_helpers", issue = "none")] +// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. +unsafe impl GetManyMutIndex for Range { + #[inline] + fn is_in_bounds(&self, len: usize) -> bool { + (self.start <= self.end) & (self.end <= len) + } + + #[inline] + fn is_overlapping(&self, other: &Self) -> bool { + (self.start < other.end) & (other.start < self.end) + } +} + +#[unstable(feature = "get_many_mut_helpers", issue = "none")] +// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. +unsafe impl GetManyMutIndex for RangeInclusive { + #[inline] + fn is_in_bounds(&self, len: usize) -> bool { + (self.start <= self.end) & (self.end < len) + } + + #[inline] + fn is_overlapping(&self, other: &Self) -> bool { + (self.start <= other.end) & (other.start <= self.end) + } +} + +#[unstable(feature = "get_many_mut_helpers", issue = "none")] +// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. +unsafe impl GetManyMutIndex for range::Range { + #[inline] + fn is_in_bounds(&self, len: usize) -> bool { + Range::from(*self).is_in_bounds(len) + } + + #[inline] + fn is_overlapping(&self, other: &Self) -> bool { + Range::from(*self).is_overlapping(&Range::from(*other)) + } +} + +#[unstable(feature = "get_many_mut_helpers", issue = "none")] +// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. +unsafe impl GetManyMutIndex for range::RangeInclusive { + #[inline] + fn is_in_bounds(&self, len: usize) -> bool { + RangeInclusive::from(*self).is_in_bounds(len) + } + + #[inline] + fn is_overlapping(&self, other: &Self) -> bool { + RangeInclusive::from(*self).is_overlapping(&RangeInclusive::from(*other)) + } +} diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 4629b770cb46d..8a473b398bb5f 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -373,7 +373,7 @@ impl str { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rustc_str_as_ptr", since = "1.32.0")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[must_use] #[inline(always)] pub const fn as_ptr(&self) -> *const u8 { @@ -391,7 +391,7 @@ impl str { #[stable(feature = "str_as_mut_ptr", since = "1.36.0")] #[rustc_const_stable(feature = "const_str_as_mut", since = "1.83.0")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[must_use] #[inline(always)] pub const fn as_mut_ptr(&mut self) -> *mut u8 { @@ -2503,7 +2503,7 @@ impl str { /// assert_eq!("GRüßE, JüRGEN ❤", s); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_uppercase(&mut self) { // SAFETY: changing ASCII letters only does not invalidate UTF-8. @@ -2531,7 +2531,7 @@ impl str { /// assert_eq!("grÜße, jÜrgen ❤", s); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_lowercase(&mut self) { // SAFETY: changing ASCII letters only does not invalidate UTF-8. diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 7f2a5424787f7..487fffba881b3 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -469,7 +469,7 @@ impl AtomicBool { /// [valid]: crate::ptr#safety /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses #[stable(feature = "atomic_from_ptr", since = "1.75.0")] - #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")] pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool { // SAFETY: guaranteed by the caller unsafe { &*ptr.cast() } @@ -1264,7 +1264,7 @@ impl AtomicPtr { /// [valid]: crate::ptr#safety /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses #[stable(feature = "atomic_from_ptr", since = "1.75.0")] - #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")] pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr { // SAFETY: guaranteed by the caller unsafe { &*ptr.cast() } @@ -2263,7 +2263,7 @@ macro_rules! atomic_int { /// [valid]: crate::ptr#safety /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses #[stable(feature = "atomic_from_ptr", since = "1.75.0")] - #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")] pub const unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a $atomic_type { // SAFETY: guaranteed by the caller unsafe { &*ptr.cast() } diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 34673707f010a..41e9c593ebdb3 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -319,7 +319,6 @@ impl<'a> ContextBuilder<'a> { /// Creates a ContextBuilder from a Waker. #[inline] #[unstable(feature = "local_waker", issue = "118959")] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_waker", since = "1.82.0"))] pub const fn from_waker(waker: &'a Waker) -> Self { // SAFETY: LocalWaker is just Waker without thread safety let local_waker = unsafe { transmute(waker) }; @@ -373,7 +372,6 @@ impl<'a> ContextBuilder<'a> { /// Builds the `Context`. #[inline] #[unstable(feature = "local_waker", issue = "118959")] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_waker", since = "1.82.0"))] pub const fn build(self) -> Context<'a> { let ContextBuilder { waker, local_waker, ext, _marker, _marker2 } = self; Context { waker, local_waker, ext: AssertUnwindSafe(ext), _marker, _marker2 } diff --git a/library/core/src/ub_checks.rs b/library/core/src/ub_checks.rs index 3e6110c9c88a7..b289f6026ffcb 100644 --- a/library/core/src/ub_checks.rs +++ b/library/core/src/ub_checks.rs @@ -47,7 +47,6 @@ use crate::intrinsics::{self, const_eval_select}; /// order to call it. Since the precompiled standard library is built with full debuginfo and these /// variables cannot be optimized out in MIR, an innocent-looking `let` can produce enough /// debuginfo to have a measurable compile-time impact on debug builds. -#[cfg_attr(bootstrap, allow_internal_unstable(const_ub_checks))] // permit this to be called in stably-const fn #[macro_export] #[unstable(feature = "ub_checks", issue = "none")] macro_rules! assert_unsafe_precondition { @@ -89,7 +88,6 @@ pub use intrinsics::ub_checks as check_library_ub; /// /// The intention is to not do that when running in the interpreter, as that one has its own /// language UB checks which generally produce better errors. -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ub_checks", issue = "none"))] #[inline] #[rustc_allow_const_fn_unstable(const_eval_select)] pub(crate) const fn check_language_ub() -> bool { diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index 7f4826402eb53..4655d35e9c437 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs @@ -1,7 +1,6 @@ ///! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually! #[inline(always)] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0"))] const fn bitset_search< const N: usize, const CHUNK_SIZE: usize, @@ -424,7 +423,6 @@ pub mod lowercase { (5, 187), (6, 78), (7, 132), ]; - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0"))] pub const fn lookup(c: char) -> bool { super::bitset_search( c as u32, @@ -549,7 +547,6 @@ pub mod uppercase { (2, 146), (2, 20), (3, 146), (3, 140), (3, 134), (4, 178), (4, 171), ]; - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0"))] pub const fn lookup(c: char) -> bool { super::bitset_search( c as u32, diff --git a/library/core/tests/fmt/mod.rs b/library/core/tests/fmt/mod.rs index 704d246139947..f7512abae3820 100644 --- a/library/core/tests/fmt/mod.rs +++ b/library/core/tests/fmt/mod.rs @@ -43,3 +43,10 @@ fn pad_integral_resets() { assert_eq!(format!("{Bar:<03}"), "1 0051 "); } + +#[test] +fn test_maybe_uninit_short() { + // Ensure that the trimmed `MaybeUninit` Debug implementation doesn't break + let x = core::mem::MaybeUninit::new(0u32); + assert_eq!(format!("{x:?}"), "MaybeUninit"); +} diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index f7825571cd7a8..40129619ce50e 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -1,7 +1,4 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(const_three_way_compare))] -#![cfg_attr(bootstrap, feature(strict_provenance))] -#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))] #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] #![cfg_attr(test, feature(cfg_match))] #![feature(alloc_layout_extra)] @@ -83,6 +80,7 @@ #![feature(step_trait)] #![feature(str_internals)] #![feature(strict_provenance_atomic_ptr)] +#![feature(strict_provenance_lints)] #![feature(test)] #![feature(trait_upcasting)] #![feature(trusted_len)] diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 9ae2bcc852649..510dd4967c961 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -2,6 +2,7 @@ use core::cell::Cell; use core::cmp::Ordering; use core::mem::MaybeUninit; use core::num::NonZero; +use core::ops::{Range, RangeInclusive}; use core::slice; #[test] @@ -2553,6 +2554,14 @@ fn test_get_many_mut_normal_2() { *a += 10; *b += 100; assert_eq!(v, vec![101, 2, 3, 14, 5]); + + let [a, b] = v.get_many_mut([0..=1, 2..=2]).unwrap(); + assert_eq!(a, &mut [101, 2][..]); + assert_eq!(b, &mut [3][..]); + a[0] += 10; + a[1] += 20; + b[0] += 100; + assert_eq!(v, vec![111, 22, 103, 14, 5]); } #[test] @@ -2563,12 +2572,23 @@ fn test_get_many_mut_normal_3() { *b += 100; *c += 1000; assert_eq!(v, vec![11, 2, 1003, 4, 105]); + + let [a, b, c] = v.get_many_mut([0..1, 4..5, 1..4]).unwrap(); + assert_eq!(a, &mut [11][..]); + assert_eq!(b, &mut [105][..]); + assert_eq!(c, &mut [2, 1003, 4][..]); + a[0] += 10; + b[0] += 100; + c[0] += 1000; + assert_eq!(v, vec![21, 1002, 1003, 4, 205]); } #[test] fn test_get_many_mut_empty() { let mut v = vec![1, 2, 3, 4, 5]; - let [] = v.get_many_mut([]).unwrap(); + let [] = v.get_many_mut::([]).unwrap(); + let [] = v.get_many_mut::, 0>([]).unwrap(); + let [] = v.get_many_mut::, 0>([]).unwrap(); assert_eq!(v, vec![1, 2, 3, 4, 5]); } @@ -2606,6 +2626,54 @@ fn test_get_many_mut_duplicate() { assert!(v.get_many_mut([1, 3, 3, 4]).is_err()); } +#[test] +fn test_get_many_mut_range_oob() { + let mut v = vec![1, 2, 3, 4, 5]; + assert!(v.get_many_mut([0..6]).is_err()); + assert!(v.get_many_mut([5..6]).is_err()); + assert!(v.get_many_mut([6..6]).is_err()); + assert!(v.get_many_mut([0..=5]).is_err()); + assert!(v.get_many_mut([0..=6]).is_err()); + assert!(v.get_many_mut([5..=5]).is_err()); +} + +#[test] +fn test_get_many_mut_range_overlapping() { + let mut v = vec![1, 2, 3, 4, 5]; + assert!(v.get_many_mut([0..1, 0..2]).is_err()); + assert!(v.get_many_mut([0..1, 1..2, 0..1]).is_err()); + assert!(v.get_many_mut([0..3, 1..1]).is_err()); + assert!(v.get_many_mut([0..3, 1..2]).is_err()); + assert!(v.get_many_mut([0..=0, 2..=2, 0..=1]).is_err()); + assert!(v.get_many_mut([0..=4, 0..=0]).is_err()); + assert!(v.get_many_mut([4..=4, 0..=0, 3..=4]).is_err()); +} + +#[test] +fn test_get_many_mut_range_empty_at_edge() { + let mut v = vec![1, 2, 3, 4, 5]; + assert_eq!( + v.get_many_mut([0..0, 0..5, 5..5]), + Ok([&mut [][..], &mut [1, 2, 3, 4, 5], &mut []]), + ); + assert_eq!( + v.get_many_mut([0..0, 0..1, 1..1, 1..2, 2..2, 2..3, 3..3, 3..4, 4..4, 4..5, 5..5]), + Ok([ + &mut [][..], + &mut [1], + &mut [], + &mut [2], + &mut [], + &mut [3], + &mut [], + &mut [4], + &mut [], + &mut [5], + &mut [], + ]), + ); +} + #[test] fn test_slice_from_raw_parts_in_const() { static FANCY: i32 = 4; diff --git a/library/panic_unwind/Cargo.toml b/library/panic_unwind/Cargo.toml index 6d1f9764efbfd..252f118fecfbb 100644 --- a/library/panic_unwind/Cargo.toml +++ b/library/panic_unwind/Cargo.toml @@ -23,7 +23,4 @@ libc = { version = "0.2", default-features = false } [lints.rust.unexpected_cfgs] level = "warn" -check-cfg = [ - # #[cfg(bootstrap)] rtems - 'cfg(target_os, values("rtems"))', -] +check-cfg = [] diff --git a/library/profiler_builtins/Cargo.toml b/library/profiler_builtins/Cargo.toml index f94ea9a6cda28..c601a41b433c7 100644 --- a/library/profiler_builtins/Cargo.toml +++ b/library/profiler_builtins/Cargo.toml @@ -9,9 +9,6 @@ bench = false doc = false [dependencies] -core = { path = "../core" } -compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] } [build-dependencies] -# FIXME: Pinned due to build error when bumped (#132556) -cc = "=1.1.22" +cc = "1.2" diff --git a/library/profiler_builtins/src/lib.rs b/library/profiler_builtins/src/lib.rs index ac685b18c2911..a258f7d31a191 100644 --- a/library/profiler_builtins/src/lib.rs +++ b/library/profiler_builtins/src/lib.rs @@ -1,11 +1,15 @@ -#![no_std] +// tidy-alphabetical-start +#![allow(internal_features)] +#![feature(no_core)] #![feature(profiler_runtime)] +#![feature(staged_api)] +// tidy-alphabetical-end + +// Other attributes: +#![no_core] #![profiler_runtime] #![unstable( feature = "profiler_runtime_lib", reason = "internal implementation detail of rustc right now", issue = "none" )] -#![allow(unused_features)] -#![allow(internal_features)] -#![feature(staged_api)] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index c1ab70b714a4c..260732dee188e 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -144,6 +144,4 @@ check-cfg = [ # and to the `backtrace` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg 'cfg(feature, values(any()))', - # #[cfg(bootstrap)] rtems - 'cfg(target_os, values("rtems"))', ] diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 24bbc2f32cf6d..09c0b61fb2b89 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -235,7 +235,7 @@ impl HashMap { /// /// The hash map will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the hash map will not allocate. + /// `capacity`. If `capacity` is zero, the hash map will not allocate. /// /// # Examples /// @@ -287,7 +287,7 @@ impl HashMap { /// /// The hash map will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the hash map will not allocate. + /// `capacity`. If `capacity` is zero, the hash map will not allocate. /// /// Warning: `hasher` is normally randomly generated, and /// is designed to allow HashMaps to be resistant to attacks that diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index f86bcdb4796ec..21a73259f6179 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -130,7 +130,7 @@ impl HashSet { /// /// The hash set will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the hash set will not allocate. + /// `capacity`. If `capacity` is zero, the hash set will not allocate. /// /// # Examples /// @@ -379,7 +379,7 @@ impl HashSet { /// /// The hash set will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the hash set will not allocate. + /// `capacity`. If `capacity` is zero, the hash set will not allocate. /// /// Warning: `hasher` is normally randomly generated, and /// is designed to allow `HashSet`s to be resistant to attacks that diff --git a/library/std/src/env.rs b/library/std/src/env.rs index d732a15117e9e..27f4daba44bf6 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -653,19 +653,28 @@ pub fn home_dir() -> Option { /// may result in "insecure temporary file" security vulnerabilities. Consider /// using a crate that securely creates temporary files or directories. /// +/// Note that the returned value may be a symbolic link, not a directory. +/// /// # Platform-specific behavior /// /// On Unix, returns the value of the `TMPDIR` environment variable if it is -/// set, otherwise for non-Android it returns `/tmp`. On Android, since there -/// is no global temporary folder (it is usually allocated per-app), it returns -/// `/data/local/tmp`. +/// set, otherwise the value is OS-specific: +/// - On Android, there is no global temporary folder (it is usually allocated +/// per-app), it returns `/data/local/tmp`. +/// - On Darwin-based OSes (macOS, iOS, etc) it returns the directory provided +/// by `confstr(_CS_DARWIN_USER_TEMP_DIR, ...)`, as recommended by [Apple's +/// security guidelines][appledoc]. +/// - On all other unix-based OSes, it returns `/tmp`. +/// /// On Windows, the behavior is equivalent to that of [`GetTempPath2`][GetTempPath2] / /// [`GetTempPath`][GetTempPath], which this function uses internally. +/// /// Note that, this [may change in the future][changes]. /// /// [changes]: io#platform-specific-behavior /// [GetTempPath2]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a /// [GetTempPath]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha +/// [appledoc]: https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/RaceConditions.html#//apple_ref/doc/uid/TP40002585-SW10 /// /// ```no_run /// use std::env; diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 79dfb47d0c499..fff140f1564fa 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -550,11 +550,15 @@ impl OsString { OsStr::from_inner_mut(self.inner.leak()) } - /// Provides plumbing to core `Vec::truncate`. - /// More well behaving alternative to allowing outer types - /// full mutable access to the core `Vec`. + /// Truncate the the `OsString` to the specified length. + /// + /// # Panics + /// Panics if `len` does not lie on a valid `OsStr` boundary + /// (as described in [`OsStr::slice_encoded_bytes`]). #[inline] - pub(crate) fn truncate(&mut self, len: usize) { + #[unstable(feature = "os_string_truncate", issue = "133262")] + pub fn truncate(&mut self, len: usize) { + self.as_os_str().inner.check_public_boundary(len); self.inner.truncate(len); } @@ -1225,7 +1229,7 @@ impl From<&OsStr> for Box { } } -#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "box_from_mut_slice", since = "1.84.0")] impl From<&mut OsStr> for Box { /// Copies the string into a newly allocated [Box]<[OsStr]>. #[inline] @@ -1305,7 +1309,7 @@ impl From<&OsStr> for Arc { } } -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut OsStr> for Arc { /// Copies the string into a newly allocated [Arc]<[OsStr]>. #[inline] @@ -1335,7 +1339,7 @@ impl From<&OsStr> for Rc { } } -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut OsStr> for Rc { /// Copies the string into a newly allocated [Rc]<[OsStr]>. #[inline] diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 555e8804eab33..2d5d869630e0e 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2804,8 +2804,9 @@ pub fn remove_dir>(path: P) -> io::Result<()> { /// /// See [`fs::remove_file`] and [`fs::remove_dir`]. /// -/// `remove_dir_all` will fail if `remove_dir` or `remove_file` fail on any constituent paths, including the root path. +/// `remove_dir_all` will fail if `remove_dir` or `remove_file` fail on any constituent paths, including the root `path`. /// As a result, the directory you are deleting must exist, meaning that this function is not idempotent. +/// Additionally, `remove_dir_all` will also fail if the `path` is not a directory. /// /// Consider ignoring the error if validating the removal is not required for your use case. /// @@ -3019,7 +3020,7 @@ impl DirBuilder { match path.parent() { Some(p) => self.create_dir_all(p)?, None => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Uncategorized, "failed to create whole tree", )); diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs index 52fe49985c65a..17721090db5de 100644 --- a/library/std/src/io/buffered/bufreader/buffer.rs +++ b/library/std/src/io/buffered/bufreader/buffer.rs @@ -41,7 +41,7 @@ impl Buffer { match Box::try_new_uninit_slice(capacity) { Ok(buf) => Ok(Self { buf, pos: 0, filled: 0, initialized: 0 }), Err(_) => { - Err(io::const_io_error!(ErrorKind::OutOfMemory, "failed to allocate read buffer")) + Err(io::const_error!(ErrorKind::OutOfMemory, "failed to allocate read buffer")) } } } diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs index c41bae2aa4e81..574eb83dc5649 100644 --- a/library/std/src/io/buffered/bufwriter.rs +++ b/library/std/src/io/buffered/bufwriter.rs @@ -96,7 +96,7 @@ impl BufWriter { pub(crate) fn try_new_buffer() -> io::Result> { Vec::try_with_capacity(DEFAULT_BUF_SIZE).map_err(|_| { - io::const_io_error!(ErrorKind::OutOfMemory, "failed to allocate write buffer") + io::const_error!(ErrorKind::OutOfMemory, "failed to allocate write buffer") }) } @@ -238,7 +238,7 @@ impl BufWriter { match r { Ok(0) => { - return Err(io::const_io_error!( + return Err(io::const_error!( ErrorKind::WriteZero, "failed to write the buffered data", )); diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index fbfdb4fa02323..b2ffeb0f95d0d 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -304,7 +304,7 @@ where self.pos = n; Ok(self.pos) } - None => Err(io::const_io_error!( + None => Err(io::const_error!( ErrorKind::InvalidInput, "invalid seek to a negative or overflowing position", )), @@ -446,7 +446,7 @@ fn reserve_and_pad( buf_len: usize, ) -> io::Result { let pos: usize = (*pos_mut).try_into().map_err(|_| { - io::const_io_error!( + io::const_error!( ErrorKind::InvalidInput, "cursor position exceeds maximum possible vector length", ) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 5d7adcace5247..03f38e220a581 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -76,31 +76,31 @@ impl fmt::Debug for Error { #[allow(dead_code)] impl Error { pub(crate) const INVALID_UTF8: Self = - const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8"); + const_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8"); pub(crate) const READ_EXACT_EOF: Self = - const_io_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer"); + const_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer"); - pub(crate) const UNKNOWN_THREAD_COUNT: Self = const_io_error!( + pub(crate) const UNKNOWN_THREAD_COUNT: Self = const_error!( ErrorKind::NotFound, "The number of hardware threads is not known for the target platform" ); pub(crate) const UNSUPPORTED_PLATFORM: Self = - const_io_error!(ErrorKind::Unsupported, "operation not supported on this platform"); + const_error!(ErrorKind::Unsupported, "operation not supported on this platform"); pub(crate) const WRITE_ALL_EOF: Self = - const_io_error!(ErrorKind::WriteZero, "failed to write whole buffer"); + const_error!(ErrorKind::WriteZero, "failed to write whole buffer"); pub(crate) const ZERO_TIMEOUT: Self = - const_io_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout"); + const_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout"); } #[stable(feature = "rust1", since = "1.0.0")] impl From for Error { /// Converts a [`alloc::ffi::NulError`] into a [`Error`]. fn from(_: alloc::ffi::NulError) -> Error { - const_io_error!(ErrorKind::InvalidInput, "data provided contains a nul byte") + const_error!(ErrorKind::InvalidInput, "data provided contains a nul byte") } } @@ -151,27 +151,38 @@ pub type RawOsError = sys::RawOsError; // (For the sake of being explicit: the alignment requirement here only matters // if `error/repr_bitpacked.rs` is in use — for the unpacked repr it doesn't // matter at all) +#[doc(hidden)] +#[unstable(feature = "io_const_error_internals", issue = "none")] #[repr(align(4))] #[derive(Debug)] -pub(crate) struct SimpleMessage { - kind: ErrorKind, - message: &'static str, -} - -impl SimpleMessage { - pub(crate) const fn new(kind: ErrorKind, message: &'static str) -> Self { - Self { kind, message } - } +pub struct SimpleMessage { + pub kind: ErrorKind, + pub message: &'static str, } -/// Creates and returns an `io::Error` for a given `ErrorKind` and constant -/// message. This doesn't allocate. -pub(crate) macro const_io_error($kind:expr, $message:expr $(,)?) { - $crate::io::error::Error::from_static_message({ - const MESSAGE_DATA: $crate::io::error::SimpleMessage = - $crate::io::error::SimpleMessage::new($kind, $message); - &MESSAGE_DATA - }) +/// Creates a new I/O error from a known kind of error and a string literal. +/// +/// Contrary to [`Error::new`], this macro does not allocate and can be used in +/// `const` contexts. +/// +/// # Example +/// ``` +/// #![feature(io_const_error)] +/// use std::io::{const_error, Error, ErrorKind}; +/// +/// const FAIL: Error = const_error!(ErrorKind::Unsupported, "tried something that never works"); +/// +/// fn not_here() -> Result<(), Error> { +/// Err(FAIL) +/// } +/// ``` +#[rustc_macro_transparency = "semitransparent"] +#[unstable(feature = "io_const_error", issue = "133448")] +#[allow_internal_unstable(hint_must_use, io_const_error_internals)] +pub macro const_error($kind:expr, $message:expr $(,)?) { + $crate::hint::must_use($crate::io::Error::from_static_message( + const { &$crate::io::SimpleMessage { kind: $kind, message: $message } }, + )) } // As with `SimpleMessage`: `#[repr(align(4))]` here is just because @@ -592,13 +603,15 @@ impl Error { /// /// This function does not allocate. /// - /// You should not use this directly, and instead use the `const_io_error!` - /// macro: `io::const_io_error!(ErrorKind::Something, "some_message")`. + /// You should not use this directly, and instead use the `const_error!` + /// macro: `io::const_error!(ErrorKind::Something, "some_message")`. /// /// This function should maybe change to `from_static_message(kind: ErrorKind)` in the future, when const generics allow that. #[inline] - pub(crate) const fn from_static_message(msg: &'static SimpleMessage) -> Error { + #[doc(hidden)] + #[unstable(feature = "io_const_error_internals", issue = "none")] + pub const fn from_static_message(msg: &'static SimpleMessage) -> Error { Self { repr: Repr::new_simple_message(msg) } } diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs index 00d04984a3854..edac6563478cd 100644 --- a/library/std/src/io/error/tests.rs +++ b/library/std/src/io/error/tests.rs @@ -1,4 +1,4 @@ -use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_io_error}; +use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_error}; use crate::assert_matches::assert_matches; use crate::mem::size_of; use crate::sys::decode_error_kind; @@ -60,7 +60,7 @@ fn test_downcasting() { #[test] fn test_const() { - const E: Error = const_io_error!(ErrorKind::NotFound, "hello"); + const E: Error = const_error!(ErrorKind::NotFound, "hello"); assert_eq!(E.kind(), ErrorKind::NotFound); assert_eq!(E.to_string(), "hello"); @@ -110,13 +110,13 @@ fn test_simple_message_packing() { }}; } - let not_static = const_io_error!(Uncategorized, "not a constant!"); + let not_static = const_error!(Uncategorized, "not a constant!"); check_simple_msg!(not_static, Uncategorized, "not a constant!"); - const CONST: Error = const_io_error!(NotFound, "definitely a constant!"); + const CONST: Error = const_error!(NotFound, "definitely a constant!"); check_simple_msg!(CONST, NotFound, "definitely a constant!"); - static STATIC: Error = const_io_error!(BrokenPipe, "a constant, sort of!"); + static STATIC: Error = const_error!(BrokenPipe, "a constant, sort of!"); check_simple_msg!(STATIC, BrokenPipe, "a constant, sort of!"); } diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 21e7077495450..4ffb04630061f 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -301,12 +301,15 @@ mod tests; pub use core::io::{BorrowedBuf, BorrowedCursor}; use core::slice::memchr; -pub(crate) use error::const_io_error; - #[stable(feature = "bufwriter_into_parts", since = "1.56.0")] pub use self::buffered::WriterPanicked; #[unstable(feature = "raw_os_error_ty", issue = "107792")] pub use self::error::RawOsError; +#[doc(hidden)] +#[unstable(feature = "io_const_error_internals", issue = "none")] +pub use self::error::SimpleMessage; +#[unstable(feature = "io_const_error", issue = "133448")] +pub use self::error::const_error; #[stable(feature = "is_terminal", since = "1.70.0")] pub use self::stdio::IsTerminal; pub(crate) use self::stdio::attempt_print_to_stderr; diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index 89e806c08911c..47cbb9614afdd 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -225,12 +225,12 @@ fn take_eof() { impl Read for R { fn read(&mut self, _: &mut [u8]) -> io::Result { - Err(io::const_io_error!(io::ErrorKind::Other, "")) + Err(io::const_error!(io::ErrorKind::Other, "")) } } impl BufRead for R { fn fill_buf(&mut self) -> io::Result<&[u8]> { - Err(io::const_io_error!(io::ErrorKind::Other, "")) + Err(io::const_error!(io::ErrorKind::Other, "")) } fn consume(&mut self, _amt: usize) {} } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 5b94f036248cb..059c8d8309c83 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -174,9 +174,6 @@ //! //! - after-main use of thread-locals, which also affects additional features: //! - [`thread::current()`] -//! - [`thread::scope()`] -//! - [`sync::mpmc`] -//! - [`sync::mpsc`] //! - before-main stdio file descriptors are not guaranteed to be open on unix platforms //! //! @@ -265,7 +262,6 @@ #![allow(unused_features)] // // Features: -#![cfg_attr(not(bootstrap), feature(autodiff))] #![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count, rt))] #![cfg_attr( all(target_vendor = "fortanix", target_env = "sgx"), @@ -277,18 +273,16 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(strict_provenance))] -#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))] #![feature(alloc_error_handler)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] #![feature(asm_experimental_arch)] +#![feature(autodiff)] #![feature(cfg_sanitizer_cfi)] #![feature(cfg_target_thread_local)] #![feature(cfi_encoding)] #![feature(concat_idents)] -#![feature(const_float_methods)] #![feature(decl_macro)] #![feature(deprecated_suggestion)] #![feature(doc_cfg)] @@ -296,7 +290,6 @@ #![feature(doc_masked)] #![feature(doc_notable_trait)] #![feature(dropck_eyepatch)] -#![feature(extended_varargs_abi_support)] #![feature(f128)] #![feature(f16)] #![feature(if_let_guard)] @@ -318,6 +311,7 @@ #![feature(rustdoc_internals)] #![feature(staged_api)] #![feature(stmt_expr_attributes)] +#![feature(strict_provenance_lints)] #![feature(thread_local)] #![feature(try_blocks)] #![feature(type_alias_impl_trait)] @@ -344,6 +338,7 @@ #![feature(fmt_internals)] #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] +#![feature(hint_must_use)] #![feature(ip)] #![feature(lazy_get)] #![feature(maybe_uninit_slice)] @@ -365,6 +360,7 @@ #![feature(strict_provenance_atomic_ptr)] #![feature(sync_unsafe_cell)] #![feature(ub_checks)] +#![feature(used_with_arg)] // tidy-alphabetical-end // // Library features (alloc): @@ -414,6 +410,7 @@ // Only for const-ness: // tidy-alphabetical-start #![feature(const_collections_with_hasher)] +#![feature(io_const_error)] #![feature(thread_local_internals)] // tidy-alphabetical-end // @@ -624,7 +621,6 @@ pub mod simd { #[doc(inline)] pub use crate::std_float::StdFloat; } -#[cfg(not(bootstrap))] #[unstable(feature = "autodiff", issue = "124509")] /// This module provides support for automatic differentiation. pub mod autodiff { @@ -658,6 +654,8 @@ pub mod arch { pub use std_detect::is_aarch64_feature_detected; #[unstable(feature = "stdarch_arm_feature_detection", issue = "111190")] pub use std_detect::is_arm_feature_detected; + #[unstable(feature = "is_loongarch_feature_detected", issue = "117425")] + pub use std_detect::is_loongarch_feature_detected; #[unstable(feature = "is_riscv_feature_detected", issue = "111192")] pub use std_detect::is_riscv_feature_detected; #[stable(feature = "simd_x86", since = "1.27.0")] diff --git a/library/std/src/net/mod.rs b/library/std/src/net/mod.rs index 3b19c743b1e24..ddd3b68dd2d63 100644 --- a/library/std/src/net/mod.rs +++ b/library/std/src/net/mod.rs @@ -84,6 +84,6 @@ where } } Err(last_err.unwrap_or_else(|| { - io::const_io_error!(ErrorKind::InvalidInput, "could not resolve to any addresses") + io::const_error!(ErrorKind::InvalidInput, "could not resolve to any addresses") })) } diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs index 6df47d7b0e0cd..674c5fb7d6ea3 100644 --- a/library/std/src/net/udp.rs +++ b/library/std/src/net/udp.rs @@ -203,9 +203,7 @@ impl UdpSocket { pub fn send_to(&self, buf: &[u8], addr: A) -> io::Result { match addr.to_socket_addrs()?.next() { Some(addr) => self.0.send_to(buf, &addr), - None => { - Err(io::const_io_error!(ErrorKind::InvalidInput, "no addresses to send data to")) - } + None => Err(io::const_error!(ErrorKind::InvalidInput, "no addresses to send data to")), } } diff --git a/library/std/src/os/darwin/mod.rs b/library/std/src/os/darwin/mod.rs index 7a057ddb861b7..3b1bd974fa313 100644 --- a/library/std/src/os/darwin/mod.rs +++ b/library/std/src/os/darwin/mod.rs @@ -13,7 +13,7 @@ //! `aarch64-apple-darwin` target names, which are mostly named that way for //! legacy reasons. -#![stable(feature = "os_darwin", since = "CURRENT_RUSTC_VERSION")] +#![stable(feature = "os_darwin", since = "1.84.0")] #![doc(cfg(target_vendor = "apple"))] pub mod fs; diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 2d087c03b04b4..388b8a88a1a48 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -173,16 +173,17 @@ impl Drop for OwnedFd { #[inline] fn drop(&mut self) { unsafe { - // Note that errors are ignored when closing a file descriptor. The - // reason for this is that if an error occurs we don't actually know if - // the file descriptor was closed or not, and if we retried (for - // something like EINTR), we might close another valid file descriptor - // opened after we closed ours. - // However, this is usually justified, as some of the major Unices - // do make sure to always close the FD, even when `close()` is interrupted, - // and the scenario is rare to begin with. - // Helpful link to an epic discussion by POSIX workgroup: - // http://austingroupbugs.net/view.php?id=529 + // Note that errors are ignored when closing a file descriptor. According to POSIX 2024, + // we can and indeed should retry `close` on `EINTR` + // (https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/close.html), + // but it is not clear yet how well widely-used implementations are conforming with this + // mandate since older versions of POSIX left the state of the FD after an `EINTR` + // unspecified. Ignoring errors is "fine" because some of the major Unices (in + // particular, Linux) do make sure to always close the FD, even when `close()` is + // interrupted, and the scenario is rare to begin with. If we retried on a + // not-POSIX-compliant implementation, the consequences could be really bad since we may + // close the wrong FD. Helpful link to an epic discussion by POSIX workgroup that led to + // the latest POSIX wording: http://austingroupbugs.net/view.php?id=529 #[cfg(not(target_os = "hermit"))] { #[cfg(unix)] diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs index ba6481f052cdf..04a45fd035a55 100644 --- a/library/std/src/os/unix/fs.rs +++ b/library/std/src/os/unix/fs.rs @@ -987,6 +987,11 @@ impl DirBuilderExt for fs::DirBuilder { /// Changing the group typically requires either being the owner and a member of the group, or /// having privileges. /// +/// Be aware that changing owner clears the `suid` and `sgid` permission bits in most cases +/// according to POSIX, usually even if the user is root. The sgid is not cleared when +/// the file is non-group-executable. See: +/// This call may also clear file capabilities, if there was any. +/// /// If called on a symbolic link, this will change the owner and group of the link target. To /// change the owner and group of the link itself, see [`lchown`]. /// diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 253e1503cf7af..56789f235fdab 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -30,14 +30,14 @@ pub(super) fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::s let bytes = path.as_os_str().as_bytes(); if bytes.contains(&0) { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "paths must not contain interior null bytes", )); } if bytes.len() >= addr.sun_path.len() { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "path must be shorter than SUN_LEN", )); @@ -119,7 +119,7 @@ impl SocketAddr { // linux returns zero bytes of address len = SUN_PATH_OFFSET as libc::socklen_t; // i.e., zero-length address } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "file descriptor did not correspond to a Unix socket", )); @@ -273,7 +273,7 @@ impl linux_ext::addr::SocketAddrExt for SocketAddr { addr.sun_family = libc::AF_UNIX as libc::sa_family_t; if name.len() + 1 > addr.sun_path.len() { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "abstract socket name must be shorter than SUN_LEN", )); diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs index 9ec3e387e2ba9..42aada131dadc 100644 --- a/library/std/src/os/wasi/fs.rs +++ b/library/std/src/os/wasi/fs.rs @@ -261,7 +261,7 @@ impl FileExt for fs::File { a if a == wasi::ADVICE_DONTNEED.raw() => wasi::ADVICE_DONTNEED, a if a == wasi::ADVICE_NOREUSE.raw() => wasi::ADVICE_NOREUSE, _ => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "invalid parameter 'advice'", )); @@ -560,6 +560,5 @@ pub fn symlink_path, U: AsRef>(old_path: P, new_path: U) -> } fn osstr2str(f: &OsStr) -> io::Result<&str> { - f.to_str() - .ok_or_else(|| io::const_io_error!(io::ErrorKind::Uncategorized, "input must be utf-8")) + f.to_str().ok_or_else(|| io::const_error!(io::ErrorKind::Uncategorized, "input must be utf-8")) } diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs index 1fcfb6e73ad03..272641ea6c7a8 100644 --- a/library/std/src/os/windows/io/socket.rs +++ b/library/std/src/os/windows/io/socket.rs @@ -101,7 +101,7 @@ impl OwnedSocket { #[cfg(target_vendor = "uwp")] pub(crate) fn set_no_inherit(&self) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "Unavailable on UWP")) + Err(io::const_error!(io::ErrorKind::Unsupported, "Unavailable on UWP")) } } diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index ac1f547c9143f..97f800dddaa43 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -27,6 +27,22 @@ use crate::sys::backtrace; use crate::sys::stdio::panic_output; use crate::{fmt, intrinsics, process, thread}; +// This forces codegen of the function called by panic!() inside the std crate, rather than in +// downstream crates. Primarily this is useful for rustc's codegen tests, which rely on noticing +// complete removal of panic from generated IR. Since begin_panic is inline(never), it's only +// codegen'd once per crate-graph so this pushes that to std rather than our codegen test crates. +// +// (See https://github.com/rust-lang/rust/pull/123244 for more info on why). +// +// If this is causing problems we can also modify those codegen tests to use a crate type like +// cdylib which doesn't export "Rust" symbols to downstream linkage units. +#[unstable(feature = "libstd_sys_internals", reason = "used by the panic! macro", issue = "none")] +#[doc(hidden)] +#[allow(dead_code)] +#[used(compiler)] +pub static EMPTY_PANIC: fn(&'static str) -> ! = + begin_panic::<&'static str> as fn(&'static str) -> !; + // Binary interface to the panic runtime that the standard library depends on. // // The standard library is tagged with `#![needs_panic_runtime]` (introduced in diff --git a/library/std/src/path.rs b/library/std/src/path.rs index b0291e3aa196f..635c7bca0e010 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1762,7 +1762,7 @@ impl From<&Path> for Box { } } -#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "box_from_mut_slice", since = "1.84.0")] impl From<&mut Path> for Box { /// Creates a boxed [`Path`] from a reference. /// @@ -2000,7 +2000,7 @@ impl From<&Path> for Arc { } } -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut Path> for Arc { /// Converts a [`Path`] into an [`Arc`] by copying the [`Path`] data into a new [`Arc`] buffer. #[inline] @@ -2030,7 +2030,7 @@ impl From<&Path> for Rc { } } -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut Path> for Rc { /// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new [`Rc`] buffer. #[inline] @@ -2504,6 +2504,7 @@ impl Path { /// assert_eq!(path.strip_prefix("/test/haha/foo.txt/"), Ok(Path::new(""))); /// /// assert!(path.strip_prefix("test").is_err()); + /// assert!(path.strip_prefix("/te").is_err()); /// assert!(path.strip_prefix("/haha").is_err()); /// /// let prefix = PathBuf::from("/test/"); @@ -3580,7 +3581,7 @@ impl Error for StripPrefixError { pub fn absolute>(path: P) -> io::Result { let path = path.as_ref(); if path.as_os_str().is_empty() { - Err(io::const_io_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute",)) + Err(io::const_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute",)) } else { sys::path::absolute(path) } diff --git a/library/std/src/prelude/common.rs b/library/std/src/prelude/common.rs index b231bd871b3b4..e4731280ffe35 100644 --- a/library/std/src/prelude/common.rs +++ b/library/std/src/prelude/common.rs @@ -12,6 +12,9 @@ pub use crate::marker::{Send, Sized, Sync, Unpin}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use crate::ops::{Drop, Fn, FnMut, FnOnce}; +#[unstable(feature = "async_closure", issue = "62290")] +#[doc(no_inline)] +pub use crate::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}; // Re-exported functions #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/sync/mpmc/array.rs b/library/std/src/sync/mpmc/array.rs index 2c8ba411f3023..a467237fef152 100644 --- a/library/std/src/sync/mpmc/array.rs +++ b/library/std/src/sync/mpmc/array.rs @@ -346,7 +346,8 @@ impl Channel { } // Block the current thread. - let sel = cx.wait_until(deadline); + // SAFETY: the context belongs to the current thread. + let sel = unsafe { cx.wait_until(deadline) }; match sel { Selected::Waiting => unreachable!(), @@ -397,7 +398,8 @@ impl Channel { } // Block the current thread. - let sel = cx.wait_until(deadline); + // SAFETY: the context belongs to the current thread. + let sel = unsafe { cx.wait_until(deadline) }; match sel { Selected::Waiting => unreachable!(), diff --git a/library/std/src/sync/mpmc/context.rs b/library/std/src/sync/mpmc/context.rs index 2371d32d4ea0d..51aa7e82e7890 100644 --- a/library/std/src/sync/mpmc/context.rs +++ b/library/std/src/sync/mpmc/context.rs @@ -69,7 +69,7 @@ impl Context { inner: Arc::new(Inner { select: AtomicUsize::new(Selected::Waiting.into()), packet: AtomicPtr::new(ptr::null_mut()), - thread: thread::current(), + thread: thread::current_or_unnamed(), thread_id: current_thread_id(), }), } @@ -112,8 +112,11 @@ impl Context { /// Waits until an operation is selected and returns it. /// /// If the deadline is reached, `Selected::Aborted` will be selected. + /// + /// # Safety + /// This may only be called from the thread this `Context` belongs to. #[inline] - pub fn wait_until(&self, deadline: Option) -> Selected { + pub unsafe fn wait_until(&self, deadline: Option) -> Selected { loop { // Check whether an operation has been selected. let sel = Selected::from(self.inner.select.load(Ordering::Acquire)); @@ -126,7 +129,8 @@ impl Context { let now = Instant::now(); if now < end { - thread::park_timeout(end - now); + // SAFETY: guaranteed by caller. + unsafe { self.inner.thread.park_timeout(end - now) }; } else { // The deadline has been reached. Try aborting select. return match self.try_select(Selected::Aborted) { @@ -135,7 +139,8 @@ impl Context { }; } } else { - thread::park(); + // SAFETY: guaranteed by caller. + unsafe { self.inner.thread.park() }; } } } diff --git a/library/std/src/sync/mpmc/list.rs b/library/std/src/sync/mpmc/list.rs index 523e6d2f3bb37..d88914f529142 100644 --- a/library/std/src/sync/mpmc/list.rs +++ b/library/std/src/sync/mpmc/list.rs @@ -444,7 +444,8 @@ impl Channel { } // Block the current thread. - let sel = cx.wait_until(deadline); + // SAFETY: the context belongs to the current thread. + let sel = unsafe { cx.wait_until(deadline) }; match sel { Selected::Waiting => unreachable!(), diff --git a/library/std/src/sync/mpmc/zero.rs b/library/std/src/sync/mpmc/zero.rs index 446881291e68e..577997c07a636 100644 --- a/library/std/src/sync/mpmc/zero.rs +++ b/library/std/src/sync/mpmc/zero.rs @@ -190,7 +190,8 @@ impl Channel { drop(inner); // Block the current thread. - let sel = cx.wait_until(deadline); + // SAFETY: the context belongs to the current thread. + let sel = unsafe { cx.wait_until(deadline) }; match sel { Selected::Waiting => unreachable!(), @@ -257,7 +258,8 @@ impl Channel { drop(inner); // Block the current thread. - let sel = cx.wait_until(deadline); + // SAFETY: the context belongs to the current thread. + let sel = unsafe { cx.wait_until(deadline) }; match sel { Selected::Waiting => unreachable!(), diff --git a/library/std/src/sync/rwlock/tests.rs b/library/std/src/sync/rwlock/tests.rs index 29cad4400f189..48d442921f7fc 100644 --- a/library/std/src/sync/rwlock/tests.rs +++ b/library/std/src/sync/rwlock/tests.rs @@ -511,12 +511,15 @@ fn test_downgrade_basic() { } #[test] +// FIXME: On macOS we use a provenance-incorrect implementation and Miri catches that issue. +// See for details. +#[cfg_attr(all(miri, target_os = "macos"), ignore)] fn test_downgrade_observe() { // Taken from the test `test_rwlock_downgrade` from: // https://github.com/Amanieu/parking_lot/blob/master/src/rwlock.rs const W: usize = 20; - const N: usize = 100; + const N: usize = if cfg!(miri) { 40 } else { 100 }; // This test spawns `W` writer threads, where each will increment a counter `N` times, ensuring // that the value they wrote has not changed after downgrading. diff --git a/library/std/src/sys/cmath.rs b/library/std/src/sys/cmath.rs index 2997e908fa1b2..ee36127cfdf1e 100644 --- a/library/std/src/sys/cmath.rs +++ b/library/std/src/sys/cmath.rs @@ -26,6 +26,7 @@ extern "C" { pub fn tgamma(n: f64) -> f64; pub fn tgammaf(n: f32) -> f32; pub fn lgamma_r(n: f64, s: &mut i32) -> f64; + #[cfg(not(target_os = "aix"))] pub fn lgammaf_r(n: f32, s: &mut i32) -> f32; pub fn acosf128(n: f128) -> f128; @@ -56,6 +57,13 @@ extern "C" { }} } +// On AIX, we don't have lgammaf_r only the f64 version, so we can +// use the f64 version lgamma_r +#[cfg(target_os = "aix")] +pub unsafe fn lgammaf_r(n: f32, s: &mut i32) -> f32 { + lgamma_r(n.into(), s) as f32 +} + // On 32-bit x86 MSVC these functions aren't defined, so we just define shims // which promote everything to f64, perform the calculation, and then demote // back to f32. While not precisely correct should be "correct enough" for now. diff --git a/library/std/src/sys/pal/common/small_c_string.rs b/library/std/src/sys/pal/common/small_c_string.rs index 3c96714b5c58c..f54505a856e05 100644 --- a/library/std/src/sys/pal/common/small_c_string.rs +++ b/library/std/src/sys/pal/common/small_c_string.rs @@ -11,7 +11,7 @@ const MAX_STACK_ALLOCATION: usize = 384; const MAX_STACK_ALLOCATION: usize = 32; const NUL_ERR: io::Error = - io::const_io_error!(io::ErrorKind::InvalidInput, "file name contained an unexpected NUL byte"); + io::const_error!(io::ErrorKind::InvalidInput, "file name contained an unexpected NUL byte"); #[inline] pub fn run_path_with_cstr(path: &Path, f: &dyn Fn(&CStr) -> io::Result) -> io::Result { diff --git a/library/std/src/sys/pal/hermit/fs.rs b/library/std/src/sys/pal/hermit/fs.rs index 17d15ed2e5045..11862a076082d 100644 --- a/library/std/src/sys/pal/hermit/fs.rs +++ b/library/std/src/sys/pal/hermit/fs.rs @@ -294,7 +294,7 @@ impl OpenOptions { (false, _, true) => Ok(O_WRONLY | O_APPEND), (true, _, true) => Ok(O_RDWR | O_APPEND), (false, false, false) => { - Err(io::const_io_error!(ErrorKind::InvalidInput, "invalid access mode")) + Err(io::const_error!(ErrorKind::InvalidInput, "invalid access mode")) } } } @@ -304,18 +304,16 @@ impl OpenOptions { (true, false) => {} (false, false) => { if self.truncate || self.create || self.create_new { - return Err(io::const_io_error!( - ErrorKind::InvalidInput, - "invalid creation mode", - )); + return Err( + io::const_error!(ErrorKind::InvalidInput, "invalid creation mode",), + ); } } (_, true) => { if self.truncate && !self.create_new { - return Err(io::const_io_error!( - ErrorKind::InvalidInput, - "invalid creation mode", - )); + return Err( + io::const_error!(ErrorKind::InvalidInput, "invalid creation mode",), + ); } } } diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index b62afb40a615f..f03fca603441d 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -42,7 +42,7 @@ pub fn unsupported() -> crate::io::Result { } pub fn unsupported_err() -> crate::io::Error { - crate::io::const_io_error!( + crate::io::const_error!( crate::io::ErrorKind::Unsupported, "operation not supported on HermitCore yet", ) diff --git a/library/std/src/sys/pal/hermit/net.rs b/library/std/src/sys/pal/hermit/net.rs index d9baa091a2321..4e12374203e38 100644 --- a/library/std/src/sys/pal/hermit/net.rs +++ b/library/std/src/sys/pal/hermit/net.rs @@ -87,7 +87,7 @@ impl Socket { loop { let elapsed = start.elapsed(); if elapsed >= timeout { - return Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out")); + return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")); } let timeout = timeout - elapsed; @@ -114,7 +114,7 @@ impl Socket { // for POLLHUP rather than read readiness if pollfd.revents & netc::POLLHUP != 0 { let e = self.take_error()?.unwrap_or_else(|| { - io::const_io_error!( + io::const_error!( io::ErrorKind::Uncategorized, "no error set after POLLHUP", ) diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs index 41f2c3e212355..2a0b8dcb4ed60 100644 --- a/library/std/src/sys/pal/hermit/thread.rs +++ b/library/std/src/sys/pal/hermit/thread.rs @@ -41,7 +41,7 @@ impl Thread { unsafe { drop(Box::from_raw(p)); } - Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Unable to create thread!")) + Err(io::const_error!(io::ErrorKind::Uncategorized, "Unable to create thread!")) } else { Ok(Thread { tid: tid }) }; diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 586ccd18c2f57..ce8a2fed4bc6b 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -48,7 +48,7 @@ pub fn unsupported() -> crate::io::Result { } pub fn unsupported_err() -> crate::io::Error { - crate::io::const_io_error!(ErrorKind::Unsupported, "operation not supported on SGX yet") + crate::io::const_error!(ErrorKind::Unsupported, "operation not supported on SGX yet") } /// This function is used to implement various functions that doesn't exist, @@ -59,7 +59,7 @@ pub fn unsupported_err() -> crate::io::Error { pub fn sgx_ineffective(v: T) -> crate::io::Result { static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false); if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) { - Err(crate::io::const_io_error!( + Err(crate::io::const_error!( ErrorKind::Uncategorized, "operation can't be trusted to have any effect on SGX", )) diff --git a/library/std/src/sys/pal/solid/fs.rs b/library/std/src/sys/pal/solid/fs.rs index 776a96ff3b7ba..04dd10ad806d3 100644 --- a/library/std/src/sys/pal/solid/fs.rs +++ b/library/std/src/sys/pal/solid/fs.rs @@ -303,7 +303,7 @@ fn cstr(path: &Path) -> io::Result { if !path.starts_with(br"\") { // Relative paths aren't supported - return Err(crate::io::const_io_error!( + return Err(crate::io::const_error!( crate::io::ErrorKind::Unsupported, "relative path is not supported on this platform", )); @@ -314,10 +314,7 @@ fn cstr(path: &Path) -> io::Result { let wrapped_path = [SAFE_PREFIX, &path, &[0]].concat(); CString::from_vec_with_nul(wrapped_path).map_err(|_| { - crate::io::const_io_error!( - io::ErrorKind::InvalidInput, - "path provided contains a nul byte", - ) + crate::io::const_error!(io::ErrorKind::InvalidInput, "path provided contains a nul byte",) }) } @@ -512,7 +509,7 @@ impl fmt::Debug for File { pub fn unlink(p: &Path) -> io::Result<()> { if stat(p)?.file_type().is_dir() { - Err(io::const_io_error!(io::ErrorKind::IsADirectory, "is a directory")) + Err(io::const_error!(io::ErrorKind::IsADirectory, "is a directory")) } else { error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Unlink(cstr(p)?.as_ptr()) }) .map_err(|e| e.as_io_error())?; @@ -542,7 +539,7 @@ pub fn rmdir(p: &Path) -> io::Result<()> { .map_err(|e| e.as_io_error())?; Ok(()) } else { - Err(io::const_io_error!(io::ErrorKind::NotADirectory, "not a directory")) + Err(io::const_error!(io::ErrorKind::NotADirectory, "not a directory")) } } @@ -570,7 +567,7 @@ pub fn remove_dir_all(path: &Path) -> io::Result<()> { pub fn readlink(p: &Path) -> io::Result { // This target doesn't support symlinks stat(p)?; - Err(io::const_io_error!(io::ErrorKind::InvalidInput, "not a symbolic link")) + Err(io::const_error!(io::ErrorKind::InvalidInput, "not a symbolic link")) } pub fn symlink(_original: &Path, _link: &Path) -> io::Result<()> { diff --git a/library/std/src/sys/pal/solid/net.rs b/library/std/src/sys/pal/solid/net.rs index c0818ecd856d2..5f6436807e27e 100644 --- a/library/std/src/sys/pal/solid/net.rs +++ b/library/std/src/sys/pal/solid/net.rs @@ -175,7 +175,7 @@ impl Socket { }; match n { - 0 => Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out")), + 0 => Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")), _ => { let can_write = writefds.num_fds != 0; if !can_write { diff --git a/library/std/src/sys/pal/solid/os.rs b/library/std/src/sys/pal/solid/os.rs index d8afcb91f67f2..57c28aed3b293 100644 --- a/library/std/src/sys/pal/solid/os.rs +++ b/library/std/src/sys/pal/solid/os.rs @@ -204,7 +204,7 @@ pub unsafe fn unsetenv(n: &OsStr) -> io::Result<()> { /// In kmclib, `setenv` and `unsetenv` don't always set `errno`, so this /// function just returns a generic error. fn cvt_env(t: c_int) -> io::Result { - if t == -1 { Err(io::const_io_error!(io::ErrorKind::Uncategorized, "failure")) } else { Ok(t) } + if t == -1 { Err(io::const_error!(io::ErrorKind::Uncategorized, "failure")) } else { Ok(t) } } pub fn temp_dir() -> PathBuf { diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index abc8e69a285f3..47d9add72b5f0 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -13,7 +13,7 @@ use r_efi::efi::{self, Guid}; use r_efi::protocols::{device_path, device_path_to_text, shell}; use crate::ffi::{OsStr, OsString}; -use crate::io::{self, const_io_error}; +use crate::io::{self, const_error}; use crate::mem::{MaybeUninit, size_of}; use crate::os::uefi::env::boot_services; use crate::os::uefi::ffi::{OsStrExt, OsStringExt}; @@ -30,7 +30,7 @@ type BootUninstallMultipleProtocolInterfaces = unsafe extern "efiapi" fn(_: r_efi::efi::Handle, _: ...) -> r_efi::efi::Status; const BOOT_SERVICES_UNAVAILABLE: io::Error = - const_io_error!(io::ErrorKind::Other, "Boot Services are no longer available"); + const_error!(io::ErrorKind::Other, "Boot Services are no longer available"); /// Locates Handles with a particular Protocol GUID. /// @@ -114,7 +114,7 @@ pub(crate) fn open_protocol( Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { NonNull::new(unsafe { protocol.assume_init() }) - .ok_or(const_io_error!(io::ErrorKind::Other, "null protocol")) + .ok_or(const_error!(io::ErrorKind::Other, "null protocol")) } } @@ -134,7 +134,7 @@ pub(crate) fn create_event( if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { - NonNull::new(event).ok_or(const_io_error!(io::ErrorKind::Other, "null protocol")) + NonNull::new(event).ok_or(const_error!(io::ErrorKind::Other, "null protocol")) } } @@ -155,10 +155,8 @@ pub(crate) unsafe fn close_event(evt: NonNull) -> io::Result /// /// Note: Some protocols need to be manually freed. It is the caller's responsibility to do so. pub(crate) fn image_handle_protocol(protocol_guid: Guid) -> io::Result> { - let system_handle = uefi::env::try_image_handle().ok_or(io::const_io_error!( - io::ErrorKind::NotFound, - "Protocol not found in Image handle" - ))?; + let system_handle = uefi::env::try_image_handle() + .ok_or(io::const_error!(io::ErrorKind::NotFound, "Protocol not found in Image handle"))?; open_protocol(system_handle, protocol_guid) } @@ -178,7 +176,7 @@ pub(crate) fn device_path_to_text(path: NonNull) -> io::R }; let path = os_string_from_raw(path_ptr) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path"))?; if let Some(boot_services) = crate::os::uefi::env::boot_services() { let boot_services: NonNull = boot_services.cast(); @@ -213,7 +211,7 @@ pub(crate) fn device_path_to_text(path: NonNull) -> io::R } } - Err(io::const_io_error!(io::ErrorKind::NotFound, "No device path to text protocol found")) + Err(io::const_error!(io::ErrorKind::NotFound, "No device path to text protocol found")) } /// Gets RuntimeServices. @@ -234,7 +232,7 @@ impl DevicePath { ) -> io::Result { let path_vec = p.encode_wide().chain(Some(0)).collect::>(); if path_vec[..path_vec.len() - 1].contains(&0) { - return Err(const_io_error!( + return Err(const_error!( io::ErrorKind::InvalidInput, "strings passed to UEFI cannot contain NULs", )); @@ -243,9 +241,9 @@ impl DevicePath { let path = unsafe { ((*protocol.as_ptr()).convert_text_to_device_path)(path_vec.as_ptr()) }; - NonNull::new(path).map(DevicePath).ok_or_else(|| { - const_io_error!(io::ErrorKind::InvalidFilename, "Invalid Device Path") - }) + NonNull::new(path) + .map(DevicePath) + .ok_or_else(|| const_error!(io::ErrorKind::InvalidFilename, "Invalid Device Path")) } static LAST_VALID_HANDLE: AtomicPtr = @@ -271,7 +269,7 @@ impl DevicePath { } } - io::Result::Err(const_io_error!( + io::Result::Err(const_error!( io::ErrorKind::NotFound, "DevicePathFromText Protocol not found" )) @@ -326,7 +324,7 @@ impl OwnedProtocol { }; let handle = NonNull::new(handle) - .ok_or(io::const_io_error!(io::ErrorKind::Uncategorized, "found null handle"))?; + .ok_or(io::const_error!(io::ErrorKind::Uncategorized, "found null handle"))?; Ok(Self { guid, handle, protocol }) } diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index c0ab52f650aa5..f29c91f3bfe68 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs @@ -95,7 +95,7 @@ pub const fn unsupported() -> std_io::Result { #[inline] pub const fn unsupported_err() -> std_io::Error { - std_io::const_io_error!(std_io::ErrorKind::Unsupported, "operation not supported on UEFI",) + std_io::const_error!(std_io::ErrorKind::Unsupported, "operation not supported on UEFI",) } pub fn decode_error_kind(code: RawOsError) -> crate::io::ErrorKind { diff --git a/library/std/src/sys/pal/uefi/os.rs b/library/std/src/sys/pal/uefi/os.rs index 27395f7c3c0b3..6d23c72ef2209 100644 --- a/library/std/src/sys/pal/uefi/os.rs +++ b/library/std/src/sys/pal/uefi/os.rs @@ -131,7 +131,7 @@ pub fn getcwd() -> io::Result { let path_ptr = unsafe { ((*shell.as_ptr()).get_cur_dir)(crate::ptr::null_mut()) }; helpers::os_string_from_raw(path_ptr) .map(PathBuf::from) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path")) + .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path")) } None => { let mut t = current_exe()?; @@ -147,7 +147,7 @@ pub fn chdir(p: &path::Path) -> io::Result<()> { let shell = helpers::open_shell().ok_or(unsupported_err())?; let mut p = helpers::os_string_to_raw(p.as_os_str()) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path"))?; let r = unsafe { ((*shell.as_ptr()).set_cur_dir)(crate::ptr::null_mut(), p.as_mut_ptr()) }; if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } @@ -290,15 +290,15 @@ mod uefi_env { pub(crate) fn set(key: &OsStr, val: &OsStr) -> io::Result<()> { let mut key_ptr = helpers::os_string_to_raw(key) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?; let mut val_ptr = helpers::os_string_to_raw(val) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?; unsafe { set_raw(key_ptr.as_mut_ptr(), val_ptr.as_mut_ptr()) } } pub(crate) fn unset(key: &OsStr) -> io::Result<()> { let mut key_ptr = helpers::os_string_to_raw(key) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?; unsafe { set_raw(key_ptr.as_mut_ptr(), crate::ptr::null_mut()) } } @@ -328,7 +328,7 @@ mod uefi_env { }); // SAFETY: val.add(start) is always NULL terminated let val = unsafe { get_raw(shell, val.add(start)) } - .ok_or(io::const_io_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?; vars.push((key, val)); start = i + 1; diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/pal/uefi/process.rs index 1b83f4b0aee88..95707ebb7f023 100644 --- a/library/std/src/sys/pal/uefi/process.rs +++ b/library/std/src/sys/pal/uefi/process.rs @@ -307,7 +307,7 @@ mod uefi_command_internal { use super::super::helpers; use crate::ffi::{OsStr, OsString}; - use crate::io::{self, const_io_error}; + use crate::io::{self, const_error}; use crate::mem::MaybeUninit; use crate::os::uefi::env::{boot_services, image_handle, system_table}; use crate::os::uefi::ffi::{OsStrExt, OsStringExt}; @@ -328,7 +328,7 @@ mod uefi_command_internal { pub fn load_image(p: &OsStr) -> io::Result { let path = helpers::DevicePath::from_text(p)?; let boot_services: NonNull = boot_services() - .ok_or_else(|| const_io_error!(io::ErrorKind::NotFound, "Boot Services not found"))? + .ok_or_else(|| const_error!(io::ErrorKind::NotFound, "Boot Services not found"))? .cast(); let mut child_handle: MaybeUninit = MaybeUninit::uninit(); let image_handle = image_handle(); @@ -369,7 +369,7 @@ mod uefi_command_internal { } let boot_services: NonNull = boot_services() - .ok_or_else(|| const_io_error!(io::ErrorKind::NotFound, "Boot Services not found"))? + .ok_or_else(|| const_error!(io::ErrorKind::NotFound, "Boot Services not found"))? .cast(); let mut exit_data_size: usize = 0; let mut exit_data: MaybeUninit<*mut u16> = MaybeUninit::uninit(); @@ -583,7 +583,7 @@ mod uefi_command_internal { OsString::from_wide(&self._buffer) .into_string() .map(Into::into) - .map_err(|_| const_io_error!(io::ErrorKind::Other, "utf8 conversion failed")) + .map_err(|_| const_error!(io::ErrorKind::Other, "utf8 conversion failed")) } extern "efiapi" fn reset( diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 96f99efb21e84..37029bcd36e30 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -559,7 +559,7 @@ impl FileAttr { return if (ext.stx_mask & libc::STATX_BTIME) != 0 { SystemTime::new(ext.stx_btime.tv_sec, ext.stx_btime.tv_nsec as i64) } else { - Err(io::const_io_error!( + Err(io::const_error!( io::ErrorKind::Unsupported, "creation time is not available for the filesystem", )) @@ -567,7 +567,7 @@ impl FileAttr { } } - Err(io::const_io_error!( + Err(io::const_error!( io::ErrorKind::Unsupported, "creation time is not available on this platform \ currently", @@ -1272,7 +1272,7 @@ impl File { target_vendor = "apple", )))] pub fn lock(&self) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "lock() not supported")) + Err(io::const_error!(io::ErrorKind::Unsupported, "lock() not supported")) } #[cfg(any( @@ -1293,7 +1293,7 @@ impl File { target_vendor = "apple", )))] pub fn lock_shared(&self) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "lock_shared() not supported")) + Err(io::const_error!(io::ErrorKind::Unsupported, "lock_shared() not supported")) } #[cfg(any( @@ -1320,7 +1320,7 @@ impl File { target_vendor = "apple", )))] pub fn try_lock(&self) -> io::Result { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "try_lock() not supported")) + Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock() not supported")) } #[cfg(any( @@ -1347,7 +1347,7 @@ impl File { target_vendor = "apple", )))] pub fn try_lock_shared(&self) -> io::Result { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "try_lock_shared() not supported")) + Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock_shared() not supported")) } #[cfg(any( @@ -1368,7 +1368,7 @@ impl File { target_vendor = "apple", )))] pub fn unlock(&self) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "unlock() not supported")) + Err(io::const_error!(io::ErrorKind::Unsupported, "unlock() not supported")) } pub fn truncate(&self, size: u64) -> io::Result<()> { @@ -1459,11 +1459,11 @@ impl File { )))] let to_timespec = |time: Option| match time { Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts), - Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_io_error!( + Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_error!( io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time" )), - Some(_) => Err(io::const_io_error!( + Some(_) => Err(io::const_error!( io::ErrorKind::InvalidInput, "timestamp is too small to set as a file time" )), @@ -1476,7 +1476,7 @@ impl File { // the same as for Redox. // `futimens` and `UTIME_OMIT` are a work in progress for vxworks. let _ = times; - Err(io::const_io_error!( + Err(io::const_error!( io::ErrorKind::Unsupported, "setting file times not supported", )) @@ -1515,7 +1515,7 @@ impl File { weak!(fn futimens(c_int, *const libc::timespec) -> c_int); match futimens.get() { Some(futimens) => futimens(self.as_raw_fd(), times.as_ptr()), - None => return Err(io::const_io_error!( + None => return Err(io::const_error!( io::ErrorKind::Unsupported, "setting file times requires Android API level >= 19", )), @@ -2090,7 +2090,7 @@ pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { #[cfg(target_os = "vxworks")] pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { let (_, _, _) = (path, uid, gid); - Err(io::const_io_error!(io::ErrorKind::Unsupported, "lchown not supported by vxworks")) + Err(io::const_error!(io::ErrorKind::Unsupported, "lchown not supported by vxworks")) } #[cfg(not(any(target_os = "fuchsia", target_os = "vxworks")))] @@ -2101,7 +2101,7 @@ pub fn chroot(dir: &Path) -> io::Result<()> { #[cfg(target_os = "vxworks")] pub fn chroot(dir: &Path) -> io::Result<()> { let _ = dir; - Err(io::const_io_error!(io::ErrorKind::Unsupported, "chroot not supported by vxworks")) + Err(io::const_error!(io::ErrorKind::Unsupported, "chroot not supported by vxworks")) } pub use remove_dir_impl::remove_dir_all; diff --git a/library/std/src/sys/pal/unix/l4re.rs b/library/std/src/sys/pal/unix/l4re.rs index 52d39dcfb16fb..37dd370c5146c 100644 --- a/library/std/src/sys/pal/unix/l4re.rs +++ b/library/std/src/sys/pal/unix/l4re.rs @@ -1,6 +1,6 @@ macro_rules! unimpl { () => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Unsupported, "No networking available on L4Re.", )); diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs index 6a67bb0a101e9..d140607869c14 100644 --- a/library/std/src/sys/pal/unix/net.rs +++ b/library/std/src/sys/pal/unix/net.rs @@ -190,7 +190,7 @@ impl Socket { loop { let elapsed = start.elapsed(); if elapsed >= timeout { - return Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out")); + return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")); } let timeout = timeout - elapsed; @@ -225,7 +225,7 @@ impl Socket { // for POLLHUP or POLLERR rather than read readiness if pollfd.revents & (libc::POLLHUP | libc::POLLERR) != 0 { let e = self.take_error()?.unwrap_or_else(|| { - io::const_io_error!( + io::const_error!( io::ErrorKind::Uncategorized, "no error set after POLLHUP", ) diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index f983d174ed61c..789a40c13e61b 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -258,7 +258,7 @@ pub fn current_exe() -> io::Result { use crate::env; use crate::io::ErrorKind; - let exe_path = env::args().next().ok_or(io::const_io_error!( + let exe_path = env::args().next().ok_or(io::const_error!( ErrorKind::NotFound, "an executable path was not found because no arguments were provided through argv" ))?; @@ -284,7 +284,7 @@ pub fn current_exe() -> io::Result { } } } - Err(io::const_io_error!(ErrorKind::NotFound, "an executable path was not found")) + Err(io::const_error!(ErrorKind::NotFound, "an executable path was not found")) } #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] @@ -340,7 +340,7 @@ pub fn current_exe() -> io::Result { 0, ))?; if path_len <= 1 { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Uncategorized, "KERN_PROC_PATHNAME sysctl returned zero-length string", )); @@ -363,7 +363,7 @@ pub fn current_exe() -> io::Result { if curproc_exe.is_file() { return crate::fs::read_link(curproc_exe); } - Err(io::const_io_error!( + Err(io::const_error!( io::ErrorKind::Uncategorized, "/proc/curproc/exe doesn't point to regular file.", )) @@ -382,10 +382,9 @@ pub fn current_exe() -> io::Result { cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _, &mut argv_len, ptr::null_mut(), 0))?; argv.set_len(argv_len as usize); if argv[0].is_null() { - return Err(io::const_io_error!( - io::ErrorKind::Uncategorized, - "no current exe available", - )); + return Err( + io::const_error!(io::ErrorKind::Uncategorized, "no current exe available",), + ); } let argv0 = CStr::from_ptr(argv[0]).to_bytes(); if argv0[0] == b'.' || argv0.iter().any(|b| *b == b'/') { @@ -405,7 +404,7 @@ pub fn current_exe() -> io::Result { ))] pub fn current_exe() -> io::Result { match crate::fs::read_link("/proc/self/exe") { - Err(ref e) if e.kind() == io::ErrorKind::NotFound => Err(io::const_io_error!( + Err(ref e) if e.kind() == io::ErrorKind::NotFound => Err(io::const_error!( io::ErrorKind::Uncategorized, "no /proc/self/exe available. Is /proc mounted?", )), @@ -476,7 +475,7 @@ pub fn current_exe() -> io::Result { ); if result != libc::B_OK { use crate::io::ErrorKind; - Err(io::const_io_error!(ErrorKind::Uncategorized, "Error getting executable path")) + Err(io::const_error!(ErrorKind::Uncategorized, "Error getting executable path")) } else { // find_path adds the null terminator. let name = CStr::from_ptr(name.as_ptr()).to_bytes(); @@ -493,7 +492,7 @@ pub fn current_exe() -> io::Result { #[cfg(target_os = "l4re")] pub fn current_exe() -> io::Result { use crate::io::ErrorKind; - Err(io::const_io_error!(ErrorKind::Unsupported, "Not yet implemented!")) + Err(io::const_error!(ErrorKind::Unsupported, "Not yet implemented!")) } #[cfg(target_os = "vxworks")] @@ -523,7 +522,7 @@ pub fn current_exe() -> io::Result { use crate::env; use crate::io::ErrorKind; - let exe_path = env::args().next().ok_or(io::const_io_error!( + let exe_path = env::args().next().ok_or(io::const_error!( ErrorKind::Uncategorized, "an executable path was not found because no arguments were provided through argv" ))?; @@ -698,12 +697,82 @@ pub fn page_size() -> usize { unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize } } +// Returns the value for [`confstr(key, ...)`][posix_confstr]. Currently only +// used on Darwin, but should work on any unix (in case we need to get +// `_CS_PATH` or `_CS_V[67]_ENV` in the future). +// +// [posix_confstr]: +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/confstr.html +// +// FIXME: Support `confstr` in Miri. +#[cfg(all(target_vendor = "apple", not(miri)))] +fn confstr(key: c_int, size_hint: Option) -> io::Result { + let mut buf: Vec = Vec::with_capacity(0); + let mut bytes_needed_including_nul = size_hint + .unwrap_or_else(|| { + // Treat "None" as "do an extra call to get the length". In theory + // we could move this into the loop below, but it's hard to do given + // that it isn't 100% clear if it's legal to pass 0 for `len` when + // the buffer isn't null. + unsafe { libc::confstr(key, core::ptr::null_mut(), 0) } + }) + .max(1); + // If the value returned by `confstr` is greater than the len passed into + // it, then the value was truncated, meaning we need to retry. Note that + // while `confstr` results don't seem to change for a process, it's unclear + // if this is guaranteed anywhere, so looping does seem required. + while bytes_needed_including_nul > buf.capacity() { + // We write into the spare capacity of `buf`. This lets us avoid + // changing buf's `len`, which both simplifies `reserve` computation, + // allows working with `Vec` instead of `Vec>`, and + // may avoid a copy, since the Vec knows that none of the bytes are needed + // when reallocating (well, in theory anyway). + buf.reserve(bytes_needed_including_nul); + // `confstr` returns + // - 0 in the case of errors: we break and return an error. + // - The number of bytes written, iff the provided buffer is enough to + // hold the entire value: we break and return the data in `buf`. + // - Otherwise, the number of bytes needed (including nul): we go + // through the loop again. + bytes_needed_including_nul = + unsafe { libc::confstr(key, buf.as_mut_ptr().cast::(), buf.capacity()) }; + } + // `confstr` returns 0 in the case of an error. + if bytes_needed_including_nul == 0 { + return Err(io::Error::last_os_error()); + } + // Safety: `confstr(..., buf.as_mut_ptr(), buf.capacity())` returned a + // non-zero value, meaning `bytes_needed_including_nul` bytes were + // initialized. + unsafe { + buf.set_len(bytes_needed_including_nul); + // Remove the NUL-terminator. + let last_byte = buf.pop(); + // ... and smoke-check that it *was* a NUL-terminator. + assert_eq!(last_byte, Some(0), "`confstr` provided a string which wasn't nul-terminated"); + }; + Ok(OsString::from_vec(buf)) +} + +#[cfg(all(target_vendor = "apple", not(miri)))] +fn darwin_temp_dir() -> PathBuf { + confstr(libc::_CS_DARWIN_USER_TEMP_DIR, Some(64)).map(PathBuf::from).unwrap_or_else(|_| { + // It failed for whatever reason (there are several possible reasons), + // so return the global one. + PathBuf::from("/tmp") + }) +} + pub fn temp_dir() -> PathBuf { crate::env::var_os("TMPDIR").map(PathBuf::from).unwrap_or_else(|| { - if cfg!(target_os = "android") { - PathBuf::from("/data/local/tmp") - } else { - PathBuf::from("/tmp") + cfg_if::cfg_if! { + if #[cfg(all(target_vendor = "apple", not(miri)))] { + darwin_temp_dir() + } else if #[cfg(target_os = "android")] { + PathBuf::from("/data/local/tmp") + } else { + PathBuf::from("/tmp") + } } }) } diff --git a/library/std/src/sys/pal/unix/os/tests.rs b/library/std/src/sys/pal/unix/os/tests.rs index efc29955b05fe..63a1cc1e94a1d 100644 --- a/library/std/src/sys/pal/unix/os/tests.rs +++ b/library/std/src/sys/pal/unix/os/tests.rs @@ -21,3 +21,28 @@ fn test_parse_glibc_version() { assert_eq!(parsed, super::parse_glibc_version(version_str)); } } + +// Smoke check `confstr`, do it for several hint values, to ensure our resizing +// logic is correct. +#[test] +#[cfg(all(target_vendor = "apple", not(miri)))] +fn test_confstr() { + for key in [libc::_CS_DARWIN_USER_TEMP_DIR, libc::_CS_PATH] { + let value_nohint = super::confstr(key, None).unwrap_or_else(|e| { + panic!("confstr({key}, None) failed: {e:?}"); + }); + let end = (value_nohint.len() + 1) * 2; + for hint in 0..end { + assert_eq!( + super::confstr(key, Some(hint)).as_deref().ok(), + Some(&*value_nohint), + "confstr({key}, Some({hint})) failed", + ); + } + } + // Smoke check that we don't loop forever or something if the input was not valid. + for hint in [None, Some(0), Some(1)] { + let hopefully_invalid = 123456789_i32; + assert!(super::confstr(hopefully_invalid, hint).is_err()); + } +} diff --git a/library/std/src/sys/pal/unix/process/process_fuchsia.rs b/library/std/src/sys/pal/unix/process/process_fuchsia.rs index 8f7d786e32fcd..b7a35718757ae 100644 --- a/library/std/src/sys/pal/unix/process/process_fuchsia.rs +++ b/library/std/src/sys/pal/unix/process/process_fuchsia.rs @@ -18,7 +18,7 @@ impl Command { let envp = self.capture_env(); if self.saw_nul() { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "nul byte found in provided data", )); @@ -38,7 +38,7 @@ impl Command { pub fn exec(&mut self, default: Stdio) -> io::Error { if self.saw_nul() { - return io::const_io_error!( + return io::const_error!( io::ErrorKind::InvalidInput, "nul byte found in provided data", ); @@ -185,7 +185,7 @@ impl Process { ))?; } if actual != 1 { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidData, "Failed to get exit status of process", )); @@ -222,7 +222,7 @@ impl Process { ))?; } if actual != 1 { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidData, "Failed to get exit status of process", )); 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 8faf1fda5464d..ec4965c1d7196 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -61,7 +61,7 @@ impl Command { let envp = self.capture_env(); if self.saw_nul() { - return Err(io::const_io_error!( + return Err(io::const_error!( ErrorKind::InvalidInput, "nul byte found in provided data", )); @@ -175,7 +175,7 @@ impl Command { // allowed to exist in dead code), but it sounds bad, so we go out of our // way to avoid that all-together. #[cfg(any(target_os = "tvos", target_os = "watchos"))] - const ERR_APPLE_TV_WATCH_NO_FORK_EXEC: Error = io::const_io_error!( + const ERR_APPLE_TV_WATCH_NO_FORK_EXEC: Error = io::const_error!( ErrorKind::Unsupported, "`fork`+`exec`-based process spawning is not supported on this target", ); @@ -218,7 +218,7 @@ impl Command { } else if delay < MAX_FORKSPAWN_SLEEP { thread::sleep(delay); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( ErrorKind::WouldBlock, "forking returned EBADF too often", )); @@ -235,7 +235,7 @@ impl Command { let envp = self.capture_env(); if self.saw_nul() { - return io::const_io_error!(ErrorKind::InvalidInput, "nul byte found in provided data",); + return io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data",); } match self.setup_io(default, true) { @@ -561,7 +561,7 @@ impl Command { } else if delay < MAX_FORKSPAWN_SLEEP { thread::sleep(delay); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( ErrorKind::WouldBlock, "posix_spawnp returned EBADF too often", )); diff --git a/library/std/src/sys/pal/unix/process/process_vxworks.rs b/library/std/src/sys/pal/unix/process/process_vxworks.rs index 38daf6af91808..e2c1b6a032624 100644 --- a/library/std/src/sys/pal/unix/process/process_vxworks.rs +++ b/library/std/src/sys/pal/unix/process/process_vxworks.rs @@ -22,7 +22,7 @@ impl Command { let envp = self.capture_env(); if self.saw_nul() { - return Err(io::const_io_error!( + return Err(io::const_error!( ErrorKind::InvalidInput, "nul byte found in provided data", )); diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 040246618360f..131a6e81b1e92 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -469,7 +469,7 @@ pub fn available_parallelism() -> io::Result> { unsafe { use libc::_syspage_ptr; if _syspage_ptr.is_null() { - Err(io::const_io_error!(io::ErrorKind::NotFound, "No syspage available")) + Err(io::const_error!(io::ErrorKind::NotFound, "No syspage available")) } else { let cpus = (*_syspage_ptr).num_cpu; NonZero::new(cpus as usize) @@ -509,7 +509,7 @@ pub fn available_parallelism() -> io::Result> { } } else { // FIXME: implement on Redox, l4re - Err(io::const_io_error!(io::ErrorKind::Unsupported, "Getting the number of hardware threads is not supported on the target platform")) + Err(io::const_error!(io::ErrorKind::Unsupported, "Getting the number of hardware threads is not supported on the target platform")) } } } diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index 535fe6b27d91e..343864d0b3fd2 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -96,7 +96,7 @@ impl Timespec { if tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64 { Ok(unsafe { Self::new_unchecked(tv_sec, tv_nsec) }) } else { - Err(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid timestamp")) + Err(io::const_error!(io::ErrorKind::InvalidData, "Invalid timestamp")) } } diff --git a/library/std/src/sys/pal/unsupported/os.rs b/library/std/src/sys/pal/unsupported/os.rs index 481fd62c04fe8..48de4312885fe 100644 --- a/library/std/src/sys/pal/unsupported/os.rs +++ b/library/std/src/sys/pal/unsupported/os.rs @@ -96,11 +96,11 @@ pub fn getenv(_: &OsStr) -> Option { } pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) + Err(io::const_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) } pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) + Err(io::const_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) } pub fn temp_dir() -> PathBuf { diff --git a/library/std/src/sys/pal/wasi/fs.rs b/library/std/src/sys/pal/wasi/fs.rs index 3296c762cca2b..0667eb9010100 100644 --- a/library/std/src/sys/pal/wasi/fs.rs +++ b/library/std/src/sys/pal/wasi/fs.rs @@ -496,7 +496,7 @@ impl File { pub fn set_times(&self, times: FileTimes) -> io::Result<()> { let to_timestamp = |time: Option| match time { Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts), - Some(_) => Err(io::const_io_error!( + Some(_) => Err(io::const_error!( io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time" )), @@ -764,8 +764,7 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop, PathBuf)> { } pub fn osstr2str(f: &OsStr) -> io::Result<&str> { - f.to_str() - .ok_or_else(|| io::const_io_error!(io::ErrorKind::Uncategorized, "input must be utf-8")) + f.to_str().ok_or_else(|| io::const_error!(io::ErrorKind::Uncategorized, "input must be utf-8")) } pub fn copy(from: &Path, to: &Path) -> io::Result { @@ -811,7 +810,7 @@ fn remove_dir_all_recursive(parent: &WasiFd, path: &Path) -> io::Result<()> { for entry in ReadDir::new(fd, dummy_root) { let entry = entry?; let path = crate::str::from_utf8(&entry.name).map_err(|_| { - io::const_io_error!(io::ErrorKind::Uncategorized, "invalid utf-8 file name found") + io::const_error!(io::ErrorKind::Uncategorized, "invalid utf-8 file name found") })?; let result: io::Result<()> = try { diff --git a/library/std/src/sys/pal/wasip2/net.rs b/library/std/src/sys/pal/wasip2/net.rs index 06e623df8438e..f009a51821f35 100644 --- a/library/std/src/sys/pal/wasip2/net.rs +++ b/library/std/src/sys/pal/wasip2/net.rs @@ -117,7 +117,7 @@ impl Socket { loop { let elapsed = start.elapsed(); if elapsed >= timeout { - return Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out")); + return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")); } let timeout = timeout - elapsed; diff --git a/library/std/src/sys/pal/windows/args.rs b/library/std/src/sys/pal/windows/args.rs index e9fc19bcb99c1..3447a0157e4c5 100644 --- a/library/std/src/sys/pal/windows/args.rs +++ b/library/std/src/sys/pal/windows/args.rs @@ -327,7 +327,7 @@ pub(crate) fn make_bat_command_line( force_quotes: bool, ) -> io::Result> { const INVALID_ARGUMENT_ERROR: io::Error = - io::const_io_error!(io::ErrorKind::InvalidInput, r#"batch file arguments are invalid"#); + io::const_error!(io::ErrorKind::InvalidInput, r#"batch file arguments are invalid"#); // Set the start of the command line to `cmd.exe /c "` // It is necessary to surround the command in an extra pair of quotes, // hence the trailing quote here. It will be closed after all arguments @@ -340,7 +340,7 @@ pub(crate) fn make_bat_command_line( // Windows file names cannot contain a `"` character or end with `\\`. // If the script name does then return an error. if script.contains(&(b'"' as u16)) || script.last() == Some(&(b'\\' as u16)) { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "Windows file names may not contain `\"` or end with `\\`" )); diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index 07e4f93a37956..5bdd5f81b9c3d 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -677,7 +677,7 @@ impl File { ) } _ => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Uncategorized, "Unsupported reparse point type", )); @@ -718,7 +718,7 @@ impl File { || times.modified.map_or(false, is_zero) || times.created.map_or(false, is_zero) { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "Cannot set file timestamp to 0", )); @@ -728,7 +728,7 @@ impl File { || times.modified.map_or(false, is_max) || times.created.map_or(false, is_max) { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "Cannot set file timestamp to 0xFFFF_FFFF_FFFF_FFFF", )); @@ -1305,10 +1305,9 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> { #[cfg(target_vendor = "uwp")] pub fn link(_original: &Path, _link: &Path) -> io::Result<()> { - return Err(io::const_io_error!( - io::ErrorKind::Unsupported, - "hard link are not supported on UWP", - )); + return Err( + io::const_error!(io::ErrorKind::Unsupported, "hard link are not supported on UWP",), + ); } pub fn stat(path: &Path) -> io::Result { @@ -1495,7 +1494,7 @@ pub fn junction_point(original: &Path, link: &Path) -> io::Result<()> { let bytes = unsafe { OsStr::from_encoded_bytes_unchecked(&abs_path[2..]) }; r"\??\UNC\".encode_utf16().chain(bytes.encode_wide()).collect() } else { - return Err(io::const_io_error!(io::ErrorKind::InvalidInput, "path is not valid")); + return Err(io::const_error!(io::ErrorKind::InvalidInput, "path is not valid")); } }; // Defined inline so we don't have to mess about with variable length buffer. @@ -1512,10 +1511,7 @@ pub fn junction_point(original: &Path, link: &Path) -> io::Result<()> { } let data_len = 12 + (abs_path.len() * 2); if data_len > u16::MAX as usize { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "`original` path is too long" - )); + return Err(io::const_error!(io::ErrorKind::InvalidInput, "`original` path is too long")); } let data_len = data_len as u16; let mut header = MountPointBuffer { diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index aca69490d7a1a..d66ff15e10bf6 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -183,7 +183,7 @@ pub fn to_u16s>(s: S) -> crate::io::Result> { maybe_result.extend(s.encode_wide()); if unrolled_find_u16s(0, &maybe_result).is_some() { - return Err(crate::io::const_io_error!( + return Err(crate::io::const_error!( ErrorKind::InvalidInput, "strings passed to WinAPI cannot contain NULs", )); diff --git a/library/std/src/sys/pal/windows/net.rs b/library/std/src/sys/pal/windows/net.rs index fd62d1f407c27..a92853c642c06 100644 --- a/library/std/src/sys/pal/windows/net.rs +++ b/library/std/src/sys/pal/windows/net.rs @@ -267,7 +267,7 @@ impl Socket { }; match count { - 0 => Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out")), + 0 => Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")), _ => { if writefds.fd_count != 1 { if let Some(e) = self.take_error()? { diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs index 17bb03fe7af04..da0daacd1dde3 100644 --- a/library/std/src/sys/pal/windows/process.rs +++ b/library/std/src/sys/pal/windows/process.rs @@ -144,7 +144,7 @@ impl AsRef for EnvKey { pub(crate) fn ensure_no_nuls>(str: T) -> io::Result { if str.as_ref().encode_wide().any(|b| b == 0) { - Err(io::const_io_error!(ErrorKind::InvalidInput, "nul byte found in provided data")) + Err(io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data")) } else { Ok(str) } @@ -439,10 +439,9 @@ fn resolve_exe<'a>( ) -> io::Result> { // Early return if there is no filename. if exe_path.is_empty() || path::has_trailing_slash(exe_path) { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "program path has no file name", - )); + return Err( + io::const_error!(io::ErrorKind::InvalidInput, "program path has no file name",), + ); } // Test if the file name has the `exe` extension. // This does a case-insensitive `ends_with`. @@ -492,7 +491,7 @@ fn resolve_exe<'a>( } } // If we get here then the executable cannot be found. - Err(io::const_io_error!(io::ErrorKind::NotFound, "program not found")) + Err(io::const_error!(io::ErrorKind::NotFound, "program not found")) } // Calls `f` for every path that should be used to find an executable. @@ -921,7 +920,7 @@ fn make_proc_thread_attribute_list( // a null pointer to retrieve the required size. let mut required_size = 0; let Ok(attribute_count) = attributes.len().try_into() else { - return Err(io::const_io_error!( + return Err(io::const_error!( ErrorKind::InvalidInput, "maximum number of ProcThreadAttributes exceeded", )); diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs index 575f2250eb91c..642c8bc4df7d1 100644 --- a/library/std/src/sys/pal/windows/stdio.rs +++ b/library/std/src/sys/pal/windows/stdio.rs @@ -107,7 +107,7 @@ fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> i if data[0] >> 6 != 0b10 { // not a continuation byte - reject incomplete_utf8.len = 0; - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidData, "Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); @@ -129,7 +129,7 @@ fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> i return Ok(1); } Err(_) => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidData, "Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); @@ -153,7 +153,7 @@ fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> i incomplete_utf8.len = 1; return Ok(1); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidData, "Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); @@ -392,7 +392,7 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result { }; if result == 0 { // We can't really do any better than forget all data and return an error. - Err(io::const_io_error!( + Err(io::const_error!( io::ErrorKind::InvalidData, "Windows stdin in console mode does not support non-UTF-16 input; \ encountered unpaired surrogate", diff --git a/library/std/src/sys/pal/xous/net/dns.rs b/library/std/src/sys/pal/xous/net/dns.rs index 1a2b56b4da5d3..ff6e49ed2d430 100644 --- a/library/std/src/sys/pal/xous/net/dns.rs +++ b/library/std/src/sys/pal/xous/net/dns.rs @@ -107,7 +107,7 @@ impl TryFrom<&str> for LookupHost { ($e:expr, $msg:expr) => { match $e { Some(r) => r, - None => return Err(io::const_io_error!(io::ErrorKind::InvalidInput, &$msg)), + None => return Err(io::const_error!(io::ErrorKind::InvalidInput, &$msg)), } }; } @@ -123,7 +123,6 @@ impl TryFrom<(&str, u16)> for LookupHost { type Error = io::Error; fn try_from(v: (&str, u16)) -> io::Result { - lookup(v.0, v.1) - .map_err(|_e| io::const_io_error!(io::ErrorKind::InvalidInput, &"DNS failure")) + lookup(v.0, v.1).map_err(|_e| io::const_error!(io::ErrorKind::InvalidInput, &"DNS failure")) } } diff --git a/library/std/src/sys/pal/xous/net/tcplistener.rs b/library/std/src/sys/pal/xous/net/tcplistener.rs index ddfb289162b69..640a02a64f525 100644 --- a/library/std/src/sys/pal/xous/net/tcplistener.rs +++ b/library/std/src/sys/pal/xous/net/tcplistener.rs @@ -9,7 +9,7 @@ use crate::{fmt, io}; macro_rules! unimpl { () => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Unsupported, &"This function is not yet implemented", )); @@ -71,7 +71,7 @@ impl TcpListener { 0, 4096, ) else { - return Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Invalid response")); + return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response")); }; // The first four bytes should be zero upon success, and will be nonzero @@ -80,16 +80,13 @@ impl TcpListener { if response[0] != 0 || valid == 0 { let errcode = response[1]; if errcode == NetError::SocketInUse as u8 { - return Err(io::const_io_error!(io::ErrorKind::ResourceBusy, &"Socket in use")); + return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use")); } else if errcode == NetError::Invalid as u8 { - return Err(io::const_io_error!( - io::ErrorKind::AddrNotAvailable, - &"Invalid address" - )); + return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, &"Invalid address")); } else if errcode == NetError::LibraryError as u8 { - return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error")); + return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Other, &"Unable to connect or internal error" )); @@ -130,16 +127,15 @@ impl TcpListener { if receive_request.raw[0] != 0 { // error case if receive_request.raw[1] == NetError::TimedOut as u8 { - return Err(io::const_io_error!(io::ErrorKind::TimedOut, &"accept timed out",)); + return Err(io::const_error!(io::ErrorKind::TimedOut, &"accept timed out",)); } else if receive_request.raw[1] == NetError::WouldBlock as u8 { - return Err(io::const_io_error!( - io::ErrorKind::WouldBlock, - &"accept would block", - )); + return Err( + io::const_error!(io::ErrorKind::WouldBlock, &"accept would block",), + ); } else if receive_request.raw[1] == NetError::LibraryError as u8 { - return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error")); + return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); } else { - return Err(io::const_io_error!(io::ErrorKind::Other, &"library error",)); + return Err(io::const_error!(io::ErrorKind::Other, &"library error",)); } } else { // accept successful @@ -163,7 +159,7 @@ impl TcpListener { port, ) } else { - return Err(io::const_io_error!(io::ErrorKind::Other, &"library error",)); + return Err(io::const_error!(io::ErrorKind::Other, &"library error",)); }; // replenish the listener @@ -175,7 +171,7 @@ impl TcpListener { Ok((TcpStream::from_listener(stream_fd, self.local.port(), port, addr), addr)) } } else { - Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unable to accept")) + Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unable to accept")) } } @@ -192,7 +188,7 @@ impl TcpListener { services::net_server(), services::NetBlockingScalar::StdSetTtlTcp(self.fd.load(Ordering::Relaxed), ttl).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|_| ()) } @@ -201,7 +197,7 @@ impl TcpListener { services::net_server(), services::NetBlockingScalar::StdGetTtlTcp(self.fd.load(Ordering::Relaxed)).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|res| res[0] as _)?) } diff --git a/library/std/src/sys/pal/xous/net/tcpstream.rs b/library/std/src/sys/pal/xous/net/tcpstream.rs index 03442cf2fcdfd..572dd6b3b6398 100644 --- a/library/std/src/sys/pal/xous/net/tcpstream.rs +++ b/library/std/src/sys/pal/xous/net/tcpstream.rs @@ -10,7 +10,7 @@ use crate::time::Duration; macro_rules! unimpl { () => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Unsupported, &"This function is not yet implemented", )); @@ -96,7 +96,7 @@ impl TcpStream { 0, 4096, ) else { - return Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Invalid response")); + return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response")); }; // The first four bytes should be zero upon success, and will be nonzero @@ -106,14 +106,11 @@ impl TcpStream { // errcode is a u8 but stuck in a u16 where the upper byte is invalid. Mask & decode accordingly. let errcode = response[0]; if errcode == NetError::SocketInUse as u8 { - return Err(io::const_io_error!(io::ErrorKind::ResourceBusy, &"Socket in use",)); + return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use",)); } else if errcode == NetError::Unaddressable as u8 { - return Err(io::const_io_error!( - io::ErrorKind::AddrNotAvailable, - &"Invalid address", - )); + return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, &"Invalid address",)); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, &"Unable to connect or internal error", )); @@ -199,7 +196,7 @@ impl TcpStream { self.read_timeout.load(Ordering::Relaxed) as usize, data_to_read, ) else { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, &"Library failure: wrong message type or messaging error" )); @@ -215,14 +212,14 @@ impl TcpStream { if result[0] != 0 { if result[1] == 8 { // timed out - return Err(io::const_io_error!(io::ErrorKind::TimedOut, &"Timeout",)); + return Err(io::const_error!(io::ErrorKind::TimedOut, &"Timeout",)); } if result[1] == 9 { // would block - return Err(io::const_io_error!(io::ErrorKind::WouldBlock, &"Would block",)); + return Err(io::const_error!(io::ErrorKind::WouldBlock, &"Would block",)); } } - Err(io::const_io_error!(io::ErrorKind::Other, &"recv_slice failure")) + Err(io::const_error!(io::ErrorKind::Other, &"recv_slice failure")) } } @@ -261,23 +258,20 @@ impl TcpStream { self.write_timeout.load(Ordering::Relaxed) as usize, buf_len, ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Internal error")))?; + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error")))?; if send_request.raw[0] != 0 { if send_request.raw[4] == 8 { // timed out - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::BrokenPipe, &"Timeout or connection closed", )); } else if send_request.raw[4] == 9 { // would block - return Err(io::const_io_error!(io::ErrorKind::WouldBlock, &"Would block",)); + return Err(io::const_error!(io::ErrorKind::WouldBlock, &"Would block",)); } else { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - &"Error when sending", - )); + return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Error when sending",)); } } Ok(u32::from_le_bytes([ @@ -310,7 +304,7 @@ impl TcpStream { 0, 0, ) else { - return Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Internal error")); + return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error")); }; let mut i = get_addr.raw.iter(); match *i.next().unwrap() { @@ -330,7 +324,7 @@ impl TcpStream { } Ok(SocketAddr::V6(SocketAddrV6::new(new_addr.into(), self.local_port, 0, 0))) } - _ => Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Internal error")), + _ => Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error")), } } @@ -339,7 +333,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdTcpStreamShutdown(self.fd, how).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|_| ()) } @@ -361,7 +355,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdSetNodelay(self.fd, enabled).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|_| ()) } @@ -370,7 +364,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdGetNodelay(self.fd).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|res| res[0] != 0)?) } @@ -382,7 +376,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdSetTtlTcp(self.fd, ttl).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|_| ()) } @@ -391,7 +385,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdGetTtlTcp(self.fd).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|res| res[0] as _)?) } diff --git a/library/std/src/sys/pal/xous/net/udp.rs b/library/std/src/sys/pal/xous/net/udp.rs index de5133280ba9d..1b7ecac6d3a7e 100644 --- a/library/std/src/sys/pal/xous/net/udp.rs +++ b/library/std/src/sys/pal/xous/net/udp.rs @@ -11,7 +11,7 @@ use crate::{fmt, io}; macro_rules! unimpl { () => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Unsupported, &"This function is not yet implemented", )); @@ -72,16 +72,16 @@ impl UdpSocket { if response[0] != 0 || valid == 0 { let errcode = response[1]; if errcode == NetError::SocketInUse as u8 { - return Err(io::const_io_error!(io::ErrorKind::ResourceBusy, &"Socket in use")); + return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use")); } else if errcode == NetError::Invalid as u8 { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, &"Port can't be 0 or invalid address" )); } else if errcode == NetError::LibraryError as u8 { - return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error")); + return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Other, &"Unable to connect or internal error" )); @@ -98,13 +98,13 @@ impl UdpSocket { nonblocking: Cell::new(false), }); } - Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Invalid response")) + Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response")) } pub fn peer_addr(&self) -> io::Result { match self.remote.get() { Some(dest) => Ok(dest), - None => Err(io::const_io_error!(io::ErrorKind::NotConnected, &"No peer specified")), + None => Err(io::const_error!(io::ErrorKind::NotConnected, &"No peer specified")), } } @@ -141,16 +141,13 @@ impl UdpSocket { if receive_request.raw[0] != 0 { // error case if receive_request.raw[1] == NetError::TimedOut as u8 { - return Err(io::const_io_error!(io::ErrorKind::TimedOut, &"recv timed out",)); + return Err(io::const_error!(io::ErrorKind::TimedOut, &"recv timed out",)); } else if receive_request.raw[1] == NetError::WouldBlock as u8 { - return Err(io::const_io_error!( - io::ErrorKind::WouldBlock, - &"recv would block", - )); + return Err(io::const_error!(io::ErrorKind::WouldBlock, &"recv would block",)); } else if receive_request.raw[1] == NetError::LibraryError as u8 { - return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error")); + return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); } else { - return Err(io::const_io_error!(io::ErrorKind::Other, &"library error",)); + return Err(io::const_error!(io::ErrorKind::Other, &"library error",)); } } else { let rr = &receive_request.raw; @@ -173,7 +170,7 @@ impl UdpSocket { port, ) } else { - return Err(io::const_io_error!(io::ErrorKind::Other, &"library error",)); + return Err(io::const_error!(io::ErrorKind::Other, &"library error",)); }; for (&s, d) in rr[22..22 + rxlen as usize].iter().zip(buf.iter_mut()) { *d = s; @@ -181,7 +178,7 @@ impl UdpSocket { Ok((rxlen as usize, addr)) } } else { - Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unable to recv")) + Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unable to recv")) } } @@ -211,7 +208,7 @@ impl UdpSocket { if let Some(addr) = self.remote.get() { self.send_to(buf, &addr) } else { - Err(io::const_io_error!(io::ErrorKind::NotConnected, &"No remote specified")) + Err(io::const_error!(io::ErrorKind::NotConnected, &"No remote specified")) } } @@ -282,22 +279,19 @@ impl UdpSocket { if response[0] != 0 || valid == 0 { let errcode = response[1]; if errcode == NetError::SocketInUse as u8 { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::ResourceBusy, &"Socket in use" )); } else if errcode == NetError::Invalid as u8 { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, &"Socket not valid" )); } else if errcode == NetError::LibraryError as u8 { - return Err(io::const_io_error!( - io::ErrorKind::Other, - &"Library error" - )); + return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Other, &"Unable to connect" )); @@ -309,7 +303,7 @@ impl UdpSocket { } Err(crate::os::xous::ffi::Error::ServerQueueFull) => { if now.elapsed() >= write_timeout { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::WouldBlock, &"Write timed out" )); @@ -318,7 +312,7 @@ impl UdpSocket { crate::thread::yield_now(); } } - _ => return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error")), + _ => return Err(io::const_error!(io::ErrorKind::Other, &"Library error")), } } } @@ -372,7 +366,7 @@ impl UdpSocket { services::net_server(), services::NetBlockingScalar::StdSetTtlUdp(self.fd, ttl).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|_| ()) } @@ -381,7 +375,7 @@ impl UdpSocket { services::net_server(), services::NetBlockingScalar::StdGetTtlUdp(self.fd).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|res| res[0] as _)?) } diff --git a/library/std/src/sys/pal/zkvm/os.rs b/library/std/src/sys/pal/zkvm/os.rs index 5d224ffd1ba5a..868b19e33b672 100644 --- a/library/std/src/sys/pal/zkvm/os.rs +++ b/library/std/src/sys/pal/zkvm/os.rs @@ -115,11 +115,11 @@ pub fn getenv(varname: &OsStr) -> Option { } pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) + Err(io::const_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) } pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) + Err(io::const_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) } pub fn temp_dir() -> PathBuf { diff --git a/library/std/src/sys/path/windows.rs b/library/std/src/sys/path/windows.rs index 9267602cb9715..de042fa3f82ab 100644 --- a/library/std/src/sys/path/windows.rs +++ b/library/std/src/sys/path/windows.rs @@ -328,7 +328,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result { if prefix.map(|x| x.is_verbatim()).unwrap_or(false) { // NULs in verbatim paths are rejected for consistency. if path.as_encoded_bytes().contains(&0) { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "strings passed to WinAPI cannot contain NULs", )); diff --git a/library/std/src/sys/random/arc4random.rs b/library/std/src/sys/random/arc4random.rs index ffabaafbee803..32467e9ebaa64 100644 --- a/library/std/src/sys/random/arc4random.rs +++ b/library/std/src/sys/random/arc4random.rs @@ -12,7 +12,6 @@ #[cfg(not(any( target_os = "haiku", target_os = "illumos", - target_os = "rtems", target_os = "solaris", target_os = "vita", )))] @@ -22,7 +21,6 @@ use libc::arc4random_buf; #[cfg(any( target_os = "haiku", // See https://git.haiku-os.org/haiku/tree/headers/compatibility/bsd/stdlib.h target_os = "illumos", // See https://www.illumos.org/man/3C/arc4random - target_os = "rtems", // See https://docs.rtems.org/branches/master/bsp-howto/getentropy.html target_os = "solaris", // See https://docs.oracle.com/cd/E88353_01/html/E37843/arc4random-3c.html target_os = "vita", // See https://github.com/vitasdk/newlib/blob/b89e5bc183b516945f9ee07eef483ecb916e45ff/newlib/libc/include/stdlib.h#L74 ))] diff --git a/library/std/src/sys/sync/condvar/no_threads.rs b/library/std/src/sys/sync/condvar/no_threads.rs index 2a67ed766aa0c..88ce39305e1ae 100644 --- a/library/std/src/sys/sync/condvar/no_threads.rs +++ b/library/std/src/sys/sync/condvar/no_threads.rs @@ -5,7 +5,6 @@ pub struct Condvar {} impl Condvar { #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_locks", since = "1.63.0"))] pub const fn new() -> Condvar { Condvar {} } diff --git a/library/std/src/sys/sync/mutex/no_threads.rs b/library/std/src/sys/sync/mutex/no_threads.rs index 7b243575e018e..57c78f454c57c 100644 --- a/library/std/src/sys/sync/mutex/no_threads.rs +++ b/library/std/src/sys/sync/mutex/no_threads.rs @@ -10,7 +10,6 @@ unsafe impl Sync for Mutex {} // no threads on this platform impl Mutex { #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_locks", since = "1.63.0"))] pub const fn new() -> Mutex { Mutex { locked: Cell::new(false) } } diff --git a/library/std/src/sys/sync/once/no_threads.rs b/library/std/src/sys/sync/once/no_threads.rs index fb1b496510aba..88a1d50361ee4 100644 --- a/library/std/src/sys/sync/once/no_threads.rs +++ b/library/std/src/sys/sync/once/no_threads.rs @@ -35,7 +35,6 @@ unsafe impl Sync for Once {} impl Once { #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_once_new", since = "1.32.0"))] pub const fn new() -> Once { Once { state: Cell::new(State::Incomplete) } } diff --git a/library/std/src/sys/sync/once/queue.rs b/library/std/src/sys/sync/once/queue.rs index 177d0d7744a6d..5beff4ce6836c 100644 --- a/library/std/src/sys/sync/once/queue.rs +++ b/library/std/src/sys/sync/once/queue.rs @@ -93,7 +93,7 @@ const QUEUE_MASK: usize = !STATE_MASK; // use interior mutability. #[repr(align(4))] // Ensure the two lower bits are free to use as state bits. struct Waiter { - thread: Cell>, + thread: Thread, signaled: AtomicBool, next: Cell<*const Waiter>, } @@ -116,7 +116,6 @@ fn to_state(current: StateAndQueue) -> usize { impl Once { #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_once_new", since = "1.32.0"))] pub const fn new() -> Once { Once { state_and_queue: AtomicPtr::new(ptr::without_provenance_mut(INCOMPLETE)) } } @@ -238,7 +237,7 @@ fn wait( return_on_poisoned: bool, ) -> StateAndQueue { let node = &Waiter { - thread: Cell::new(Some(thread::current())), + thread: thread::current_or_unnamed(), signaled: AtomicBool::new(false), next: Cell::new(ptr::null()), }; @@ -277,7 +276,8 @@ fn wait( // can park ourselves, the result could be this thread never gets // unparked. Luckily `park` comes with the guarantee that if it got // an `unpark` just before on an unparked thread it does not park. - thread::park(); + // SAFETY: we retrieved this handle on the current thread above. + unsafe { node.thread.park() } } return state_and_queue.load(Acquire); @@ -309,7 +309,7 @@ impl Drop for WaiterQueue<'_> { let mut queue = to_queue(current); while !queue.is_null() { let next = (*queue).next.get(); - let thread = (*queue).thread.take().unwrap(); + let thread = (*queue).thread.clone(); (*queue).signaled.store(true, Release); thread.unpark(); queue = next; diff --git a/library/std/src/sys/sync/rwlock/no_threads.rs b/library/std/src/sys/sync/rwlock/no_threads.rs index c11e59f719e93..573d0d602dbd6 100644 --- a/library/std/src/sys/sync/rwlock/no_threads.rs +++ b/library/std/src/sys/sync/rwlock/no_threads.rs @@ -10,7 +10,6 @@ unsafe impl Sync for RwLock {} // no threads on this platform impl RwLock { #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_locks", since = "1.63.0"))] pub const fn new() -> RwLock { RwLock { mode: Cell::new(0) } } diff --git a/library/std/src/sys/sync/rwlock/queue.rs b/library/std/src/sys/sync/rwlock/queue.rs index 51330f8fafe57..bd15f8ee952c9 100644 --- a/library/std/src/sys/sync/rwlock/queue.rs +++ b/library/std/src/sys/sync/rwlock/queue.rs @@ -118,7 +118,7 @@ use crate::mem; use crate::ptr::{self, NonNull, null_mut, without_provenance_mut}; use crate::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release}; use crate::sync::atomic::{AtomicBool, AtomicPtr}; -use crate::thread::{self, Thread, ThreadId}; +use crate::thread::{self, Thread}; /// The atomic lock state. type AtomicState = AtomicPtr<()>; @@ -217,9 +217,7 @@ impl Node { /// Prepare this node for waiting. fn prepare(&mut self) { // Fall back to creating an unnamed `Thread` handle to allow locking in TLS destructors. - self.thread.get_or_init(|| { - thread::try_current().unwrap_or_else(|| Thread::new_unnamed(ThreadId::new())) - }); + self.thread.get_or_init(thread::current_or_unnamed); self.completed = AtomicBool::new(false); } diff --git a/library/std/src/sys/thread_local/key/racy.rs b/library/std/src/sys/thread_local/key/racy.rs index 97df8997b80de..e1bc08eabb358 100644 --- a/library/std/src/sys/thread_local/key/racy.rs +++ b/library/std/src/sys/thread_local/key/racy.rs @@ -30,7 +30,6 @@ const KEY_SENTVAL: usize = 0; const KEY_SENTVAL: usize = libc::PTHREAD_KEYS_MAX + 1; impl LazyKey { - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "thread_local_internals", issue = "none"))] pub const fn new(dtor: Option) -> LazyKey { LazyKey { key: atomic::AtomicUsize::new(KEY_SENTVAL), dtor } } diff --git a/library/std/src/sys/thread_local/os.rs b/library/std/src/sys/thread_local/os.rs index 58f291ffdb985..00d2e30bd6036 100644 --- a/library/std/src/sys/thread_local/os.rs +++ b/library/std/src/sys/thread_local/os.rs @@ -60,7 +60,6 @@ struct Value { } impl Storage { - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "thread_local_internals", issue = "none"))] pub const fn new() -> Storage { Storage { key: LazyKey::new(Some(destroy_value::)), marker: PhantomData } } diff --git a/library/std/src/sys_common/fs.rs b/library/std/src/sys_common/fs.rs index a25a7244660bb..bfd684d295b89 100644 --- a/library/std/src/sys_common/fs.rs +++ b/library/std/src/sys_common/fs.rs @@ -5,7 +5,7 @@ use crate::io::{self, Error, ErrorKind}; use crate::path::Path; use crate::sys_common::ignore_notfound; -pub(crate) const NOT_FILE_ERROR: Error = io::const_io_error!( +pub(crate) const NOT_FILE_ERROR: Error = io::const_error!( ErrorKind::InvalidInput, "the source path is neither a regular file nor a symlink to a regular file", ); diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs index 5a0ad90758101..74306978d2284 100644 --- a/library/std/src/sys_common/net.rs +++ b/library/std/src/sys_common/net.rs @@ -122,7 +122,7 @@ pub fn sockaddr_to_addr(storage: &c::sockaddr_storage, len: usize) -> io::Result *(storage as *const _ as *const c::sockaddr_in6) }))) } - _ => Err(io::const_io_error!(ErrorKind::InvalidInput, "invalid argument")), + _ => Err(io::const_error!(ErrorKind::InvalidInput, "invalid argument")), } } @@ -185,7 +185,7 @@ impl TryFrom<&str> for LookupHost { ($e:expr, $msg:expr) => { match $e { Some(r) => r, - None => return Err(io::const_io_error!(io::ErrorKind::InvalidInput, $msg)), + None => return Err(io::const_error!(io::ErrorKind::InvalidInput, $msg)), } }; } diff --git a/library/std/src/thread/current.rs b/library/std/src/thread/current.rs index e6eb90c4c30a5..1048ef973560e 100644 --- a/library/std/src/thread/current.rs +++ b/library/std/src/thread/current.rs @@ -165,6 +165,23 @@ pub(crate) fn try_current() -> Option { } } +/// Gets a handle to the thread that invokes it. If the handle stored in thread- +/// local storage was already destroyed, this creates a new unnamed temporary +/// handle to allow thread parking in nearly all situations. +pub(crate) fn current_or_unnamed() -> Thread { + let current = CURRENT.get(); + if current > DESTROYED { + unsafe { + let current = ManuallyDrop::new(Thread::from_raw(current)); + (*current).clone() + } + } else if current == DESTROYED { + Thread::new_unnamed(id::get_or_init()) + } else { + init_current(current) + } +} + /// Gets a handle to the thread that invokes it. /// /// # Examples @@ -226,17 +243,17 @@ fn init_current(current: *mut ()) -> Thread { // a particular API should be entirely allocation-free, feel free to open // an issue on the Rust repository, we'll see what we can do. rtabort!( - "\n - Attempted to access thread-local data while allocating said data.\n - Do not access functions that allocate in the global allocator!\n - This is a bug in the global allocator.\n - " + "\n\ + Attempted to access thread-local data while allocating said data.\n\ + Do not access functions that allocate in the global allocator!\n\ + This is a bug in the global allocator.\n\ + " ) } else { debug_assert_eq!(current, DESTROYED); panic!( - "use of std::thread::current() is not possible after the thread's - local data has been destroyed" + "use of std::thread::current() is not possible after the thread's \ + local data has been destroyed" ) } } diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index 9edb3fa41933d..56cf438bd9bbe 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -237,7 +237,6 @@ impl LocalKey { reason = "recently added to create a key", issue = "none" )] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "thread_local_internals", issue = "none"))] pub const unsafe fn new(inner: fn(Option<&mut Option>) -> *const T) -> LocalKey { LocalKey { inner } } @@ -252,6 +251,19 @@ impl LocalKey { /// This function will `panic!()` if the key currently has its /// destructor running, and it **may** panic if the destructor has /// previously been run for this thread. + /// + /// # Examples + /// + /// ``` + /// thread_local! { + /// pub static STATIC: String = String::from("I am"); + /// } + /// + /// assert_eq!( + /// STATIC.with(|original_value| format!("{original_value} initialized")), + /// "I am initialized", + /// ); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn with(&'static self, f: F) -> R where @@ -273,6 +285,19 @@ impl LocalKey { /// /// This function will still `panic!()` if the key is uninitialized and the /// key's initializer panics. + /// + /// # Examples + /// + /// ``` + /// thread_local! { + /// pub static STATIC: String = String::from("I am"); + /// } + /// + /// assert_eq!( + /// STATIC.try_with(|original_value| format!("{original_value} initialized")), + /// Ok(String::from("I am initialized")), + /// ); + /// ``` #[stable(feature = "thread_local_try_with", since = "1.26.0")] #[inline] pub fn try_with(&'static self, f: F) -> Result @@ -452,7 +477,7 @@ impl LocalKey> { /// Panics if the key currently has its destructor running, /// and it **may** panic if the destructor has previously been run for this thread. /// - /// # Example + /// # Examples /// /// ``` /// use std::cell::RefCell; @@ -483,7 +508,7 @@ impl LocalKey> { /// Panics if the key currently has its destructor running, /// and it **may** panic if the destructor has previously been run for this thread. /// - /// # Example + /// # Examples /// /// ``` /// use std::cell::RefCell; diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 2c2cc58a9dda7..2ff44fcd4c6b7 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -186,7 +186,7 @@ mod current; #[stable(feature = "rust1", since = "1.0.0")] pub use current::current; -pub(crate) use current::{current_id, drop_current, set_current, try_current}; +pub(crate) use current::{current_id, current_or_unnamed, drop_current, set_current, try_current}; mod spawnhook; @@ -1146,9 +1146,9 @@ pub fn park_timeout_ms(ms: u32) { #[stable(feature = "park_timeout", since = "1.4.0")] pub fn park_timeout(dur: Duration) { let guard = PanicGuard; - // SAFETY: park_timeout is called on the parker owned by this thread. + // SAFETY: park_timeout is called on a handle owned by this thread. unsafe { - current().0.parker().park_timeout(dur); + current().park_timeout(dur); } // No panic occurred, do not abort. forget(guard); @@ -1446,6 +1446,15 @@ impl Thread { unsafe { self.0.parker().park() } } + /// Like the public [`park_timeout`], but callable on any handle. This is + /// used to allow parking in TLS destructors. + /// + /// # Safety + /// May only be called from the thread to which this handle belongs. + pub(crate) unsafe fn park_timeout(&self, dur: Duration) { + unsafe { self.0.parker().park_timeout(dur) } + } + /// Atomically makes the handle's token available if it is not already. /// /// Every thread is equipped with some basic low-level blocking support, via diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs index b2305b1eda7e1..0033fc3a73283 100644 --- a/library/std/src/thread/scoped.rs +++ b/library/std/src/thread/scoped.rs @@ -1,4 +1,4 @@ -use super::{Builder, JoinInner, Result, Thread, current, park}; +use super::{Builder, JoinInner, Result, Thread, current_or_unnamed}; use crate::marker::PhantomData; use crate::panic::{AssertUnwindSafe, catch_unwind, resume_unwind}; use crate::sync::Arc; @@ -140,7 +140,7 @@ where let scope = Scope { data: Arc::new(ScopeData { num_running_threads: AtomicUsize::new(0), - main_thread: current(), + main_thread: current_or_unnamed(), a_thread_panicked: AtomicBool::new(false), }), env: PhantomData, @@ -152,7 +152,8 @@ where // Wait until all the threads are finished. while scope.data.num_running_threads.load(Ordering::Acquire) != 0 { - park(); + // SAFETY: this is the main thread, the handle belongs to us. + unsafe { scope.data.main_thread.park() }; } // Throw any panic from `f`, or the return value of `f` if no thread panicked. @@ -176,7 +177,7 @@ impl<'scope, 'env> Scope<'scope, 'env> { /// thread. If the spawned thread panics, [`join`] will return an [`Err`] containing /// the panic payload. /// - /// If the join handle is dropped, the spawned thread will implicitly joined at the + /// If the join handle is dropped, the spawned thread will be implicitly joined at the /// end of the scope. In that case, if the spawned thread panics, [`scope`] will /// panic after all threads are joined. /// diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index 569a1b3299e5f..96ddae16f0ab3 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -37,7 +37,4 @@ system-llvm-libunwind = [] [lints.rust.unexpected_cfgs] level = "warn" -check-cfg = [ - # #[cfg(bootstrap)] rtems - 'cfg(target_os, values("rtems"))', -] +check-cfg = [] diff --git a/license-metadata.json b/license-metadata.json new file mode 100644 index 0000000000000..09cc369356584 --- /dev/null +++ b/license-metadata.json @@ -0,0 +1,269 @@ +{ + "files": { + "children": [ + { + "children": [ + { + "children": [ + { + "children": [ + { + "children": [ + { + "directories": [], + "files": [ + "analyzer-decls.h", + "malloc-macro.h" + ], + "license": { + "copyright": [ + "2000-2024 Free Software Foundation, Inc" + ], + "spdx": "GPL-2.0-only" + }, + "type": "group" + } + ], + "license": { + "copyright": [ + "2007-2011 Atheros Communications Inc", + "2011-2012,2017 Qualcomm Atheros, Inc", + "2016-2017 Erik Stromdahl " + ], + "spdx": "ISC" + }, + "name": "c-c++-common/analyzer", + "type": "directory" + } + ], + "license": { + "copyright": [ + "2000-2024 Free Software Foundation, Inc" + ], + "spdx": "GPL-2.0-only" + }, + "name": "gcc/testsuite", + "type": "directory" + }, + { + "license": { + "copyright": [ + "2000-2024 Free Software Foundation, Inc" + ], + "spdx": "GCC-exception-3.1" + }, + "name": "libstdc++-v3/config/os/aix/os_defines.h", + "type": "file" + } + ], + "license": { + "copyright": [ + "1997-2024 Free Software Foundation, Inc" + ], + "spdx": "GPL-3.0-or-later" + }, + "name": "src/gcc", + "type": "directory" + }, + { + "children": [ + { + "license": { + "copyright": [ + "The Rust Project Developers (see https://thanks.rust-lang.org)" + ], + "spdx": "Apache-2.0 OR MIT" + }, + "name": "noscript.css", + "type": "file" + }, + { + "license": { + "copyright": [ + "Nicolas Gallagher and Jonathan Neal" + ], + "spdx": "MIT" + }, + "name": "normalize.css", + "type": "file" + } + ], + "license": { + "copyright": [ + "2016 Ike Ku, Jessica Stokes and Leon Guan", + "The Rust Project Developers (see https://thanks.rust-lang.org)" + ], + "spdx": "Apache-2.0 OR MIT" + }, + "name": "src/librustdoc/html/static/css", + "type": "directory" + }, + { + "children": [ + { + "license": { + "copyright": [ + "The Rust Project Developers (see https://thanks.rust-lang.org)" + ], + "spdx": "Apache-2.0 OR MIT" + }, + "name": "README.txt", + "type": "file" + }, + { + "directories": [], + "files": [ + "FiraSans-LICENSE.txt", + "FiraSans-Medium.woff2", + "FiraSans-Regular.woff2" + ], + "license": { + "copyright": [ + "2014, Mozilla Foundation", + "2014, Telefonica S.A" + ], + "spdx": "OFL-1.1" + }, + "type": "group" + }, + { + "directories": [], + "files": [ + "NanumBarunGothic-LICENSE.txt", + "NanumBarunGothic.ttf.woff2" + ], + "license": { + "copyright": [ + "2010 NAVER Corporation" + ], + "spdx": "OFL-1.1" + }, + "type": "group" + } + ], + "license": { + "copyright": [ + "2010, 2012, 2014-2023, Adobe Systems Incorporated" + ], + "spdx": "OFL-1.1" + }, + "name": "src/librustdoc/html/static/fonts", + "type": "directory" + }, + { + "license": { + "copyright": [ + "2003-2019 University of Illinois at Urbana-Champaign", + "The Rust Project Developers (see https://thanks.rust-lang.org)" + ], + "spdx": "Apache-2.0 WITH LLVM-exception AND (Apache-2.0 OR MIT)" + }, + "name": "compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp", + "type": "file" + }, + { + "children": [], + "license": { + "copyright": [ + "2014 Alex Crichton", + "The Rust Project Developers (see https://thanks.rust-lang.org)" + ], + "spdx": "Apache-2.0 OR MIT" + }, + "name": "library/backtrace", + "type": "directory" + }, + { + "license": { + "copyright": [ + "1991-2024 Unicode, Inc" + ], + "spdx": "Unicode-3.0" + }, + "name": "library/core/src/unicode/unicode_data.rs", + "type": "file" + }, + { + "children": [], + "license": { + "copyright": [ + "2019 The Crossbeam Project Developers", + "The Rust Project Developers (see https://thanks.rust-lang.org)" + ], + "spdx": "Apache-2.0 OR MIT" + }, + "name": "library/std/src/sync/mpmc", + "type": "directory" + }, + { + "license": { + "copyright": [ + "2016 The Fuchsia Authors", + "The Rust Project Developers (see https://thanks.rust-lang.org)" + ], + "spdx": "BSD-2-Clause AND (Apache-2.0 OR MIT)" + }, + "name": "library/std/src/sys/sync/mutex/fuchsia.rs", + "type": "file" + }, + { + "children": [], + "license": { + "copyright": [ + "Rust on Embedded Devices Working Group", + "The Rust Project Developers (see https://thanks.rust-lang.org)" + ], + "spdx": "Apache-2.0 OR CC-BY-SA-4.0 OR MIT" + }, + "name": "src/doc/embedded-book", + "type": "directory" + }, + { + "children": [], + "license": { + "copyright": [ + "2014 Jorge Aparicio", + "The Rust Project Developers (see https://thanks.rust-lang.org)" + ], + "spdx": "Apache-2.0 OR MIT" + }, + "name": "src/doc/rust-by-example", + "type": "directory" + }, + { + "license": { + "copyright": [ + "2014-2021 Knut Sveidqvist" + ], + "spdx": "MIT" + }, + "name": "src/doc/rustc-dev-guide/mermaid.min.js", + "type": "file" + }, + { + "children": [], + "license": { + "copyright": [ + "2003-2019 University of Illinois at Urbana-Champaign", + "2003-2019 by the contributors listed in CREDITS.TXT (https://github.com/rust-lang/llvm-project/blob/7738295178045041669876bf32b0543ec8319a5c/llvm/CREDITS.TXT)", + "2010 Apple Inc" + ], + "spdx": "Apache-2.0 WITH LLVM-exception AND NCSA" + }, + "name": "src/llvm-project", + "type": "directory" + } + ], + "license": { + "copyright": [ + "The Rust Project Developers (see https://thanks.rust-lang.org)" + ], + "spdx": "Apache-2.0 OR MIT" + }, + "name": ".", + "type": "directory" + } + ], + "type": "root" + } +} \ No newline at end of file diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index efcac4f0953d0..86d23d9bd0246 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "bitflags" @@ -84,9 +84,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.22" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0" +checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" dependencies = [ "shlex", ] @@ -99,9 +99,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.18" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -109,9 +109,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.18" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstyle", "clap_lex", @@ -119,9 +119,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.29" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8937760c3f4c60871870b8c3ee5f9b30771f792a7045c48bcbba999d7d6b3b8e" +checksum = "11611dca53440593f38e6b25ec629de50b14cdfa63adc0fb856115a2c6d97595" dependencies = [ "clap", ] @@ -161,9 +161,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" dependencies = [ "libc", ] @@ -324,9 +324,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.159" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libredox" @@ -379,9 +379,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.4" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] @@ -414,9 +414,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -432,18 +432,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags", ] [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -452,15 +452,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ "bitflags", "errno", @@ -498,18 +498,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -518,9 +518,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", @@ -547,9 +547,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "syn" -version = "2.0.79" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -571,9 +571,9 @@ dependencies = [ [[package]] name = "tar" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ff6c40d3aedb5e06b57c6f669ad17ab063dd1e63d977c6a88e7f4dfa4f04020" +checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" dependencies = [ "filetime", "libc", diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 7950f1004a2d5..fcd97b7b5898f 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -37,7 +37,7 @@ test = false # Most of the time updating these dependencies requires modifications to the # bootstrap codebase(e.g., https://github.com/rust-lang/rust/issues/124565); # otherwise, some targets will fail. That's why these dependencies are explicitly pinned. -cc = "=1.1.22" +cc = "=1.2.0" cmake = "=0.1.48" build_helper = { path = "../build_helper" } @@ -47,7 +47,7 @@ fd-lock = "4.0" home = "0.5" ignore = "0.4" libc = "0.2" -object = { version = "0.36.3", default-features = false, features = ["archive", "coff", "read_core", "unaligned"] } +object = { version = "0.36.3", default-features = false, features = ["archive", "coff", "read_core", "std", "unaligned"] } opener = "0.5" semver = "1.0" serde = "1.0" diff --git a/src/bootstrap/defaults/config.compiler.toml b/src/bootstrap/defaults/config.compiler.toml index 57a0ca5a7183b..a737de3bd0856 100644 --- a/src/bootstrap/defaults/config.compiler.toml +++ b/src/bootstrap/defaults/config.compiler.toml @@ -19,6 +19,9 @@ lto = "off" # Forces frame pointers to be used with `-Cforce-frame-pointers`. # This can be helpful for profiling at a small performance cost. frame-pointers = true +# Compiler contributors often want to build rustc even without any changes to +# e.g. check that it builds locally and check the baseline behavior of a +# compiler built from latest `master` commit. download-rustc = false [llvm] diff --git a/src/bootstrap/defaults/config.dist.toml b/src/bootstrap/defaults/config.dist.toml index 4346a9c2dd11a..7b381b416ca8a 100644 --- a/src/bootstrap/defaults/config.dist.toml +++ b/src/bootstrap/defaults/config.dist.toml @@ -16,6 +16,7 @@ download-ci-llvm = false # We have several defaults in bootstrap that depend on whether the channel is `dev` (e.g. `omit-git-hash` and `download-ci-llvm`). # Make sure they don't get set when installing from source. channel = "nightly" +# Never download a rustc, distributions must build a fresh compiler. download-rustc = false lld = true # Build the llvm-bitcode-linker diff --git a/src/bootstrap/defaults/config.library.toml b/src/bootstrap/defaults/config.library.toml index 67ceb22052409..b43796d6f206b 100644 --- a/src/bootstrap/defaults/config.library.toml +++ b/src/bootstrap/defaults/config.library.toml @@ -10,7 +10,9 @@ bench-stage = 0 incremental = true # Make the compiler and standard library faster to build, at the expense of a ~20% runtime slowdown. lto = "off" -download-rustc = false +# Download rustc by default for library profile if compiler-affecting +# directories are not modified. For CI this is disabled. +download-rustc = "if-unchanged" [llvm] # Will download LLVM from CI if available on your platform. diff --git a/src/bootstrap/defaults/config.tools.toml b/src/bootstrap/defaults/config.tools.toml index 76b47a841b3f2..64097320caba7 100644 --- a/src/bootstrap/defaults/config.tools.toml +++ b/src/bootstrap/defaults/config.tools.toml @@ -3,6 +3,9 @@ [rust] # This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower. incremental = true +# Most commonly, tools contributors do not need to modify the compiler, so +# downloading a CI rustc is a good default for tools profile. +download-rustc = "if-unchanged" [build] # Document with the in-tree rustdoc by default, since `download-rustc` makes it quick to compile. diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 409a644b9be19..ee813de1c9e26 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -99,7 +99,7 @@ fn main() { // HACK: Since the commit script uses hard links, we can't actually tell if it was installed by x.py setup or not. // We could see if it's identical to src/etc/pre-push.sh, but pre-push may have been modified in the meantime. // Instead, look for this comment, which is almost certainly not in any custom hook. - if fs::read_to_string(pre_commit).map_or(false, |contents| { + if fs::read_to_string(pre_commit).is_ok_and(|contents| { contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570") }) { println!( diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 8e088682f92de..0cacd6e4f37ac 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -330,7 +330,7 @@ fn copy_third_party_objects( if target == "x86_64-fortanix-unknown-sgx" || builder.config.llvm_libunwind(target) == LlvmLibunwind::InTree - && (target.contains("linux") || target.contains("fuchsia")) + && (target.contains("linux") || target.contains("fuchsia") || target.contains("aix")) { let libunwind_path = copy_llvm_libunwind(builder, target, &builder.sysroot_target_libdir(*compiler, target)); @@ -1655,7 +1655,7 @@ impl Step for Sysroot { let mut add_filtered_files = |suffix, contents| { for path in contents { let path = Path::new(&path); - if path.parent().map_or(false, |parent| parent.ends_with(suffix)) { + if path.parent().is_some_and(|parent| parent.ends_with(suffix)) { filtered_files.push(path.file_name().unwrap().to_owned()); } } diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 0216ac811621c..a636c4a9ef131 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1023,7 +1023,7 @@ impl Step for PlainSourceTarball { let mut cmd = command(&builder.initial_cargo); cmd.arg("vendor").arg("--versioned-dirs"); - for p in default_paths_to_vendor(builder) { + for (p, _) in default_paths_to_vendor(builder) { cmd.arg("--sync").arg(p); } diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index 5ca4321d85555..29a96f7767281 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -56,10 +56,7 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F fn get_rustfmt_version(build: &Builder<'_>) -> Option<(String, PathBuf)> { let stamp_file = build.out.join("rustfmt.stamp"); - let mut cmd = command(match build.initial_rustfmt() { - Some(p) => p, - None => return None, - }); + let mut cmd = command(build.initial_rustfmt()?); cmd.arg("--version"); let output = cmd.allow_failure().run_capture(build); @@ -279,7 +276,7 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) { Box::new(move |entry| { let cwd = std::env::current_dir(); let entry = t!(entry); - if entry.file_type().map_or(false, |t| t.is_file()) { + if entry.file_type().is_some_and(|t| t.is_file()) { formatted_paths_ref.lock().unwrap().push({ // `into_path` produces an absolute path. Try to strip `cwd` to get a shorter // relative path. diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index a6dff7fde8054..c76504761beb2 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -181,8 +181,7 @@ impl Step for CollectLicenseMetadata { panic!("REUSE is required to collect the license metadata"); }; - // Temporary location, it will be moved to src/etc once it's accurate. - let dest = builder.out.join("license-metadata.json"); + let dest = builder.src.join("license-metadata.json"); let mut cmd = builder.tool_cmd(Tool::CollectLicenseMetadata); cmd.env("REUSE_EXE", reuse); @@ -209,14 +208,14 @@ impl Step for GenerateCopyright { } fn run(self, builder: &Builder<'_>) -> Self::Output { - let license_metadata = builder.ensure(CollectLicenseMetadata); - - // Temporary location, it will be moved to the proper one once it's accurate. + let license_metadata = builder.src.join("license-metadata.json"); let dest = builder.out.join("COPYRIGHT.html"); + let dest_libstd = builder.out.join("COPYRIGHT-library.html"); let mut cmd = builder.tool_cmd(Tool::GenerateCopyright); cmd.env("LICENSE_METADATA", &license_metadata); cmd.env("DEST", &dest); + cmd.env("DEST_LIBSTD", &dest_libstd); cmd.env("OUT_DIR", &builder.out); cmd.env("CARGO", &builder.initial_cargo); cmd.run(builder); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index dcea9f5f7d1d6..f670452f4effe 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3,12 +3,14 @@ //! `./x.py test` (aka [`Kind::Test`]) is currently allowed to reach build steps in other modules. //! However, this contains ~all test parts we expect people to be able to build and run locally. +use std::collections::HashSet; use std::ffi::{OsStr, OsString}; use std::path::{Path, PathBuf}; use std::{env, fs, iter}; use clap_complete::shells; +use crate::core::build_steps::compile::run_cargo; use crate::core::build_steps::doc::DocumentationFormat; use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget; use crate::core::build_steps::tool::{self, SourceType, Tool}; @@ -261,12 +263,16 @@ pub struct Cargo { host: TargetSelection, } +impl Cargo { + const CRATE_PATH: &str = "src/tools/cargo"; +} + impl Step for Cargo { type Output = (); const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/cargo") + run.path(Self::CRATE_PATH) } fn make_run(run: RunConfig<'_>) { @@ -284,7 +290,7 @@ impl Step for Cargo { Mode::ToolRustc, self.host, Kind::Test, - "src/tools/cargo", + Self::CRATE_PATH, SourceType::Submodule, &[], ); @@ -299,6 +305,9 @@ impl Step for Cargo { // those features won't be able to land. cargo.env("CARGO_TEST_DISABLE_NIGHTLY", "1"); cargo.env("PATH", path_for_cargo(builder, compiler)); + // Cargo's test suite requires configurations from its own `.cargo/config.toml`. + // Change to the directory so Cargo can read from it. + cargo.current_dir(builder.src.join(Self::CRATE_PATH)); #[cfg(feature = "build-metrics")] builder.metrics.begin_test_suite( @@ -1062,7 +1071,7 @@ impl Step for Tidy { if builder.config.channel == "dev" || builder.config.channel == "nightly" { builder.info("fmt check"); if builder.initial_rustfmt().is_none() { - let inferred_rustfmt_dir = builder.initial_rustc.parent().unwrap(); + let inferred_rustfmt_dir = builder.initial_sysroot.join("bin"); eprintln!( "\ ERROR: no `rustfmt` binary found in {PATH} @@ -2185,6 +2194,7 @@ struct BookTest { path: PathBuf, name: &'static str, is_ext_doc: bool, + dependencies: Vec<&'static str>, } impl Step for BookTest { @@ -2237,6 +2247,57 @@ impl BookTest { // Books often have feature-gated example text. rustbook_cmd.env("RUSTC_BOOTSTRAP", "1"); rustbook_cmd.env("PATH", new_path).arg("test").arg(path); + + // Books may also need to build dependencies. For example, `TheBook` has + // code samples which use the `trpl` crate. For the `rustdoc` invocation + // to find them them successfully, they need to be built first and their + // paths used to generate the + let libs = if !self.dependencies.is_empty() { + let mut lib_paths = vec![]; + for dep in self.dependencies { + let mode = Mode::ToolRustc; + let target = builder.config.build; + let cargo = tool::prepare_tool_cargo( + builder, + compiler, + mode, + target, + Kind::Build, + dep, + SourceType::Submodule, + &[], + ); + + let stamp = builder + .cargo_out(compiler, mode, target) + .join(PathBuf::from(dep).file_name().unwrap()) + .with_extension("stamp"); + + let output_paths = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false); + let directories = output_paths + .into_iter() + .filter_map(|p| p.parent().map(ToOwned::to_owned)) + .fold(HashSet::new(), |mut set, dir| { + set.insert(dir); + set + }); + + lib_paths.extend(directories); + } + lib_paths + } else { + vec![] + }; + + if !libs.is_empty() { + let paths = libs + .into_iter() + .map(|path| path.into_os_string()) + .collect::>() + .join(OsStr::new(",")); + rustbook_cmd.args([OsString::from("--library-path"), paths]); + } + builder.add_rust_test_threads(&mut rustbook_cmd); let _guard = builder.msg( Kind::Test, @@ -2295,6 +2356,7 @@ macro_rules! test_book { $name:ident, $path:expr, $book_name:expr, default=$default:expr $(,submodules = $submodules:expr)? + $(,dependencies=$dependencies:expr)? ; )+) => { $( @@ -2324,11 +2386,21 @@ macro_rules! test_book { builder.require_submodule(submodule, None); } )* + + let dependencies = vec![]; + $( + let mut dependencies = dependencies; + for dep in $dependencies { + dependencies.push(dep); + } + )? + builder.ensure(BookTest { compiler: self.compiler, path: PathBuf::from($path), name: $book_name, is_ext_doc: !$default, + dependencies, }); } } @@ -2343,7 +2415,7 @@ test_book!( RustcBook, "src/doc/rustc", "rustc", default=true; RustByExample, "src/doc/rust-by-example", "rust-by-example", default=false, submodules=["src/doc/rust-by-example"]; EmbeddedBook, "src/doc/embedded-book", "embedded-book", default=false, submodules=["src/doc/embedded-book"]; - TheBook, "src/doc/book", "book", default=false, submodules=["src/doc/book"]; + TheBook, "src/doc/book", "book", default=false, submodules=["src/doc/book"], dependencies=["src/doc/book/packages/trpl"]; UnstableBook, "src/doc/unstable-book", "unstable-book", default=true; EditionGuide, "src/doc/edition-guide", "edition-guide", default=false, submodules=["src/doc/edition-guide"]; ); @@ -3404,7 +3476,6 @@ impl Step for CodegenCranelift { // FIXME remove once vendoring is handled .arg("--skip-test") .arg("testsuite.extended_sysroot"); - cargo.args(builder.config.test_args()); cargo.into_cmd().run(builder); } @@ -3599,14 +3670,42 @@ impl Step for TestFloatParse { &[], ); - cargo_run.arg("--"); - if builder.config.args().is_empty() { - // By default, exclude tests that take longer than ~1m. - cargo_run.arg("--skip-huge"); - } else { - cargo_run.args(builder.config.args()); + if !matches!(env::var("FLOAT_PARSE_TESTS_NO_SKIP_HUGE").as_deref(), Ok("1") | Ok("true")) { + cargo_run.args(["--", "--skip-huge"]); } cargo_run.into_cmd().run(builder); } } + +#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] +pub struct CollectLicenseMetadata; + +impl Step for CollectLicenseMetadata { + type Output = PathBuf; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/collect-license-metadata") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(CollectLicenseMetadata); + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + let Some(reuse) = &builder.config.reuse else { + panic!("REUSE is required to collect the license metadata"); + }; + + let dest = builder.src.join("license-metadata.json"); + + let mut cmd = builder.tool_cmd(Tool::CollectLicenseMetadata); + cmd.env("REUSE_EXE", reuse); + cmd.env("DEST", &dest); + cmd.env("ONLY_CHECK", "1"); + cmd.run(builder); + + dest + } +} diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs index 82a6b4d4f28cb..26d0f100ffd52 100644 --- a/src/bootstrap/src/core/build_steps/vendor.rs +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -4,24 +4,27 @@ use crate::core::build_steps::tool::SUBMODULES_FOR_RUSTBOOK; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::utils::exec::command; -/// List of default paths used for vendoring for `x vendor` and dist tarballs. -pub fn default_paths_to_vendor(builder: &Builder<'_>) -> Vec { - let mut paths = vec![]; - for p in [ - "src/tools/cargo/Cargo.toml", - "src/tools/rust-analyzer/Cargo.toml", - "compiler/rustc_codegen_cranelift/Cargo.toml", - "compiler/rustc_codegen_gcc/Cargo.toml", - "library/Cargo.toml", - "src/bootstrap/Cargo.toml", - "src/tools/rustbook/Cargo.toml", - "src/tools/rustc-perf/Cargo.toml", - "src/tools/opt-dist/Cargo.toml", - ] { - paths.push(builder.src.join(p)); - } - - paths +/// Returns the cargo workspaces to vendor for `x vendor` and dist tarballs. +/// +/// Returns a `Vec` of `(path_to_manifest, submodules_required)` where +/// `path_to_manifest` is the cargo workspace, and `submodules_required` is +/// the set of submodules that must be available. +pub fn default_paths_to_vendor(builder: &Builder<'_>) -> Vec<(PathBuf, Vec<&'static str>)> { + [ + ("src/tools/cargo/Cargo.toml", vec!["src/tools/cargo"]), + ("src/tools/rust-analyzer/Cargo.toml", vec![]), + ("compiler/rustc_codegen_cranelift/Cargo.toml", vec![]), + ("compiler/rustc_codegen_gcc/Cargo.toml", vec![]), + ("library/Cargo.toml", vec![]), + ("src/bootstrap/Cargo.toml", vec![]), + ("src/tools/rustbook/Cargo.toml", SUBMODULES_FOR_RUSTBOOK.into()), + ("src/tools/rustc-perf/Cargo.toml", vec!["src/tools/rustc-perf"]), + ("src/tools/opt-dist/Cargo.toml", vec![]), + ("src/doc/book/packages/trpl/Cargo.toml", vec![]), + ] + .into_iter() + .map(|(path, submodules)| (builder.src.join(path), submodules)) + .collect() } #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -56,13 +59,16 @@ impl Step for Vendor { cmd.arg("--versioned-dirs"); } + let to_vendor = default_paths_to_vendor(builder); // These submodules must be present for `x vendor` to work. - for submodule in SUBMODULES_FOR_RUSTBOOK.iter().chain(["src/tools/cargo"].iter()) { - builder.build.require_submodule(submodule, None); + for (_, submodules) in &to_vendor { + for submodule in submodules { + builder.build.require_submodule(submodule, None); + } } // Sync these paths by default. - for p in default_paths_to_vendor(builder) { + for (p, _) in &to_vendor { cmd.arg("--sync").arg(p); } diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index d59e0fa728807..73bc7195ac24c 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -258,11 +258,11 @@ impl PathSet { // internal use only fn check(p: &TaskPath, needle: &Path, module: Kind) -> bool { - if let Some(p_kind) = &p.kind { - p.path.ends_with(needle) && *p_kind == module - } else { - p.path.ends_with(needle) - } + let check_path = || { + // This order is important for retro-compatibility, as `starts_with` was introduced later. + p.path.ends_with(needle) || p.path.starts_with(needle) + }; + if let Some(p_kind) = &p.kind { check_path() && *p_kind == module } else { check_path() } } /// Return all `TaskPath`s in `Self` that contain any of the `needles`, removing the @@ -915,6 +915,7 @@ impl<'a> Builder<'a> { test::HtmlCheck, test::RustInstaller, test::TestFloatParse, + test::CollectLicenseMetadata, // Run bootstrap close to the end as it's unlikely to fail test::Bootstrap, // Run run-make last, since these won't pass without make on Windows @@ -1261,7 +1262,7 @@ impl<'a> Builder<'a> { pub fn sysroot_libdir_relative(&self, compiler: Compiler) -> &Path { match self.config.libdir_relative() { Some(relative_libdir) if compiler.stage >= 1 => relative_libdir, - _ if compiler.stage == 0 => &self.build.initial_libdir, + _ if compiler.stage == 0 => &self.build.initial_relative_libdir, _ => Path::new("lib"), } } @@ -1522,15 +1523,19 @@ impl<'a> Builder<'a> { pub(crate) fn maybe_open_in_browser(&self, path: impl AsRef) { if self.was_invoked_explicitly::(Kind::Doc) { self.open_in_browser(path); + } else { + self.info(&format!("Doc path: {}", path.as_ref().display())); } } pub(crate) fn open_in_browser(&self, path: impl AsRef) { + let path = path.as_ref(); + if self.config.dry_run() || !self.config.cmd.open() { + self.info(&format!("Doc path: {}", path.display())); return; } - let path = path.as_ref(); self.info(&format!("Opening doc {}", path.display())); if let Err(err) = opener::open(path) { self.info(&format!("{err}\n")); diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 21c5f7232a15c..a1c8bff0db97e 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -5,6 +5,10 @@ use crate::Flags; use crate::core::build_steps::doc::DocumentationFormat; use crate::core::config::Config; +static TEST_TRIPLE_1: &str = "i686-unknown-haiku"; +static TEST_TRIPLE_2: &str = "i686-unknown-hurd-gnu"; +static TEST_TRIPLE_3: &str = "i686-unknown-netbsd"; + fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config { configure_with_args(&[cmd.to_owned()], host, target) } @@ -37,7 +41,7 @@ fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config .join(&thread::current().name().unwrap_or("unknown").replace(":", "-")); t!(fs::create_dir_all(&dir)); config.out = dir; - config.build = TargetSelection::from_user("A-A"); + config.build = TargetSelection::from_user(TEST_TRIPLE_1); config.hosts = host.iter().map(|s| TargetSelection::from_user(s)).collect(); config.targets = target.iter().map(|s| TargetSelection::from_user(s)).collect(); config @@ -58,48 +62,28 @@ fn run_build(paths: &[PathBuf], config: Config) -> Cache { fn check_cli(paths: [&str; N]) { run_build( &paths.map(PathBuf::from), - configure_with_args(&paths.map(String::from), &["A-A"], &["A-A"]), + configure_with_args(&paths.map(String::from), &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]), ); } macro_rules! std { ($host:ident => $target:ident, stage = $stage:literal) => { compile::Std::new( - Compiler { - host: TargetSelection::from_user(concat!( - stringify!($host), - "-", - stringify!($host) - )), - stage: $stage, - }, - TargetSelection::from_user(concat!(stringify!($target), "-", stringify!($target))), + Compiler { host: TargetSelection::from_user($host), stage: $stage }, + TargetSelection::from_user($target), ) }; } macro_rules! doc_std { - ($host:ident => $target:ident, stage = $stage:literal) => {{ - doc::Std::new( - $stage, - TargetSelection::from_user(concat!(stringify!($target), "-", stringify!($target))), - DocumentationFormat::Html, - ) - }}; + ($host:ident => $target:ident, stage = $stage:literal) => {{ doc::Std::new($stage, TargetSelection::from_user($target), DocumentationFormat::Html) }}; } macro_rules! rustc { ($host:ident => $target:ident, stage = $stage:literal) => { compile::Rustc::new( - Compiler { - host: TargetSelection::from_user(concat!( - stringify!($host), - "-", - stringify!($host) - )), - stage: $stage, - }, - TargetSelection::from_user(concat!(stringify!($target), "-", stringify!($target))), + Compiler { host: TargetSelection::from_user($host), stage: $stage }, + TargetSelection::from_user($target), ) }; } @@ -135,7 +119,7 @@ fn test_intersection() { #[test] fn validate_path_remap() { - let build = Build::new(configure("test", &["A-A"], &["A-A"])); + let build = Build::new(configure("test", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1])); PATH_REMAP .iter() @@ -148,7 +132,7 @@ fn validate_path_remap() { #[test] fn check_missing_paths_for_x_test_tests() { - let build = Build::new(configure("test", &["A-A"], &["A-A"])); + let build = Build::new(configure("test", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1])); let (_, tests_remap_paths) = PATH_REMAP.iter().find(|(target_path, _)| *target_path == "tests").unwrap(); @@ -172,7 +156,7 @@ fn check_missing_paths_for_x_test_tests() { #[test] fn test_exclude() { - let mut config = configure("test", &["A-A"], &["A-A"]); + let mut config = configure("test", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]); config.skip = vec!["src/tools/tidy".into()]; let cache = run_build(&[], config); @@ -187,7 +171,7 @@ fn test_exclude() { fn test_exclude_kind() { let path = PathBuf::from("compiler/rustc_data_structures"); - let mut config = configure("test", &["A-A"], &["A-A"]); + let mut config = configure("test", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]); // Ensure our test is valid, and `test::Rustc` would be run without the exclude. assert!(run_build(&[], config.clone()).contains::()); // Ensure tests for rustc are not skipped. @@ -200,16 +184,22 @@ fn test_exclude_kind() { /// Ensure that if someone passes both a single crate and `library`, all library crates get built. #[test] fn alias_and_path_for_library() { - let mut cache = - run_build(&["library".into(), "core".into()], configure("build", &["A-A"], &["A-A"])); + let mut cache = run_build( + &["library".into(), "core".into()], + configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]), + ); assert_eq!(first(cache.all::()), &[ - std!(A => A, stage = 0), - std!(A => A, stage = 1) + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1) ]); - let mut cache = - run_build(&["library".into(), "core".into()], configure("doc", &["A-A"], &["A-A"])); - assert_eq!(first(cache.all::()), &[doc_std!(A => A, stage = 0)]); + let mut cache = run_build( + &["library".into(), "core".into()], + configure("doc", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]), + ); + assert_eq!(first(cache.all::()), &[ + doc_std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0) + ]); } #[test] @@ -248,18 +238,18 @@ fn ci_rustc_if_unchanged_logic() { mod defaults { use pretty_assertions::assert_eq; - use super::{configure, first, run_build}; + use super::{TEST_TRIPLE_1, TEST_TRIPLE_2, configure, first, run_build}; use crate::Config; use crate::core::builder::*; #[test] fn build_default() { - let mut cache = run_build(&[], configure("build", &["A-A"], &["A-A"])); + let mut cache = run_build(&[], configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1])); - let a = TargetSelection::from_user("A-A"); + let a = TargetSelection::from_user(TEST_TRIPLE_1); assert_eq!(first(cache.all::()), &[ - std!(A => A, stage = 0), - std!(A => A, stage = 1), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1), ]); assert!(!cache.all::().is_empty()); // Make sure rustdoc is only built once. @@ -269,16 +259,20 @@ mod defaults { // - this is the compiler it's _linked_ to, not built with. &[tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }], ); - assert_eq!(first(cache.all::()), &[rustc!(A => A, stage = 0)],); + assert_eq!(first(cache.all::()), &[ + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0) + ],); } #[test] fn build_stage_0() { - let config = Config { stage: 0, ..configure("build", &["A-A"], &["A-A"]) }; + let config = Config { stage: 0, ..configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]) }; let mut cache = run_build(&[], config); - let a = TargetSelection::from_user("A-A"); - assert_eq!(first(cache.all::()), &[std!(A => A, stage = 0)]); + let a = TargetSelection::from_user(TEST_TRIPLE_1); + assert_eq!(first(cache.all::()), &[ + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0) + ]); assert!(!cache.all::().is_empty()); assert_eq!( first(cache.all::()), @@ -291,11 +285,14 @@ mod defaults { #[test] fn build_cross_compile() { - let config = Config { stage: 1, ..configure("build", &["A-A", "B-B"], &["A-A", "B-B"]) }; + let config = Config { + stage: 1, + ..configure("build", &[TEST_TRIPLE_1, TEST_TRIPLE_2], &[TEST_TRIPLE_1, TEST_TRIPLE_2]) + }; let mut cache = run_build(&[], config); - let a = TargetSelection::from_user("A-A"); - let b = TargetSelection::from_user("B-B"); + let a = TargetSelection::from_user(TEST_TRIPLE_1); + let b = TargetSelection::from_user(TEST_TRIPLE_2); // Ideally, this build wouldn't actually have `target: a` // rustdoc/rustcc/std here (the user only requested a host=B build, so @@ -303,10 +300,10 @@ mod defaults { // (since we're producing stage 1 libraries/binaries). But currently // bootstrap is just a bit buggy here; this should be fixed though. assert_eq!(first(cache.all::()), &[ - std!(A => A, stage = 0), - std!(A => A, stage = 1), - std!(A => B, stage = 0), - std!(A => B, stage = 1), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 0), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1), ]); assert_eq!(first(cache.all::()), &[ compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, @@ -318,18 +315,18 @@ mod defaults { tool::Rustdoc { compiler: Compiler { host: b, stage: 1 } }, ],); assert_eq!(first(cache.all::()), &[ - rustc!(A => A, stage = 0), - rustc!(A => B, stage = 0), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 0), ]); } #[test] fn doc_default() { - let mut config = configure("doc", &["A-A"], &["A-A"]); + let mut config = configure("doc", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]); config.compiler_docs = true; config.cmd = Subcommand::Doc { open: false, json: false }; let mut cache = run_build(&[], config); - let a = TargetSelection::from_user("A-A"); + let a = TargetSelection::from_user(TEST_TRIPLE_1); // error_index_generator uses stage 0 to share rustdoc artifacts with the // rustdoc tool. @@ -349,7 +346,7 @@ mod defaults { mod dist { use pretty_assertions::assert_eq; - use super::{Config, first, run_build}; + use super::{Config, TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3, first, run_build}; use crate::core::builder::*; fn configure(host: &[&str], target: &[&str]) -> Config { @@ -358,9 +355,9 @@ mod dist { #[test] fn dist_baseline() { - let mut cache = run_build(&[], configure(&["A-A"], &["A-A"])); + let mut cache = run_build(&[], configure(&[TEST_TRIPLE_1], &[TEST_TRIPLE_1])); - let a = TargetSelection::from_user("A-A"); + let a = TargetSelection::from_user(TEST_TRIPLE_1); assert_eq!(first(cache.all::()), &[dist::Docs { host: a },]); assert_eq!(first(cache.all::()), &[dist::Mingw { host: a },]); @@ -380,10 +377,11 @@ mod dist { #[test] fn dist_with_targets() { - let mut cache = run_build(&[], configure(&["A-A"], &["A-A", "B-B"])); + let mut cache = + run_build(&[], configure(&[TEST_TRIPLE_1], &[TEST_TRIPLE_1, TEST_TRIPLE_2])); - let a = TargetSelection::from_user("A-A"); - let b = TargetSelection::from_user("B-B"); + let a = TargetSelection::from_user(TEST_TRIPLE_1); + let b = TargetSelection::from_user(TEST_TRIPLE_2); assert_eq!(first(cache.all::()), &[dist::Docs { host: a }, dist::Docs { host: b @@ -403,10 +401,13 @@ mod dist { #[test] fn dist_with_hosts() { - let mut cache = run_build(&[], configure(&["A-A", "B-B"], &["A-A", "B-B"])); + let mut cache = run_build( + &[], + configure(&[TEST_TRIPLE_1, TEST_TRIPLE_2], &[TEST_TRIPLE_1, TEST_TRIPLE_2]), + ); - let a = TargetSelection::from_user("A-A"); - let b = TargetSelection::from_user("B-B"); + let a = TargetSelection::from_user(TEST_TRIPLE_1); + let b = TargetSelection::from_user(TEST_TRIPLE_2); assert_eq!(first(cache.all::()), &[dist::Docs { host: a }, dist::Docs { host: b @@ -423,19 +424,20 @@ mod dist { dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, ]); assert_eq!(first(cache.all::()), &[ - std!(A => A, stage = 0), - std!(A => A, stage = 1), - std!(A => A, stage = 2), - std!(A => B, stage = 1), - std!(A => B, stage = 2), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2), ],); assert_eq!(first(cache.all::()), &[dist::Src]); } #[test] fn dist_only_cross_host() { - let b = TargetSelection::from_user("B-B"); - let mut config = configure(&["A-A", "B-B"], &["A-A", "B-B"]); + let b = TargetSelection::from_user(TEST_TRIPLE_2); + let mut config = + configure(&[TEST_TRIPLE_1, TEST_TRIPLE_2], &[TEST_TRIPLE_1, TEST_TRIPLE_2]); config.docs = false; config.extended = true; config.hosts = vec![b]; @@ -445,18 +447,25 @@ mod dist { compiler: Compiler { host: b, stage: 2 } },]); assert_eq!(first(cache.all::()), &[ - rustc!(A => A, stage = 0), - rustc!(A => B, stage = 1), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1), ]); } #[test] fn dist_with_targets_and_hosts() { - let mut cache = run_build(&[], configure(&["A-A", "B-B"], &["A-A", "B-B", "C-C"])); + let mut cache = run_build( + &[], + configure(&[TEST_TRIPLE_1, TEST_TRIPLE_2], &[ + TEST_TRIPLE_1, + TEST_TRIPLE_2, + TEST_TRIPLE_3, + ]), + ); - let a = TargetSelection::from_user("A-A"); - let b = TargetSelection::from_user("B-B"); - let c = TargetSelection::from_user("C-C"); + let a = TargetSelection::from_user(TEST_TRIPLE_1); + let b = TargetSelection::from_user(TEST_TRIPLE_2); + let c = TargetSelection::from_user(TEST_TRIPLE_3); assert_eq!(first(cache.all::()), &[ dist::Docs { host: a }, @@ -482,11 +491,11 @@ mod dist { #[test] fn dist_with_empty_host() { - let config = configure(&[], &["C-C"]); + let config = configure(&[], &[TEST_TRIPLE_3]); let mut cache = run_build(&[], config); - let a = TargetSelection::from_user("A-A"); - let c = TargetSelection::from_user("C-C"); + let a = TargetSelection::from_user(TEST_TRIPLE_1); + let c = TargetSelection::from_user(TEST_TRIPLE_3); assert_eq!(first(cache.all::()), &[dist::Docs { host: c },]); assert_eq!(first(cache.all::()), &[dist::Mingw { host: c },]); @@ -498,10 +507,13 @@ mod dist { #[test] fn dist_with_same_targets_and_hosts() { - let mut cache = run_build(&[], configure(&["A-A", "B-B"], &["A-A", "B-B"])); + let mut cache = run_build( + &[], + configure(&[TEST_TRIPLE_1, TEST_TRIPLE_2], &[TEST_TRIPLE_1, TEST_TRIPLE_2]), + ); - let a = TargetSelection::from_user("A-A"); - let b = TargetSelection::from_user("B-B"); + let a = TargetSelection::from_user(TEST_TRIPLE_1); + let b = TargetSelection::from_user(TEST_TRIPLE_2); assert_eq!(first(cache.all::()), &[dist::Docs { host: a }, dist::Docs { host: b @@ -519,11 +531,11 @@ mod dist { ]); assert_eq!(first(cache.all::()), &[dist::Src]); assert_eq!(first(cache.all::()), &[ - std!(A => A, stage = 0), - std!(A => A, stage = 1), - std!(A => A, stage = 2), - std!(A => B, stage = 1), - std!(A => B, stage = 2), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2), ]); assert_eq!(first(cache.all::()), &[ compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, @@ -535,7 +547,11 @@ mod dist { #[test] fn build_all() { - let build = Build::new(configure(&["A-A", "B-B"], &["A-A", "B-B", "C-C"])); + let build = Build::new(configure(&[TEST_TRIPLE_1, TEST_TRIPLE_2], &[ + TEST_TRIPLE_1, + TEST_TRIPLE_2, + TEST_TRIPLE_3, + ])); let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[ "compiler/rustc".into(), @@ -543,53 +559,53 @@ mod dist { ]); assert_eq!(first(builder.cache.all::()), &[ - std!(A => A, stage = 0), - std!(A => A, stage = 1), - std!(A => A, stage = 2), - std!(A => B, stage = 1), - std!(A => B, stage = 2), - std!(A => C, stage = 2), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_3, stage = 2), ]); assert_eq!(builder.cache.all::().len(), 5); assert_eq!(first(builder.cache.all::()), &[ - rustc!(A => A, stage = 0), - rustc!(A => A, stage = 1), - rustc!(A => A, stage = 2), - rustc!(A => B, stage = 1), - rustc!(A => B, stage = 2), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2), ]); } #[test] fn llvm_out_behaviour() { - let mut config = configure(&["A-A"], &["B-B"]); + let mut config = configure(&[TEST_TRIPLE_1], &[TEST_TRIPLE_2]); config.llvm_from_ci = true; let build = Build::new(config.clone()); - let target = TargetSelection::from_user("A-A"); + let target = TargetSelection::from_user(TEST_TRIPLE_1); assert!(build.llvm_out(target).ends_with("ci-llvm")); - let target = TargetSelection::from_user("B-B"); + let target = TargetSelection::from_user(TEST_TRIPLE_2); assert!(build.llvm_out(target).ends_with("llvm")); config.llvm_from_ci = false; let build = Build::new(config.clone()); - let target = TargetSelection::from_user("A-A"); + let target = TargetSelection::from_user(TEST_TRIPLE_1); assert!(build.llvm_out(target).ends_with("llvm")); } #[test] fn build_with_empty_host() { - let config = configure(&[], &["C-C"]); + let config = configure(&[], &[TEST_TRIPLE_3]); let build = Build::new(config); let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); - let a = TargetSelection::from_user("A-A"); + let a = TargetSelection::from_user(TEST_TRIPLE_1); assert_eq!(first(builder.cache.all::()), &[ - std!(A => A, stage = 0), - std!(A => A, stage = 1), - std!(A => C, stage = 2), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1), + std!(TEST_TRIPLE_1 => TEST_TRIPLE_3, stage = 2), ]); assert_eq!(first(builder.cache.all::()), &[ compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, @@ -597,14 +613,14 @@ mod dist { compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, ]); assert_eq!(first(builder.cache.all::()), &[ - rustc!(A => A, stage = 0), - rustc!(A => A, stage = 1), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1), ]); } #[test] fn test_with_no_doc_stage0() { - let mut config = configure(&["A-A"], &["A-A"]); + let mut config = configure(&[TEST_TRIPLE_1], &[TEST_TRIPLE_1]); config.stage = 0; config.paths = vec!["library/std".into()]; config.cmd = Subcommand::Test { @@ -626,7 +642,7 @@ mod dist { let build = Build::new(config); let mut builder = Builder::new(&build); - let host = TargetSelection::from_user("A-A"); + let host = TargetSelection::from_user(TEST_TRIPLE_1); builder.run_step_descriptions(&[StepDescription::from::(Kind::Test)], &[ "library/std".into(), @@ -644,13 +660,13 @@ mod dist { #[test] fn doc_ci() { - let mut config = configure(&["A-A"], &["A-A"]); + let mut config = configure(&[TEST_TRIPLE_1], &[TEST_TRIPLE_1]); config.compiler_docs = true; config.cmd = Subcommand::Doc { open: false, json: false }; let build = Build::new(config); let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]); - let a = TargetSelection::from_user("A-A"); + let a = TargetSelection::from_user(TEST_TRIPLE_1); // error_index_generator uses stage 1 to share rustdoc artifacts with the // rustdoc tool. @@ -671,7 +687,7 @@ mod dist { #[test] fn test_docs() { // Behavior of `x.py test` doing various documentation tests. - let mut config = configure(&["A-A"], &["A-A"]); + let mut config = configure(&[TEST_TRIPLE_1], &[TEST_TRIPLE_1]); config.cmd = Subcommand::Test { test_args: vec![], compiletest_rustc_args: vec![], @@ -693,7 +709,7 @@ mod dist { let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]); - let a = TargetSelection::from_user("A-A"); + let a = TargetSelection::from_user(TEST_TRIPLE_1); // error_index_generator uses stage 1 to share rustdoc artifacts with the // rustdoc tool. diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index e706aba977b6e..b0fbff79b9013 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -379,6 +379,7 @@ pub struct Config { pub initial_cargo: PathBuf, pub initial_rustc: PathBuf, pub initial_cargo_clippy: Option, + pub initial_sysroot: PathBuf, #[cfg(not(test))] initial_rustfmt: RefCell, @@ -1563,8 +1564,6 @@ impl Config { ); } - config.initial_cargo_clippy = cargo_clippy; - config.initial_rustc = if let Some(rustc) = rustc { if !flags.skip_stage0_validation { config.check_stage0_version(&rustc, "rustc"); @@ -1580,6 +1579,10 @@ impl Config { .join(exe("rustc", config.build)) }; + config.initial_sysroot = config.initial_rustc.ancestors().nth(2).unwrap().into(); + + config.initial_cargo_clippy = cargo_clippy; + config.initial_cargo = if let Some(cargo) = cargo { if !flags.skip_stage0_validation { config.check_stage0_version(&cargo, "cargo"); @@ -1587,12 +1590,7 @@ impl Config { cargo } else { config.download_beta_toolchain(); - config - .out - .join(config.build) - .join("stage0") - .join("bin") - .join(exe("cargo", config.build)) + config.initial_sysroot.join("bin").join(exe("cargo", config.build)) }; // NOTE: it's important this comes *after* we set `initial_rustc` just above. @@ -1665,7 +1663,7 @@ impl Config { } config.llvm_assertions = - toml.llvm.as_ref().map_or(false, |llvm| llvm.assertions.unwrap_or(false)); + toml.llvm.as_ref().is_some_and(|llvm| llvm.assertions.unwrap_or(false)); // Store off these values as options because if they're not provided // we'll infer default values for them later @@ -1771,8 +1769,37 @@ impl Config { std_features: std_features_toml, } = rust; - config.download_rustc_commit = - config.download_ci_rustc_commit(download_rustc, config.llvm_assertions); + // FIXME(#133381): alt rustc builds currently do *not* have rustc debug assertions + // enabled. We should not download a CI alt rustc if we need rustc to have debug + // assertions (e.g. for crashes test suite). This can be changed once something like + // [Enable debug assertions on alt + // builds](https://github.com/rust-lang/rust/pull/131077) lands. + // + // Note that `rust.debug = true` currently implies `rust.debug-assertions = true`! + // + // This relies also on the fact that the global default for `download-rustc` will be + // `false` if it's not explicitly set. + let debug_assertions_requested = matches!(rustc_debug_assertions_toml, Some(true)) + || (matches!(debug_toml, Some(true)) + && !matches!(rustc_debug_assertions_toml, Some(false))); + + if debug_assertions_requested { + if let Some(ref opt) = download_rustc { + if opt.is_string_or_true() { + eprintln!( + "WARN: currently no CI rustc builds have rustc debug assertions \ + enabled. Please either set `rust.debug-assertions` to `false` if you \ + want to use download CI rustc or set `rust.download-rustc` to `false`." + ); + } + } + } + + config.download_rustc_commit = config.download_ci_rustc_commit( + download_rustc, + debug_assertions_requested, + config.llvm_assertions, + ); debug = debug_toml; rustc_debug_assertions = rustc_debug_assertions_toml; @@ -2778,6 +2805,7 @@ impl Config { fn download_ci_rustc_commit( &self, download_rustc: Option, + debug_assertions_requested: bool, llvm_assertions: bool, ) -> Option { if !is_download_ci_available(&self.build.triple, llvm_assertions) { @@ -2786,8 +2814,12 @@ impl Config { // If `download-rustc` is not set, default to rebuilding. let if_unchanged = match download_rustc { - None => self.rust_info.is_managed_git_subrepository(), - Some(StringOrBool::Bool(false)) => return None, + // Globally default `download-rustc` to `false`, because some contributors don't use + // profiles for reasons such as: + // - They need to seamlessly switch between compiler/library work. + // - They don't want to use compiler profile because they need to override too many + // things and it's easier to not use a profile. + None | Some(StringOrBool::Bool(false)) => return None, Some(StringOrBool::Bool(true)) => false, Some(StringOrBool::String(s)) if s == "if-unchanged" => { if !self.rust_info.is_managed_git_subrepository() { @@ -2845,6 +2877,14 @@ impl Config { return None; } + if debug_assertions_requested { + eprintln!( + "WARN: `rust.debug-assertions = true` will prevent downloading CI rustc as alt CI \ + rustc is not currently built with debug assertions." + ); + return None; + } + Some(commit) } diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index db1f5b0833826..db35e6907e661 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -427,9 +427,8 @@ impl Config { let version = &self.stage0_metadata.compiler.version; let host = self.build; - let bin_root = self.out.join(host).join("stage0"); - let clippy_stamp = bin_root.join(".clippy-stamp"); - let cargo_clippy = bin_root.join("bin").join(exe("cargo-clippy", host)); + let clippy_stamp = self.initial_sysroot.join(".clippy-stamp"); + let cargo_clippy = self.initial_sysroot.join("bin").join(exe("cargo-clippy", host)); if cargo_clippy.exists() && !program_out_of_date(&clippy_stamp, date) { return cargo_clippy; } @@ -830,7 +829,7 @@ download-rustc = false fn path_is_dylib(path: &Path) -> bool { // The .so is not necessarily the extension, it might be libLLVM.so.18.1 - path.to_str().map_or(false, |path| path.contains(".so")) + path.to_str().is_some_and(|path| path.contains(".so")) } /// Checks whether the CI rustc is available for the given target triple. diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index fabb4f2b13bca..dcf68cbeeda71 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -135,19 +135,15 @@ pub fn check(build: &mut Build) { // We need cmake, but only if we're actually building LLVM or sanitizers. let building_llvm = !build.config.llvm_from_ci - && build - .hosts - .iter() - .map(|host| { - build.config.llvm_enabled(*host) - && build - .config - .target_config - .get(host) - .map(|config| config.llvm_config.is_none()) - .unwrap_or(true) - }) - .any(|build_llvm_ourselves| build_llvm_ourselves); + && build.hosts.iter().any(|host| { + build.config.llvm_enabled(*host) + && build + .config + .target_config + .get(host) + .map(|config| config.llvm_config.is_none()) + .unwrap_or(true) + }); let need_cmake = building_llvm || build.config.any_sanitizers_to_build(); if need_cmake && cmd_finder.maybe_have("cmake").is_none() { diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index c384fd6bf4351..0ecf61ffcd903 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -158,7 +158,7 @@ pub struct Build { initial_rustc: PathBuf, initial_cargo: PathBuf, initial_lld: PathBuf, - initial_libdir: PathBuf, + initial_relative_libdir: PathBuf, initial_sysroot: PathBuf, // Runtime state filled in later on @@ -312,46 +312,19 @@ impl Build { let in_tree_llvm_info = config.in_tree_llvm_info.clone(); let in_tree_gcc_info = config.in_tree_gcc_info.clone(); - let initial_target_libdir_str = if config.dry_run() { - "/dummy/lib/path/to/lib/".to_string() - } else { - output( - Command::new(&config.initial_rustc) - .arg("--target") - .arg(config.build.rustc_target_arg()) - .arg("--print") - .arg("target-libdir"), - ) - }; + let initial_target_libdir_str = + config.initial_sysroot.join("lib/rustlib").join(config.build).join("lib"); + let initial_target_dir = Path::new(&initial_target_libdir_str).parent().unwrap(); let initial_lld = initial_target_dir.join("bin").join("rust-lld"); - let initial_sysroot = if config.dry_run() { - "/dummy".to_string() - } else { - output(Command::new(&config.initial_rustc).arg("--print").arg("sysroot")) - } - .trim() - .to_string(); - - // FIXME(Zalathar): Determining this path occasionally fails locally for - // unknown reasons, so we print some extra context to help track down why. - let find_initial_libdir = || { - let initial_libdir = - initial_target_dir.parent()?.parent()?.strip_prefix(&initial_sysroot).ok()?; - Some(initial_libdir.to_path_buf()) - }; - let Some(initial_libdir) = find_initial_libdir() else { - panic!( - "couldn't determine `initial_libdir`: -- config.initial_rustc: {rustc:?} -- initial_target_libdir_str: {initial_target_libdir_str:?} -- initial_target_dir: {initial_target_dir:?} -- initial_sysroot: {initial_sysroot:?} -", - rustc = config.initial_rustc, - ); - }; + let initial_relative_libdir = initial_target_dir + .ancestors() + .nth(2) + .unwrap() + .strip_prefix(&config.initial_sysroot) + .expect("Couldn’t determine initial relative libdir.") + .to_path_buf(); let version = std::fs::read_to_string(src.join("src").join("version")) .expect("failed to read src/version"); @@ -380,11 +353,11 @@ impl Build { } let mut build = Build { + initial_lld, + initial_relative_libdir, initial_rustc: config.initial_rustc.clone(), initial_cargo: config.initial_cargo.clone(), - initial_lld, - initial_libdir, - initial_sysroot: initial_sysroot.into(), + initial_sysroot: config.initial_sysroot.clone(), local_rebuild: config.local_rebuild, fail_fast: config.cmd.fail_fast(), doc_tests: config.cmd.doc_tests(), diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 7f62ffb20db80..41a541d726940 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -305,4 +305,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "`rust.llvm-tools` is now enabled by default when no `config.toml` is provided.", }, + ChangeInfo { + change_id: 133068, + severity: ChangeSeverity::Warning, + summary: "Revert `rust.download-rustc` global default to `false` and only use `rust.download-rustc = \"if-unchanged\"` default for library and tools profile. As alt CI rustc is built without debug assertions, `rust.debug-assertions = true` will now inhibit downloading CI rustc.", + }, ]; diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 9ca036a2afd43..923cc2dfc28ce 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -55,24 +55,24 @@ pub fn exe(name: &str, target: TargetSelection) -> String { /// Returns `true` if the file name given looks like a dynamic library. pub fn is_dylib(path: &Path) -> bool { - path.extension().and_then(|ext| ext.to_str()).map_or(false, |ext| { + path.extension().and_then(|ext| ext.to_str()).is_some_and(|ext| { ext == "dylib" || ext == "so" || ext == "dll" || (ext == "a" && is_aix_shared_archive(path)) }) } fn is_aix_shared_archive(path: &Path) -> bool { - // FIXME(#133268): reading the entire file as &[u8] into memory seems excessive - // look into either mmap it or use the ReadCache - let data = match fs::read(path) { - Ok(data) => data, + let file = match fs::File::open(path) { + Ok(file) => file, Err(_) => return false, }; - let file = match ArchiveFile::parse(&*data) { - Ok(file) => file, + let reader = object::ReadCache::new(file); + let archive = match ArchiveFile::parse(&reader) { + Ok(result) => result, Err(_) => return false, }; - file.members() + archive + .members() .filter_map(Result::ok) .any(|entry| String::from_utf8_lossy(entry.name()).contains(".so")) } diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile index f0afb570cc4a0..d408cd518a00b 100644 --- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile +++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile @@ -63,6 +63,7 @@ ENV SCRIPT \ /scripts/validate-toolstate.sh && \ /scripts/validate-error-codes.sh && \ reuse --include-submodules lint && \ + python3 ../x.py test collect-license-metadata && \ # Runs checks to ensure that there are no issues in our JS code. es-check es2019 ../src/librustdoc/html/static/js/*.js && \ eslint -c ../src/librustdoc/html/static/.eslintrc.js ../src/librustdoc/html/static/js/*.js && \ diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile index 17fc1a5749299..2a09cd54b139a 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile @@ -84,7 +84,10 @@ ENV RUST_CONFIGURE_ARGS \ --enable-new-symbol-mangling ENV HOST_TARGET x86_64-unknown-linux-gnu -ENV FORCE_CI_RUSTC 1 + +# FIXME(#133381): currently rustc alt builds do *not* have rustc debug +# assertions enabled! Therefore, we cannot force download CI rustc. +#ENV FORCE_CI_RUSTC 1 COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/ COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/ diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 9a51a3f4268c5..2f59892acf6a5 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -48,7 +48,7 @@ runners: envs: env-x86_64-apple-tests: &env-x86_64-apple-tests - SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc + SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc -- --exact RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.12 @@ -384,13 +384,12 @@ auto: SCRIPT: make ci-msvc <<: *job-windows-8c - - image: x86_64-msvc-ext + # x86_64-msvc-ext is split into multiple jobs to run tests in parallel. + - image: x86_64-msvc-ext1 env: - SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo && src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows - HOST_TARGET: x86_64-pc-windows-msvc - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld --save-toolstates=/tmp/toolstate/toolstates.json - DEPLOY_TOOLSTATES_JSON: toolstates-windows.json - <<: *job-windows-8c + SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld + <<: *job-windows # Temporary builder to workaround CI issues # See @@ -406,6 +405,15 @@ auto: RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld <<: *job-windows + # Run `checktools.sh` and upload the toolstate file. + - image: x86_64-msvc-ext3 + env: + SCRIPT: src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows + HOST_TARGET: x86_64-pc-windows-msvc + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld --save-toolstates=/tmp/toolstate/toolstates.json + DEPLOY_TOOLSTATES_JSON: toolstates-windows.json + <<: *job-windows + # 32/64-bit MinGW builds. # # We are using MinGW with POSIX threads since LLVM requires diff --git a/src/doc/book b/src/doc/book index f38ce8baef98c..e16dd73690a6c 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit f38ce8baef98cb20229e56f1be2d50e345f11792 +Subproject commit e16dd73690a6cc3ecdc5f5d94bbc3ce158a42e16 diff --git a/src/doc/edition-guide b/src/doc/edition-guide index 915f9b319c282..f48b0e842a391 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit 915f9b319c2823f310430ecdecd86264a7870d7e +Subproject commit f48b0e842a3911c63240e955d042089e9e0894c7 diff --git a/src/doc/nomicon b/src/doc/nomicon index eac89a3cbe6c4..0674321898cd4 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit eac89a3cbe6c4714e5029ae8b5a1c556fd4e8c42 +Subproject commit 0674321898cd454764ab69702819d39a919afd68 diff --git a/src/doc/reference b/src/doc/reference index 41ccb0e647830..5c86c739ec71b 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 41ccb0e6478305401dad92e8fd3d04a4304edb4c +Subproject commit 5c86c739ec71b8bc839310ff47fa94e94635bba9 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index b679e71c2d66c..787b4166ccc67 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit b679e71c2d66c6fe13e06b99ac61773b866213f0 +Subproject commit 787b4166ccc67bd8f72a6e3ef6685ce9ce82909a diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index cb43feca758df..e987d06b0f31f 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -119,17 +119,14 @@ files. It takes one of the following values: * `n`, `no`, `off` or `false`: omit bitcode from rlibs. LLVM bitcode is required when rustc is performing link-time optimization (LTO). -It is also required on some targets like iOS ones where vendors look for LLVM -bitcode. Embedded bitcode will appear in rustc-generated object files inside of -a section whose name is defined by the target platform. Most of the time this is -`.llvmbc`. +Embedded bitcode will appear in rustc-generated object files inside of a section +whose name is defined by the target platform. Most of the time this is `.llvmbc`. The use of `-C embed-bitcode=no` can significantly improve compile times and reduce generated file sizes if your compilation does not actually need bitcode -(e.g. if you're not compiling for iOS or you're not performing LTO). For these -reasons, Cargo uses `-C embed-bitcode=no` whenever possible. Likewise, if you -are building directly with `rustc` we recommend using `-C embed-bitcode=no` -whenever you are not using LTO. +(e.g. if you're not performing LTO). For these reasons, Cargo uses `-C embed-bitcode=no` +whenever possible. Likewise, if you are building directly with `rustc` we recommend +using `-C embed-bitcode=no` whenever you are not using LTO. If combined with `-C lto`, `-C embed-bitcode=no` will cause `rustc` to abort at start-up, because the combination is invalid. diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index f38d34fccd492..0942b5ebfee37 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -179,7 +179,7 @@ This informs `rustc` of the name of your crate. ## `--edition`: specify the edition to use -This flag takes a value of `2015`, `2018` or `2021`. The default is `2015`. More +This flag takes a value of `2015`, `2018`,`2021`, or `2024`. The default is `2015`. More information about editions may be found in the [edition guide]. [edition guide]: ../edition-guide/introduction.html 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 e7e3fd01c4dc7..3c3e35a51b801 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 @@ -16,7 +16,7 @@ BE8 architecture is the default big-endian architecture for Arm since [Armv6](ht The target is cross-compiled. This target supports `std` in the normal way (indeed only nominal changes are required from the standard Arm configuration). ## Target definition -The target definition can be seen [here](https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec/armeb_unknown_linux_gnueabi.rs). In particular, it should be noted that the `features` specify that this target is built for the Armv8 core. Though this can likely be modified as required. +The target definition can be seen [here](https://github.com/rust-lang/rust/blob/master/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs). In particular, it should be noted that the `features` specify that this target is built for the Armv8 core. Though this can likely be modified as required. ## Building the target Because it is Tier 3, rust does not yet ship pre-compiled artifacts for this target. 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 60e06c404c0d6..6f09ce42dbbdd 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 @@ -64,6 +64,22 @@ There are no special requirements for testing and running the target. For testing cross builds on the host, please refer to the "Cross-compilation toolchains and C code" section below. +If you want to do native testing but do not have your own s390x +machine, there are several options how to get access to one: + +* The [IBM LinuxONE Community Cloud][cloud-community] provides a + self-service portal where you can create s390x virtual machine + instances. These are intended for temporary use (limited to 120 days). + +* The [IBM LinuxONE Open Source Cloud][cloud-opensource] provides + permanent access to s390x machines. This requires approval by IBM, + which will normally be granted if you're planning to use the machine + to work on an open-source project that is relevant to the IBM Z + ecosystem - the Rust compiler would certainly qualify. + +[cloud-community]: https://linuxone.cloud.marist.edu/ +[cloud-opensource]: https://community.ibm.com/zsystems/form/l1cc-oss-vm-request/ + ## Cross-compilation toolchains and C code Rust code built using the target is compatible with C code compiled with diff --git a/src/doc/rustdoc/src/write-documentation/documentation-tests.md b/src/doc/rustdoc/src/write-documentation/documentation-tests.md index c93893b5ada84..e02c26bd42bd6 100644 --- a/src/doc/rustdoc/src/write-documentation/documentation-tests.md +++ b/src/doc/rustdoc/src/write-documentation/documentation-tests.md @@ -360,7 +360,7 @@ are added. # fn foo() {} ``` -`edition2015`, `edition2018` and `edition2021` tell `rustdoc` +`edition2015`, `edition2018`, `edition2021`, and `edition2024` tell `rustdoc` that the code sample should be compiled using the respective edition of Rust. ```rust diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md index 01de12bb90e98..12a73f0508b21 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md @@ -30,6 +30,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg32` | None\* | `r` | | NVPTX | `reg64` | None\* | `l` | | Hexagon | `reg` | `r[0-28]` | `r` | +| Hexagon | `preg` | `p[0-3]` | Only clobbers | | PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` | | PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` | | PowerPC | `freg` | `f[0-31]` | `f` | @@ -70,6 +71,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg32` | None | `i8`, `i16`, `i32`, `f32` | | NVPTX | `reg64` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | | Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32` | +| Hexagon | `preg` | N/A | Only clobbers | | PowerPC | `reg` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | | PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | | PowerPC | `freg` | None | `f32`, `f64` | diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-reg.md b/src/doc/unstable-book/src/language-features/asm-experimental-reg.md new file mode 100644 index 0000000000000..a251573d276cb --- /dev/null +++ b/src/doc/unstable-book/src/language-features/asm-experimental-reg.md @@ -0,0 +1,40 @@ +# `asm_experimental_arch` + +The tracking issue for this feature is: [#133416] + +[#133416]: https://github.com/rust-lang/rust/issues/133416 + +------------------------ + +This tracks support for additional registers in architectures where inline assembly is already stable. + +## Register classes + +| Architecture | Register class | Registers | LLVM constraint code | +| ------------ | -------------- | --------- | -------------------- | +| s390x | `vreg` | `v[0-31]` | `v` | + +> **Notes**: +> - s390x `vreg` is clobber-only in stable. + +## Register class supported types + +| Architecture | Register class | Target feature | Allowed types | +| ------------ | -------------- | -------------- | ------------- | +| s390x | `vreg` | `vector` | `i32`, `f32`, `i64`, `f64`, `i128`, `f128`, `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | + +## Register aliases + +| Architecture | Base register | Aliases | +| ------------ | ------------- | ------- | + +## Unsupported registers + +| Architecture | Unsupported register | Reason | +| ------------ | -------------------- | ------ | + +## Template modifiers + +| Architecture | Register class | Modifier | Example output | LLVM modifier | +| ------------ | -------------- | -------- | -------------- | ------------- | +| s390x | `vreg` | None | `%v0` | None | diff --git a/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md b/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md deleted file mode 100644 index b20c30ec8f1c8..0000000000000 --- a/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md +++ /dev/null @@ -1,10 +0,0 @@ -# `extended_varargs_abi_support` - -The tracking issue for this feature is: [#100189] - -[#100189]: https://github.com/rust-lang/rust/issues/100189 - ------------------------- - -This feature adds the possibility of using `sysv64`, `win64` or `efiapi` calling -conventions on functions with varargs. diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index c47937a3b7301..415fe09718c2b 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -17,27 +17,27 @@ _x.py() { _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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -53,7 +53,7 @@ _x.py() { '-h[Print help (see more with '\''--help'\'')]' \ '--help[Print help (see more with '\''--help'\'')]' \ '::paths -- paths for the subcommand:_files' \ -'::free_args -- arguments passed to subcommands:' \ +'::free_args -- arguments passed to subcommands:_default' \ ":: :_x.py_commands" \ "*::: :->bootstrap" \ && ret=0 @@ -67,27 +67,27 @@ _x.py() { _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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -109,27 +109,27 @@ _arguments "${_arguments_options[@]}" : \ _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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '--all-targets[Check all targets]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ @@ -150,33 +150,33 @@ _arguments "${_arguments_options[@]}" : \ ;; (clippy) _arguments "${_arguments_options[@]}" : \ -'*-A+[clippy lints to allow]:LINT: ' \ -'*-D+[clippy lints to deny]:LINT: ' \ -'*-W+[clippy lints to warn on]:LINT: ' \ -'*-F+[clippy lints to forbid]:LINT: ' \ +'*-A+[clippy lints to allow]:LINT:_default' \ +'*-D+[clippy lints to deny]:LINT:_default' \ +'*-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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '--fix[]' \ '--allow-dirty[]' \ '--allow-staged[]' \ @@ -201,27 +201,27 @@ _arguments "${_arguments_options[@]}" : \ _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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -243,27 +243,27 @@ _arguments "${_arguments_options[@]}" : \ _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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '--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)]' \ @@ -287,27 +287,27 @@ _arguments "${_arguments_options[@]}" : \ _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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '--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)]' \ @@ -329,35 +329,35 @@ _arguments "${_arguments_options[@]}" : \ ;; (test) _arguments "${_arguments_options[@]}" : \ -'*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS: ' \ -'*--compiletest-rustc-args=[extra options to pass the compiler when running compiletest tests]:ARGS: ' \ -'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell)]:EXTRA_CHECKS: ' \ -'--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE: ' \ -'--pass=[force {check,build,run}-pass tests to this mode]:check | build | run: ' \ -'--run=[whether to execute run-* tests]:auto | always | never: ' \ +'*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS:_default' \ +'*--compiletest-rustc-args=[extra options to pass the compiler when running compiletest tests]:ARGS:_default' \ +'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell)]:EXTRA_CHECKS:_default' \ +'--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \ +'--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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '--no-fail-fast[run all tests regardless of failure]' \ '--no-doc[do not run doc tests]' \ '--doc[only run doc tests]' \ @@ -384,30 +384,30 @@ _arguments "${_arguments_options[@]}" : \ ;; (miri) _arguments "${_arguments_options[@]}" : \ -'*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS: ' \ +'*--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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '--no-fail-fast[run all tests regardless of failure]' \ '--no-doc[do not run doc tests]' \ '--doc[only run doc tests]' \ @@ -430,30 +430,30 @@ _arguments "${_arguments_options[@]}" : \ ;; (bench) _arguments "${_arguments_options[@]}" : \ -'*--test-args=[]:TEST_ARGS: ' \ +'*--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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -473,29 +473,29 @@ _arguments "${_arguments_options[@]}" : \ ;; (clean) _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: ' \ +'--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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '--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,27 +518,27 @@ _arguments "${_arguments_options[@]}" : \ _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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -560,27 +560,27 @@ _arguments "${_arguments_options[@]}" : \ _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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -600,30 +600,30 @@ _arguments "${_arguments_options[@]}" : \ ;; (run) _arguments "${_arguments_options[@]}" : \ -'*--args=[arguments for the tool]:ARGS: ' \ +'*--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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -645,27 +645,27 @@ _arguments "${_arguments_options[@]}" : \ _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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -688,27 +688,27 @@ _arguments "${_arguments_options[@]}" : \ _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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '--run[run suggested tests]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ @@ -732,27 +732,27 @@ _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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '--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,27 +775,27 @@ _arguments "${_arguments_options[@]}" : \ _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=[build target of the stage0 compiler]:BUILD:( )' \ -'--host=[host targets to build]:HOST:( )' \ -'--target=[target targets to build]:TARGET:( )' \ +'--build=[build target of the stage0 compiler]:BUILD:' \ +'--host=[host targets to build]:HOST:' \ +'--target=[target targets to build]:TARGET:' \ '*--exclude=[build paths to exclude]:PATH:_files' \ '*--skip=[build paths to skip]:PATH:_files' \ -'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \ '--on-fail=[command to run on failure]:CMD:_cmdstring' \ -'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ -'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ -'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \ '--src=[path to the root of the rust checkout]:DIR:_files -/' \ -'-j+[number of jobs to run in parallel]:JOBS:( )' \ -'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'-j+[number of jobs to run in parallel]:JOBS:' \ +'--jobs=[number of jobs to run in parallel]:JOBS:' \ '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ -'--error-format=[rustc error format]:FORMAT:( )' \ +'--error-format=[rustc error format]:FORMAT:' \ '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ '--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: ' \ -'*--set=[override options in config.toml]:section.option=value:( )' \ +'*--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:' \ '*-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_providers.py b/src/etc/lldb_providers.py index bace228454ebb..a42ce111ebcc2 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -32,7 +32,7 @@ # You can find more information and examples here: # 1. https://lldb.llvm.org/varformats.html # 2. https://lldb.llvm.org/use/python-reference.html -# 3. https://lldb.llvm.org/python_reference/lldb.formatters.cpp.libcxx-pysrc.html +# 3. https://github.com/llvm/llvm-project/blob/llvmorg-8.0.1/lldb/www/python_reference/lldb.formatters.cpp-pysrc.html # 4. https://github.com/llvm-mirror/lldb/tree/master/examples/summaries/cocoa #################################################################################################### diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 3fe567b1c3974..185898c31b75b 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet, IndexEntry}; use rustc_hir as hir; use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData}; use rustc_middle::bug; +use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::{self, Region, Ty}; use rustc_span::def_id::DefId; use rustc_span::symbol::{Symbol, kw}; @@ -182,7 +183,7 @@ fn clean_param_env<'tcx>( .is_some_and(|pred| tcx.lang_items().sized_trait() == Some(pred.def_id())) }) .map(|pred| { - tcx.fold_regions(pred, |r, _| match *r { + fold_regions(tcx, pred, |r, _| match *r { // FIXME: Don't `unwrap_or`, I think we should panic if we encounter an infer var that // we can't map to a concrete region. However, `AutoTraitFinder` *does* leak those kinds // of `ReVar`s for some reason at the time of writing. See `rustdoc-ui/` tests. diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 9255242611afc..0dfb8a52ebabd 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -391,7 +391,7 @@ fn write_with_opt_paren( Ok(()) } -impl<'a> fmt::Display for Display<'a> { +impl fmt::Display for Display<'_> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match *self.0 { Cfg::Not(ref child) => match **child { diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 5ddd6188c2d86..d81c47886d2d5 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -367,7 +367,7 @@ pub(crate) fn build_impls( let tcx = cx.tcx; // for each implementation of an item represented by `did`, build the clean::Item for that impl - for &did in tcx.inherent_impls(did).into_iter() { + for &did in tcx.inherent_impls(did).iter() { cx.with_param_env(did, |cx| { build_impl(cx, did, attrs, ret); }); @@ -382,7 +382,7 @@ pub(crate) fn build_impls( if tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) { let type_ = if tcx.is_trait(did) { SimplifiedType::Trait(did) } else { SimplifiedType::Adt(did) }; - for &did in tcx.incoherent_impls(type_).into_iter() { + for &did in tcx.incoherent_impls(type_).iter() { cx.with_param_env(did, |cx| { build_impl(cx, did, attrs, ret); }); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 031696d445d22..093f216accbe4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -325,11 +325,11 @@ fn clean_where_predicate<'tcx>( predicate: &hir::WherePredicate<'tcx>, cx: &mut DocContext<'tcx>, ) -> Option { - if !predicate.in_where_clause() { + if !predicate.kind.in_where_clause() { return None; } - Some(match *predicate { - hir::WherePredicate::BoundPredicate(ref wbp) => { + Some(match *predicate.kind { + hir::WherePredicateKind::BoundPredicate(ref wbp) => { let bound_params = wbp .bound_generic_params .iter() @@ -342,12 +342,12 @@ fn clean_where_predicate<'tcx>( } } - hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate { + hir::WherePredicateKind::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate { lifetime: clean_lifetime(wrp.lifetime, cx), bounds: wrp.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(), }, - hir::WherePredicate::EqPredicate(ref wrp) => WherePredicate::EqPredicate { + hir::WherePredicateKind::EqPredicate(ref wrp) => WherePredicate::EqPredicate { lhs: clean_ty(wrp.lhs_ty, cx), rhs: clean_ty(wrp.rhs_ty, cx).into(), }, @@ -2509,24 +2509,14 @@ fn clean_generic_args<'tcx>( let args = generic_args .args .iter() - .filter_map(|arg| { - Some(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, cx)), - // Checking for `is_desugared_from_effects` on the `AnonConst` not only accounts for the case - // where the argument is `host` but for all possible cases (e.g., `true`, `false`). - hir::GenericArg::Const(hir::ConstArg { - is_desugared_from_effects: true, - .. - }) => { - return None; - } - hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(clean_const(ct, cx))), - hir::GenericArg::Infer(_inf) => GenericArg::Infer, - }) + .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, cx)), + hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(clean_const(ct, cx))), + hir::GenericArg::Infer(_inf) => GenericArg::Infer, }) .collect::>() .into(); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index a10a6a92bf57e..01d2661f73ede 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -264,17 +264,19 @@ impl ExternalCrate { // rendering by delegating everything to a hash map. let as_primitive = |res: Res| { let Res::Def(DefKind::Mod, def_id) = res else { return None }; - tcx.get_attrs(def_id, sym::rustc_doc_primitive).find_map(|attr| { - let attr_value = attr.value_str().expect("syntax should already be validated"); - let Some(prim) = PrimitiveType::from_symbol(attr_value) else { - span_bug!( - attr.span, - "primitive `{attr_value}` is not a member of `PrimitiveType`" - ); - }; + tcx.get_attrs(def_id, sym::rustc_doc_primitive) + .map(|attr| { + let attr_value = attr.value_str().expect("syntax should already be validated"); + let Some(prim) = PrimitiveType::from_symbol(attr_value) else { + span_bug!( + attr.span, + "primitive `{attr_value}` is not a member of `PrimitiveType`" + ); + }; - Some((def_id, prim)) - }) + (def_id, prim) + }) + .next() }; if root.is_local() { @@ -339,7 +341,7 @@ pub(crate) struct ItemInner { impl std::ops::Deref for Item { type Target = ItemInner; fn deref(&self) -> &ItemInner { - &*self.inner + &self.inner } } @@ -412,7 +414,7 @@ impl Item { pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Option { let kind = match &self.kind { - ItemKind::StrippedItem(k) => &*k, + ItemKind::StrippedItem(k) => k, _ => &self.kind, }; match kind { @@ -1870,7 +1872,7 @@ impl PrimitiveType { .get(self) .into_iter() .flatten() - .flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter()) + .flat_map(move |&simp| tcx.incoherent_impls(simp).iter()) .copied() } @@ -1878,7 +1880,7 @@ impl PrimitiveType { Self::simplified_types() .values() .flatten() - .flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter()) + .flat_map(move |&simp| tcx.incoherent_impls(simp).iter()) .copied() } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 5071ed1c47faa..34c91e33db700 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -178,7 +178,7 @@ impl fmt::Debug for Options { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { struct FmtExterns<'a>(&'a Externs); - impl<'a> fmt::Debug for FmtExterns<'a> { + impl fmt::Debug for FmtExterns<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_map().entries(self.0.iter()).finish() } @@ -508,7 +508,7 @@ impl Options { }; let parts_out_dir = - match matches.opt_str("parts-out-dir").map(|p| PathToParts::from_flag(p)).transpose() { + match matches.opt_str("parts-out-dir").map(PathToParts::from_flag).transpose() { Ok(parts_out_dir) => parts_out_dir, Err(e) => dcx.fatal(e), }; diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 25e576e9e63aa..da1316a19cc33 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -700,7 +700,7 @@ impl IndividualTestOptions { fn new(options: &RustdocOptions, test_id: &Option, test_path: PathBuf) -> Self { let outdir = if let Some(ref path) = options.persist_doctests { let mut path = path.clone(); - path.push(&test_id.as_deref().unwrap_or("")); + path.push(test_id.as_deref().unwrap_or("")); if let Err(err) = std::fs::create_dir_all(&path) { eprintln!("Couldn't create directory for doctest executables: {err}"); diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index 27d0be133fea8..dc68f48f635b3 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -88,7 +88,7 @@ impl<'tcx> HirCollector<'tcx> { } } -impl<'tcx> HirCollector<'tcx> { +impl HirCollector<'_> { fn visit_testable( &mut self, name: String, diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index ff0d537b19f75..e387eb010bebd 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -203,7 +203,7 @@ impl Cache { } } -impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { +impl DocFolder for CacheBuilder<'_, '_> { fn fold_item(&mut self, item: clean::Item) -> Option { if item.item_id.is_local() { debug!( diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index 31a2701f06a54..48771571f8ff4 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -11,7 +11,7 @@ use unicode_segmentation::UnicodeSegmentation; /// string when passed to a format string. pub(crate) struct Escape<'a>(pub &'a str); -impl<'a> fmt::Display for Escape<'a> { +impl fmt::Display for Escape<'_> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { // Because the internet is always right, turns out there's not that many // characters to escape: http://stackoverflow.com/questions/7381974 @@ -49,7 +49,7 @@ impl<'a> fmt::Display for Escape<'a> { /// difference, use [`Escape`]. pub(crate) struct EscapeBodyText<'a>(pub &'a str); -impl<'a> fmt::Display for EscapeBodyText<'a> { +impl fmt::Display for EscapeBodyText<'_> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { // Because the internet is always right, turns out there's not that many // characters to escape: http://stackoverflow.com/questions/7381974 @@ -86,7 +86,7 @@ impl<'a> fmt::Display for EscapeBodyText<'a> { /// difference, use [`Escape`]. pub(crate) struct EscapeBodyTextWithWbr<'a>(pub &'a str); -impl<'a> fmt::Display for EscapeBodyTextWithWbr<'a> { +impl fmt::Display for EscapeBodyTextWithWbr<'_> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { let EscapeBodyTextWithWbr(text) = *self; if text.len() < 8 { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 2f9e7976ca142..0a563b1df2620 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -9,6 +9,7 @@ use std::borrow::Cow; use std::cell::Cell; +use std::cmp::Ordering; use std::fmt::{self, Display, Write}; use std::iter::{self, once}; @@ -785,16 +786,20 @@ pub(crate) fn href_relative_parts<'fqp>( ); } } - // e.g. linking to std::sync::atomic from std::sync - if relative_to_fqp.len() < fqp.len() { - Box::new(fqp[relative_to_fqp.len()..fqp.len()].iter().copied()) - // e.g. linking to std::sync from std::sync::atomic - } else if fqp.len() < relative_to_fqp.len() { - let dissimilar_part_count = relative_to_fqp.len() - fqp.len(); - Box::new(iter::repeat(sym::dotdot).take(dissimilar_part_count)) - // linking to the same module - } else { - Box::new(iter::empty()) + match relative_to_fqp.len().cmp(&fqp.len()) { + Ordering::Less => { + // e.g. linking to std::sync::atomic from std::sync + Box::new(fqp[relative_to_fqp.len()..fqp.len()].iter().copied()) + } + Ordering::Greater => { + // e.g. linking to std::sync from std::sync::atomic + let dissimilar_part_count = relative_to_fqp.len() - fqp.len(); + Box::new(iter::repeat(sym::dotdot).take(dissimilar_part_count)) + } + Ordering::Equal => { + // linking to the same module + Box::new(iter::empty()) + } } } @@ -1296,7 +1301,7 @@ impl clean::Impl { self.print_type(inner_type, f, use_absolute, cx)?; write!(f, ">")?; } else { - write!(f, "{}<", anchor(ty.def_id(), last, cx).to_string())?; + write!(f, "{}<", anchor(ty.def_id(), last, cx))?; self.print_type(inner_type, f, use_absolute, cx)?; write!(f, ">")?; } @@ -1384,7 +1389,7 @@ impl clean::Impl { write!(f, ">")?; } } else { - fmt_type(&type_, f, use_absolute, cx)?; + fmt_type(type_, f, use_absolute, cx)?; } Ok(()) } @@ -1531,14 +1536,14 @@ impl clean::FnDecl { (None, Some(last_i)) if i != last_i => write!(f, ", ")?, (None, Some(_)) => (), (Some(n), Some(last_i)) if i != last_i => write!(f, ",\n{}", Indent(n + 4))?, - (Some(_), Some(_)) => write!(f, ",\n")?, + (Some(_), Some(_)) => writeln!(f, ",")?, } } if self.c_variadic { match line_wrapping_indent { None => write!(f, ", ...")?, - Some(n) => write!(f, "{}...\n", Indent(n + 4))?, + Some(n) => writeln!(f, "{}...", Indent(n + 4))?, }; } diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 29f6f92a6b28e..48a537ad5e7ad 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -144,7 +144,7 @@ struct TokenHandler<'a, 'tcx, F: Write> { href_context: Option>, } -impl<'a, 'tcx, F: Write> TokenHandler<'a, 'tcx, F> { +impl TokenHandler<'_, '_, F> { fn handle_exit_span(&mut self) { // We can't get the last `closing_tags` element using `pop()` because `closing_tags` is // being used in `write_pending_elems`. @@ -181,6 +181,9 @@ impl<'a, 'tcx, F: Write> TokenHandler<'a, 'tcx, F> { // current parent tag is not the same as our pending content. let close_tag = if self.pending_elems.len() > 1 && let Some(current_class) = current_class + // `PreludeTy` can never include more than an ident so it should not generate + // a wrapping `span`. + && !matches!(current_class, Class::PreludeTy(_)) { Some(enter_span(self.out, current_class, &self.href_context)) } else { @@ -204,7 +207,7 @@ impl<'a, 'tcx, F: Write> TokenHandler<'a, 'tcx, F> { } } -impl<'a, 'tcx, F: Write> Drop for TokenHandler<'a, 'tcx, F> { +impl Drop for TokenHandler<'_, '_, F> { /// When leaving, we need to flush all pending data to not have missing content. fn drop(&mut self) { if self.pending_exit_span.is_some() { @@ -333,7 +336,7 @@ enum Class { /// `Ident` isn't rendered in the HTML but we still need it for the `Span` it contains. Ident(Span), Lifetime, - PreludeTy, + PreludeTy(Span), PreludeVal, QuestionMark, Decoration(&'static str), @@ -381,7 +384,7 @@ impl Class { Class::Bool => "bool-val", Class::Ident(_) => "", Class::Lifetime => "lifetime", - Class::PreludeTy => "prelude-ty", + Class::PreludeTy(_) => "prelude-ty", Class::PreludeVal => "prelude-val", Class::QuestionMark => "question-mark", Class::Decoration(kind) => kind, @@ -392,7 +395,7 @@ impl Class { /// a "span" (a tuple representing `(lo, hi)` equivalent of `Span`). fn get_span(self) -> Option { match self { - Self::Ident(sp) | Self::Self_(sp) | Self::Macro(sp) => Some(sp), + Self::Ident(sp) | Self::Self_(sp) | Self::Macro(sp) | Self::PreludeTy(sp) => Some(sp), Self::Comment | Self::DocComment | Self::Attribute @@ -403,7 +406,6 @@ impl Class { | Self::Number | Self::Bool | Self::Lifetime - | Self::PreludeTy | Self::PreludeVal | Self::QuestionMark | Self::Decoration(_) => None, @@ -411,6 +413,7 @@ impl Class { } } +#[derive(Debug)] enum Highlight<'a> { Token { text: &'a str, class: Option }, EnterSpan { class: Class }, @@ -847,7 +850,7 @@ impl<'src> Classifier<'src> { } TokenKind::Ident => match get_real_ident_class(text, false) { None => match text { - "Option" | "Result" => Class::PreludeTy, + "Option" | "Result" => Class::PreludeTy(self.new_span(before, text)), "Some" | "None" | "Ok" | "Err" => Class::PreludeVal, // "union" is a weak keyword and is only considered as a keyword when declaring // a union type. @@ -1014,7 +1017,7 @@ fn string_without_closing_tag( .ok() .map(|(url, _, _)| url), LinkFromSrc::Doc(def_id) => { - format::href_with_root_path(*def_id, context, Some(&href_context.root_path)) + format::href_with_root_path(*def_id, context, Some(href_context.root_path)) .ok() .map(|(doc_link, _, _)| doc_link) } diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 31ccfeb38738c..b4bc0b80d6c66 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -33,7 +33,7 @@ pub(crate) struct Page<'a> { pub(crate) rust_logo: bool, } -impl<'a> Page<'a> { +impl Page<'_> { pub(crate) fn get_static_root_path(&self) -> String { match self.static_root_path { Some(s) => s.to_string(), diff --git a/src/librustdoc/html/length_limit.rs b/src/librustdoc/html/length_limit.rs index 8562e103dc17e..fdb1ddc1f5311 100644 --- a/src/librustdoc/html/length_limit.rs +++ b/src/librustdoc/html/length_limit.rs @@ -77,7 +77,7 @@ impl HtmlWithLimit { /// This function will panic if called with a non-alphabetic `tag_name`. pub(super) fn open_tag(&mut self, tag_name: &'static str) { assert!( - tag_name.chars().all(|c| ('a'..='z').contains(&c)), + tag_name.chars().all(|c: char| c.is_ascii_lowercase()), "tag_name contained non-alphabetic chars: {tag_name:?}", ); self.queued_tags.push(tag_name); @@ -85,16 +85,15 @@ impl HtmlWithLimit { /// Close the most recently opened HTML tag. pub(super) fn close_tag(&mut self) { - match self.unclosed_tags.pop() { + if let Some(tag_name) = self.unclosed_tags.pop() { // Close the most recently opened tag. - Some(tag_name) => write!(self.buf, "").unwrap(), - // There are valid cases where `close_tag()` is called without - // there being any tags to close. For example, this occurs when - // a tag is opened after the length limit is exceeded; - // `flush_queue()` will never be called, and thus, the tag will - // not end up being added to `unclosed_tags`. - None => {} + write!(self.buf, "").unwrap() } + // There are valid cases where `close_tag()` is called without + // there being any tags to close. For example, this occurs when + // a tag is opened after the length limit is exceeded; + // `flush_queue()` will never be called, and thus, the tag will + // not end up being added to `unclosed_tags`. } /// Write all queued tags and add them to the `unclosed_tags` list. diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 1d42ec8eec7cb..b6829d5457ba7 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -499,7 +499,7 @@ struct HeadingLinks<'a, 'b, 'ids, I> { heading_offset: HeadingOffset, } -impl<'a, 'b, 'ids, I> HeadingLinks<'a, 'b, 'ids, I> { +impl<'b, 'ids, I> HeadingLinks<'_, 'b, 'ids, I> { fn new( iter: I, toc: Option<&'b mut TocBuilder>, @@ -510,9 +510,7 @@ impl<'a, 'b, 'ids, I> HeadingLinks<'a, 'b, 'ids, I> { } } -impl<'a, 'b, 'ids, I: Iterator>> Iterator - for HeadingLinks<'a, 'b, 'ids, I> -{ +impl<'a, I: Iterator>> Iterator for HeadingLinks<'a, '_, '_, I> { type Item = SpannedEvent<'a>; fn next(&mut self) -> Option { @@ -908,7 +906,7 @@ impl<'a, 'tcx> TagIterator<'a, 'tcx> { } fn parse_string(&mut self, start: usize) -> Option { - while let Some((pos, c)) = self.inner.next() { + for (pos, c) in self.inner.by_ref() { if c == '"' { return Some(Indices { start: start + 1, end: pos }); } @@ -1032,7 +1030,7 @@ impl<'a, 'tcx> TagIterator<'a, 'tcx> { /// Returns `false` if an error was emitted. fn skip_paren_block(&mut self) -> bool { - while let Some((_, c)) = self.inner.next() { + for (_, c) in self.inner.by_ref() { if c == ')' { return true; } @@ -1074,9 +1072,8 @@ impl<'a, 'tcx> TagIterator<'a, 'tcx> { return Some(LangStringToken::LangToken(&self.data[start..pos])); } return self.next(); - } else if pos == start && is_leading_char(c) { - continue; - } else if pos != start && is_bareword_char(c) { + } else if (pos == start && is_leading_char(c)) || (pos != start && is_bareword_char(c)) + { continue; } else { self.emit_error(format!("unexpected character `{c}`")); @@ -1088,7 +1085,7 @@ impl<'a, 'tcx> TagIterator<'a, 'tcx> { } } -impl<'a, 'tcx> Iterator for TagIterator<'a, 'tcx> { +impl<'a> Iterator for TagIterator<'a, '_> { type Item = LangStringToken<'a>; fn next(&mut self) -> Option { @@ -1324,7 +1321,7 @@ impl Markdown<'_> { let mut replacer = |broken_link: BrokenLink<'_>| { links .iter() - .find(|link| &*link.original_text == &*broken_link.reference) + .find(|link| *link.original_text == *broken_link.reference) .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into())) }; @@ -1358,7 +1355,7 @@ impl MarkdownWithToc<'_> { let mut replacer = |broken_link: BrokenLink<'_>| { links .iter() - .find(|link| &*link.original_text == &*broken_link.reference) + .find(|link| *link.original_text == *broken_link.reference) .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into())) }; @@ -1428,7 +1425,7 @@ impl MarkdownSummaryLine<'_> { let mut replacer = |broken_link: BrokenLink<'_>| { links .iter() - .find(|link| &*link.original_text == &*broken_link.reference) + .find(|link| *link.original_text == *broken_link.reference) .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into())) }; @@ -1475,7 +1472,7 @@ fn markdown_summary_with_limit( let mut replacer = |broken_link: BrokenLink<'_>| { link_names .iter() - .find(|link| &*link.original_text == &*broken_link.reference) + .find(|link| *link.original_text == *broken_link.reference) .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into())) }; @@ -1556,7 +1553,7 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin let mut replacer = |broken_link: BrokenLink<'_>| { link_names .iter() - .find(|link| &*link.original_text == &*broken_link.reference) + .find(|link| *link.original_text == *broken_link.reference) .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into())) }; @@ -1751,7 +1748,7 @@ pub(crate) fn markdown_links<'md, R>( }; let mut broken_link_callback = |link: BrokenLink<'md>| Some((link.reference, "".into())); - let mut event_iter = Parser::new_with_broken_link_callback( + let event_iter = Parser::new_with_broken_link_callback( md, main_body_opts(), Some(&mut broken_link_callback), @@ -1759,7 +1756,7 @@ pub(crate) fn markdown_links<'md, R>( .into_offset_iter(); let mut links = Vec::new(); - while let Some((event, span)) = event_iter.next() { + for (event, span) in event_iter { match event { Event::Start(Tag::Link { link_type, dest_url, .. }) if may_be_doc_link(link_type) => { let range = match link_type { @@ -1821,7 +1818,7 @@ pub(crate) fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_>) -> Vec>> Footnotes<'a, 'b, I> { } } -impl<'a, 'b, I: Iterator>> Iterator for Footnotes<'a, 'b, I> { +impl<'a, I: Iterator>> Iterator for Footnotes<'a, '_, I> { type Item = SpannedEvent<'a>; fn next(&mut self) -> Option { diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 5f255c18ec6aa..3a8144621747c 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -200,7 +200,7 @@ impl<'tcx> Context<'tcx> { }; title.push_str(" - Rust"); let tyname = it.type_(); - let desc = plain_text_summary(&it.doc_value(), &it.link_names(&self.cache())); + let desc = plain_text_summary(&it.doc_value(), &it.link_names(self.cache())); let desc = if !desc.is_empty() { desc } else if it.is_crate() { @@ -739,7 +739,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { &shared.layout, &page, "", - scrape_examples_help(&*shared), + scrape_examples_help(&shared), &shared.style_files, ); shared.fs.write(scrape_examples_help_file, v)?; @@ -779,7 +779,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { self.render_redirect_pages = item.is_stripped(); } let item_name = item.name.unwrap(); - self.dst.push(&*item_name.as_str()); + self.dst.push(item_name.as_str()); self.current.push(item_name); info!("Recursing into {}", self.dst.display()); @@ -812,7 +812,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { unreachable!() }; let items = self.build_sidebar_items(module); - let js_dst = self.dst.join(&format!("sidebar-items{}.js", self.shared.resource_suffix)); + let js_dst = self.dst.join(format!("sidebar-items{}.js", self.shared.resource_suffix)); let v = format!("window.SIDEBAR_ITEMS = {};", serde_json::to_string(&items).unwrap()); self.shared.fs.write(js_dst, v)?; } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index f11356b44d885..7c5048cd164b7 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -151,13 +151,13 @@ impl RenderType { string.push('{'); write_optional_id(self.id, string); string.push('{'); - for generic in &self.generics.as_deref().unwrap_or_default()[..] { + for generic in self.generics.as_deref().unwrap_or_default() { generic.write_to_string(string); } string.push('}'); if self.bindings.is_some() { string.push('{'); - for binding in &self.bindings.as_deref().unwrap_or_default()[..] { + for binding in self.bindings.as_deref().unwrap_or_default() { string.push('{'); binding.0.write_to_string(string); string.push('{'); @@ -1963,7 +1963,7 @@ fn render_impl( w, "
{}
", Markdown { - content: &*dox, + content: dox, links: &i.impl_item.links(cx), ids: &mut cx.id_map, error_codes: cx.shared.codes, @@ -2093,9 +2093,7 @@ pub(crate) fn small_url_encode(s: String) -> String { // and https://url.spec.whatwg.org/#urlencoded-parsing // and https://url.spec.whatwg.org/#url-code-points fn dont_escape(c: u8) -> bool { - (b'a' <= c && c <= b'z') - || (b'A' <= c && c <= b'Z') - || (b'0' <= c && c <= b'9') + c.is_ascii_alphanumeric() || c == b'-' || c == b'_' || c == b'.' @@ -2150,7 +2148,7 @@ pub(crate) fn small_url_encode(s: String) -> String { } } -fn get_id_for_impl<'tcx>(tcx: TyCtxt<'tcx>, impl_id: ItemId) -> String { +fn get_id_for_impl(tcx: TyCtxt<'_>, impl_id: ItemId) -> String { use rustc_middle::ty::print::with_forced_trimmed_paths; let (type_, trait_) = match impl_id { ItemId::Auto { trait_, for_ } => { @@ -2381,7 +2379,7 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec { let fqp = cache.exact_paths.get(&did).or_else(get_extern); if let Some(path) = fqp { - out.push(join_with_double_colon(&path)); + out.push(join_with_double_colon(path)); } }; @@ -2462,8 +2460,8 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c }; // Generate the HTML for a single example, being the title and code block - let write_example = |mut w: &mut W, (path, call_data): (&PathBuf, &CallData)| -> bool { - let contents = match fs::read_to_string(&path) { + let write_example = |w: &mut W, (path, call_data): (&PathBuf, &CallData)| -> bool { + let contents = match fs::read_to_string(path) { Ok(contents) => contents, Err(err) => { let span = item.span(tcx).map_or(DUMMY_SP, |span| span.inner()); @@ -2532,7 +2530,7 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c decoration_info.insert("highlight", byte_ranges); sources::print_src( - &mut w, + w, contents_subset, file_span, cx, @@ -2581,7 +2579,7 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c // An example may fail to write if its source can't be read for some reason, so this method // continues iterating until a write succeeds let write_and_skip_failure = |w: &mut W, it: &mut Peekable<_>| { - while let Some(example) = it.next() { + for example in it.by_ref() { if write_example(&mut *w, example) { break; } diff --git a/src/librustdoc/html/render/ordered_json.rs b/src/librustdoc/html/render/ordered_json.rs index 7abe40eef3bdb..d1dddfebc83a2 100644 --- a/src/librustdoc/html/render/ordered_json.rs +++ b/src/librustdoc/html/render/ordered_json.rs @@ -23,7 +23,7 @@ impl OrderedJson { pub(crate) fn array_sorted, I: IntoIterator>(items: I) -> Self { let items = items .into_iter() - .sorted_unstable_by(|a, b| a.borrow().cmp(&b.borrow())) + .sorted_unstable_by(|a, b| a.borrow().cmp(b.borrow())) .format_with(",", |item, f| f(item.borrow())); Self(format!("[{}]", items)) } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index d247e90d298db..dc205252507c5 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -751,7 +751,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: } if !required_methods.is_empty() { - write!(w, " // Required method{}\n", pluralize(required_methods.len())); + writeln!(w, " // Required method{}", pluralize(required_methods.len())); } for (pos, m) in required_methods.iter().enumerate() { render_assoc_item( @@ -773,7 +773,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: } if !provided_methods.is_empty() { - write!(w, " // Provided method{}\n", pluralize(provided_methods.len())); + writeln!(w, " // Provided method{}", pluralize(provided_methods.len())); } for (pos, m) in provided_methods.iter().enumerate() { render_assoc_item( @@ -940,7 +940,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: "Dyn Compatibility", "dyn-compatibility", None, - &format!( + format!( "

This trait is not \ dyn compatible.

\

In older versions of Rust, dyn compatibility was called \"object safety\", \ @@ -1225,14 +1225,14 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c w, cx, Some(&t.generics), - &variants, + variants, variants_count, has_stripped_entries, *is_non_exhaustive, enum_def_id, ) }); - item_variants(w, cx, it, &variants, enum_def_id); + item_variants(w, cx, it, variants, enum_def_id); } clean::TypeAliasInnerType::Union { fields } => { wrap_item(w, |w| { @@ -1824,7 +1824,7 @@ fn item_constant( name = it.name.unwrap(), generics = generics.print(cx), typ = ty.print(cx), - where_clause = print_where_clause(&generics, cx, 0, Ending::NoNewline), + where_clause = print_where_clause(generics, cx, 0, Ending::NoNewline), ); // FIXME: The code below now prints @@ -2194,7 +2194,7 @@ fn render_union<'a, 'cx: 'a>( f.write_str(" ")?; } - write!(f, "{{\n")?; + writeln!(f, "{{")?; let count_fields = fields.iter().filter(|field| matches!(field.kind, clean::StructFieldItem(..))).count(); let toggle = should_hide_fields(count_fields); @@ -2204,9 +2204,9 @@ fn render_union<'a, 'cx: 'a>( for field in fields { if let clean::StructFieldItem(ref ty) = field.kind { - write!( + writeln!( f, - " {}{}: {},\n", + " {}{}: {},", visibility_print_with_space(field, cx), field.name.unwrap(), ty.print(cx) @@ -2215,7 +2215,7 @@ fn render_union<'a, 'cx: 'a>( } if it.has_stripped_entries().unwrap() { - write!(f, " /* private fields */\n")?; + writeln!(f, " /* private fields */")?; } if toggle { toggle_close(&mut f); @@ -2355,7 +2355,7 @@ fn document_non_exhaustive_header(item: &clean::Item) -> &str { if item.is_non_exhaustive() { " (Non-exhaustive)" } else { "" } } -fn document_non_exhaustive<'a>(item: &'a clean::Item) -> impl fmt::Display + 'a { +fn document_non_exhaustive(item: &clean::Item) -> impl fmt::Display + '_ { display_fn(|f| { if item.is_non_exhaustive() { write!( diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index f91fdfa1fb5f5..cfb62c3ca1640 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -55,10 +55,10 @@ pub(crate) struct SerializedSearchIndex { const DESC_INDEX_SHARD_LEN: usize = 128 * 1024; /// Builds the search index from the collected metadata -pub(crate) fn build_index<'tcx>( +pub(crate) fn build_index( krate: &clean::Crate, cache: &mut Cache, - tcx: TyCtxt<'tcx>, + tcx: TyCtxt<'_>, ) -> SerializedSearchIndex { // Maps from ID to position in the `crate_paths` array. let mut itemid_to_pathid = FxHashMap::default(); @@ -126,7 +126,7 @@ pub(crate) fn build_index<'tcx>( let mut lastpathid = 0isize; // First, on function signatures - let mut search_index = std::mem::replace(&mut cache.search_index, Vec::new()); + let mut search_index = std::mem::take(&mut cache.search_index); for item in search_index.iter_mut() { fn insert_into_map( map: &mut FxHashMap, @@ -194,7 +194,7 @@ pub(crate) fn build_index<'tcx>( { let exact_fqp = exact_paths .get(&defid) - .or_else(|| external_paths.get(&defid).map(|&(ref fqp, _)| fqp)) + .or_else(|| external_paths.get(&defid).map(|(fqp, _)| fqp)) // Re-exports only count if the name is exactly the same. // This is a size optimization, since it means we only need // to store the name once (and the path is re-used for everything @@ -298,7 +298,7 @@ pub(crate) fn build_index<'tcx>( true }); } - let Some(id) = ty.id.clone() else { + let Some(id) = ty.id else { assert!(ty.generics.is_some()); return; }; @@ -372,7 +372,7 @@ pub(crate) fn build_index<'tcx>( if let Some(&(ref fqp, short)) = paths.get(&defid) { let exact_fqp = exact_paths .get(&defid) - .or_else(|| external_paths.get(&defid).map(|&(ref fqp, _)| fqp)) + .or_else(|| external_paths.get(&defid).map(|(fqp, _)| fqp)) .filter(|exact_fqp| { exact_fqp.last() == Some(&item.name) && *exact_fqp != fqp }); @@ -397,7 +397,7 @@ pub(crate) fn build_index<'tcx>( // Their parent carries the exact fqp instead. let exact_fqp = exact_paths .get(&defid) - .or_else(|| external_paths.get(&defid).map(|&(ref fqp, _)| fqp)); + .or_else(|| external_paths.get(&defid).map(|(fqp, _)| fqp)); item.exact_path = exact_fqp.and_then(|fqp| { // Re-exports only count if the name is exactly the same. // This is a size optimization, since it means we only need @@ -426,7 +426,7 @@ pub(crate) fn build_index<'tcx>( } // Omit the parent path if it is same to that of the prior item. - if lastpath == &item.path { + if lastpath == item.path { item.path.clear(); } else { lastpath = &item.path; @@ -512,7 +512,7 @@ pub(crate) fn build_index<'tcx>( } } - impl<'a> Serialize for CrateData<'a> { + impl Serialize for CrateData<'_> { fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -640,7 +640,7 @@ pub(crate) fn build_index<'tcx>( let mut last_name = None; for (index, item) in self.items.iter().enumerate() { let n = item.ty as u8; - let c = char::try_from(n + b'A').expect("item types must fit in ASCII"); + let c = char::from(n + b'A'); assert!(c <= 'z', "item types must fit within ASCII printables"); types.push(c); @@ -741,22 +741,22 @@ pub(crate) fn build_index<'tcx>( let mut len: usize = 0; let mut item_index: u32 = 0; for desc in std::iter::once(&crate_doc).chain(crate_items.iter().map(|item| &item.desc)) { - if desc == "" { + if desc.is_empty() { empty_desc.push(item_index); item_index += 1; continue; } if set.len() >= DESC_INDEX_SHARD_LEN { - result.push((len, std::mem::replace(&mut set, String::new()))); + result.push((len, std::mem::take(&mut set))); len = 0; } else if len != 0 { set.push('\n'); } - set.push_str(&desc); + set.push_str(desc); len += 1; item_index += 1; } - result.push((len, std::mem::replace(&mut set, String::new()))); + result.push((len, std::mem::take(&mut set))); (empty_desc, result) }; @@ -792,9 +792,9 @@ pub(crate) fn build_index<'tcx>( SerializedSearchIndex { index, desc } } -pub(crate) fn get_function_type_for_search<'tcx>( +pub(crate) fn get_function_type_for_search( item: &clean::Item, - tcx: TyCtxt<'tcx>, + tcx: TyCtxt<'_>, impl_generics: Option<&(clean::Type, clean::Generics)>, parent: Option, cache: &Cache, @@ -861,7 +861,7 @@ fn get_index_type_id( match *clean_type { clean::Type::Path { ref path, .. } => Some(RenderTypeId::DefId(path.def_id())), clean::DynTrait(ref bounds, _) => { - bounds.get(0).map(|b| RenderTypeId::DefId(b.trait_.def_id())) + bounds.first().map(|b| RenderTypeId::DefId(b.trait_.def_id())) } clean::Primitive(p) => Some(RenderTypeId::Primitive(p)), clean::BorrowedRef { .. } => Some(RenderTypeId::Primitive(clean::PrimitiveType::Reference)), @@ -953,7 +953,7 @@ fn simplify_fn_type<'a, 'tcx>( WherePredicate::BoundPredicate { ty, .. } => *ty == *arg, _ => false, }) { - let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]); + let bounds = where_pred.get_bounds().unwrap_or(&[]); for bound in bounds.iter() { if let Some(path) = bound.get_trait_path() { let ty = Type::Path { path }; @@ -1043,7 +1043,7 @@ fn simplify_fn_type<'a, 'tcx>( simplify_fn_type( self_, generics, - &ty, + ty, tcx, recurse + 1, &mut ty_generics, @@ -1058,7 +1058,7 @@ fn simplify_fn_type<'a, 'tcx>( simplify_fn_type( self_, generics, - &ty, + ty, tcx, recurse + 1, &mut ty_generics, @@ -1074,7 +1074,7 @@ fn simplify_fn_type<'a, 'tcx>( simplify_fn_type( self_, generics, - &ty, + ty, tcx, recurse + 1, &mut ty_generics, @@ -1117,7 +1117,7 @@ fn simplify_fn_type<'a, 'tcx>( ); let ty_bindings = vec![(RenderTypeId::AssociatedType(sym::Output), ty_output)]; res.push(RenderType { - id: get_index_type_id(&arg, rgen), + id: get_index_type_id(arg, rgen), bindings: Some(ty_bindings), generics: Some(ty_generics), }); @@ -1134,7 +1134,7 @@ fn simplify_fn_type<'a, 'tcx>( simplify_fn_type( self_, generics, - &type_, + type_, tcx, recurse + 1, &mut ty_generics, @@ -1249,7 +1249,7 @@ fn simplify_fn_type<'a, 'tcx>( } } } - let id = get_index_type_id(&arg, rgen); + let id = get_index_type_id(arg, rgen); if id.is_some() || !ty_generics.is_empty() { res.push(RenderType { id, @@ -1261,11 +1261,11 @@ fn simplify_fn_type<'a, 'tcx>( } } -fn simplify_fn_constraint<'a, 'tcx>( +fn simplify_fn_constraint<'a>( self_: Option<&'a Type>, generics: &Generics, constraint: &'a clean::AssocItemConstraint, - tcx: TyCtxt<'tcx>, + tcx: TyCtxt<'_>, recurse: usize, res: &mut Vec<(RenderTypeId, Vec)>, rgen: &mut FxIndexMap)>, @@ -1347,9 +1347,9 @@ fn simplify_fn_constraint<'a, 'tcx>( /// /// i.e. `fn foo>(x: u32, y: B)` will return /// `[u32, Display, Option]`. -fn get_fn_inputs_and_outputs<'tcx>( +fn get_fn_inputs_and_outputs( func: &Function, - tcx: TyCtxt<'tcx>, + tcx: TyCtxt<'_>, impl_or_trait_generics: Option<&(clean::Type, clean::Generics)>, cache: &Cache, ) -> (Vec, Vec, Vec, Vec>) { diff --git a/src/librustdoc/html/render/search_index/encode.rs b/src/librustdoc/html/render/search_index/encode.rs index 8d715814faad7..8816ea650593b 100644 --- a/src/librustdoc/html/render/search_index/encode.rs +++ b/src/librustdoc/html/render/search_index/encode.rs @@ -25,7 +25,7 @@ pub(crate) fn write_vlqhex_to_string(n: i32, string: &mut String) { break; } shift = shift.wrapping_sub(4); - mask = mask >> 4; + mask >>= 4; } // now write the rest while shift < 32 { @@ -33,7 +33,7 @@ pub(crate) fn write_vlqhex_to_string(n: i32, string: &mut String) { let hex = char::try_from(if shift == 0 { '`' } else { '@' } as u32 + hexit).unwrap(); string.push(hex); shift = shift.wrapping_sub(4); - mask = mask >> 4; + mask >>= 4; } } @@ -64,7 +64,7 @@ impl Container { Container::Array(array) => { array.push(value); if array.len() >= 4096 { - let array = std::mem::replace(array, Vec::new()); + let array = std::mem::take(array); *self = Container::Bits(Box::new([0; 1024])); for value in array { self.push(value); @@ -123,7 +123,7 @@ impl Container { if 2 + 4 * r >= 2 * array.len() + 2 { return false; } - let array = std::mem::replace(array, Vec::new()); + let array = std::mem::take(array); *self = Container::Run(Vec::new()); for value in array { self.push(value); @@ -145,7 +145,7 @@ pub(crate) fn write_bitmap_to_bytes( let mut keys = Vec::::new(); let mut containers = Vec::::new(); let mut key: u16; - let mut domain_iter = domain.into_iter().copied().peekable(); + let mut domain_iter = domain.iter().copied().peekable(); let mut has_run = false; while let Some(entry) = domain_iter.next() { key = (entry >> 16).try_into().expect("shifted off the top 16 bits, so it should fit"); @@ -236,7 +236,7 @@ pub(crate) fn write_bitmap_to_bytes( pub(crate) fn bitmap_to_string(domain: &[u32]) -> String { let mut buf = Vec::new(); let mut strbuf = String::new(); - write_bitmap_to_bytes(&domain, &mut buf).unwrap(); + write_bitmap_to_bytes(domain, &mut buf).unwrap(); BASE64_STANDARD.encode_string(&buf, &mut strbuf); strbuf } diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 6df9486e65809..76de8d872311e 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -44,7 +44,7 @@ pub(super) struct Sidebar<'a> { pub(super) path: String, } -impl<'a> Sidebar<'a> { +impl Sidebar<'_> { /// Only create a `

` if there are any blocks /// which should actually be rendered. pub fn should_render_blocks(&self) -> bool { @@ -564,9 +564,9 @@ pub(crate) fn sidebar_module_like( .filter(|sec| item_sections_in_use.contains(sec)) .map(|sec| Link::new(ids.derive(sec.id()), sec.name())) .collect(); - let header = if let Some(first_section) = item_sections.get(0) { + let header = if let Some(first_section) = item_sections.first() { Link::new( - first_section.href.to_owned(), + first_section.href.clone(), if module_like.is_crate() { "Crate Items" } else { "Module Items" }, ) } else { diff --git a/src/librustdoc/html/render/sorted_template.rs b/src/librustdoc/html/render/sorted_template.rs index 28f7766d7c7ac..dc894840f92a0 100644 --- a/src/librustdoc/html/render/sorted_template.rs +++ b/src/librustdoc/html/render/sorted_template.rs @@ -84,7 +84,7 @@ impl FromStr for SortedTemplate { let offset = offset .strip_suffix(F::COMMENT_END) .ok_or(Error("last line expected to end with a comment"))?; - let offset: Offset = serde_json::from_str(&offset).map_err(|_| { + let offset: Offset = serde_json::from_str(offset).map_err(|_| { Error("could not find insertion location descriptor object on last line") })?; let (before, mut s) = diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index d4cca562d6c4a..81d79a6be9683 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -63,7 +63,7 @@ struct SpanMapVisitor<'tcx> { pub(crate) matches: FxHashMap, } -impl<'tcx> SpanMapVisitor<'tcx> { +impl SpanMapVisitor<'_> { /// This function is where we handle `hir::Path` elements and add them into the "span map". fn handle_path(&mut self, path: &rustc_hir::Path<'_>) { match path.res { diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index c82f7e9aaf927..7c676469597dc 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -68,8 +68,8 @@ pub(crate) fn write_shared( let _lock = try_err!(flock::Lock::new(&lock_file, true, true, true), &lock_file); let SerializedSearchIndex { index, desc } = - build_index(&krate, &mut Rc::get_mut(&mut cx.shared).unwrap().cache, tcx); - write_search_desc(cx, &krate, &desc)?; // does not need to be merged + build_index(krate, &mut Rc::get_mut(&mut cx.shared).unwrap().cache, tcx); + write_search_desc(cx, krate, &desc)?; // does not need to be merged let crate_name = krate.name(cx.tcx()); let crate_name = crate_name.as_str(); // rand @@ -80,7 +80,7 @@ pub(crate) fn write_shared( src_files_js: SourcesPart::get(cx, &crate_name_json)?, search_index_js: SearchIndexPart::get(index, &cx.shared.resource_suffix)?, all_crates: AllCratesPart::get(crate_name_json.clone(), &cx.shared.resource_suffix)?, - crates_index: CratesIndexPart::get(&crate_name, &external_crates)?, + crates_index: CratesIndexPart::get(crate_name, &external_crates)?, trait_impl: TraitAliasPart::get(cx, &crate_name_json)?, type_impl: TypeAliasPart::get(cx, krate, &crate_name_json)?, }; @@ -112,7 +112,7 @@ pub(crate) fn write_shared( md_opts.output = cx.dst.clone(); md_opts.external_html = cx.shared.layout.external_html.clone(); try_err!( - crate::markdown::render_and_write(&index_page, md_opts, cx.shared.edition()), + crate::markdown::render_and_write(index_page, md_opts, cx.shared.edition()), &index_page ); } @@ -158,13 +158,13 @@ fn write_rendered_cross_crate_info( let m = &opt.should_merge; if opt.emit.is_empty() || opt.emit.contains(&EmitType::InvocationSpecific) { if include_sources { - write_rendered_cci::(SourcesPart::blank, dst, &crates, m)?; + write_rendered_cci::(SourcesPart::blank, dst, crates, m)?; } - write_rendered_cci::(SearchIndexPart::blank, dst, &crates, m)?; - write_rendered_cci::(AllCratesPart::blank, dst, &crates, m)?; + write_rendered_cci::(SearchIndexPart::blank, dst, crates, m)?; + write_rendered_cci::(AllCratesPart::blank, dst, crates, m)?; } - write_rendered_cci::(TraitAliasPart::blank, dst, &crates, m)?; - write_rendered_cci::(TypeAliasPart::blank, dst, &crates, m)?; + write_rendered_cci::(TraitAliasPart::blank, dst, crates, m)?; + write_rendered_cci::(TypeAliasPart::blank, dst, crates, m)?; Ok(()) } @@ -234,7 +234,7 @@ fn write_search_desc( &cx.shared.resource_suffix, ); let path = path.join(filename); - let part = OrderedJson::serialize(&part).unwrap(); + let part = OrderedJson::serialize(part).unwrap(); let part = format!("searchState.loadedDescShard({encoded_crate_name}, {i}, {part})"); create_parents(&path)?; try_err!(fs::write(&path, part), &path); @@ -261,7 +261,7 @@ impl CrateInfo { .iter() .map(|parts_path| { let path = &parts_path.0; - let parts = try_err!(fs::read(&path), &path); + let parts = try_err!(fs::read(path), &path); let parts: CrateInfo = try_err!(serde_json::from_slice(&parts), &path); Ok::<_, Error>(parts) }) @@ -439,7 +439,7 @@ impl CratesIndexPart { const DELIMITER: &str = "\u{FFFC}"; // users are being naughty if they have this let content = format!("

List of all crates

    {DELIMITER}
"); - let template = layout::render(layout, &page, "", content, &style_files); + let template = layout::render(layout, &page, "", content, style_files); match SortedTemplate::from_template(&template, DELIMITER) { Ok(template) => template, Err(e) => panic!( @@ -534,7 +534,7 @@ impl Hierarchy { } fn add_path(self: &Rc, path: &Path) { - let mut h = Rc::clone(&self); + let mut h = Rc::clone(self); let mut elems = path .components() .filter_map(|s| match s { @@ -606,7 +606,7 @@ impl TypeAliasPart { cache, cx, }; - DocVisitor::visit_crate(&mut type_impl_collector, &krate); + DocVisitor::visit_crate(&mut type_impl_collector, krate); let cx = type_impl_collector.cx; let aliased_types = type_impl_collector.aliased_types; for aliased_type in aliased_types.values() { @@ -623,7 +623,7 @@ impl TypeAliasPart { // render_impl will filter out "impossible-to-call" methods // to make that functionality work here, it needs to be called with // each type alias, and if it gives a different result, split the impl - for &(type_alias_fqp, ref type_alias_item) in type_aliases { + for &(type_alias_fqp, type_alias_item) in type_aliases { let mut buf = Buffer::html(); cx.id_map = Default::default(); cx.deref_id_map = Default::default(); @@ -643,8 +643,8 @@ impl TypeAliasPart { super::render_impl( &mut buf, cx, - *impl_, - &type_alias_item, + impl_, + type_alias_item, assoc_link, RenderMode::Normal, None, @@ -680,7 +680,7 @@ impl TypeAliasPart { path.push(component.as_str()); } let aliased_item_type = aliased_type.target_type; - path.push(&format!( + path.push(format!( "{aliased_item_type}.{}.js", aliased_type.target_fqp[aliased_type.target_fqp.len() - 1] )); @@ -781,7 +781,7 @@ impl TraitAliasPart { for component in &remote_path[..remote_path.len() - 1] { path.push(component.as_str()); } - path.push(&format!("{remote_item_type}.{}.js", remote_path[remote_path.len() - 1])); + path.push(format!("{remote_item_type}.{}.js", remote_path[remote_path.len() - 1])); let part = OrderedJson::array_sorted( implementors @@ -865,7 +865,7 @@ struct AliasedTypeImpl<'cache, 'item> { type_aliases: Vec<(&'cache [Symbol], &'item Item)>, } -impl<'cx, 'cache, 'item> DocVisitor<'item> for TypeImplCollector<'cx, 'cache, 'item> { +impl<'item> DocVisitor<'item> for TypeImplCollector<'_, '_, 'item> { fn visit_item(&mut self, it: &'item Item) { self.visit_item_recur(it); let cache = self.cache; @@ -963,15 +963,13 @@ fn get_path_parts( crates_info: &[CrateInfo], ) -> FxIndexMap> { let mut templates: FxIndexMap> = FxIndexMap::default(); - crates_info - .iter() - .map(|crate_info| T::from_crate_info(crate_info).parts.iter()) - .flatten() - .for_each(|(path, part)| { - let path = dst.join(&path); + crates_info.iter().flat_map(|crate_info| T::from_crate_info(crate_info).parts.iter()).for_each( + |(path, part)| { + let path = dst.join(path); let part = part.to_string(); templates.entry(path).or_default().push(part); - }); + }, + ); templates } @@ -994,10 +992,10 @@ where if !should_merge.read_rendered_cci { return Ok(make_blank()); } - match fs::read_to_string(&path) { + match fs::read_to_string(path) { Ok(template) => Ok(try_err!(SortedTemplate::from_str(&template), &path)), Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(make_blank()), - Err(e) => Err(Error::new(e, &path)), + Err(e) => Err(Error::new(e, path)), } } diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index f4a0ef01c253b..2fe9364c259c3 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -35,8 +35,8 @@ pub(crate) fn render(cx: &mut Context<'_>, krate: &clean::Crate) -> Result<(), E Ok(()) } -pub(crate) fn collect_local_sources<'tcx>( - tcx: TyCtxt<'tcx>, +pub(crate) fn collect_local_sources( + tcx: TyCtxt<'_>, src_root: &Path, krate: &clean::Crate, ) -> FxIndexMap { @@ -80,7 +80,7 @@ impl LocalSourcesCollector<'_, '_> { let href = RefCell::new(PathBuf::new()); clean_path( - &self.src_root, + self.src_root, &p, |component| { href.borrow_mut().push(component); diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 66a8a19892886..90aa5904dafe8 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -36,6 +36,8 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ --button-border-radius: 2px; --toolbar-button-border-radius: 6px; --code-block-border-radius: 6px; + --impl-items-indent: 0.3em; + --docblock-indent: 24px; } /* See FiraSans-LICENSE.txt for the Fira Sans license. */ @@ -909,7 +911,7 @@ both the code example and the line numbers, so we need to remove the radius in t .docblock h6 { font-size: 0.875rem; } .docblock { - margin-left: 24px; + margin-left: var(--docblock-indent); position: relative; } @@ -982,7 +984,11 @@ div.where { .item-info { display: block; - margin-left: 24px; + margin-left: var(--docblock-indent); +} +.impl-items > .item-info { + /* Margin of docblocks + margin of impl block items. */ + margin-left: calc(var(--docblock-indent) + var(--impl-items-indent)); } .item-info code { @@ -2166,6 +2172,15 @@ details.toggle > summary:not(.hideme)::before { left: -24px; } +/* We indent items of an impl block to have a visual marker that these items are part + of this impl block. */ +.impl-items > *:not(.item-info), +/* We also indent the first top doc comment the same to still keep an indent on the + doc block while aligning it with the impl block items. */ +.implementors-toggle > .docblock { + margin-left: var(--impl-items-indent); +} + details.big-toggle > summary:not(.hideme)::before { left: -34px; top: 9px; @@ -2255,6 +2270,10 @@ If you update this line, then you also need to update the line with the same war in src-script.js and main.js */ @media (max-width: 700px) { + :root { + --impl-items-indent: 0.7em; + } + /* When linking to an item with an `id` (for instance, by clicking a link in the sidebar, or visiting a URL with a fragment like `#method.new`, we don't want the item to be obscured by the topbar. Anything with an `id` gets scroll-margin-top equal to .mobile-topbar's size. @@ -2454,19 +2473,20 @@ in src-script.js and main.js padding-top: 0; } - /* Position of the "[-]" element. */ - details.toggle:not(.top-doc) > summary, .impl-items > section { + details.implementors-toggle:not(.top-doc) > summary { margin-left: 10px; } - .impl-items > details.toggle > summary:not(.hideme)::before, - #main-content > details.toggle:not(.top-doc) > summary::before, - #main-content > div > details.toggle > summary::before { - left: -11px; + + .impl-items > details.toggle > summary:not(.hideme)::before { + left: -20px; } /* Align summary-nested and unnested item-info gizmos. */ + summary > .item-info { + margin-left: 10px; + } .impl-items > .item-info { - margin-left: 34px; + margin-left: calc(var(--impl-items-indent) + 10px); } .src nav.sub { @@ -2500,24 +2520,24 @@ in src-script.js and main.js } @media print { + :root { + --docblock-indent: 0; + } + nav.sidebar, nav.sub, .out-of-band, a.src, #copy-path, details.toggle[open] > summary::before, details.toggle > summary::before, details.toggle.top-doc > summary { display: none; } - .docblock { - margin-left: 0; - } - main { padding: 10px; } } @media (max-width: 464px) { - .docblock { - margin-left: 12px; + :root { + --docblock-indent: 12px; } .docblock code { diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index a4dc8cd1ed912..6457ac731cb76 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -57,7 +57,7 @@ pub(crate) fn suffix_path(filename: &str, suffix: &str) -> PathBuf { pub(crate) fn static_filename(filename: &str, sha256: &str) -> PathBuf { let filename = filename.rsplit('/').next().unwrap(); - suffix_path(filename, &sha256) + suffix_path(filename, sha256) } macro_rules! static_files { diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index df97c5ea2634a..560ed872ef3af 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -73,7 +73,7 @@ impl<'tcx> JsonRenderer<'tcx> { .map(|i| { let item = &i.impl_item; self.item(item.clone()).unwrap(); - self.id_from_item(&item) + self.id_from_item(item) }) .collect() }) @@ -104,7 +104,7 @@ impl<'tcx> JsonRenderer<'tcx> { if item.item_id.is_local() || is_primitive_impl { self.item(item.clone()).unwrap(); - Some(self.id_from_item(&item)) + Some(self.id_from_item(item)) } else { None } @@ -223,7 +223,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { | types::ItemEnum::Macro(_) | types::ItemEnum::ProcMacro(_) => false, }; - let removed = self.index.borrow_mut().insert(new_item.id.clone(), new_item.clone()); + let removed = self.index.borrow_mut().insert(new_item.id, new_item.clone()); // FIXME(adotinthevoid): Currently, the index is duplicated. This is a sanity check // to make sure the items are unique. The main place this happens is when an item, is @@ -289,7 +289,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { format_version: types::FORMAT_VERSION, }; if let Some(ref out_dir) = self.out_dir { - try_err!(create_dir_all(&out_dir), out_dir); + try_err!(create_dir_all(out_dir), out_dir); let mut p = out_dir.clone(); p.push(output_crate.index.get(&output_crate.root).unwrap().name.clone().unwrap()); diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs index 2afb9e549d902..dcc27cd62e389 100644 --- a/src/librustdoc/lint.rs +++ b/src/librustdoc/lint.rs @@ -222,7 +222,7 @@ pub(crate) static RUSTDOC_LINTS: Lazy> = Lazy::new(|| { }); pub(crate) fn register_lints(_sess: &Session, lint_store: &mut LintStore) { - lint_store.register_lints(&**RUSTDOC_LINTS); + lint_store.register_lints(&RUSTDOC_LINTS); lint_store.register_group( true, "rustdoc::all", diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 9f9a093da8a38..135aa79906010 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -118,7 +118,7 @@ fn limit_filename_len(filename: String) -> String { } } -impl<'a, 'b> CoverageCalculator<'a, 'b> { +impl CoverageCalculator<'_, '_> { fn to_json(&self) -> String { serde_json::to_string( &self @@ -188,7 +188,7 @@ impl<'a, 'b> CoverageCalculator<'a, 'b> { } } -impl<'a, 'b> DocVisitor<'_> for CoverageCalculator<'a, 'b> { +impl DocVisitor<'_> for CoverageCalculator<'_, '_> { fn visit_item(&mut self, i: &clean::Item) { if !i.item_id.is_local() { // non-local items are skipped because they can be out of the users control, diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 484bdb5627c37..bf851b278b82a 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -34,7 +34,7 @@ pub(crate) fn check_doc_test_visibility(krate: Crate, cx: &mut DocContext<'_>) - krate } -impl<'a, 'tcx> DocVisitor<'_> for DocTestVisibilityLinter<'a, 'tcx> { +impl DocVisitor<'_> for DocTestVisibilityLinter<'_, '_> { fn visit_item(&mut self, item: &Item) { look_for_tests(self.cx, &item.doc_value(), item); @@ -106,7 +106,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - level != lint::Level::Allow || matches!(source, LintLevelSource::Default) } -pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { +pub(crate) fn look_for_tests(cx: &DocContext<'_>, dox: &str, item: &Item) { let Some(hir_id) = DocContext::as_local_hir_id(cx.tcx, item.item_id) else { // If non-local, no need to check anything. return; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 140fda7091885..c9d1ceb0a91a9 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -53,12 +53,12 @@ pub(crate) fn collect_intra_doc_links<'a, 'tcx>( (krate, collector) } -fn filter_assoc_items_by_name_and_namespace<'a>( - tcx: TyCtxt<'a>, +fn filter_assoc_items_by_name_and_namespace( + tcx: TyCtxt<'_>, assoc_items_of: DefId, ident: Ident, ns: Namespace, -) -> impl Iterator + 'a { +) -> impl Iterator + '_ { tcx.associated_items(assoc_items_of).filter_by_name_unhygienic(ident.name).filter(move |item| { item.kind.namespace() == ns && tcx.hygienic_eq(ident, item.ident(tcx), assoc_items_of) }) @@ -232,7 +232,7 @@ impl UrlFragment { s.push_str(kind); s.push_str(tcx.item_name(def_id).as_str()); } - UrlFragment::UserWritten(raw) => s.push_str(&raw), + UrlFragment::UserWritten(raw) => s.push_str(raw), } } } @@ -307,7 +307,7 @@ pub(crate) struct AmbiguousLinks { resolved: Vec<(Res, Option)>, } -impl<'a, 'tcx> LinkCollector<'a, 'tcx> { +impl<'tcx> LinkCollector<'_, 'tcx> { /// Given a full link, parse it as an [enum struct variant]. /// /// In particular, this will return an error whenever there aren't three @@ -339,7 +339,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // If there's no third component, we saw `[a::b]` before and it failed to resolve. // So there's no partial res. let path = split.next().ok_or_else(no_res)?; - let ty_res = self.resolve_path(&path, TypeNS, item_id, module_id).ok_or_else(no_res)?; + let ty_res = self.resolve_path(path, TypeNS, item_id, module_id).ok_or_else(no_res)?; match ty_res { Res::Def(DefKind::Enum, did) => match tcx.type_of(did).instantiate_identity().kind() { @@ -628,7 +628,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { .map(|item| (root_res, item.def_id)) .collect::>() }) - .unwrap_or(Vec::new()) + .unwrap_or_default() } } Res::Def(DefKind::TyAlias, did) => { @@ -693,7 +693,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // Checks if item_name belongs to `impl SomeItem` let mut assoc_items: Vec<_> = tcx .inherent_impls(did) - .into_iter() + .iter() .flat_map(|&imp| { filter_assoc_items_by_name_and_namespace( tcx, @@ -878,7 +878,7 @@ fn is_derive_trait_collision(ns: &PerNS, ResolutionFailu } } -impl<'a, 'tcx> DocVisitor<'_> for LinkCollector<'a, 'tcx> { +impl DocVisitor<'_> for LinkCollector<'_, '_> { fn visit_item(&mut self, item: &Item) { self.resolve_links(item); self.visit_item_recur(item) @@ -1152,7 +1152,7 @@ impl LinkCollector<'_, '_> { } cache.paths.get(&did).is_some() - || cache.external_paths.get(&did).is_some() + || cache.external_paths.contains_key(&did) || !did.is_local() } @@ -1271,7 +1271,7 @@ impl LinkCollector<'_, '_> { } res.def_id(self.cx.tcx).map(|page_id| ItemLink { - link: Box::::from(&*diag_info.ori_link), + link: Box::::from(diag_info.ori_link), link_text: link_text.clone(), page_id, fragment, @@ -1293,7 +1293,7 @@ impl LinkCollector<'_, '_> { let page_id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id)); Some(ItemLink { - link: Box::::from(&*diag_info.ori_link), + link: Box::::from(diag_info.ori_link), link_text: link_text.clone(), page_id, fragment, @@ -1387,7 +1387,7 @@ impl LinkCollector<'_, '_> { ) .unwrap_or_else(|| item.attr_span(self.cx.tcx)); rustc_session::parse::feature_err( - &self.cx.tcx.sess, + self.cx.tcx.sess, sym::intra_doc_pointers, span, "linking to associated items of raw pointers is experimental", @@ -1414,7 +1414,7 @@ impl LinkCollector<'_, '_> { // FIXME: it would be nice to check that the feature gate was enabled in the original crate, not just ignore it altogether. // However I'm not sure how to check that across crates. - if let Some(candidate) = candidates.get(0) + if let Some(candidate) = candidates.first() && candidate.0 == Res::Primitive(PrimitiveType::RawPointer) && key.path_str.contains("::") // We only want to check this if this is an associated item. @@ -1493,7 +1493,7 @@ impl LinkCollector<'_, '_> { } } resolution_failure(self, diag, path_str, disambiguator, smallvec![err]); - return vec![]; + vec![] } } } @@ -1509,15 +1509,12 @@ impl LinkCollector<'_, '_> { type_ns: candidate(TypeNS), value_ns: candidate(ValueNS).and_then(|v_res| { for (res, _) in v_res.iter() { - match res { - // Constructors are picked up in the type namespace. - Res::Def(DefKind::Ctor(..), _) => { - return Err(ResolutionFailure::WrongNamespace { - res: *res, - expected_ns: TypeNS, - }); - } - _ => {} + // Constructors are picked up in the type namespace. + if let Res::Def(DefKind::Ctor(..), _) = res { + return Err(ResolutionFailure::WrongNamespace { + res: *res, + expected_ns: TypeNS, + }); } } Ok(v_res) @@ -1536,7 +1533,7 @@ impl LinkCollector<'_, '_> { disambiguator, candidates.into_iter().filter_map(|res| res.err()).collect(), ); - return vec![]; + vec![] } else if len == 1 { candidates.into_iter().filter_map(|res| res.ok()).flatten().collect::>() } else { @@ -1850,7 +1847,7 @@ fn report_diagnostic( (sp, MarkdownLinkRange::Destination(md_range)) } MarkdownLinkRange::WholeLink(md_range) => ( - source_span_for_markdown_range(tcx, dox, &md_range, &item.attrs.doc_strings), + source_span_for_markdown_range(tcx, dox, md_range, &item.attrs.doc_strings), link_range.clone(), ), }; @@ -1985,8 +1982,7 @@ fn resolution_failure( .tcx .resolutions(()) .all_macro_rules - .get(&Symbol::intern(path_str)) - .is_some() + .contains_key(&Symbol::intern(path_str)) { diag.note(format!( "`macro_rules` named `{path_str}` exists in this crate, \ diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index f358908032285..87f85c5731528 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -229,7 +229,7 @@ struct SyntheticImplCollector<'a, 'tcx> { impls: Vec, } -impl<'a, 'tcx> DocVisitor<'_> for SyntheticImplCollector<'a, 'tcx> { +impl DocVisitor<'_> for SyntheticImplCollector<'_, '_> { fn visit_item(&mut self, i: &Item) { if i.is_struct() || i.is_enum() || i.is_union() { // FIXME(eddyb) is this `doc(hidden)` check needed? @@ -256,7 +256,7 @@ impl<'cache> ItemAndAliasCollector<'cache> { } } -impl<'cache> DocVisitor<'_> for ItemAndAliasCollector<'cache> { +impl DocVisitor<'_> for ItemAndAliasCollector<'_> { fn visit_item(&mut self, i: &Item) { self.items.insert(i.item_id); @@ -276,7 +276,7 @@ struct BadImplStripper<'a> { cache: &'a Cache, } -impl<'a> BadImplStripper<'a> { +impl BadImplStripper<'_> { fn keep_impl(&self, ty: &Type, is_deref: bool) -> bool { if let Generic(_) = ty { // keep impls made on generics diff --git a/src/librustdoc/passes/lint.rs b/src/librustdoc/passes/lint.rs index 35b62370abb29..1ecb53e61ac39 100644 --- a/src/librustdoc/passes/lint.rs +++ b/src/librustdoc/passes/lint.rs @@ -25,7 +25,7 @@ pub(crate) fn run_lints(krate: Crate, cx: &mut DocContext<'_>) -> Crate { krate } -impl<'a, 'tcx> DocVisitor<'_> for Linter<'a, 'tcx> { +impl DocVisitor<'_> for Linter<'_, '_> { fn visit_item(&mut self, item: &Item) { let Some(hir_id) = DocContext::as_local_hir_id(self.cx.tcx, item.item_id) else { // If non-local, no need to check anything. @@ -34,7 +34,7 @@ impl<'a, 'tcx> DocVisitor<'_> for Linter<'a, 'tcx> { let dox = item.doc_value(); if !dox.is_empty() { let may_have_link = dox.contains(&[':', '['][..]); - let may_have_block_comment_or_html = dox.contains(&['<', '>']); + let may_have_block_comment_or_html = dox.contains(['<', '>']); // ~~~rust // // This is a real, supported commonmark syntax for block code // ~~~ diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs index 1397eadb2884c..77d7cf5772d67 100644 --- a/src/librustdoc/passes/lint/bare_urls.rs +++ b/src/librustdoc/passes/lint/bare_urls.rs @@ -18,7 +18,7 @@ use crate::html::markdown::main_body_opts; pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &str) { let report_diag = |cx: &DocContext<'_>, msg: &'static str, range: Range| { - let sp = source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs.doc_strings) + let sp = source_span_for_markdown_range(cx.tcx, dox, &range, &item.attrs.doc_strings) .unwrap_or_else(|| item.attr_span(cx.tcx)); cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| { lint.primary_message(msg) @@ -34,14 +34,14 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & }); }; - let mut p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter(); + let mut p = Parser::new_ext(dox, main_body_opts()).into_offset_iter(); while let Some((event, range)) = p.next() { match event { Event::Text(s) => find_raw_urls(cx, &s, range, &report_diag), // We don't want to check the text inside code blocks or links. Event::Start(tag @ (Tag::CodeBlock(_) | Tag::Link { .. })) => { - while let Some((event, _)) = p.next() { + for (event, _) in p.by_ref() { match event { Event::End(end) if mem::discriminant(&end) == mem::discriminant(&tag.to_end()) => diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index e0dc5b4c51333..20d65d8cd9f02 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -150,7 +150,7 @@ impl Translate for BufferEmitter { } fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle { - &**self.fallback_bundle + &self.fallback_bundle } } diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs index 223174838ade0..3fb154dc51549 100644 --- a/src/librustdoc/passes/lint/html_tags.rs +++ b/src/librustdoc/passes/lint/html_tags.rs @@ -15,7 +15,7 @@ use crate::html::markdown::main_body_opts; pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &str) { let tcx = cx.tcx; let report_diag = |msg: String, range: &Range, is_open_tag: bool| { - let sp = match source_span_for_markdown_range(tcx, &dox, range, &item.attrs.doc_strings) { + let sp = match source_span_for_markdown_range(tcx, dox, range, &item.attrs.doc_strings) { Some(sp) => sp, None => item.attr_span(tcx), }; @@ -30,7 +30,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & let mut generics_end = range.end; if let Some(Some(mut generics_start)) = (is_open_tag && dox[..generics_end].ends_with('>')) - .then(|| extract_path_backwards(&dox, range.start)) + .then(|| extract_path_backwards(dox, range.start)) { while generics_start != 0 && generics_end < dox.len() @@ -39,19 +39,19 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & { generics_end += 1; generics_start -= 1; - if let Some(new_start) = extract_path_backwards(&dox, generics_start) { + if let Some(new_start) = extract_path_backwards(dox, generics_start) { generics_start = new_start; } - if let Some(new_end) = extract_path_forward(&dox, generics_end) { + if let Some(new_end) = extract_path_forward(dox, generics_end) { generics_end = new_end; } } - if let Some(new_end) = extract_path_forward(&dox, generics_end) { + if let Some(new_end) = extract_path_forward(dox, generics_end) { generics_end = new_end; } let generics_sp = match source_span_for_markdown_range( tcx, - &dox, + dox, &(generics_start..generics_end), &item.attrs.doc_strings, ) { @@ -125,7 +125,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & } }; - let p = Parser::new_with_broken_link_callback(&dox, main_body_opts(), Some(&mut replacer)) + let p = Parser::new_with_broken_link_callback(dox, main_body_opts(), Some(&mut replacer)) .into_offset_iter(); for (event, range) in p { @@ -233,7 +233,7 @@ fn extract_path_forward(text: &str, start_pos: usize) -> Option { break; } } - while let Some(c) = chars.next() { + for c in chars { if is_id_continue(c) { current_pos += c.len_utf8(); } else { diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index f3599688454b2..6bc4374c06b1d 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -35,12 +35,12 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId) { } } -fn check_redundant_explicit_link_for_did<'md>( +fn check_redundant_explicit_link_for_did( cx: &DocContext<'_>, item: &Item, did: DefId, hir_id: HirId, - doc: &'md str, + doc: &str, ) { let Some(local_item_id) = did.as_local() else { return; @@ -71,7 +71,7 @@ fn check_redundant_explicit_link_for_did<'md>( return; }; - check_redundant_explicit_link(cx, item, hir_id, &doc, &resolutions); + check_redundant_explicit_link(cx, item, hir_id, doc, resolutions); } fn check_redundant_explicit_link<'md>( @@ -90,60 +90,52 @@ fn check_redundant_explicit_link<'md>( .into_offset_iter(); while let Some((event, link_range)) = offset_iter.next() { - match event { - Event::Start(Tag::Link { link_type, dest_url, .. }) => { - let link_data = collect_link_data(&mut offset_iter); - - if let Some(resolvable_link) = link_data.resolvable_link.as_ref() { - if &link_data.display_link.replace('`', "") != resolvable_link { - // Skips if display link does not match to actual - // resolvable link, usually happens if display link - // has several segments, e.g. - // [this is just an `Option`](Option) - continue; - } + if let Event::Start(Tag::Link { link_type, dest_url, .. }) = event { + let link_data = collect_link_data(&mut offset_iter); + + if let Some(resolvable_link) = link_data.resolvable_link.as_ref() { + if &link_data.display_link.replace('`', "") != resolvable_link { + // Skips if display link does not match to actual + // resolvable link, usually happens if display link + // has several segments, e.g. + // [this is just an `Option`](Option) + continue; } + } - let explicit_link = dest_url.to_string(); - let display_link = link_data.resolvable_link.clone()?; - - if explicit_link.ends_with(&display_link) || display_link.ends_with(&explicit_link) - { - match link_type { - LinkType::Inline | LinkType::ReferenceUnknown => { - check_inline_or_reference_unknown_redundancy( - cx, - item, - hir_id, - doc, - resolutions, - link_range, - dest_url.to_string(), - link_data, - if link_type == LinkType::Inline { - (b'(', b')') - } else { - (b'[', b']') - }, - ); - } - LinkType::Reference => { - check_reference_redundancy( - cx, - item, - hir_id, - doc, - resolutions, - link_range, - &dest_url, - link_data, - ); - } - _ => {} + let explicit_link = dest_url.to_string(); + let display_link = link_data.resolvable_link.clone()?; + + if explicit_link.ends_with(&display_link) || display_link.ends_with(&explicit_link) { + match link_type { + LinkType::Inline | LinkType::ReferenceUnknown => { + check_inline_or_reference_unknown_redundancy( + cx, + item, + hir_id, + doc, + resolutions, + link_range, + dest_url.to_string(), + link_data, + if link_type == LinkType::Inline { (b'(', b')') } else { (b'[', b']') }, + ); + } + LinkType::Reference => { + check_reference_redundancy( + cx, + item, + hir_id, + doc, + resolutions, + link_range, + &dest_url, + link_data, + ); } + _ => {} } } - _ => {} } } @@ -169,18 +161,18 @@ fn check_inline_or_reference_unknown_redundancy( if dest_res == display_res { let link_span = - source_span_for_markdown_range(cx.tcx, &doc, &link_range, &item.attrs.doc_strings) + source_span_for_markdown_range(cx.tcx, doc, &link_range, &item.attrs.doc_strings) .unwrap_or(item.attr_span(cx.tcx)); let explicit_span = source_span_for_markdown_range( cx.tcx, - &doc, + doc, &offset_explicit_range(doc, link_range, open, close), &item.attrs.doc_strings, )?; let display_span = source_span_for_markdown_range( cx.tcx, - &doc, - &resolvable_link_range, + doc, + resolvable_link_range, &item.attrs.doc_strings, )?; @@ -210,27 +202,27 @@ fn check_reference_redundancy( let (resolvable_link, resolvable_link_range) = (&link_data.resolvable_link?, &link_data.resolvable_link_range?); let (dest_res, display_res) = - (find_resolution(resolutions, &dest)?, find_resolution(resolutions, resolvable_link)?); + (find_resolution(resolutions, dest)?, find_resolution(resolutions, resolvable_link)?); if dest_res == display_res { let link_span = - source_span_for_markdown_range(cx.tcx, &doc, &link_range, &item.attrs.doc_strings) + source_span_for_markdown_range(cx.tcx, doc, &link_range, &item.attrs.doc_strings) .unwrap_or(item.attr_span(cx.tcx)); let explicit_span = source_span_for_markdown_range( cx.tcx, - &doc, + doc, &offset_explicit_range(doc, link_range.clone(), b'[', b']'), &item.attrs.doc_strings, )?; let display_span = source_span_for_markdown_range( cx.tcx, - &doc, - &resolvable_link_range, + doc, + resolvable_link_range, &item.attrs.doc_strings, )?; let def_span = source_span_for_markdown_range( cx.tcx, - &doc, + doc, &offset_reference_def_range(doc, dest, link_range), &item.attrs.doc_strings, )?; @@ -263,7 +255,7 @@ fn collect_link_data<'input, F: BrokenLinkCallback<'input>>( let mut display_link = String::new(); let mut is_resolvable = true; - while let Some((event, range)) = offset_iter.next() { + for (event, range) in offset_iter.by_ref() { match event { Event::Text(code) => { let code = code.to_string(); diff --git a/src/librustdoc/passes/lint/unescaped_backticks.rs b/src/librustdoc/passes/lint/unescaped_backticks.rs index d79f682a580f8..88f4c3ac1cd79 100644 --- a/src/librustdoc/passes/lint/unescaped_backticks.rs +++ b/src/librustdoc/passes/lint/unescaped_backticks.rs @@ -22,7 +22,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & .find(|link| *link.original_text == *broken_link.reference) .map(|link| ((*link.href).into(), (*link.new_text).into())) }; - let parser = Parser::new_with_broken_link_callback(&dox, main_body_opts(), Some(&mut replacer)) + let parser = Parser::new_with_broken_link_callback(dox, main_body_opts(), Some(&mut replacer)) .into_offset_iter(); let mut element_stack = Vec::new(); @@ -44,7 +44,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & // use the span of the entire attribute as a fallback. let span = source_span_for_markdown_range( tcx, - &dox, + dox, &(backtick_index..backtick_index + 1), &item.attrs.doc_strings, ) @@ -61,12 +61,12 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & // "foo` `bar`" -> "`foo` `bar`" if let Some(suggest_index) = clamp_start(guess, &element.suggestible_ranges) - && can_suggest_backtick(&dox, suggest_index) + && can_suggest_backtick(dox, suggest_index) { suggest_insertion( cx, item, - &dox, + dox, lint, suggest_index, '`', @@ -80,11 +80,11 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & // Don't `clamp_end` here, because the suggestion is guaranteed to be inside // an inline code node and we intentionally "break" the inline code here. let suggest_index = guess; - if can_suggest_backtick(&dox, suggest_index) { + if can_suggest_backtick(dox, suggest_index) { suggest_insertion( cx, item, - &dox, + dox, lint, suggest_index, '`', @@ -98,15 +98,15 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & if !element.prev_code_guess.is_confident() { // "`foo` bar`" -> "`foo` `bar`" if let Some(guess) = - guess_start_of_code(&dox, element.element_range.start..backtick_index) + guess_start_of_code(dox, element.element_range.start..backtick_index) && let Some(suggest_index) = clamp_start(guess, &element.suggestible_ranges) - && can_suggest_backtick(&dox, suggest_index) + && can_suggest_backtick(dox, suggest_index) { suggest_insertion( cx, item, - &dox, + dox, lint, suggest_index, '`', @@ -120,16 +120,16 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & // if we already suggested opening backtick. For example: // "foo`." -> "`foo`." or "foo`s" -> "`foo`s". if let Some(guess) = - guess_end_of_code(&dox, backtick_index + 1..element.element_range.end) + guess_end_of_code(dox, backtick_index + 1..element.element_range.end) && let Some(suggest_index) = clamp_end(guess, &element.suggestible_ranges) - && can_suggest_backtick(&dox, suggest_index) + && can_suggest_backtick(dox, suggest_index) && (!help_emitted || suggest_index - backtick_index > 2) { suggest_insertion( cx, item, - &dox, + dox, lint, suggest_index, '`', @@ -148,7 +148,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & suggest_insertion( cx, item, - &dox, + dox, lint, backtick_index, '\\', @@ -177,13 +177,13 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & let is_confident = text_inside.starts_with(char::is_whitespace) || text_inside.ends_with(char::is_whitespace); - if let Some(guess) = guess_end_of_code(&dox, range_inside) { + if let Some(guess) = guess_end_of_code(dox, range_inside) { // Find earlier end of code. element.prev_code_guess = PrevCodeGuess::End { guess, is_confident }; } else { // Find alternate start of code. let range_before = element.element_range.start..event_range.start; - if let Some(guess) = guess_start_of_code(&dox, range_before) { + if let Some(guess) = guess_start_of_code(dox, range_before) { element.prev_code_guess = PrevCodeGuess::Start { guess, is_confident }; } } @@ -421,7 +421,7 @@ fn suggest_insertion( if let Some(span) = source_span_for_markdown_range( cx.tcx, - &dox, + dox, &(insert_index..insert_index), &item.attrs.doc_strings, ) { diff --git a/src/librustdoc/passes/lint/unportable_markdown.rs b/src/librustdoc/passes/lint/unportable_markdown.rs index f8368a866c882..a3c3134f4c2c5 100644 --- a/src/librustdoc/passes/lint/unportable_markdown.rs +++ b/src/librustdoc/passes/lint/unportable_markdown.rs @@ -49,8 +49,8 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & | cmarkn::Options::ENABLE_TASKLISTS | cmarkn::Options::ENABLE_SMART_PUNCTUATION } - let mut parser_new = cmarkn::Parser::new_ext(&dox, main_body_opts_new()).into_offset_iter(); - while let Some((event, span)) = parser_new.next() { + let parser_new = cmarkn::Parser::new_ext(dox, main_body_opts_new()).into_offset_iter(); + for (event, span) in parser_new { if let cmarkn::Event::Start(cmarkn::Tag::BlockQuote(_)) = event { if !dox[span.clone()].starts_with("> ") { spaceless_block_quotes.insert(span.start); @@ -71,8 +71,8 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & | cmarko::Options::ENABLE_TASKLISTS | cmarko::Options::ENABLE_SMART_PUNCTUATION } - let mut parser_old = cmarko::Parser::new_ext(&dox, main_body_opts_old()).into_offset_iter(); - while let Some((event, span)) = parser_old.next() { + let parser_old = cmarko::Parser::new_ext(dox, main_body_opts_old()).into_offset_iter(); + for (event, span) in parser_old { if let cmarko::Event::Start(cmarko::Tag::BlockQuote) = event { if !dox[span.clone()].starts_with("> ") { spaceless_block_quotes.remove(&span.start); @@ -88,13 +88,13 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & for start in spaceless_block_quotes { let (span, precise) = - source_span_for_markdown_range(tcx, &dox, &(start..start + 1), &item.attrs.doc_strings) + source_span_for_markdown_range(tcx, dox, &(start..start + 1), &item.attrs.doc_strings) .map(|span| (span, true)) .unwrap_or_else(|| (item.attr_span(tcx), false)); tcx.node_span_lint(crate::lint::UNPORTABLE_MARKDOWN, hir_id, span, |lint| { lint.primary_message("unportable markdown"); - lint.help(format!("confusing block quote with no space after the `>` marker")); + lint.help("confusing block quote with no space after the `>` marker".to_string()); if precise { lint.span_suggestion( span.shrink_to_hi(), @@ -113,7 +113,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & } for (_caret, span) in missing_footnote_references { let (ref_span, precise) = - source_span_for_markdown_range(tcx, &dox, &span, &item.attrs.doc_strings) + source_span_for_markdown_range(tcx, dox, &span, &item.attrs.doc_strings) .map(|span| (span, true)) .unwrap_or_else(|| (item.attr_span(tcx), false)); diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index 350be37f553da..572c9bf7552fa 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -27,7 +27,7 @@ struct CfgPropagator<'a, 'tcx> { cx: &'a mut DocContext<'tcx>, } -impl<'a, 'tcx> CfgPropagator<'a, 'tcx> { +impl CfgPropagator<'_, '_> { // Some items need to merge their attributes with their parents' otherwise a few of them // (mostly `cfg` ones) will be missing. fn merge_with_parent_attributes(&mut self, item: &mut Item) { @@ -65,7 +65,7 @@ impl<'a, 'tcx> CfgPropagator<'a, 'tcx> { } } -impl<'a, 'tcx> DocFolder for CfgPropagator<'a, 'tcx> { +impl DocFolder for CfgPropagator<'_, '_> { fn fold_item(&mut self, mut item: Item) -> Option { let old_parent_cfg = self.parent_cfg.clone(); diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index a28487cc79e5d..a81b130a218b3 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -30,7 +30,7 @@ struct StabilityPropagator<'a, 'tcx> { cx: &'a mut DocContext<'tcx>, } -impl<'a, 'tcx> DocFolder for StabilityPropagator<'a, 'tcx> { +impl DocFolder for StabilityPropagator<'_, '_> { fn fold_item(&mut self, mut item: Item) -> Option { let parent_stability = self.parent_stability; diff --git a/src/librustdoc/passes/strip_aliased_non_local.rs b/src/librustdoc/passes/strip_aliased_non_local.rs index a078eec048ece..fa7737bc14386 100644 --- a/src/librustdoc/passes/strip_aliased_non_local.rs +++ b/src/librustdoc/passes/strip_aliased_non_local.rs @@ -21,7 +21,7 @@ struct AliasedNonLocalStripper<'tcx> { tcx: TyCtxt<'tcx>, } -impl<'tcx> DocFolder for AliasedNonLocalStripper<'tcx> { +impl DocFolder for AliasedNonLocalStripper<'_> { fn fold_item(&mut self, i: Item) -> Option { Some(match i.kind { clean::TypeAliasItem(..) => { @@ -39,7 +39,7 @@ struct NonLocalStripper<'tcx> { tcx: TyCtxt<'tcx>, } -impl<'tcx> DocFolder for NonLocalStripper<'tcx> { +impl DocFolder for NonLocalStripper<'_> { fn fold_item(&mut self, i: Item) -> Option { // If not local, we want to respect the original visibility of // the field and not the one given by the user for the currrent crate. @@ -50,7 +50,7 @@ impl<'tcx> DocFolder for NonLocalStripper<'tcx> { { if i.is_doc_hidden() // Default to *not* stripping items with inherited visibility. - || i.visibility(self.tcx).map_or(false, |viz| viz != Visibility::Public) + || i.visibility(self.tcx).is_some_and(|viz| viz != Visibility::Public) { return Some(strip_item(i)); } diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 4ef5f7f20a917..a71bb62e56c74 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -57,7 +57,7 @@ struct Stripper<'a, 'tcx> { last_reexport: Option, } -impl<'a, 'tcx> Stripper<'a, 'tcx> { +impl Stripper<'_, '_> { fn set_last_reexport_then_fold_item(&mut self, i: Item) -> Item { let prev_from_reexport = self.last_reexport; if i.inline_stmt_id.is_some() { @@ -86,7 +86,7 @@ impl<'a, 'tcx> Stripper<'a, 'tcx> { } } -impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> { +impl DocFolder for Stripper<'_, '_> { fn fold_item(&mut self, i: Item) -> Option { let has_doc_hidden = i.is_doc_hidden(); let is_impl_or_exported_macro = match i.kind { diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 98b3446c26d23..60909754b3330 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -37,7 +37,7 @@ fn is_item_reachable( } } -impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> { +impl DocFolder for Stripper<'_, '_> { fn fold_item(&mut self, i: Item) -> Option { match i.kind { clean::StrippedItem(..) => { @@ -171,7 +171,7 @@ pub(crate) struct ImplStripper<'a, 'tcx> { pub(crate) document_hidden: bool, } -impl<'a> ImplStripper<'a, '_> { +impl ImplStripper<'_, '_> { #[inline] fn should_keep_impl(&self, item: &Item, for_def_id: DefId) -> bool { if !for_def_id.is_local() || self.retained.contains(&for_def_id.into()) { @@ -193,7 +193,7 @@ impl<'a> ImplStripper<'a, '_> { } } -impl<'a> DocFolder for ImplStripper<'a, '_> { +impl DocFolder for ImplStripper<'_, '_> { fn fold_item(&mut self, i: Item) -> Option { if let clean::ImplItem(ref imp) = i.kind { // Impl blocks can be skipped if they are: empty; not a trait impl; and have no @@ -259,7 +259,7 @@ pub(crate) struct ImportStripper<'tcx> { pub(crate) document_hidden: bool, } -impl<'tcx> ImportStripper<'tcx> { +impl ImportStripper<'_> { fn import_should_be_hidden(&self, i: &Item, imp: &clean::Import) -> bool { if self.is_json_output { // FIXME: This should be handled the same way as for HTML output. @@ -270,11 +270,11 @@ impl<'tcx> ImportStripper<'tcx> { } } -impl<'tcx> DocFolder for ImportStripper<'tcx> { +impl DocFolder for ImportStripper<'_> { fn fold_item(&mut self, i: Item) -> Option { match &i.kind { clean::ImportItem(imp) - if !self.document_hidden && self.import_should_be_hidden(&i, &imp) => + if !self.document_hidden && self.import_should_be_hidden(&i, imp) => { None } diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs index 2c00bb7e13295..a49fb06bde35f 100644 --- a/src/librustdoc/theme.rs +++ b/src/librustdoc/theme.rs @@ -54,7 +54,7 @@ fn skip_comment(iter: &mut Peekable>) { /// Skips a line comment (`//`). fn skip_line_comment(iter: &mut Peekable>) { - while let Some(c) = iter.next() { + for c in iter.by_ref() { if c == '\n' { break; } diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs index bfa285c57fa93..c2e8ffd7665b8 100644 --- a/src/librustdoc/visit.rs +++ b/src/librustdoc/visit.rs @@ -55,7 +55,7 @@ pub(crate) trait DocVisitor<'a>: Sized { /// Don't override! fn visit_item_recur(&mut self, item: &'a Item) { match &item.kind { - StrippedItem(i) => self.visit_inner_recur(&*i), + StrippedItem(i) => self.visit_inner_recur(i), _ => self.visit_inner_recur(&item.kind), } } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 31c33fbf49737..11f06f7d917c5 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -312,7 +312,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(ref 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); @@ -476,7 +476,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self.add_to_current_mod(item, renamed, import_id); } } - hir::ItemKind::Macro(ref 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: @@ -496,7 +496,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self.add_to_current_mod(item, renamed, import_id); } } - hir::ItemKind::Mod(ref m) => { + hir::ItemKind::Mod(m) => { self.enter_mod(item.owner_id.def_id, m, name, renamed, import_id); } hir::ItemKind::Fn(..) @@ -560,7 +560,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // We need to implement this visitor so it'll go everywhere and retrieve items we're interested in // such as impl blocks in const blocks. -impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> { +impl<'tcx> Visitor<'tcx> for RustdocVisitor<'_, 'tcx> { type NestedFilter = nested_filter::All; fn nested_visit_map(&mut self) -> Self::Map { diff --git a/src/stage0 b/src/stage0 index 57a01edb6fdc7..23ee3304b4226 100644 --- a/src/stage0 +++ b/src/stage0 @@ -14,456 +14,456 @@ nightly_branch=master # All changes below this comment will be overridden the next time the # tool is executed. -compiler_date=2024-10-16 +compiler_date=2024-11-27 compiler_version=beta -rustfmt_date=2024-10-16 +rustfmt_date=2024-11-27 rustfmt_version=nightly -dist/2024-10-16/rustc-beta-aarch64-apple-darwin.tar.gz=24719797bf50fb494c61cf4711d6bb238ea9e789a1b10d957abb23f9849a06cd -dist/2024-10-16/rustc-beta-aarch64-apple-darwin.tar.xz=5eed456f0034e2b31ed4f6089163dd5e86ecb04630371e408aca741c32d845c5 -dist/2024-10-16/rustc-beta-aarch64-pc-windows-msvc.tar.gz=f337d992f4a730d39ae571d602f15d2c66ed0b6abf1b2c63112b570e855ac409 -dist/2024-10-16/rustc-beta-aarch64-pc-windows-msvc.tar.xz=d22b4f26ba8b82e32114311c1f0386d0126eecffa2accab8ca9ecd6a7aa38400 -dist/2024-10-16/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=047735b5c90fca9f26e5eca2a1d24dcac6fdddfddcb89c9d1e2f6d0af0199946 -dist/2024-10-16/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=c70bce1fa2a6e98577683d94473ca7046e8add65b85792e9887fee4edb8bdcb7 -dist/2024-10-16/rustc-beta-aarch64-unknown-linux-musl.tar.gz=4c75417b640557b35172ea384fa34a3e8da1960efdf4a40cf8d1fdbdd50ee997 -dist/2024-10-16/rustc-beta-aarch64-unknown-linux-musl.tar.xz=f7f5e67b831af5fdb28266fadd7cfd9f092c066f7e7322b058d6fb2bc7f6ff77 -dist/2024-10-16/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=5d94f4e51767b02ddcdafdcaba3404a3133d308fe98c7bf5145a41bde8146319 -dist/2024-10-16/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=49166b4eb2e18e009ebde1e4c133adcacc3d5257fbd63b07418642d5c841957a -dist/2024-10-16/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=9e51ecc782cf9738adafd70c055ed793ab895c9616619c525cb52d7412cdf884 -dist/2024-10-16/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=d60502f25273c2552997de281727b0f5914a2a97f32310f921ea714c5a1080d7 -dist/2024-10-16/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=5796a33eda8d7b47c8982d3a2e425728cf681043151a291fea107b3aca9ff1a7 -dist/2024-10-16/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=71fb2132822aa284cae878a76f9996092316942f84dc5a674fb8be17eb391cb0 -dist/2024-10-16/rustc-beta-i686-pc-windows-gnu.tar.gz=d089cdb87961d00e7dc51c767993342a2fa704756a94c421be7f195dfa6c5293 -dist/2024-10-16/rustc-beta-i686-pc-windows-gnu.tar.xz=42865105f308f7e0cf9af250b54086eaa20da8ef13e9cbf82380340a9db4ce90 -dist/2024-10-16/rustc-beta-i686-pc-windows-msvc.tar.gz=5753e00d74de3ceb1af0dc533496d7db6295d673eb05aea779734a519b5f789f -dist/2024-10-16/rustc-beta-i686-pc-windows-msvc.tar.xz=dff93d0c39e8653f01248f0db05123018c63c92a1d3861935b12ad1818b00864 -dist/2024-10-16/rustc-beta-i686-unknown-linux-gnu.tar.gz=4e2e06e503be7d15211dad18911ce951491d2596cef466ae8282af840184427c -dist/2024-10-16/rustc-beta-i686-unknown-linux-gnu.tar.xz=77d0d69f3e0c2b32bd1ccb73f12b5b770a1a720e7928859d454f42e611f77d67 -dist/2024-10-16/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=5faa3516ecfe77f8fb21ba80e78c21a1b039f5fffae508cceffd04c8c329f152 -dist/2024-10-16/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=8f086e53b3abffd7c947f5b0784f9977ed4559e654805bc3877ada99072d38e4 -dist/2024-10-16/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=2147f76d151c513aaef63cb2365bb2c9a8d0eb21a6b1c7c2ff535dab0882c46a -dist/2024-10-16/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=db2c17f1f3e0af9ad56982e1396a031df07939aa04c73795f541b16161fc3bdf -dist/2024-10-16/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=e5d3fabc7902695ccf85171dd16cfe772a480dce203004da0853170450e57b1c -dist/2024-10-16/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=db2f03a41470e60a0070b4d96590ae049c23d2c0f8c07a5778023a4ecf3e52eb -dist/2024-10-16/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=49610d2df0b6ece6b2afc583db707eed0a6a12ef99a8ba0a82f9acb7c1e15fca -dist/2024-10-16/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=801a92eebf0c068c88a48129b054c4ecea143f38468ff5d53e28fd00a0fad6de -dist/2024-10-16/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=db8a9c4bc9313627d5ad2ed2ebe91b6129958254a32862aec67edee10cdf9bca -dist/2024-10-16/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=fb2f2f2acb7516d98a6abf17e84e8b36beb7179c69776d69465f1c981466321d -dist/2024-10-16/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=87effe21c4b4333769fa7b4b0fc4bd43edaabc1c8ba33e75480cb4da0d59dae9 -dist/2024-10-16/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=71701db843d0974b4fc09afb65e3872faaaf66bfda258c9627576efe8f998f96 -dist/2024-10-16/rustc-beta-s390x-unknown-linux-gnu.tar.gz=6485ed4c99deffdde4eee34e46b8be2eeb65a3f8f4b4eb032a4ccd9c6f4e29e7 -dist/2024-10-16/rustc-beta-s390x-unknown-linux-gnu.tar.xz=e8ee8b61386d490c8e59e0c2ccb30fb7758ea0ff0b1448d5f946d9fc58496a11 -dist/2024-10-16/rustc-beta-x86_64-apple-darwin.tar.gz=23e36a4892e948a6dc231d15913562f1f95f798a62a38315a6b19244aaf78385 -dist/2024-10-16/rustc-beta-x86_64-apple-darwin.tar.xz=2db43b3b599eab832a13c784d3a1bc60c3222f5bfce8e112688e1478837b8c25 -dist/2024-10-16/rustc-beta-x86_64-pc-windows-gnu.tar.gz=099c529cc84219ae3ed9a33dbc5265c46a01c8cffb8989e66e367078bc981eec -dist/2024-10-16/rustc-beta-x86_64-pc-windows-gnu.tar.xz=efef4dd4a40d4f96d151293031783688c84b088a5f2cdde84d931bd44aee923a -dist/2024-10-16/rustc-beta-x86_64-pc-windows-msvc.tar.gz=28633202a502121e9369e93a8cc66bcb52b2cc959d7598f9bbb8e4c840381baa -dist/2024-10-16/rustc-beta-x86_64-pc-windows-msvc.tar.xz=c7b879d2e7d7c21eafc7b8e9f18f009d2d38f91a2eafa51d25d38e3b51e17ef3 -dist/2024-10-16/rustc-beta-x86_64-unknown-freebsd.tar.gz=69bdb56ac4f47fa614fa9e8be5218a492d31a423454c192ed5850f49357687e5 -dist/2024-10-16/rustc-beta-x86_64-unknown-freebsd.tar.xz=36c995c1dd55ab4501f250a77f27cce34330daa2a3e74129ce389aa23b4e3a05 -dist/2024-10-16/rustc-beta-x86_64-unknown-illumos.tar.gz=84bb641a5576ef0e93c7b5bae7417eae344f32271a0ebc31bb987d15316815a3 -dist/2024-10-16/rustc-beta-x86_64-unknown-illumos.tar.xz=a7311a345dddc9f8cf1eab6b3e82658fadb485bd755a115d4d6ffdfb42a5625e -dist/2024-10-16/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=9def7618829111d1014e21fb0bc10abc26459e59ce61fdac5fb3b63583f472c6 -dist/2024-10-16/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=97d124a65a7d7e5610901521b565ff031313685cc37a1caf89de58d952065c3c -dist/2024-10-16/rustc-beta-x86_64-unknown-linux-musl.tar.gz=101a440c383011cb4621825481582a81bfbad0ac03439542bd8d05ccb5aaf2c4 -dist/2024-10-16/rustc-beta-x86_64-unknown-linux-musl.tar.xz=4148b4311ce8e1cc5dae86d5f27e207496b85e5c23a53c7bc5b05ba18918f717 -dist/2024-10-16/rustc-beta-x86_64-unknown-netbsd.tar.gz=25c5c35f2acd37a7c72eb8dc546cb6e9f62b3e76e1569d188bbe2aa9b31ea3e1 -dist/2024-10-16/rustc-beta-x86_64-unknown-netbsd.tar.xz=9b84ce176d4015ed8f6946ef2d42f2f601cf419d1a6477f44bd6b7c7d27c95fc -dist/2024-10-16/rust-std-beta-aarch64-apple-darwin.tar.gz=ebdf49b8d4fab00c7fb4d396c54caf5cb234389b7353856734b960f908c3cff9 -dist/2024-10-16/rust-std-beta-aarch64-apple-darwin.tar.xz=4d0d5fbc235d8cc78e9997302c45916008e203ba7f02edcd061290fb9639ee8f -dist/2024-10-16/rust-std-beta-aarch64-apple-ios.tar.gz=6693f5a06df0ea5929df18b633ad6373d098db4454d0e1d35e4c19b6dd7fa4ed -dist/2024-10-16/rust-std-beta-aarch64-apple-ios.tar.xz=351a1a2a13316161edcf97238d868cf4b1b5216bdf28ca0aff5a1dba2a1258f4 -dist/2024-10-16/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=f0e13e1700a1cbc1489c0a5728ce6c0f5ba1432a75ca2c0c0573b9fcf130ae9b -dist/2024-10-16/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=825550e3a2afbe15130dcf7b702ea62b3b90f8a1e0b850cd6e9a5b5dd180e72d -dist/2024-10-16/rust-std-beta-aarch64-apple-ios-sim.tar.gz=f77a6c24301c5c7165de3bf51b5b6d45e7d37a82d00446d1abbe5a5c591ca616 -dist/2024-10-16/rust-std-beta-aarch64-apple-ios-sim.tar.xz=5a9507e0c06b252196203b01319355e4d246eddead60993262bd680b6a1d2315 -dist/2024-10-16/rust-std-beta-aarch64-linux-android.tar.gz=eca36ae4253e5f1b51c065631a650135b71797b452a7fbf6dfa17c49a01f71d9 -dist/2024-10-16/rust-std-beta-aarch64-linux-android.tar.xz=1da17cca8397bedda8b5403ddcc9f7686d7ad207daa7389a6cf80f922bac8140 -dist/2024-10-16/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=1a4eea434371a7d95b473410a42d8409995119c85954f94a75b8b0a69aa3095b -dist/2024-10-16/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=cea3d7d9568d2ed86ab11d28f5a02cf36210971b798c4d61e133357c24108f6f -dist/2024-10-16/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=355fa0988a68a1a331a2794a573cd065e6fbbe8b312e187dfff59f4f4245cc5f -dist/2024-10-16/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=c93347602b0133e0da072243ba9419c95179f9f548b6284612967d7b80a42144 -dist/2024-10-16/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=c4305667ed2a77764c729fe236491b239cea7c2605039c2bc28a926d21f343cc -dist/2024-10-16/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=02b6b621a1b3b91e25482400680cd38be806d7de541cf364d0ed181a92fdcbf5 -dist/2024-10-16/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=830e1b90ea156eee05b0c5fab514d82558e2473eb5f6bddfeafa51e7417315c2 -dist/2024-10-16/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=c5910437177f607439a6b18bd05b93c3965f915a0d372fb540deecf044b21880 -dist/2024-10-16/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=7a0f343b5fa50168a3edd0770dee148c82e43e7b2b82e2149ca22badeade3218 -dist/2024-10-16/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=dc4d7b3cb830451044726e72b848e529e92ec0330e610f06b07f8ed37415c3cd -dist/2024-10-16/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=8a9e341e6f208d5036e4c774f68b75802c64c53c4a9381ffd5a62e9b3c486cdd -dist/2024-10-16/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=fd24b56cc9891d9a1246e62eb33f6de8385acb265ca875af79f2593ff4bd323d -dist/2024-10-16/rust-std-beta-aarch64-unknown-none.tar.gz=51a58a9f663de787ca58da8e4ed705a1099bfeca945eaab3bbce01edd45aff4b -dist/2024-10-16/rust-std-beta-aarch64-unknown-none.tar.xz=47fcf0fcdabaddde929e4828c1de1db3986af1d32a752c057ec69aee9c8f6162 -dist/2024-10-16/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=207281137a1b6ec8c1df21c581c23a6db7bfdd11c550749203bbe24b9ae80019 -dist/2024-10-16/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=217625e68479d09d8e63f931983e030ea9f0829cdd559ba88bf657e711c96aa6 -dist/2024-10-16/rust-std-beta-aarch64-unknown-uefi.tar.gz=4c5fa8fc4e18723c4522a1e93e9e343e35f02e74fc82e6fc44951bf7e1849371 -dist/2024-10-16/rust-std-beta-aarch64-unknown-uefi.tar.xz=f4440f97ebab6a79d50683169994cef569a427cb1811b85ee196432d4e2d0b38 -dist/2024-10-16/rust-std-beta-arm-linux-androideabi.tar.gz=ab7dfa2b8aff6bb7514798d11970e4c09c8a4844d7408e295c547f1a87c23ea0 -dist/2024-10-16/rust-std-beta-arm-linux-androideabi.tar.xz=fb9ce70893a8c89bc3e66dd6ded2e0c4813c96bd0781b6c3b420a278c53ba4cd -dist/2024-10-16/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=4650f832189a221337fc172c2ffa113ff209774949ae12e7ef159117a02e984e -dist/2024-10-16/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=f6bb5528b914311802fdb9816260e8a57531fedc5f68bef2dc6ba83d59d5ce4c -dist/2024-10-16/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=2fff203abd959498321680582bb969de89c9de4718b38e06cc91a789d7fd415e -dist/2024-10-16/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=df5cadfd5895ee1552bbcfebc40b34826481932bdde309ecb2c13f55541ca2c0 -dist/2024-10-16/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=e29900d97e62c7568395191e1230fa6f98f971c1593303810f05d4db5c68592e -dist/2024-10-16/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=4455ff5a1de11281aca0df4f3f6d33d245314ce4276bda9d161bf850eda24ad6 -dist/2024-10-16/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=26fcafd19aee4fcba45875d0f35aeceed7cb0a0fa070e6a2447b3d9b86170c8a -dist/2024-10-16/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=cc43780fa58e7fa1d23a3b5e2695dfd3f4ac3c02398756516c395f4546e2042d -dist/2024-10-16/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=a67a25cdaa3fabdd2b619434e3b98f05acc13f25cc7ebf8f936e7f3d1761e272 -dist/2024-10-16/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=e8ee762127e02a73614e636b77d34d927f34e967cadd79158ca6ea27687c679a -dist/2024-10-16/rust-std-beta-armebv7r-none-eabi.tar.gz=7343489518ad6d354f9bfcbbc884d1c0e4fc88c4650cc68d9b9b84ee12b750b2 -dist/2024-10-16/rust-std-beta-armebv7r-none-eabi.tar.xz=eef35d9c016fdb67b9825104558ca0fc1aec3af8a738636a0f24797ad270b8e6 -dist/2024-10-16/rust-std-beta-armebv7r-none-eabihf.tar.gz=ed36702bbf1d45c263b8b52a06f2b4a9783c6ec78db28e00d317acd09a549977 -dist/2024-10-16/rust-std-beta-armebv7r-none-eabihf.tar.xz=e4fbf4007af9858e1bebffef6bdb4c66f419b035c8fb385dc70d46ce2e312e2e -dist/2024-10-16/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=1eebca6a4ed9b04a1cd3fc57f8f75bda14cc03c8909385586c8a084e46aa96fd -dist/2024-10-16/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=0bf68ccaa22a4782f23a34b8a52ca250b183e265f12bffde7cda9ddac515040c -dist/2024-10-16/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=6f7b932bb0176fefbcc1de700a36da7c60dac609ec91e6bf351e4c42ea6fb119 -dist/2024-10-16/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=a0d9397caf812fa479da6b389b653fcff451f8d54fa0545e5c908e73391b6dee -dist/2024-10-16/rust-std-beta-armv7-linux-androideabi.tar.gz=5be2ca5bd0340fa2e7ffe435081d1848ab883e46a9c0f07eee69f7dd9d08e0f6 -dist/2024-10-16/rust-std-beta-armv7-linux-androideabi.tar.xz=ed563b78d4201ce29ba79cf6ebf5a3b7d8020611309e39b8790c59edcdd05b29 -dist/2024-10-16/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=53f7928406a1a14dfc6774fb2704bfa9c68091b135b750c5e46e3610e00e8c72 -dist/2024-10-16/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=d71cf98a8b6dfa2cc1682819d1bc5bbfe0eae819f63bb91d64e4f52bbee4158f -dist/2024-10-16/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=f65eccc2a47e34d96faa94954c738813d9b5acae351936b07df6ee2ee8592296 -dist/2024-10-16/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=4f44230338a6b6bc17a8a2a80125ba18a9dedb6f9347c6e93b7f7b88c87e4468 -dist/2024-10-16/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=80eae216bc5c3f77817d244f0d81cc13704894c1c7bde30c89b4f58b6049767f -dist/2024-10-16/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=b8036aee8615786593f83c3e7808eac2a59ad44ae9f5959b9719fd475b3197b0 -dist/2024-10-16/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=95ca16bf6931261a62f4a3637495c02450d34fd0a0ee8abe350881b9aa0bc773 -dist/2024-10-16/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=df92b9f5ec3ea09c2cc48e4c91d41ecb1fa82db87180458b1e051bbceeb4efc2 -dist/2024-10-16/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=26a4426464874411bf51cf0148569c9a110681632d228dc9c9d57fbe24292e93 -dist/2024-10-16/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=70ee4948185aec3b556c963ba030abbb6424e09190e31afb11d063bc2ba21664 -dist/2024-10-16/rust-std-beta-armv7a-none-eabi.tar.gz=50c5b3d721cb5d83ab5f277c24eecbdbde32bdbc208bc0597830329fd19bf786 -dist/2024-10-16/rust-std-beta-armv7a-none-eabi.tar.xz=9add40fc1a971f135796a8020e3ecbc6ccfa657714cee2535866f2af38fcde97 -dist/2024-10-16/rust-std-beta-armv7r-none-eabi.tar.gz=d9e4695576a9f34e67804a636de6164fa7d381ac2193095cd2daa74fe148b748 -dist/2024-10-16/rust-std-beta-armv7r-none-eabi.tar.xz=6592a61388b53c3d3040245b8634715026f1e2a020a118edaf43f98839537aa3 -dist/2024-10-16/rust-std-beta-armv7r-none-eabihf.tar.gz=da24db2c8642e8273ef7d0e74fd32a1045ec99f5201b35d0116ba1818ab330d3 -dist/2024-10-16/rust-std-beta-armv7r-none-eabihf.tar.xz=75574d203e5e15973ce1e6e12a43d6b26825844382ef76b05c4dd568912fd16b -dist/2024-10-16/rust-std-beta-i586-pc-windows-msvc.tar.gz=2e4bab4042bac836ac40e07c36c6057273d6bffaf97b1b22a64cd0876d48895d -dist/2024-10-16/rust-std-beta-i586-pc-windows-msvc.tar.xz=f335988ba2ae2853c4c8928562fa6ed81a2bbd2bd5d09dbcebd7e64cbc7d458e -dist/2024-10-16/rust-std-beta-i586-unknown-linux-gnu.tar.gz=e96921c51d49ae28871286147d589bb59eec596826d1e0eeddd928f57ed4499f -dist/2024-10-16/rust-std-beta-i586-unknown-linux-gnu.tar.xz=c17d7cbbc6bb30899a1a94f74f380bb54878b927ebe58b31592f7adb64d7b5fb -dist/2024-10-16/rust-std-beta-i586-unknown-linux-musl.tar.gz=f9030f5b2ae0411349f1f4fabd00efa3e1117ca5dc5ba60fe87f33f94e51787b -dist/2024-10-16/rust-std-beta-i586-unknown-linux-musl.tar.xz=d45b9c7c6f8de53f99b550a6d673bf8ff29e507c60ef63271d7d5ac73c765e07 -dist/2024-10-16/rust-std-beta-i686-linux-android.tar.gz=2a6b9c893d2d8bbdb5900c4105fe54a988101c7d69f504e4d2983ba7aaadbbd4 -dist/2024-10-16/rust-std-beta-i686-linux-android.tar.xz=94c884a0cd03fe092bdfb6fe718fd335921a82c9c2887e0e68a13fe6a183a877 -dist/2024-10-16/rust-std-beta-i686-pc-windows-gnu.tar.gz=2d4a8b299987ab046536db276f3c4ea97413be5915189b9af085e4a4ba7b28ab -dist/2024-10-16/rust-std-beta-i686-pc-windows-gnu.tar.xz=eb60bf4d73fa45fe61730427287585939ff1a14efa8910877546818167b343cc -dist/2024-10-16/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=ec0f11f5cce47e6ad288393dafaa69b27fc5207194e886f0a00b4e6c3a006164 -dist/2024-10-16/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=10a5c127538bc9b951c62692ca4d626cd669919d5bb2236ef6112da28db028a5 -dist/2024-10-16/rust-std-beta-i686-pc-windows-msvc.tar.gz=7c9afcae592f5494ffd2baa95947b4fa5483c795e516852b463170e4797984cc -dist/2024-10-16/rust-std-beta-i686-pc-windows-msvc.tar.xz=ad9381999c1846c188d7264992c79faf413d675fdd70f22f25afcf84ed6e3b22 -dist/2024-10-16/rust-std-beta-i686-unknown-freebsd.tar.gz=9b4ea3de244aaf14b6759807444bb983ec5732b119faad1c9437eb2c02d407ed -dist/2024-10-16/rust-std-beta-i686-unknown-freebsd.tar.xz=88f975eff5146af6ae548e2d7be8d402ca3d6f470b6760b75e27dedcac9f70fb -dist/2024-10-16/rust-std-beta-i686-unknown-linux-gnu.tar.gz=8a8a255695d36a86ab32abe9f37f9f6f3e9b75eee75953486d82f186d8342180 -dist/2024-10-16/rust-std-beta-i686-unknown-linux-gnu.tar.xz=00a55b220767f3b692286bea728208bf665ea9a54869f82b31805b40ff56f763 -dist/2024-10-16/rust-std-beta-i686-unknown-linux-musl.tar.gz=96e838064bfdace0fcd5596c50714585a221a5116e2825aba448cc1f188d0edf -dist/2024-10-16/rust-std-beta-i686-unknown-linux-musl.tar.xz=78c5be28afda04d536a634a049c175b38d46309eb4b02126ba2cda3102b92d45 -dist/2024-10-16/rust-std-beta-i686-unknown-uefi.tar.gz=41a11092091b1f3b508f606978c0ac026e94614fe4b2207522b4f5f3d6c3262b -dist/2024-10-16/rust-std-beta-i686-unknown-uefi.tar.xz=a2250a5bb179549426ead55edaf3eba7626ee57a5e2c578057c3166348a47523 -dist/2024-10-16/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=782998317c6c9cca107e84538ee166a37490b287efb437e5da9bf799178084b1 -dist/2024-10-16/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=75b15b6d6db6f801a74419aa294b9537aa6e92b4d9d4c482e66aa6e319accee5 -dist/2024-10-16/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=003a9949067435194f6a9bc6ea742876d5894ade67b5831c111826aa8ba5c2d5 -dist/2024-10-16/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=5f1a4b6acfc1c82049c13ee2553ac20df016062feb368a54e44aead601105987 -dist/2024-10-16/rust-std-beta-loongarch64-unknown-none.tar.gz=f5e851d27f7017832de64c134727b7cd045495ed93fece21101c1e32b4c4c5e2 -dist/2024-10-16/rust-std-beta-loongarch64-unknown-none.tar.xz=289a56a0ee6087fbebed28a8d2110961c08889724d1a776a41094d5589cd112d -dist/2024-10-16/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=86cc3aa69dd4b18fc8435b6f6c1c73a24dc0b031cd79f942f6bc20a11f093f67 -dist/2024-10-16/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=3e29c510424862fbd96cf61e89b6f9d64cef3c0274dea125f4af2c2a84816f5d -dist/2024-10-16/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=7506febb3ffaf1e763084d06a8dc9da096155c6a609a5c4c26feb993688f45f4 -dist/2024-10-16/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=9c7e50509abfe5f0faa41eb526effa915e0799f59e5404e5a667c5f674a1ed18 -dist/2024-10-16/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=6070daa8b4fc8bfb6c392767ac669a80067520c0fa85c923cb435c03a5ba6b9b -dist/2024-10-16/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=32e4064ed11bc521f26e222897ca651704e41bd42df214eb618b6fffcb909b56 -dist/2024-10-16/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=51a092e812baf52f5eb7100e433fc1d5ac7cd984f8062b7d960711b9b88f1431 -dist/2024-10-16/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=444bcbf145d1aff19d8e2474191ee4ff0be738c7c3b1ded12e1a9bb35d700c2f -dist/2024-10-16/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=9a4968669cb034ebdd0623f57f86a674df513abf6c01cbffce0d104447f0aacf -dist/2024-10-16/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=11e478ed0cf115eaed256e9f0f64ab9f879ea0fb26b2f520a6388d3efe705422 -dist/2024-10-16/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=0476e97436699b50ce459b3c38b55425b81864162639997bc14bce33fd7ea429 -dist/2024-10-16/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=f76163c6963a7f1e29cc6a348b68e3c0659b739383273029eefac4d292280a3f -dist/2024-10-16/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=f922ff15e927c047bed29d64534218d392bb584e12abdba09d9d9243613de3b4 -dist/2024-10-16/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=0131845949fe27479123189bca11f2ff13aa14e0349c0901407cf65723271fad -dist/2024-10-16/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=a7898b83bf49203172e6191cc720b6b184aca6cdbe44386278fab0e6c8ca4bca -dist/2024-10-16/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=d5a4a03dfa52f732af211ae3ed3220fd76c5a2a6babada0bf94de3817e71cca9 -dist/2024-10-16/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=c074043d065a85860d2f99b657035b87a1ee7fdcea53c557035a8da6fbba96ad -dist/2024-10-16/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=9a02c6c4c5cf7c57942a89da30869d7bbe2b0f5bf7374b7dec868bb5f84e00f6 -dist/2024-10-16/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=1c016db6ffad0ecc552025777b2d2df5a54d6ec3a215eb2b4af0f1ccc6e45f14 -dist/2024-10-16/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=399d56e3525aeb354a0c9250f070a43a7426e185960db6d8b57484f47ad11a4d -dist/2024-10-16/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=64f01a83583f4d025c95b3b2c09b86c4bae123c72a66a6a0995994d4226d34fa -dist/2024-10-16/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=794cb971242dedc2926a6b56badeffd1b4aa4f1753a22a1228eda8f336c2a5c5 -dist/2024-10-16/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=1eaa20562af0921066ae04c8e1d9191ecfc4f9816a721ad2797c47b58a343084 -dist/2024-10-16/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=423b35248c797ea494e6462b4a9c16e49649f0105b06b16c6137799a82f0a401 -dist/2024-10-16/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=38a31b095b74cb4b678ecd797ed768f4f9f967a201b79f21b059ef8a39fbd4f9 -dist/2024-10-16/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=d7a53419a2f604102bda0d0b8ee9aba790082ccb0d63c31ff28be15f37ee87d6 -dist/2024-10-16/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=0cbccec64f57ca0951fe678299cf17a7aec8bb2a8d71aa7fea1a26cd720b38ca -dist/2024-10-16/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=aed7bcbb60aa5444ed8a8e1ccc7b74cc978b7e1646eb618a1899ebe61adf2c34 -dist/2024-10-16/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=0cd68dad85a5cc084d8a0cddc275cd5e932e50cea18d3d622d03ecca068008e4 -dist/2024-10-16/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=0873ae093594ae2d93f19003ded34d1d6d4884757e0a5a790d4766be4bd7622a -dist/2024-10-16/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=ae70c9e9edd7d83776cdd0013e081d3b16dadb2a2504037b245acc82f104112f -dist/2024-10-16/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=810c1346632064535769e8fb15ac207de45f06700e8cc9875b3971c44725a3df -dist/2024-10-16/rust-std-beta-sparcv9-sun-solaris.tar.gz=0538ccf4739439c52d6c7d99b573e7d8163a834a6163720829816d291e067217 -dist/2024-10-16/rust-std-beta-sparcv9-sun-solaris.tar.xz=8064bfdddb99ba6ff202ab92e3492bd2191ea11387b930a35fcde5ac7e341c29 -dist/2024-10-16/rust-std-beta-thumbv6m-none-eabi.tar.gz=a988938091594f39015783e78a334d72d41f5a3646a3da09fe7a7a0db7ec2662 -dist/2024-10-16/rust-std-beta-thumbv6m-none-eabi.tar.xz=0dbf287df801225c52d4dcbfd7afdfd5c1bb8410d9342885c092a4982a0d038b -dist/2024-10-16/rust-std-beta-thumbv7em-none-eabi.tar.gz=d5b46640810193ee163ef6cf3bb8d506b6844104c3d00c033d436d79ee790dcf -dist/2024-10-16/rust-std-beta-thumbv7em-none-eabi.tar.xz=f4e7ee83d5392e2496b9d3fc1e42b45d73be3b67e723a2e62f931c11a61480af -dist/2024-10-16/rust-std-beta-thumbv7em-none-eabihf.tar.gz=0fa0ba0ca7c4e73f8b9ff2800919484cad7d902cc5e704e5aa3adb742cf6a6a0 -dist/2024-10-16/rust-std-beta-thumbv7em-none-eabihf.tar.xz=ce3f3f3bc51cf79449df550b8c3fbcac588444b3234f379b93076034be6a40e7 -dist/2024-10-16/rust-std-beta-thumbv7m-none-eabi.tar.gz=3b2aee46d16f38cf43cdd3f3fab78df181bab6438cb012c2caa56fa097ad1402 -dist/2024-10-16/rust-std-beta-thumbv7m-none-eabi.tar.xz=3ee398b8497b7920f5d3cb18be2334ce440ec61b11e80c3ffb9eb1d898be45cc -dist/2024-10-16/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=26a67116e52dc1fcf179dd226fc28e3e21f2d2b482330d254b5882502573ee6b -dist/2024-10-16/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=d051ae1bc98060db4a2ca7fa3c3dfc6c3107632631edac41d553e4b192ccc2d3 -dist/2024-10-16/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=dc34a8335b1a9dc077e38b4e4a8222d84340de604a6af547fa17bb142cd0c4da -dist/2024-10-16/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=2d5c375d09bcaad6f983d4c4e0762532feb1d3706beacbf3a8d2e4fd75bf0c71 -dist/2024-10-16/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=30c73a59d9138a542337fbb2be848a152172be272a25a1ad9a28f37510e35e94 -dist/2024-10-16/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=467775974be97da92015790d49cb4f89d967ed1fd7846456b4b30e20f9585501 -dist/2024-10-16/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=06db2989a00b1913822cec211225b0d37143dfe1e62d394c18c04954f7396ac0 -dist/2024-10-16/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=65de9bf3cfc8ac6910953b2d3b2e9de532220f692519875e7da50a6493500fe5 -dist/2024-10-16/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=26a6aec0f92b238c4d75c9eda3ecbb8bf0f1628ea5bdf52941e7b5ca398ec03a -dist/2024-10-16/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=7a4b72ba1d507f418b30d7a110eb5e9025872e2398f0aa68abbef150f4c49ef1 -dist/2024-10-16/rust-std-beta-wasm32-unknown-emscripten.tar.gz=cf04dc8f1df723dbca4fa3a1155dc3bced6b3c96588bf41f6bcc196b74ae19cf -dist/2024-10-16/rust-std-beta-wasm32-unknown-emscripten.tar.xz=4fd17a62d10d27c13818cc3dbe1c62aa85d9c7123b88310d12cc40939010ec97 -dist/2024-10-16/rust-std-beta-wasm32-unknown-unknown.tar.gz=64ddae5e3e08ede16960f50595c4205de9962e0f5b8de9de5df1e9a8946bf66a -dist/2024-10-16/rust-std-beta-wasm32-unknown-unknown.tar.xz=0d6449807c02e1ef817fa2d378e77d9becd3a1560192bc9fdfad84cdee5cc8b3 -dist/2024-10-16/rust-std-beta-wasm32-wasi.tar.gz=c4ba753891162f604effac480ded4c536f294e39768f41d7b4fea1ab28c71be3 -dist/2024-10-16/rust-std-beta-wasm32-wasi.tar.xz=46a6f680f19ee2ddeb41e7aa13bb91a893ae27ae89ec41c36094f6e4db4a3e0d -dist/2024-10-16/rust-std-beta-wasm32-wasip1.tar.gz=3f89ca539044a79abd2b25f12d08ae954a7fcdcdf0288239c57d241b225776f9 -dist/2024-10-16/rust-std-beta-wasm32-wasip1.tar.xz=18a922eb41f5c907bfb624d18ca882dfd569f6775105dcdc29e7c7eb49187859 -dist/2024-10-16/rust-std-beta-wasm32-wasip1-threads.tar.gz=6dec5910a96e7a8e0713c109c993df44094e03fc8ac90b1a99f72dfdf84798f7 -dist/2024-10-16/rust-std-beta-wasm32-wasip1-threads.tar.xz=00e21ba70b0ee2760dcd51bf68f6be74c5cf38fc301476f406bf1f1d21ae7503 -dist/2024-10-16/rust-std-beta-wasm32-wasip2.tar.gz=c0b620ffb0debcd0f20155b1be250627450f14b4f62b32d9d9e4ee4c4e57cca7 -dist/2024-10-16/rust-std-beta-wasm32-wasip2.tar.xz=4d14c5de2f92b67c99e6fd2342d4ee968805d9eb68d4f9d1f549bb27e866f3b0 -dist/2024-10-16/rust-std-beta-x86_64-apple-darwin.tar.gz=b3ffba3cdef26174462e65847414458eba1c6aea63a78f6087497a04b427295b -dist/2024-10-16/rust-std-beta-x86_64-apple-darwin.tar.xz=1923ee9008ca30677642d1e66463555ba6fcee88dc0ed947e0ece7e4ce4efdd4 -dist/2024-10-16/rust-std-beta-x86_64-apple-ios.tar.gz=e8f1cd196c5e3b10a58f640cc8bdf3d015e1b23d49724112aaa7e4019cf01107 -dist/2024-10-16/rust-std-beta-x86_64-apple-ios.tar.xz=5fec3b22adc67fc6e4ef2cb873d446cb1520cfcee2ef4248e3dcc2816ada683e -dist/2024-10-16/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=852e5067d47ac896c18e424cedcb984b0b4724b7fcd05e550151de2781603737 -dist/2024-10-16/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=2333f02b870c6e7b673f5e8e166bf9166c3f6d1586daafa4eeb626d8de5b305e -dist/2024-10-16/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=5c2bfde266aefa83ef9e65448900f4aa73e1d91de3719ada2512230a69090e2c -dist/2024-10-16/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=218f4a4861812e38992bf261e390e95fbe67402f89827e6ac1b68fa42c705166 -dist/2024-10-16/rust-std-beta-x86_64-linux-android.tar.gz=5cd9859a22f77dffae58fb6573a8f5e23dc75bf030f54c152714777e5a01eef3 -dist/2024-10-16/rust-std-beta-x86_64-linux-android.tar.xz=be754bee393794ac427718b687f5e4aaf61aa1544795ed0da0b9d20e77e45803 -dist/2024-10-16/rust-std-beta-x86_64-pc-solaris.tar.gz=556f48c0ee8276bc847f3519dc0dfb72bd11cf27add709815da47f5cbb48716d -dist/2024-10-16/rust-std-beta-x86_64-pc-solaris.tar.xz=aa185610d66b606913d1102f62b62c5bbf9c5baf2e091d14d37c30b1526fb583 -dist/2024-10-16/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=1a7dd15c91fb1597593b27dc0b72bc0b1a6e758935efae3c9db714cd624d7639 -dist/2024-10-16/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=be18c0a1f2d0a1852c81ac1619a01d04d0c8c22472655710f643d86cb559508d -dist/2024-10-16/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=e18f210cfe890af8285da5f99cc476770daa78cddb7f8213f7f26f66111e17ef -dist/2024-10-16/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=b207877400dbfad09b6a3c2917516b63faa159f922ad03911736634ff46898d1 -dist/2024-10-16/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=6f277d2e2e9a9057e2a2c8045c3949ab36ee8ed58b64829b10470e0c6b111671 -dist/2024-10-16/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=51a102726ddf492dbc530437047fcb4d5e542dc4ace0e64da21c7ec79ebc001c -dist/2024-10-16/rust-std-beta-x86_64-unknown-freebsd.tar.gz=eeb6a46dd78fe3b477454c256ba8486b906e7a7ed044e686bd4f8c868265bd90 -dist/2024-10-16/rust-std-beta-x86_64-unknown-freebsd.tar.xz=67e103b9742ebf2798fe8e2647a6755a1d253301fea13a5193ced5bc394b9a0c -dist/2024-10-16/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=b42fcd18458cff0ffa0902a0797e9b42cdf9475f5e84279972e4010608a14ba3 -dist/2024-10-16/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=878e3950e0aefbd5c5c155f1ba2a4e8abebab10e3e77311403fc2c475e6da9df -dist/2024-10-16/rust-std-beta-x86_64-unknown-illumos.tar.gz=d72be5ca5fde3ac33da483058b8132707c93647652245864c988158e6dd70ca1 -dist/2024-10-16/rust-std-beta-x86_64-unknown-illumos.tar.xz=270959bb47366b7276717b677c5303ba0d579c9fd1f98fcf3774ce033caf0015 -dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=33370d376f3ecd80ddb5f614eef222c601e2df5dd18ae98ec034922790f56218 -dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=061a262fe98e6e1b41df6f9f60367259d44215f528938574098ede8698985c94 -dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=70328a15c8e29be07f248bb073336f06eba613c377ea4e98a1e0a4abe5e2eb6e -dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=ac389ebe5ca69cb382fd104161c9068bd8aa4d28960d578f2d925faafffb61da -dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=22d350bc0718b999d88e715cba73ef1860e1b1b8efac026f46d9050952d739b3 -dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=0761b9cb94210ee40fd0dbde38cd049a9e727a73da4ebc2cf10e5db92e6860de -dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=35f975847adac17d19abba5385b951ce2015dd8b62ce4b0a716ac612808cc9d7 -dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=5a9679805c1bdfa835aee94ed0d3ed4d2b4d0b6a8e2ec4471fcbcefd331cb200 -dist/2024-10-16/rust-std-beta-x86_64-unknown-netbsd.tar.gz=e4269be360d9823bccf6f7d71e4f51feeb8e955c7851d5bb6527055d709b68b7 -dist/2024-10-16/rust-std-beta-x86_64-unknown-netbsd.tar.xz=58880cc63fb93bbbb78fa4268eb69b37464b429de2f007abf05f5fd7c53aec8a -dist/2024-10-16/rust-std-beta-x86_64-unknown-none.tar.gz=42c77c14c433f43a092bef5ea0cfa60aea747301a9499c66bdd81d7998a74143 -dist/2024-10-16/rust-std-beta-x86_64-unknown-none.tar.xz=0cdfb3cf58d8f6db3bd65f4848aec8a431ffb4e1a5f79e56ceafe09849a96ac3 -dist/2024-10-16/rust-std-beta-x86_64-unknown-redox.tar.gz=35ba471138c115ac3e1ac3560fe8590038cb6002d22a45dd92f09a868270d223 -dist/2024-10-16/rust-std-beta-x86_64-unknown-redox.tar.xz=f250b60b52e2f84864406a0ef7e2f8896e1373f4f14f555a47a2019fd370f553 -dist/2024-10-16/rust-std-beta-x86_64-unknown-uefi.tar.gz=7332cbab92c48611604eb13ac025b845fd0dc0bfe838a4edb02f8266a5245aeb -dist/2024-10-16/rust-std-beta-x86_64-unknown-uefi.tar.xz=7cbef4955ee702d845116c59742194b1019d67f564145cf809ecec67245ca8af -dist/2024-10-16/cargo-beta-aarch64-apple-darwin.tar.gz=59321dd2f962c7b14514fdf1ec96907c16735a03a799479055f40f17883b8b6e -dist/2024-10-16/cargo-beta-aarch64-apple-darwin.tar.xz=336c7dff9f3a1d9de819a32f62eb518dd94d45ee591afb01d329127a2146c3fb -dist/2024-10-16/cargo-beta-aarch64-pc-windows-msvc.tar.gz=00c53e3a327909882282a32850c82e4aa18508a5e355532951d380e985b75c79 -dist/2024-10-16/cargo-beta-aarch64-pc-windows-msvc.tar.xz=39d09b49740b0512a84fd5351d473c5802de30721f621cf99ccd0178d8eebd60 -dist/2024-10-16/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=dcb522627c49811d2e6eb133725e301089a4942da1347721ea28f2cdd670685a -dist/2024-10-16/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=b9ce402bb130d35e482ee360f8f142726ff51bac3954aeed14800eef0bd96f6d -dist/2024-10-16/cargo-beta-aarch64-unknown-linux-musl.tar.gz=670c0b78cd5c985e6bacb2bb2cc3a5a2478c2623992c4cc35d0d4c624e1b4b16 -dist/2024-10-16/cargo-beta-aarch64-unknown-linux-musl.tar.xz=8a936c0c457a1d5c659611e7a69fe9934313d9ceea04c0a0eb393e28544ce7b1 -dist/2024-10-16/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=10150caa2130a73443942f1dde7c849172b57b7b9e07e8939cd6c126c701d7d7 -dist/2024-10-16/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=4dc0ffb898e66661a1b9844b965a0b0ca115bd6d9bb25fd5c5df022fdbeb56bf -dist/2024-10-16/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=6db24d0a3eb7de6e3d40dceccf6a92ed86e170e0c4dd2ebc9702652655ad664b -dist/2024-10-16/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=c5699a6a4ad49c34a77c94a4982b1a0ea7f6dea84d2771c24fdc05dfe9d4cdb4 -dist/2024-10-16/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=f5621b39e7608e8461b559f3c3e57969e7eadce82798b395ba41e6302b2e0283 -dist/2024-10-16/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=d7f62c0ac375f56d9ebbd0edbfaee4684d7d47ed8ad38bf7d25fb75a5770bdb1 -dist/2024-10-16/cargo-beta-i686-pc-windows-gnu.tar.gz=b895fa9240c3a6c089cde6b08a21408b5a6f38818c4a9cf25394b17e9610da96 -dist/2024-10-16/cargo-beta-i686-pc-windows-gnu.tar.xz=e26de92566339b932cdf4a4ee90464f1f3863d89534c03a3c9f9a632a278993d -dist/2024-10-16/cargo-beta-i686-pc-windows-msvc.tar.gz=ba64512c0732f5821ac4d1eb7fb53c0f340847c0cbc7dd5f88f67e03bc3f58ee -dist/2024-10-16/cargo-beta-i686-pc-windows-msvc.tar.xz=cf9872ad8ce5621faf517c2796620f24c1a99bccff7f328b7e7650e89e604b22 -dist/2024-10-16/cargo-beta-i686-unknown-linux-gnu.tar.gz=23496080baad6b976f8680b7f6c856461a410a4dce5c66a41cfa220d9479cd95 -dist/2024-10-16/cargo-beta-i686-unknown-linux-gnu.tar.xz=9799594bddbe1e04e1d625a6ead04efdd4749d4f0773585d21ba2be6636f0bee -dist/2024-10-16/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=5a1b95969f002c25717751337951aed39e6f6256ee58acce150d5ffaf0046300 -dist/2024-10-16/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=36bab05ec8b39c7e230ed78f64b2680ea21fa9f7997c980c22edde61c0799b5a -dist/2024-10-16/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=19bfbd70b98c0bbbf29a0a796572d1661b8902132087173ca0e6aaadb4d51d09 -dist/2024-10-16/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=629e42e188447a392bfc7cef5fe04c31380ee30523dc0bc33b0f3c02bd2fd82c -dist/2024-10-16/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=5d8b1daa253ebe0750e6f073b8367b053de09b4f209327d4114bfa60b2bb5602 -dist/2024-10-16/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=545d7ad3b7b0b5d2ec0b4bb70b7e31dd823048d6087d6c3fa2139f307ea35fbb -dist/2024-10-16/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=2111cbc7586a1e58dc7e6e54a63157f9606f5586c7bb72ffa15f1a94284d4c97 -dist/2024-10-16/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=0d6702d3ec5a6aa9dfb06d565e4e16b27cd3d445871bf2344c876d7ffe2f8a32 -dist/2024-10-16/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=0f750831b518b452a2ac17c9bab3a02f30f58bba6ffcd962eed06012102c7b31 -dist/2024-10-16/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=6d476e16109e9bc5dd055c537a9382ce154d2837a32bc2c165a1aec76ba1ba43 -dist/2024-10-16/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=850bbca95670afa1262b5d46bb02f0bb367c83f851bc2a9817f8bf2eda9bd2ef -dist/2024-10-16/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=f42b3b5cb506886bcfc92c0a7f3dd3d0668bdda0f2db657b98becb4c0e99bfd1 -dist/2024-10-16/cargo-beta-s390x-unknown-linux-gnu.tar.gz=f3a8541b3e6c12f350fcfbf43a8efb2a8bb48a62e055d9dc522d568b94476f43 -dist/2024-10-16/cargo-beta-s390x-unknown-linux-gnu.tar.xz=12c5411791c715562c99dd211095c9924142053d510e17e6ec50b7b8b927eda1 -dist/2024-10-16/cargo-beta-x86_64-apple-darwin.tar.gz=95885bfcf5fc1de80d0f9b5415dd261136d5577b7d61716c184a6c6379acca21 -dist/2024-10-16/cargo-beta-x86_64-apple-darwin.tar.xz=881c9d88bf2a848f5b5cd61d18068e2dda3542a65e93ab373e3a047cc30369d2 -dist/2024-10-16/cargo-beta-x86_64-pc-windows-gnu.tar.gz=c04ca1768c5925d5c7e19d5f232adbda355469974b19a2a130a6967db94b56c3 -dist/2024-10-16/cargo-beta-x86_64-pc-windows-gnu.tar.xz=bc02593e98f5393ce2032fb605ec2bc053a1a19311a5a80d27c3a552ec8b968b -dist/2024-10-16/cargo-beta-x86_64-pc-windows-msvc.tar.gz=8ffb930c33ad454806f2f61a10949a3fa5b92b9313454927dbd76928955ed7f2 -dist/2024-10-16/cargo-beta-x86_64-pc-windows-msvc.tar.xz=ef0bbe8512b3dc9bdc9f3a47abf2834bcde1fd7f59e319f7c7040b7100ba1f8a -dist/2024-10-16/cargo-beta-x86_64-unknown-freebsd.tar.gz=eb21f7739dbd7c120dc9552360e8aa6e1e0eee14d80ea16e3dcecb9e94efe7c0 -dist/2024-10-16/cargo-beta-x86_64-unknown-freebsd.tar.xz=9e287f3d0c7e402dbc121cd737fd2360dfcd97fa886770aae93c07474494bb77 -dist/2024-10-16/cargo-beta-x86_64-unknown-illumos.tar.gz=1cb86b6953ec99e95d92d61ead263021d16921cfe6152b6331efb838c46be85c -dist/2024-10-16/cargo-beta-x86_64-unknown-illumos.tar.xz=c356e671ca97dcb4d945567e33f06911d5269fdebc19fe83a9313f574d446576 -dist/2024-10-16/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=7613e679837e2769b9e8df5b8785fdb7e51665379e64547bae9d6015eb8e45c0 -dist/2024-10-16/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=39ae7207f84ee3da16ee11271070e8b82d2991cde29771d5154bb2957d9beccc -dist/2024-10-16/cargo-beta-x86_64-unknown-linux-musl.tar.gz=4dfaa69f4377bb724eb7d1990aea7ac219a960b690601769f8e06b72f59f86b4 -dist/2024-10-16/cargo-beta-x86_64-unknown-linux-musl.tar.xz=4cf72f3f0048e8cfb2b05566cbc1d76e9730cf1f71f9d0f3a71bd9379f30b08c -dist/2024-10-16/cargo-beta-x86_64-unknown-netbsd.tar.gz=e1d3ff748dcf1777bc2d999ec82f0b8a67295f91a9cb07a9c1123cd5424928c3 -dist/2024-10-16/cargo-beta-x86_64-unknown-netbsd.tar.xz=7e21e89e218118d536d489d16e77e667df7ba7c809135ba179e7097a2243df5d -dist/2024-10-16/clippy-beta-aarch64-apple-darwin.tar.gz=244ed83cac923e00647cdd3aab9d0479cf420991e9e06eee5ffd8acc9e5a199e -dist/2024-10-16/clippy-beta-aarch64-apple-darwin.tar.xz=6dd93a671fca0efb2d3b8cc461aba66483624327a382fd714a526832034c8438 -dist/2024-10-16/clippy-beta-aarch64-pc-windows-msvc.tar.gz=56710fa9c7d46fb881903e08e407c258e3ffc75ce3de0226dcdc3709dc59180e -dist/2024-10-16/clippy-beta-aarch64-pc-windows-msvc.tar.xz=6ee782709786c310fb1e887cc576e7e61b0a4b120f6a46c7dea1e2f2bf7dad1d -dist/2024-10-16/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=06f0ee2195349921d1ae791fa1628fceaa7adb377968fa09dbe17aa77c762a47 -dist/2024-10-16/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=6e792e91db8b54e0cfb9eaed8187b5202ac5d5735ed0f73080a6a73bf15ce683 -dist/2024-10-16/clippy-beta-aarch64-unknown-linux-musl.tar.gz=bde52962b121472cd1b755c506b9362ff88ec582cb3fe9d307948c51f4d96f1c -dist/2024-10-16/clippy-beta-aarch64-unknown-linux-musl.tar.xz=70a06d5b8175d078bd246adf45f3058d362f0b128f1dc11d3797840b28692bf5 -dist/2024-10-16/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=ab8b54d8436dbc6af279a048d2b75eea9eabfa369f23c51fc1c47388f642a755 -dist/2024-10-16/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=a2715009144defc9aea3ff0d6a15485d8feedd37b333658470d479600fe87ffd -dist/2024-10-16/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=a1863b47208051a231f9571bdac3628d8afdfca7eac3b1cb7a04a843c176ae80 -dist/2024-10-16/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=a5926e8e3e2867a8fa87db77dc26bd18734f84a4a685374dda07d50d21068f62 -dist/2024-10-16/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=f70eabd386aac93c676485bd42845e62b34c034b8710bf0db24a440c03b15bce -dist/2024-10-16/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=cfde41ebe7398d0858bf507b9322c5f4959becd5a3a4624027b4bf3321730a29 -dist/2024-10-16/clippy-beta-i686-pc-windows-gnu.tar.gz=3d988126d6a0ed9133b73b8aea3b16d6355db8ad83254a7499f7dc3b414d62f8 -dist/2024-10-16/clippy-beta-i686-pc-windows-gnu.tar.xz=6efe88aab2daa0c7df17bbb449c2b815e085ca7e859b17bb578978d18ca2ea04 -dist/2024-10-16/clippy-beta-i686-pc-windows-msvc.tar.gz=2c2eb32ebe3ec89a985c07ce87cc1dbc627f5f8588aeac72fd381c6e19034095 -dist/2024-10-16/clippy-beta-i686-pc-windows-msvc.tar.xz=fe2d2ae70e0ce102794450d4259b706d3bda2c5b05bd21a863b2ecd8ed54274b -dist/2024-10-16/clippy-beta-i686-unknown-linux-gnu.tar.gz=0d633381b174f04523f13cc574e79af5041a231aa61b0befc406c7e3ccb0ebf3 -dist/2024-10-16/clippy-beta-i686-unknown-linux-gnu.tar.xz=029558aecdd4862dc74ce9726a462f1d34a7e2a6eda5bf791995dfd6933096e7 -dist/2024-10-16/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=2bdaa7f730f30db62ed0661f135227c54249786a78a8022428ead03766c9e29b -dist/2024-10-16/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=2a4f5982eac9cb5e8372d35c13a7832d532a31e5c38d13b0643d16832e1e341e -dist/2024-10-16/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=a9a1fc5b74e19a567c45ce1789c7bfd50b28774bca8320886108e4a18a1d7765 -dist/2024-10-16/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=9e957652f80b2de14c5a8f5faaa5662d0ebd26e18b2bc5d248587d72413e483b -dist/2024-10-16/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=a9fa9caea0f784ed096b3ff204a8261126102e05456c52d544c7036f9ee30c41 -dist/2024-10-16/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=0e3d3472e3e73b02aca8797ecaa2471e472d361b0c44126e4bfc2d25a8fad96c -dist/2024-10-16/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=211c52eed69942aed1e6b1fb4799232ea4fd3f898a44a4bb6343336e89dfec74 -dist/2024-10-16/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=8c07b34223e465e17094b7e20efdbf8ec6ef5aa042485d3cfbc6ef58dbca0be9 -dist/2024-10-16/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=b3fc3cc6e81ef118eada3c01fc3535dfc622b92377d8e735f80d7661b4b847fb -dist/2024-10-16/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=e885c534589fac79046bb31b92aefe7674dee13c8df1a456e91ca63e9d92c6d5 -dist/2024-10-16/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=fcfbf29d105ade4a6d7537dc44d01c6de2de70d066afd8ac3af58bf3bcb6f7d0 -dist/2024-10-16/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=a5425df8cd724fd992de26434090e157e9d148d063161bfb43789d6b4234ad02 -dist/2024-10-16/clippy-beta-s390x-unknown-linux-gnu.tar.gz=ab96fc1c538a9a526124bc2cf3e97edd655f29f8d6d310b3b5f017cfbe6311e3 -dist/2024-10-16/clippy-beta-s390x-unknown-linux-gnu.tar.xz=096de4e9f80f40a294dfd1ba32e9de038c3449b2760189a5c9e46cf8e36dc0d6 -dist/2024-10-16/clippy-beta-x86_64-apple-darwin.tar.gz=5614651ef2acd5ce1d43cc2504d353e471d9c8c425c16e3649f81e1cef44b86f -dist/2024-10-16/clippy-beta-x86_64-apple-darwin.tar.xz=26e39442af2251c52bcd275c7ae25a88211ec2f582bbe7a29724f816768c9781 -dist/2024-10-16/clippy-beta-x86_64-pc-windows-gnu.tar.gz=b2626513cbcd9b1456dce8543c2b11458eb052434f9ca84a6e926a77e5be2362 -dist/2024-10-16/clippy-beta-x86_64-pc-windows-gnu.tar.xz=87403c11e1b92bbbc2651183b2b480c41d9c7e0fa6f08551702c6ab308fbbf5e -dist/2024-10-16/clippy-beta-x86_64-pc-windows-msvc.tar.gz=929029e67d34bc813061c524490b8f0030d31097fc1fd439acd4d8c3545589a1 -dist/2024-10-16/clippy-beta-x86_64-pc-windows-msvc.tar.xz=1584df60f086c6af01f06023236f612bf59be9d5b991bd09ed66f4c505737533 -dist/2024-10-16/clippy-beta-x86_64-unknown-freebsd.tar.gz=d5ee8cfefbf164d33529f1a777437f49216e93173a2ac04b605e74fea89fc6a3 -dist/2024-10-16/clippy-beta-x86_64-unknown-freebsd.tar.xz=9469aead14fc03ebe984e51bbee0db6d1cd8e877b67ca361c44939e2464a95fe -dist/2024-10-16/clippy-beta-x86_64-unknown-illumos.tar.gz=79bd918b2a391cbeb885b7075b1e0534054c81784c332a2aa8539d0e1cd15f69 -dist/2024-10-16/clippy-beta-x86_64-unknown-illumos.tar.xz=16b808026a4fdfaa85a4ac01b01b4fc79c4824a651bd4e412e4ee9b0011eca4c -dist/2024-10-16/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=62224af7a1831140fc3f06e7e918191e9443751549ec5c96afdcb3ffb5b18e06 -dist/2024-10-16/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=78bab115fa696fc95d911655575032fc9af324c8b6df136044f11681239e5c41 -dist/2024-10-16/clippy-beta-x86_64-unknown-linux-musl.tar.gz=1a76ea2b1596acd396585d78d01be5d3b795641d7b20f84379cd2c344e7536e9 -dist/2024-10-16/clippy-beta-x86_64-unknown-linux-musl.tar.xz=63ac980b41b0a3b744d94727af6ee1679b8bc4c50db4ef68402d0253b1852ffb -dist/2024-10-16/clippy-beta-x86_64-unknown-netbsd.tar.gz=eba61354aecfea64815a68b569122e029501d85876d37f5ea4119f36f932e146 -dist/2024-10-16/clippy-beta-x86_64-unknown-netbsd.tar.xz=37f9395e78a2bf2977b38929b9511e9668f26e23705d025609f028b282aeaee2 -dist/2024-10-16/rustfmt-nightly-aarch64-apple-darwin.tar.gz=05cc308cd0c35063b43a45dab3e84001e2d580b10431c74899a86cd8971e5b36 -dist/2024-10-16/rustfmt-nightly-aarch64-apple-darwin.tar.xz=aede50889786bc1e902162b9347cf59ee67b15e902b0ed78d7187d3c24a7c4a0 -dist/2024-10-16/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=1c25ee283dbc720b471d435ed952e6d794ecacafd4c889a2ad8d43725cba8ded -dist/2024-10-16/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=67602978481a53b0b4681523d94bf79ad731a369cc088c3b0adf8e7d54b1fbce -dist/2024-10-16/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=ed7c9c38071f9d1e632104ff1d9a9407efec99d74eabd127db795c56e84b9d73 -dist/2024-10-16/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=65ee60bfefa1334cece9f5da72789d90b4b5918e7afea2b47aa4d1450d9a1237 -dist/2024-10-16/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=e92d5ddf80c94bdc34697bec4d7a1b1ea677e5fc6c68c41059a7829e53e95505 -dist/2024-10-16/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=2f1737178817318d1543deabd865aa83a1f395a36cc83e3717157b4dad827f22 -dist/2024-10-16/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=a4be0eb92a011ed940db67973d5fb62c4b5d3fdd52a08981223c5fa5278826b5 -dist/2024-10-16/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=a47b2dab4f20f53e6c29fbce06383144a67ece61a63f33c3fb86beaabfe4bce5 -dist/2024-10-16/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=7bfef0a8b7cb4a905ad145311c320a8ccb2048e806ef68688a1423009770b35a -dist/2024-10-16/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=d944161b92bdd74f3ba533b94b67a3a361a01b82fa5c156710608f00c46913ec -dist/2024-10-16/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=46a46ad32e2829550e301a84212f057faf21bf67ff6862f77f11cb0e13f80453 -dist/2024-10-16/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=d917336a949ad5a5f0fcfe1ef261d87d4dcbde22b467258543c50715a9041d64 -dist/2024-10-16/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=38a9cd401774ff1d832e536ed0aca9a3f0d5593814bd6db9ba4f8341a5545fd3 -dist/2024-10-16/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=fa2194663d11d517bbd67c157fc40cf67149246c391e9b8adf0a46c2eb96c860 -dist/2024-10-16/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=c5271c244d8055401d3d3a97873064b93915dbcc52108cb9b61381af1ebe99ad -dist/2024-10-16/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=56c6a0cedf3ec4667d65a209477cfe0d395e534654b49e28efbd3836e8a0dae7 -dist/2024-10-16/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=c4325b80bfc63dc58c4632ede188efdc94aa4cad49abfa4e57d81faad673a35c -dist/2024-10-16/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=35b4fba91cad3bf9e627d59baf1f1864e30d002b05696c61498e73fd0e0f299f -dist/2024-10-16/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=b2f856cc81be2c6f2c4250ec88cbab0a51c3d59e73fefd66cae9b1a91a32b0bb -dist/2024-10-16/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=1b1a40377a8a13b74f62f5bb382cb8056930c543b97261d32613c53826c758da -dist/2024-10-16/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=98b1f0fc4f45eae47a6cae7e7d4d9734979d8f860c7c96da281fa1d9ed3ca39f -dist/2024-10-16/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=bae7dbd1342d5aa89c335f1dcdac0d93f5cd8198ce9f869ef4c32dba8bc6c0d7 -dist/2024-10-16/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=cb5dc166002aba8a95f7e10d2d9e93a66d51483540c7e733b528bfccdbc74d9f -dist/2024-10-16/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=c070a48d0aad7ce42cfe5eba9477a0f54a9e04c9ec5c770e91bd2db55d0d764a -dist/2024-10-16/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=424c0d9a047ac228cfed286d0a2936b857e1c575ddebd931ca634e0501c125da -dist/2024-10-16/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=b067b3d095a5b53191ff148d0e89baed0b53c2099142d885961220548b904c52 -dist/2024-10-16/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=01acab58a327ee34d100e67a4a40a9efb66a64d478d6bcaaf94ce35874296c42 -dist/2024-10-16/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=c1a715f7502ef54a236d4ebe15488ec4c1c5cc5b1c50eea416a5b9c57de66f53 -dist/2024-10-16/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=cb014573a52f2d6776e47f3f728ae1e8b05feac2274c5916b1545675e658fc15 -dist/2024-10-16/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=5abf6bf36bcb57c0492e9bb4953ef78a61acf347d20ab788b4b31da44ae3bd39 -dist/2024-10-16/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=0bee2c4ea3f8ba07c189f7e2e0df1b2627b7bb638823fde2839d46a353e0480a -dist/2024-10-16/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=df352612d69dff13b59da185581a48062e54ee07161b1fe205b92d0687a4e896 -dist/2024-10-16/rustfmt-nightly-x86_64-apple-darwin.tar.gz=b7b44f5fb37fac58a83c2220a68c251513fcca96c51a71b189152a78cf095cf9 -dist/2024-10-16/rustfmt-nightly-x86_64-apple-darwin.tar.xz=f5876f1d8181880e4ecb71eaa2477b0431dd0bbb45e6a4da8f20bc31426cb43d -dist/2024-10-16/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=cae33e30d7b2e5589a6fe681345f6edbf406aa803d0d521ea182a575ee32dca2 -dist/2024-10-16/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=21324d7c6949bd12c841db8904d9485dd709f8c324e7aea31f2a9eb2a32844c0 -dist/2024-10-16/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=cfccffb90721492cc79212ba49dd88361c6d38eab24ca4fbfd8110c2eefea001 -dist/2024-10-16/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=05c528e683c40467ed3911ec5f852914e117fd71e8a0826f17d91295d4f1b047 -dist/2024-10-16/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=97cd5e773bfebd3e1d78dc3d486a75b969e30f1dd0311d07c337440d275d0443 -dist/2024-10-16/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=19989c6e9ce4d67e068d449b92dfedd8e07bd1a287cee0410f43aa43432346f9 -dist/2024-10-16/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=c3d8ed4650b4f7902a8643bfee849926892aea2e664400b858f61000966042cd -dist/2024-10-16/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=6b0dce2bb77036d154d15ffb2495480ed8c8cc441dc8979b4fd767af80e0736d -dist/2024-10-16/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=de7b427a783d588a778a2301a1bf8e4fec076ede2006e275f45d82a87e965feb -dist/2024-10-16/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=43fdb72c7e74c86eedbb01631ec357c2cf469512c0c591d15f35f747bcfbbd30 -dist/2024-10-16/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=3fccaaf7106f47302eb3c489dd722a91727e25351278a17f81d06fbb4cd4041d -dist/2024-10-16/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=988d6c342a4561790d1024455be643e17525ae07e02fe5238fc61d00c91d3cd6 -dist/2024-10-16/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=71c10377a84b3bd612a83cd2822bc6c0eb4a540c681114d63be368da84ef3766 -dist/2024-10-16/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=1e6a3c7080334663ef6fe246eae3482a05446b83c8a0c659084ca8186b9cab01 -dist/2024-10-16/rustc-nightly-aarch64-apple-darwin.tar.gz=e68c96b5d6fc204944cd1bfd80e2c6a8332dedede98a968e170fa657e012ec1f -dist/2024-10-16/rustc-nightly-aarch64-apple-darwin.tar.xz=9f7138fecf991a17483e0359c7a5a0b4292cffeafdd4b52b7c1021cbf993ec5c -dist/2024-10-16/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=0f31c36e6b6b765e9814dd193861e2ae2a176160f22aaff6211a6da3efbc1fd0 -dist/2024-10-16/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=ab4cbc70a6002bdba2955fbbdd99f03d3e54d14d32bd2f7250be6a323f39dfd9 -dist/2024-10-16/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=e088594f42b88494401df68cc60b8d94a4c1199e3549aa6dffd513b0c5f7508a -dist/2024-10-16/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=a204d11814dfb6a3283ed84abf8b88492283eb6cfbec018a0f249d496e2db5f1 -dist/2024-10-16/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=802ae62e1023c460739670a12b8a331637cec02aec14769bf0bbdbad44217555 -dist/2024-10-16/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=9ab24e33a80a442a540720377855710c2b33617531daa625dff537d1251bb9b4 -dist/2024-10-16/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=08a139d7e1ad8559d3add81416581984d24eb997f5d03f2ea85a76eac62df57e -dist/2024-10-16/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=dc9dface28b81a1b241a6ad034cd910221866cff7188d94929bd80e3d2dc1598 -dist/2024-10-16/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=ecfb3225d805cb7faeb185e43471b35decc735c1330bcb45d54cbb93fac0db4f -dist/2024-10-16/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=60437f2b7cd51cebff36687bc904c7493ef834e39033c08e35883b3de03ed15f -dist/2024-10-16/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=aab495b49ad218fbaf6f36e0dc82ae76dd867ca77411568f15039e494154d890 -dist/2024-10-16/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=51648f6d14e8684c3f258ede3e97371c1530be584b5bc47a92b7bce84d70b397 -dist/2024-10-16/rustc-nightly-i686-pc-windows-gnu.tar.gz=6bf818c20105a30461336053b40b9b298388b341766536137a3fd6039e7885ad -dist/2024-10-16/rustc-nightly-i686-pc-windows-gnu.tar.xz=60346687b8359a3df7bc4d7beb5532be716bb699fe8aec76664b5b5b4d7cacfc -dist/2024-10-16/rustc-nightly-i686-pc-windows-msvc.tar.gz=48b542959792f1cb4c316ee417fec68ccab0ee76a68accbe667fc56ca9d5a367 -dist/2024-10-16/rustc-nightly-i686-pc-windows-msvc.tar.xz=b83ebe192f8e2d82fdb0765952e69e4234f11fd6a0a4a69d089b2df42a3c637f -dist/2024-10-16/rustc-nightly-i686-unknown-linux-gnu.tar.gz=03b36beaf28462424b3b70e6a944d24a22a551c4fd9c245cfd5eef464047ec30 -dist/2024-10-16/rustc-nightly-i686-unknown-linux-gnu.tar.xz=e00e81bfca624087f97ae2ff675adf08a72519240e31cfaf0f4da238d7be8050 -dist/2024-10-16/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=f71e27157be06043624ebb769cffc92593d4db6d2a9edabec6815d0f9be64b9f -dist/2024-10-16/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=5bd77608b891be20b38739d2b1cd4319feeb13f92214e550a01c599349fd6ce2 -dist/2024-10-16/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=0cda1b3a287843431991468cf8dea7a34221d42153e9421ed89a8f58d048e01b -dist/2024-10-16/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=57f3a4d73a40ffe0dad530334f2e584c1279ce3b81458023f034bf8c35dc6641 -dist/2024-10-16/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=5d7c5164b12ad921f1d8461d0edeb17566bf4d5861d6b0f18f66ac1a91b7306d -dist/2024-10-16/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=8ba849b777182977ad9b87c002bff49ff9ad2007932abab98509e96274b9c7d9 -dist/2024-10-16/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=03c12e5d01a6f0b66dfd728610fc0df2f3bef8d5cf418a4d5a385b11f35ecd81 -dist/2024-10-16/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=db0b2d5a9a12c9c8aa0d5d3a320ef8f815ea2ac84718e1bbe94514e7480db6b5 -dist/2024-10-16/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=2e3a85da6e7a74b079a5bbbbcd433e0271b89b873aec22c19537669bd908a98c -dist/2024-10-16/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=2b19af7ec21a9e442975b073455e4b3a2711832f6f4a521335034f47dd7725e3 -dist/2024-10-16/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=c293489afe56e4ab984bab7c0ea8db292464b1b0a83b3efac3d38079f71303b2 -dist/2024-10-16/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=fad8d9fce164461c81c5fca56c3557e76635f70ad755cfdb1a448faf161a6b02 -dist/2024-10-16/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=1a4d7fb7e5d74649270e79fcdd5b7686bf3db6985d3a781ebb1f069404639884 -dist/2024-10-16/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=cb1ca19ca8a99b68a1665937c2bfde2a275ff2746cd8b50e097202352a0f7cba -dist/2024-10-16/rustc-nightly-x86_64-apple-darwin.tar.gz=32d6c59ee1bb8d1449393b37ae9399d24ecbfcaa6dc5831ad2bdfb3a586c8ab9 -dist/2024-10-16/rustc-nightly-x86_64-apple-darwin.tar.xz=5a9237c1b359da2c6aac0d6c9202f527d5982310477c414c3c03c6eee50feaf3 -dist/2024-10-16/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=9b03ad10b3e5de01a813fd9be676135de072de0d3fe6db63e82ff881b9d81c51 -dist/2024-10-16/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=1e7b91da95fa7fba74c4f8937fc9e02b592c4a66260aab1a4feca24e136501e3 -dist/2024-10-16/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=59efe9285d460cf8080d3aaed31742cc7ae5dffebb9bdd3410be22a061fa8dc0 -dist/2024-10-16/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=e64edab835454e2024081b9c447798075cc2df3703a8b627d9661c32233c8540 -dist/2024-10-16/rustc-nightly-x86_64-unknown-freebsd.tar.gz=c1ceabe8ad4f89b401a72a6a02843a5f31267cb9762d1a8c30dbcb51c1967488 -dist/2024-10-16/rustc-nightly-x86_64-unknown-freebsd.tar.xz=456708749343846153490593eebc55d78ae347d0a1096d0fdbea19c99aa24d9e -dist/2024-10-16/rustc-nightly-x86_64-unknown-illumos.tar.gz=e01be583da5371501755ca0f6d44cd2abef40543d7d97448933e27ba0de78c8e -dist/2024-10-16/rustc-nightly-x86_64-unknown-illumos.tar.xz=42dca4d9e7d76109a3c963b5783554d6ce0171001d744f3fa6b5001bc6ad66a1 -dist/2024-10-16/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=4464cc28f6a15d5a2a1de098f28224848d0b91779bb70ace3106f3a6208d25dd -dist/2024-10-16/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=5f9b9cf42730255c27bef5187241736693b5e39de9fde935da25c9f33deb4325 -dist/2024-10-16/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=d6c2b41d4fff28d12b254d3cdab480ac4a81054e50794b6cfb7ed30065cad5a1 -dist/2024-10-16/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=1acfe2f78ff7aa747e5b307b40ff5a8be5e8076897b78b2fb5828d1bb1d74cf1 -dist/2024-10-16/rustc-nightly-x86_64-unknown-netbsd.tar.gz=9d5bfab5bfb9e6d627a5acd1f54fb164538e84c449aa3ea15841636257ec7ab4 -dist/2024-10-16/rustc-nightly-x86_64-unknown-netbsd.tar.xz=dddd1663a821d99ea19864435e1c7daed6bcb4fd914e6b79c94d644836bc8d1a \ No newline at end of file +dist/2024-11-27/rustc-beta-aarch64-apple-darwin.tar.gz=58e2ba5f6a388a5bc9ecfa1c7ec4ba3efd9662e1875ea5fba484c75c5f930227 +dist/2024-11-27/rustc-beta-aarch64-apple-darwin.tar.xz=95f3ed14a6e3093cdee83f80227c7966783fffcc0ff0be6ef095df0dc744b9f8 +dist/2024-11-27/rustc-beta-aarch64-pc-windows-msvc.tar.gz=687b58e25baa685be9357048cc1e0c469c25dc6530db55e0179234615ff4d289 +dist/2024-11-27/rustc-beta-aarch64-pc-windows-msvc.tar.xz=694e2405efb25c53575599ad6573d8c4646a168e5d4bde922ef5e7d43f3e530c +dist/2024-11-27/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=4b42d00e701f90c1fff9a692f1bc1da957fcadbd1813c3066dc1f1990bceadcc +dist/2024-11-27/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=4f83a8cced878c03aea2d6cec7e1d588c2b6590850664f28f3b49a3be3a8b827 +dist/2024-11-27/rustc-beta-aarch64-unknown-linux-musl.tar.gz=bae97ca3778fbaa40f6db4da4f6da0b2bb870e9880165fc3126363f55a1fb23a +dist/2024-11-27/rustc-beta-aarch64-unknown-linux-musl.tar.xz=3e617e866a8c03fef243dede8c086d085a6564aeeb5570bada62db5a16e95f2a +dist/2024-11-27/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=96d2f23814db8286de9ffce7bab033aa4dc656f83aa39418c8f877a5befbb100 +dist/2024-11-27/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=0433a866c4d8a434990746216232759345d3ef556b0b92358b231fc1e727962e +dist/2024-11-27/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=6a776c6eb2b7b4992eed6a127d11b8845695cdc5d23938ced2267f88f8d97033 +dist/2024-11-27/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=2649e0f522755dcd511a6459258c3c3a24808fc49d3513f3d9098b17bd0f2c79 +dist/2024-11-27/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=02a65e970ee930b46c2d10e1eb3d2e6f2420e08bbef039f10a8311baf57f274f +dist/2024-11-27/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=3843610c7ecf98948a5f78a364c223d520a084bc8c49ec0c3c8ec48bad6c0bf8 +dist/2024-11-27/rustc-beta-i686-pc-windows-gnu.tar.gz=75288ca1e65157b8902195ec2fff31015017c90d3b8f51890f2f851529b200cb +dist/2024-11-27/rustc-beta-i686-pc-windows-gnu.tar.xz=5c694e50b41cd6f2c7b59b891eda3e728a1a2c56617b96c9da001b35885637b4 +dist/2024-11-27/rustc-beta-i686-pc-windows-msvc.tar.gz=6d1a66c090322ccf272a425c779f9165398e6bd9e0c7e5d0a5f262086d43ed88 +dist/2024-11-27/rustc-beta-i686-pc-windows-msvc.tar.xz=e826fe8be287f8969d11f620da9d01ea0d913eba145fb79ae86bc78674f1b919 +dist/2024-11-27/rustc-beta-i686-unknown-linux-gnu.tar.gz=31e0d9a1ff97d92c391cc913fd865a0c8afd614279654350d469bdf881a1b1a3 +dist/2024-11-27/rustc-beta-i686-unknown-linux-gnu.tar.xz=3b11a6be4863cb6ad420b66558b7745431834d1fac5dbda899a384dc30b526cf +dist/2024-11-27/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=59d96cd092a56d12ea796b65225479803edadbdcb483effdfa36e191f73483f1 +dist/2024-11-27/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=0714a469cbd7d96118e9260f80fedf34b21234776904e9c8ec5b71c9493dd36a +dist/2024-11-27/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=25113ca9719a036ae581f68df4dda74f1446b49ababe7bb194510fbd1b296e7a +dist/2024-11-27/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=25bd910ea722fe2d4a1e66089352c92f97759ec7212af2b9a04431b469ed8e12 +dist/2024-11-27/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=7a83c9f63d88849c4d691ad1d7fbe7ab5924b5a7d76378ddff5024269be95310 +dist/2024-11-27/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=fbbb11b4c986186d94b0e00ebc70400d0071efc2ba3b802abdd877d86b8cacdd +dist/2024-11-27/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=6223dff24490e3e8506dfbe2b12620155d7c05fce92191cb01f3b28e269bf1be +dist/2024-11-27/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=6fb1edea73bcb76d9cb6061d1aba15ee4655a212c1bf96328a225c7c05df3462 +dist/2024-11-27/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=0b7bc9ec0c40a6203fb62eb71fb6eeab43a4f64a2f7d0d51a1e0d041a216adb1 +dist/2024-11-27/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=d77a49acbf26b8c9a2a5f79fdc640feb1c81b9fa38f442b81f69127f49c7cde7 +dist/2024-11-27/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=bdf45a37fad10df4822690ea73840b38ee3e1048878982e625efbad3b2054f28 +dist/2024-11-27/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=ad6a2f03b2e27711e1ec4eb75502782c4bc0200cfaca2b5246e0bd5b86bf29ad +dist/2024-11-27/rustc-beta-s390x-unknown-linux-gnu.tar.gz=b0cc3024a717d33775dbea63e83f317f8826e564ceb4ecb7a6cf23676f66ccdc +dist/2024-11-27/rustc-beta-s390x-unknown-linux-gnu.tar.xz=9d5b44a82803d5de5355ffced6ec1dcb9860950910bba6dc54878ad4da7ff444 +dist/2024-11-27/rustc-beta-x86_64-apple-darwin.tar.gz=c7174c35b530453182f5f0b15c6684c030a2ff2770f4cc1a4a4ba75695e53b99 +dist/2024-11-27/rustc-beta-x86_64-apple-darwin.tar.xz=c68c26159a3fb4d4380fb25488aa78223989893d7786b8ec947d82ce0cc905bc +dist/2024-11-27/rustc-beta-x86_64-pc-windows-gnu.tar.gz=c97caf7877097d78fe2191e715e3a45d827d28c27b4dabf0747f8ca522ee43f5 +dist/2024-11-27/rustc-beta-x86_64-pc-windows-gnu.tar.xz=b7794ecabc42698cb77c1c90d66676a8b1b3632108ab95954ee496ee7d6e5708 +dist/2024-11-27/rustc-beta-x86_64-pc-windows-msvc.tar.gz=28068a6e050abe21933920dba3ead2261f7d0c09687d5a86a5db51cca6e72ea9 +dist/2024-11-27/rustc-beta-x86_64-pc-windows-msvc.tar.xz=3860d7ec8564019c79551727a3a54c66453a7d654fbb89b8feeae75d9021fa77 +dist/2024-11-27/rustc-beta-x86_64-unknown-freebsd.tar.gz=6c2a918f8d40ba01e648565c98ea120d32562dd93820e8f2e33abb2aef08e1da +dist/2024-11-27/rustc-beta-x86_64-unknown-freebsd.tar.xz=5d1edcc6c4be49849c3c2d1c3c173d4a127db3cfb615093e5ee396e0d0c77366 +dist/2024-11-27/rustc-beta-x86_64-unknown-illumos.tar.gz=a64c30d82dca58d09bfa38e72bbe1457b48b101157193a3ee33dd85922bbfe9d +dist/2024-11-27/rustc-beta-x86_64-unknown-illumos.tar.xz=87d14b146386fe1f9e24fedc25e1bf9682913bbd7537047b0baef0d74cad5473 +dist/2024-11-27/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=3f186913535ac59446e249f4d3e35e3d93a3f8207b31ee31b3f70af8344856bc +dist/2024-11-27/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=0c17a60ebac74a9cdfc2ec69fd71a21e370ff178f4c83be6020642b55b6d78ab +dist/2024-11-27/rustc-beta-x86_64-unknown-linux-musl.tar.gz=327973698dd0ffe9b2d56b3b5929f82ec552f2002b4113fc9a738e27b0005ac0 +dist/2024-11-27/rustc-beta-x86_64-unknown-linux-musl.tar.xz=d7e2f768922ae36a9eb302667398ee308c13f829c03235682529fce90253813d +dist/2024-11-27/rustc-beta-x86_64-unknown-netbsd.tar.gz=13f327974170a0423ea6e7241cd3a454ab8c39b657a707c08f2e306a7a657b45 +dist/2024-11-27/rustc-beta-x86_64-unknown-netbsd.tar.xz=5c75388802c0ddcfa51336883f4039b6f7963e0efbe47c209bb455c12951990b +dist/2024-11-27/rust-std-beta-aarch64-apple-darwin.tar.gz=84c4c02fdecc669c5d26c49120fdece5899133c098f5ef791ea19aba33936dea +dist/2024-11-27/rust-std-beta-aarch64-apple-darwin.tar.xz=7ea047840073e6ad3123a61ca799bc56c951edbb71cb8495ecbc2029759a0190 +dist/2024-11-27/rust-std-beta-aarch64-apple-ios.tar.gz=dfb8207b4b3bc13a9704fd1d212d92a22a0e7a57293f24f28bcaa846ad4c08b6 +dist/2024-11-27/rust-std-beta-aarch64-apple-ios.tar.xz=96940a84d95b4cfdde84a501758c9dd83f5d6cb5afce9142917d5cb3dd75c040 +dist/2024-11-27/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=4ed66daf59e9a8b61d66caef4b2248be72049282518d7526be771301bee2b905 +dist/2024-11-27/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=013d59e32097917b269c45a837bff380a41c4f6401b0c145264cca5a1bbd91c3 +dist/2024-11-27/rust-std-beta-aarch64-apple-ios-sim.tar.gz=270a0322dd3c2342745faa8797f4f64da8c0028b322385d209ff65cf04965a47 +dist/2024-11-27/rust-std-beta-aarch64-apple-ios-sim.tar.xz=9d54f7f51c99f17ba9cfe7cbe005ddbfe598f8af6df1dfccc9ef37029cc08b41 +dist/2024-11-27/rust-std-beta-aarch64-linux-android.tar.gz=9ae4c1d6044b2c3586791f127108e308e0a381e8e14ecc20b3830ae5258a03c2 +dist/2024-11-27/rust-std-beta-aarch64-linux-android.tar.xz=689225ea098a88a88e8e2269ef53f964405a6c31b3ee2bda0fef98da4ed9178e +dist/2024-11-27/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=f1d9c996cbe468ca93b15c76b84c544930d7452f1eff2968a298c885203f14cb +dist/2024-11-27/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=f3f8c088d74c81b2457ddff57008cb908cc86e16d0fac60d10969e45210d88d6 +dist/2024-11-27/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=fb4e5d66911a47bd63429686885cd5c7f0a6310b25622f36bb43a754300526be +dist/2024-11-27/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=ab6c7d346bfd72f06fbbc198743bda35fcb7fd1e131c05c54935b6ceff282f17 +dist/2024-11-27/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=32b2e0d5161f7d8354d846c91e5cb25530e78351dfcff4ebf0a6fba669e2c483 +dist/2024-11-27/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=656fc4a8af570b28b3f83cd59d4e5226f15d11b5d8c26b58ca2c1b2a4e18c4df +dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=13c98efcde78c1e187f728509f2950a0a407ba32e730877cb9ca4cbb4ba01469 +dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=6372891715046375fd0a04e80c95bf79080db2d136e187b02ea96647e9281407 +dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=db156e0d5db6f04621e625e92323a04091c049a8b5e2b4f7e0fb2e50b81ab2ec +dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=b610214bb59b8f58be96b84b0f13e5f50473e21039f6e827fa16c446d0e9ccba +dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=99f96b0bda31bf21853c96b3618408587f275f46ea9bd7d1fc741e58343a5625 +dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=dfa1f209f546b457aa6ef742a645f00f55c70fde86522c737f7a560494170157 +dist/2024-11-27/rust-std-beta-aarch64-unknown-none.tar.gz=4735b29991a2337a7e2016c5a827635e17ac149372efafc0442a86b0dc0759fb +dist/2024-11-27/rust-std-beta-aarch64-unknown-none.tar.xz=fead0635c572aa4f5e5564e497f1b7e892217ebe52fea54aedacbefb32f6343d +dist/2024-11-27/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=bbb9b6fedb874a61d99d22b4cdb2d20d8b9e6c69924922312692aa526851b960 +dist/2024-11-27/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=9e0d48236676dc9947565daf0c2605316c5b4abc06bdb1c343559c46b9c4e304 +dist/2024-11-27/rust-std-beta-aarch64-unknown-uefi.tar.gz=e230ffa3d46dbe5330416cdf8b7235b8dc2cf119ef8990b422eeebd017ebd17f +dist/2024-11-27/rust-std-beta-aarch64-unknown-uefi.tar.xz=38a5560575740f92cb8664d204924cf7a2972e0f2f396852d8a22befd2cdd848 +dist/2024-11-27/rust-std-beta-arm-linux-androideabi.tar.gz=0b0a9f95d10484207c52fcd8ab1bd56903b53f18ce46fe263d5b7bb085044246 +dist/2024-11-27/rust-std-beta-arm-linux-androideabi.tar.xz=91f7655ab2bce397a0821edc0f523dbf2bac0af39a50ead106eb1de637ec5c44 +dist/2024-11-27/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=e8210f03bc18661954f147dedd0b4af721d005866c0c4fea1e91594cd6c9bc2b +dist/2024-11-27/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=56a623817e6a600e802727d59d4cd653e84cb628695e39ecb23ae99065113115 +dist/2024-11-27/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=310a408bde58335d8011af480d4f8c38745865772d71631596cef1a79f9f4fc2 +dist/2024-11-27/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=fd6766ea9e828adc2e43ff1654a459785eed05ad00c7f6804c742ff8ae8f6b8a +dist/2024-11-27/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=e663e30526d85d89f41456a3d5bcd411397cb69e7cb9508aa1472b015963fd18 +dist/2024-11-27/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=0361504ada464a7d21e7ac66fdf9e1e820695f3a8ca4854695e78a748c5c7a18 +dist/2024-11-27/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=c375be97e626900d809390c61bf6f2d689c9fca8e58c85e4e02b694bed4c5ce0 +dist/2024-11-27/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=c33e3b4f9098860f75fcc9a8f86c7e7173692ad4c19cbb2c0de068961f87c192 +dist/2024-11-27/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=3f50d9afd9df4db85958e4575429dd4c80b6702a8d91c3f1d9327345aaadefe0 +dist/2024-11-27/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=0016d3a6ec8351ee9fac2eeae358a0854a3c2b360822bb3ba670255e8f27f57e +dist/2024-11-27/rust-std-beta-armebv7r-none-eabi.tar.gz=f23117b972ccd21c0a6f4db4b544401045c9f157595a297fb56d7e864cf190fe +dist/2024-11-27/rust-std-beta-armebv7r-none-eabi.tar.xz=ab9be4bb25b1575af276cbec7fb1a1f8c683741b0f137bca7b4b61ab13575645 +dist/2024-11-27/rust-std-beta-armebv7r-none-eabihf.tar.gz=673561456e26bc992cb6a888c34c0b6b13e1bd0d3e0764360a785a6c3369f0d0 +dist/2024-11-27/rust-std-beta-armebv7r-none-eabihf.tar.xz=29c6f01c636bcd901b88e92c60874c454369efd41f690d74b1fa2adf3450166a +dist/2024-11-27/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=c214d4439676a19c057324dc736d63aa0328ac74c0eb9ced8d782d8bc89757ae +dist/2024-11-27/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=4baf85ac632750c35d007bcae8f23720208c5197f4a1d49b0a85b2b0e137f603 +dist/2024-11-27/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=a7e81c0e80f2508c81ba9d8e658dabeb19af2de6f7365f6e377d39e99d8449e7 +dist/2024-11-27/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=3f37f746aaa03107573a3a2b201c15bf86777ec405dc03640e7d3f24f718f67f +dist/2024-11-27/rust-std-beta-armv7-linux-androideabi.tar.gz=fe7c7ecb8a8e612caf0e7ecf04d18ccaed31d8b93911ded6b3cba0c78fcbbddc +dist/2024-11-27/rust-std-beta-armv7-linux-androideabi.tar.xz=d571b714821de4b7d2accad221b5e043e7f9aead8dbc06586f4f7ff3f3f3e38e +dist/2024-11-27/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=663396f0e4c45bfc041b1a502b64627620f499ca6343664633761c3fb1c2229e +dist/2024-11-27/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=4d8c47d74958e3b1058ab721e9c6635774afad0252f251b0c9fe4f0895d0c81e +dist/2024-11-27/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=3cba82809bc1204b6e8f62877c5e9f9a08f111da7d439032cc30d55be0e88fd7 +dist/2024-11-27/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=d525a4dde496e72fd18c6f2a525756d652ced436007f513267e9201d8b1c0a40 +dist/2024-11-27/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=ec0311a0722f205b117160817b2137e9a73f0f4e540930d61c831ceba1265f0d +dist/2024-11-27/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=c63c4a28225dfca26baab129f06d8537fae5710083046f203a2fb73c50b48671 +dist/2024-11-27/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=52eae1bdf37366bf406cff95e5e7979d0651979ae5ad4c036e8badddc8ec8b82 +dist/2024-11-27/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=542791fb5cd80fe5515ab0812c9fd8671f083151d4262fc76d26f7723ba961e1 +dist/2024-11-27/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=91697f75c762bdb51f19348953768a45bc37c389c2e904a56f4f092604ed2d1c +dist/2024-11-27/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=a79a7a5974b365f70598c413da3db8262d14414e3b4d48dde45f529bca4c6ef8 +dist/2024-11-27/rust-std-beta-armv7a-none-eabi.tar.gz=6eec497ec2aaf6c5beb8e6dfbeaf32190b6f7206aebffb7499b5fdd7e5e7643a +dist/2024-11-27/rust-std-beta-armv7a-none-eabi.tar.xz=234924a6746fed2efa112b0b805d0ca56252b6cde82e6422774871e9c009fed6 +dist/2024-11-27/rust-std-beta-armv7r-none-eabi.tar.gz=1b0cd107412fae22266267bd8eccd2b39a36afa8936da3888d0bd0d2f4cfdb1c +dist/2024-11-27/rust-std-beta-armv7r-none-eabi.tar.xz=0d0d1ee48f9032df88ea7b3f73f06300686f4d5b9fc16f1d4554caf8356cfd74 +dist/2024-11-27/rust-std-beta-armv7r-none-eabihf.tar.gz=72f0549de44925bd08286e092261164dac47826124123e3fe707411a3dfa756c +dist/2024-11-27/rust-std-beta-armv7r-none-eabihf.tar.xz=eb45acd55dd70be3670de83c8cbef5b6ef05827b3f97b7c71679a19c88f8f3e6 +dist/2024-11-27/rust-std-beta-i586-pc-windows-msvc.tar.gz=edd8dadbba618f2a786dfcc68e4a5c7f2b7cf1528d1c16ca6ddbc52622df95c6 +dist/2024-11-27/rust-std-beta-i586-pc-windows-msvc.tar.xz=ae59c5d77b31aeac30c22104abc0abda6b7f725419e9f86db6cae634ededf262 +dist/2024-11-27/rust-std-beta-i586-unknown-linux-gnu.tar.gz=8996c94269e4c60270d253ea75bddb9482facc441ee2314a387888924bea1d92 +dist/2024-11-27/rust-std-beta-i586-unknown-linux-gnu.tar.xz=f6b59e3d6e7f0e458c048ad4aad9a2da23f3b54aeac20a905d2e00379da1bd6a +dist/2024-11-27/rust-std-beta-i586-unknown-linux-musl.tar.gz=85f22b148be72691214dee620eac582405dc3b8937d2ef7c480c9070b963af3a +dist/2024-11-27/rust-std-beta-i586-unknown-linux-musl.tar.xz=4b48538541dd20fad8569cb3f0994d5ce6aceaacdd8b319d00b0234cefc5c267 +dist/2024-11-27/rust-std-beta-i686-linux-android.tar.gz=6e5ce19fc4cd8cf4dbaca8b31f4032b08ee413ce20f354186e4945efd4e8b6af +dist/2024-11-27/rust-std-beta-i686-linux-android.tar.xz=5e78b98abdf2b7348381863052c109beec025a5f68285ce72e6f6e9245c22ce3 +dist/2024-11-27/rust-std-beta-i686-pc-windows-gnu.tar.gz=50057f990d1127e7d693b1c5b9539b19262a478130bed51dbc2837d61d2db6da +dist/2024-11-27/rust-std-beta-i686-pc-windows-gnu.tar.xz=ea524b276e42a1cb918625df12b8d3397ada5ecd43bb9ad5c676747e1f916c8b +dist/2024-11-27/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=c7c9093e277187590b86ea02fcd940071c8bce93a894396d73953276ec58eb1d +dist/2024-11-27/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=a67879ff0dcc591d30a155fd972149953eaac3b139bec9aca3a383dc277ddbc6 +dist/2024-11-27/rust-std-beta-i686-pc-windows-msvc.tar.gz=a086c8272f9c7c0db3d5de37b027478dfc22fc577c613254a821700c645df3c9 +dist/2024-11-27/rust-std-beta-i686-pc-windows-msvc.tar.xz=8ac4b938e0b643e47d6d0ba6e5283887fcc73cb1a825fc065c35879b085d9c28 +dist/2024-11-27/rust-std-beta-i686-unknown-freebsd.tar.gz=3614b95b54ca24c598e3ed6e14aaa86f7048c2a5be2b3e9f97d9ca00f3d890ce +dist/2024-11-27/rust-std-beta-i686-unknown-freebsd.tar.xz=6d36127f5c113b01300fa0d54062bc1137b51d2514346c8d84bafb9f2c56a972 +dist/2024-11-27/rust-std-beta-i686-unknown-linux-gnu.tar.gz=a6d33a96eeb667f3f4649ea6ccdd6212a183bce85f095ff7db5036c3a50d35a6 +dist/2024-11-27/rust-std-beta-i686-unknown-linux-gnu.tar.xz=bab1dada484d61bb96e2834da5fc6ed5d4d788e6636849e9802f9fb6bff45d55 +dist/2024-11-27/rust-std-beta-i686-unknown-linux-musl.tar.gz=0ac331a1c9e384430a5f316809bffdf01bae3ae9cc1f807f07142ffde7388602 +dist/2024-11-27/rust-std-beta-i686-unknown-linux-musl.tar.xz=136341bbf4c820dfc98e96cee41fa0e9fcbc7d81d2772407efaf1d4be6d10f7f +dist/2024-11-27/rust-std-beta-i686-unknown-uefi.tar.gz=32f06ca3b2752a8687e2f282a59823671fcec672bffc0775a9fb27da50b6bb11 +dist/2024-11-27/rust-std-beta-i686-unknown-uefi.tar.xz=b2f376089b39a34f3308833ce9bf65200f9665e5c55bbda3e5b7e9c5096b7e67 +dist/2024-11-27/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=a2ca950893c93be71c7db707230b98674a29c013546e27d95bdf8c3c6eebf9a7 +dist/2024-11-27/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=c70b58f4583578347e9f0fa20d17bd5fc51d88717095e05d73091209f2a363be +dist/2024-11-27/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=ed284c40b6253c022e39718dc2af2e4100ca7e805d35d86aca04937586f26ece +dist/2024-11-27/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=3efcabf46e0d02505ebf0926c6c14e0c70838f9b510f2328ccd98dd0fa977794 +dist/2024-11-27/rust-std-beta-loongarch64-unknown-none.tar.gz=9b9f8418fdf64fef652f15b28a1a1f2f8c63c18da8b323994f10f921010721ab +dist/2024-11-27/rust-std-beta-loongarch64-unknown-none.tar.xz=fdc673e4b250424c6dafc18a165ffb592aecd7b897e483af8ca54aa145a0e6a9 +dist/2024-11-27/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=802d22c1c364a58402f9313c6ba2f58b79f3cf3163842a608b78680fa2b3d476 +dist/2024-11-27/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=dc4932d91d8a2887d309dbd6317d6c41afd083043f44742138ca7c97f60b931c +dist/2024-11-27/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=636b19ca036fc7ddcf358062c98f6bcf31e8c2cd035cbb9dc0a6b96c81217f7c +dist/2024-11-27/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=31f80fc50be95bf665d21fe52b714532ff34ebfcdc0c975bb68f7d2f2cebd0e0 +dist/2024-11-27/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=f2c83275df652bc5b387525e77a1aa30bac31fb301b304ddd7e6bf402e140c34 +dist/2024-11-27/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=41358bdb20fe3a97a95fd7b656b1ed03d5b8012354d8cfad2437bc9ef6c7aeb6 +dist/2024-11-27/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=49b8f286b4abb3b34bd38c92ea3e15efbd1f623d5efa7bcff10711b595363579 +dist/2024-11-27/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=283f065701c77fa47a2d5413d20fa40989fbbcc75bc938889de6c4f9b6b9e53e +dist/2024-11-27/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=d0ee5ba5dd6f94dc6ca981be0d55f2e3f51c2af25877131a7a74e0ab9848dc3d +dist/2024-11-27/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=79c78bb31022ec8e7a3fad9823c5d22ac553d389104844110473d1877d8c8302 +dist/2024-11-27/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=b953686e3034f2b51033a2630328c8eb5f59fdf8ef4e26189bddb8efb4c482cf +dist/2024-11-27/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=fb25ac2e68594d379f915f0555b3ded2b1a7b5a67144e12eb62949f540b0d957 +dist/2024-11-27/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=fbf5a16a57de3a7e846389aebe18bc7871f43e67eff39fc9b4744b5a445b2639 +dist/2024-11-27/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=55a92aa5770924a21b706724c15f58d66ef2ca5b630f7025f6ba1416152ef350 +dist/2024-11-27/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=b880b7209ea604761ad2a46832925d32fc547737b879645fd3cf99ec235e7b39 +dist/2024-11-27/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=c48cc6a6fda06fab014c0b8fef49006dd32fb71f8e981ba44a0c25d47fbfe034 +dist/2024-11-27/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=7d133b6c8d0e8b8ec8b65a74ed8d64a22e2fa5e4f6d4a1e36f9e0ebb8826f40e +dist/2024-11-27/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=1c507e003c38115bfffe8701df1ff7aed6ad16ef5ac4b383f84bd2d6aa0216bd +dist/2024-11-27/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=111a909b3d1a04b328ca1c1f247ee4eaaa84349eeaa8df77f7901bbc0efc94c1 +dist/2024-11-27/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=d29f92ed071c60259feaa8005eb5392da549f8e2069fecb1b77e112f89cf1bbc +dist/2024-11-27/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=241b1ec9ef6a89277944c9d8021f521284dc28822c5f80513b6cd94d2bdd1d64 +dist/2024-11-27/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=9f5b02be846fa2084becc5616f024094d47beca102442ac7a0e3588e0f12ee7e +dist/2024-11-27/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=7272eae1625415c0f57bf541dd62c14e02b9946ca1de04615827a1f5218c2181 +dist/2024-11-27/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=d4bcd0068d3c9e7351565fec57ca68d36c9ddbfe59249a6bd2c56930ebad2257 +dist/2024-11-27/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=758ccc47004398add2e3cfef52e4839e14dc4d132a215658e576e590401a28ca +dist/2024-11-27/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=6902fee1027b0136f8dc5179e69e24ed9e34366e9409129b9ba223043ddadea1 +dist/2024-11-27/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=3024570f3e382a57fce0e832c52d080a83d42206d8412b724361bd1f0087ec4d +dist/2024-11-27/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=20eaa72b6fa32b9884b43030a0bee554bafa9de3f3b51c5768ba0ff47ec492c1 +dist/2024-11-27/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=a3eae70be3fa5b0a56cc88cc6433cdb7c42b3b974caf0d879d21a5219f4f826e +dist/2024-11-27/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=1da88d1882d4dd1f15ca97e016f392a01b56951882ae75929023e83fa557d796 +dist/2024-11-27/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=387cc8ccaeed6f9c6a8c9d21004e45ac97a9739643a63448eb893e13ed4df22d +dist/2024-11-27/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=1b9afe3631fb7847b2a8a8f483fc00ca203ccc18ae298339801dab1c7b06b3b3 +dist/2024-11-27/rust-std-beta-sparcv9-sun-solaris.tar.gz=f9a4d2115d6fce06e0da7a9f579b197d383034c218573e145b3c7dae0aad21d4 +dist/2024-11-27/rust-std-beta-sparcv9-sun-solaris.tar.xz=c352bc631e538d4e68eaaccdfb9dca1c9dc8ff0ef4a75d8ee91016aada39d717 +dist/2024-11-27/rust-std-beta-thumbv6m-none-eabi.tar.gz=d97851ca9193d98192a55aeaf695973ac706e6ba3e198643c200cf410817b424 +dist/2024-11-27/rust-std-beta-thumbv6m-none-eabi.tar.xz=89a6524a3743e5a769a583b4a6bf8a76ef5b45c67b7e39da7ae24b687bed4943 +dist/2024-11-27/rust-std-beta-thumbv7em-none-eabi.tar.gz=6fe614db166618a8f2ccb5807e02884daa8bd8dfded2164f88d79fc688047020 +dist/2024-11-27/rust-std-beta-thumbv7em-none-eabi.tar.xz=91c5e4f4575ab004119797988679077e5057881ad9a7f6790b673dd062a8b7ee +dist/2024-11-27/rust-std-beta-thumbv7em-none-eabihf.tar.gz=d0e05467fb1562ed7d6687a50b7fafa14ba0c2aad328f0e7c19eaca1ee366475 +dist/2024-11-27/rust-std-beta-thumbv7em-none-eabihf.tar.xz=0473372df5fece49e58efcd3b2a702bb93e47ec149b38fd5244ad667804e7c63 +dist/2024-11-27/rust-std-beta-thumbv7m-none-eabi.tar.gz=e6b6130a1a571325cc1bda8ddba6b2672104c2feeed5c93c6022bfcc8ba4b247 +dist/2024-11-27/rust-std-beta-thumbv7m-none-eabi.tar.xz=d4c739c42104e04aba55b96a3ad434e11b013ba44649dd3a648cfbb15de83eb9 +dist/2024-11-27/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=e427d5d6a53abfb53b436df96457d58eedc648198fce6b1d976b50de18cbc31a +dist/2024-11-27/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=11142018c11849c21adaa7096abf50d0c923f3b8f07d67eb96d6860d428e9b27 +dist/2024-11-27/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=46596d8f2271dd5a6f0f84387ac19d0e81976adfc6050b6aab6cc554102fe469 +dist/2024-11-27/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=f3d0c9db1c50a018540278433fed2e0ae4bc798aa0dac87cf0f55ad1808618a1 +dist/2024-11-27/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=c46fc4bf174fc54f5565fa04e80efff4e853642e3e5f0bf5b696a2bd6e7ae817 +dist/2024-11-27/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=706c10ef22cc16b3d4cab8fc09d8783384313b9f774229470b8ae1dd292850b2 +dist/2024-11-27/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=b9cec80ed374f7b5f22f1446e3f2e0dacfaa0e2d4d6c631ad66cc42a23e156f7 +dist/2024-11-27/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=41c67ee95e72a3d10bdf739c4841bd937c4e0b19c33451724c1f603b4bd2a318 +dist/2024-11-27/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=5ad8603f98cff0d5d015c72f3a55730d75d59680a867c067928bf4586c00d805 +dist/2024-11-27/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=61a75701f7e000f86f318a04dc6746f029fb933e0ea94944d76c7eefca1f24b2 +dist/2024-11-27/rust-std-beta-wasm32-unknown-emscripten.tar.gz=89bfbfea23974ed75a53ff134386992e9c257d3e51a55eb49847aec9c5ba6b13 +dist/2024-11-27/rust-std-beta-wasm32-unknown-emscripten.tar.xz=e34d1586bc6767b4b244f98754badda706645fdec7168ddc0a409b9f95f2b18d +dist/2024-11-27/rust-std-beta-wasm32-unknown-unknown.tar.gz=8a88bb923e138d0015c8f46bc1c3d5f2f5f75f40dddfca72a49eed42c080d1db +dist/2024-11-27/rust-std-beta-wasm32-unknown-unknown.tar.xz=79a980f2b999c3e3b04d7e327bd2b548007039b45da705847c6da2bfec3ffc04 +dist/2024-11-27/rust-std-beta-wasm32-wasip1.tar.gz=454e2c4b46b4684e591c6e4c0f1ce8e3c44623a29d561be3a481ae008072dbd5 +dist/2024-11-27/rust-std-beta-wasm32-wasip1.tar.xz=4dcf652ab51fe03c4691de46365218dc483cf1f7c2f5a552a38509685a0ca873 +dist/2024-11-27/rust-std-beta-wasm32-wasip1-threads.tar.gz=c2c34d9b3998633cfa145dc2a5568a99d1fe26b91c5be55a08870a1d27db4af7 +dist/2024-11-27/rust-std-beta-wasm32-wasip1-threads.tar.xz=4d5b25e4b5fb71d879f15f320f7513eec1ad078d3ca6f525ebf56b9620bdb5ad +dist/2024-11-27/rust-std-beta-wasm32-wasip2.tar.gz=e1385a340d3d9a4003cc456156bfbb1435a5255b2bdae3a40b6d7339768bdc81 +dist/2024-11-27/rust-std-beta-wasm32-wasip2.tar.xz=245e7914174d213ddbb550b09fff200f419bcd632de98548a470013891666410 +dist/2024-11-27/rust-std-beta-wasm32v1-none.tar.gz=d5d924ea001f914bf87df8765b013db6e838a930a4865e95f8d35bfaa86bc81e +dist/2024-11-27/rust-std-beta-wasm32v1-none.tar.xz=bb98d0d55f38f2308bf99d4e5f11842683452571075eefa5b4e1f18f2bd553bf +dist/2024-11-27/rust-std-beta-x86_64-apple-darwin.tar.gz=edd5e7ea230a13be750dd74c5f7a7dee20db8683f7978aeb352307a0ce110b9d +dist/2024-11-27/rust-std-beta-x86_64-apple-darwin.tar.xz=c6cec9a501d9873e3c7abdefd5b9418f7250c8cb915be8b816cb48dedf1f201e +dist/2024-11-27/rust-std-beta-x86_64-apple-ios.tar.gz=e970c2a4ebfb69219dc66e4c7541cf22c52da5f94983c7c914df1f93beda3d31 +dist/2024-11-27/rust-std-beta-x86_64-apple-ios.tar.xz=594ae9bf5f1501322d986dc91249a48a61c22371513b872fd63e134097ac55ca +dist/2024-11-27/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=d57bf579b4629417dbe1c02506db4a4ba4428871a2684141d21303e6c99551f5 +dist/2024-11-27/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=714db83e7563a5f286fb37bc629b64834a9ed981bb9a05931122072f95e39bf8 +dist/2024-11-27/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=feafcba9c46ba3e5fa0bd9b5bedc05ef3423c9962dc4d25a7b2367e3e1caa679 +dist/2024-11-27/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=78fbc8f45df64dca21da7223b5d081111922f2268fcc4f1f83595d159d310bce +dist/2024-11-27/rust-std-beta-x86_64-linux-android.tar.gz=74fb57da7f2907afbaa2a7a73847273ef81e2d6902a326f1ae87767677a864d3 +dist/2024-11-27/rust-std-beta-x86_64-linux-android.tar.xz=3216eb73d9c9effcd2a2de7f63d78055c3d7e50fb8141e2910a45a36ce744ffb +dist/2024-11-27/rust-std-beta-x86_64-pc-solaris.tar.gz=3df431c8941ac28906c3a6568d3debe478d9349d868ea8bd3ad79e65792c20e8 +dist/2024-11-27/rust-std-beta-x86_64-pc-solaris.tar.xz=548c2a6104148bf0da21bf5e009b80522fd15539077a62021a64f16282815a5e +dist/2024-11-27/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=235228431d67feb4c8e6aad44e20bf68574f335e8f948808b597ae98d827171d +dist/2024-11-27/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=5a2d4ed70aed26f902cf45e1dcabc5f25884cf6e9aaff775405ba9c1f0a5cacd +dist/2024-11-27/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=818131158e8be6af4b762750f7927c4a799346c94059a6073230da79b4408720 +dist/2024-11-27/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=fc08b39833e2c9319dcb55cef5c6d1f0110aea794c9a6f163ca39749a22a94b9 +dist/2024-11-27/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=6164c3ade38c03113193301b815c52df0ee84a4ca1c8ef21e1a56d386e28df00 +dist/2024-11-27/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=0846126e6c4cf2b5184979b6025fbb7bddb5c22905bc7ba31fff69f6b1459280 +dist/2024-11-27/rust-std-beta-x86_64-unknown-freebsd.tar.gz=ae308e29be13a176b26c142347a81facf8c11ef1a28e67d5898f4f2a0d3344ca +dist/2024-11-27/rust-std-beta-x86_64-unknown-freebsd.tar.xz=e80bcba8b011a4dd3f7b2a2cea69b5a95ae2cde9b2d9078ac8fdd492ac162139 +dist/2024-11-27/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=b25f0d605b7f4a2a93adb746e32f59bfc26af569a4169e9fb203cb33751d1575 +dist/2024-11-27/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=010f35236062a651b1b54d7c928068efca8dc486856b84b04e98f4f97583bf32 +dist/2024-11-27/rust-std-beta-x86_64-unknown-illumos.tar.gz=db3d258c2caea73b469feb9c11fbd3bcc29d22c3969c406321d11f05c24974ed +dist/2024-11-27/rust-std-beta-x86_64-unknown-illumos.tar.xz=a952b0c2bbed9085525c041c957f00b6b1020e031149dba70c09a1a0d40db3ad +dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=817d3d3a931eba2255bd5721435cba7604fe37a72c18a179c1fd5f06dc3b97a1 +dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=170a54aa50f161576d4b0d103f2ab6dcbbb81ee57a5a47f7fbd181128f6c17ff +dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=ea991dce55415ed7462abbeb1ac1c70795cb628b0460e14230e8cecd41117fca +dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=a8f620c3a641f8f4c29d88e4cc54d7637aeb18cf8eaed8571ce558835f742601 +dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=875e2e3309b1deccc1a4476e4847a2849df32e0e2a394e4ddf3b4abd1feca534 +dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=23f21ac664b3341771109ac69d094518a512391b86219ffec50725dc68a08504 +dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=680f5b2c63f58643bd34f9921e2c1699a549410ab06bfd04ce991907e8fd7d8f +dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=dd10f6f3ce39489b6e3f3f638573e850c36518e3b2e8ffad0c50c3143e3a8124 +dist/2024-11-27/rust-std-beta-x86_64-unknown-netbsd.tar.gz=fd31ba490f0bfc53530e34e6e5ab35a52eebee616efc8ed18d473065ea885230 +dist/2024-11-27/rust-std-beta-x86_64-unknown-netbsd.tar.xz=daffc01050f5cf0b5ece91717d7a4c42cd4a148c4c11f641b494d9c375df5177 +dist/2024-11-27/rust-std-beta-x86_64-unknown-none.tar.gz=376d571641a9f1f75fadf951da91bb73ba94a5495d7d33389f5f914ccbec57bb +dist/2024-11-27/rust-std-beta-x86_64-unknown-none.tar.xz=ffd9e826537dc94c6d8e767ef5a61d1fcf0385b8ccbe508ff9177de0fe772939 +dist/2024-11-27/rust-std-beta-x86_64-unknown-redox.tar.gz=447e434b5e40f7882d7adb6d0346629e0e3e92d0f339c7781e5a437898a84b4a +dist/2024-11-27/rust-std-beta-x86_64-unknown-redox.tar.xz=bc21caabcb492ca648e19a8f3b9dc1a1bf7792135a202831deb554ec3ea11077 +dist/2024-11-27/rust-std-beta-x86_64-unknown-uefi.tar.gz=40ca7d9ebcf6610c26f2921c0560729e708f5661bf6167266e9d8cb3987ad0b3 +dist/2024-11-27/rust-std-beta-x86_64-unknown-uefi.tar.xz=06966d5901f5d9accadb47c4d1e561f3f95bd050f3f8e78f30000389f39e9b6c +dist/2024-11-27/cargo-beta-aarch64-apple-darwin.tar.gz=e1a24f081ddd93b483c0f1c196bae676163db50fef0a994bc47c2a7c98c9dfa7 +dist/2024-11-27/cargo-beta-aarch64-apple-darwin.tar.xz=d51a5f0669906eceeee4e09b079828e2ebf3404aaedf1fb20745339205270ee0 +dist/2024-11-27/cargo-beta-aarch64-pc-windows-msvc.tar.gz=e135a5f0f83432b58d9e093c6d560b021a133707e39e1ded90a28a9967105e0f +dist/2024-11-27/cargo-beta-aarch64-pc-windows-msvc.tar.xz=1fbe65015cb8c7ab0b863ffc6f7aa72d3bf52f7830957ede8915c61a22e5b993 +dist/2024-11-27/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=9d4e830e9ba582302865fcefe31883cef4a471e77d46e70838e549ca11a0fbce +dist/2024-11-27/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=233f6347a36e806dcf27ecad4906c90bb3353051f440a819989efcf091cb78b8 +dist/2024-11-27/cargo-beta-aarch64-unknown-linux-musl.tar.gz=6cd719a7255a0eb1f11592b9a92d0aa4986363f624ee0d6077fcc253acab66a8 +dist/2024-11-27/cargo-beta-aarch64-unknown-linux-musl.tar.xz=b874ca8285ad1936adc70a9323cf80f06322b1e6d5925f54b58500129830f0ca +dist/2024-11-27/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=ec7200319224ccabe814cb051e51d147f1ae8c763413002fd03c9263a02c2320 +dist/2024-11-27/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=86e96c80a91862e59123272c80f1cfabdca56bfddcd66af4a5e840af7421c4e1 +dist/2024-11-27/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=3f7cfdcb28fe8c3f0dde58c24a0c424652b40d00a24fc50891351fa5bff5c15e +dist/2024-11-27/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=2d5a184b0103ac943ec4f6756fbc7126773e739e0d120acea7b3244c7cd19b1b +dist/2024-11-27/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=9a77540943f28584d90b4bcae4e234cc9d833eb732f65d7fbd680a0f4e915da4 +dist/2024-11-27/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=7696a065951b7d7179b30ff2fd16a05675b6bd4250f293666b98ec05299113a5 +dist/2024-11-27/cargo-beta-i686-pc-windows-gnu.tar.gz=eaff75076ad71a4291af5465dedf0fb0998dc171e35ab8f707ac63b43e89c38a +dist/2024-11-27/cargo-beta-i686-pc-windows-gnu.tar.xz=205d3d19726a1a87a1533d94f77b73ed9de8181906acb48088dca22835aa7a83 +dist/2024-11-27/cargo-beta-i686-pc-windows-msvc.tar.gz=58da319889533ff7be5c9142c2abdd1ade79de10eb83d7ef82ebd93b75607f8b +dist/2024-11-27/cargo-beta-i686-pc-windows-msvc.tar.xz=5ae699d0f6b9e210a988af5b8f2f0c4d62fb1695ed6fa55718fdf05298039b9c +dist/2024-11-27/cargo-beta-i686-unknown-linux-gnu.tar.gz=362f6338ea929ceb632307031e049dee1b3ed998f5cf160654c327c5e0e7ed39 +dist/2024-11-27/cargo-beta-i686-unknown-linux-gnu.tar.xz=88f14ca7b5c8af006f3c54749b61747485f7e93fde4c65b5969e73503d12c5c2 +dist/2024-11-27/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=9ee8f29e3e715cd7c85e679fd01ca724a27503a50edb0e6f8912f289630bc7a5 +dist/2024-11-27/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=4c643f0d18ba101c2b248e1df32ec3ddba82efc0d5f9b47945d484fd3d462794 +dist/2024-11-27/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=f70952c63e2eebd05acc326cfa667595535fc36db34bc0262fda4ba100ff2145 +dist/2024-11-27/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=0546a908cc12884801c35b461f98db01e87a7f92d276ca6cb6b89eb76c596e2c +dist/2024-11-27/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=3534e839b34603e4e2b32fb8ecc76163ea3b9cd9907c1a22fde4165860d1fb56 +dist/2024-11-27/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=b402a2e73debd81dc5cbc866f00c2ca82f676e2f923193674969af0ab34ad311 +dist/2024-11-27/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=fa69011557fdde5af1f78f33f9ba75a1d6f4488b9d8edd2958582593dba347fe +dist/2024-11-27/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=679be0bf62c7371b92f1824c8718662672ac3ef2d79e8af5c752fe34effbe333 +dist/2024-11-27/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=ecc2ba0da5c1057136eb105ec0727e55396e414d75efe0c2b96bef0477961574 +dist/2024-11-27/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=a89ad44842df861c69c6633ba79bf4ecefc38419d5669b6f22a265dd7be836f2 +dist/2024-11-27/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=051437ff7d177bdeb7a5a0eb947d27b8cf352c8e809b9311a1cc21b785a5a8b5 +dist/2024-11-27/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=1a4f50972104a95c404e778279a4acd42176cae45f58d316d601e7f38dc7bbc0 +dist/2024-11-27/cargo-beta-s390x-unknown-linux-gnu.tar.gz=bbe9812fe890b900e71aa4714dabd2f3e67bdc610fe0bbd5aea645ee807dd0ff +dist/2024-11-27/cargo-beta-s390x-unknown-linux-gnu.tar.xz=eebac7e8555f44ea9094750b61bd11d758197a72d4d436e1713e4bca42fa8080 +dist/2024-11-27/cargo-beta-x86_64-apple-darwin.tar.gz=6773b94f012a3d3589e2bca28f35dd23208fb245f107e4a17b8b3e7f893c038a +dist/2024-11-27/cargo-beta-x86_64-apple-darwin.tar.xz=d3a20dbd60545b0162dc06499317e342bea077cff369e053eb89e85e2b640188 +dist/2024-11-27/cargo-beta-x86_64-pc-windows-gnu.tar.gz=39e16c97c0b22533dfa674d6e8f5bf5df256e2b426d02dca5ed33e246f18d05b +dist/2024-11-27/cargo-beta-x86_64-pc-windows-gnu.tar.xz=ffd939f901c64a17c3f24fc69744cd2af1c176a45d8e5fa8209067ada403db7d +dist/2024-11-27/cargo-beta-x86_64-pc-windows-msvc.tar.gz=8addc12e74a983f3166b89d1d53ce87c92f38c7c3a62ec7c66580aa424d20516 +dist/2024-11-27/cargo-beta-x86_64-pc-windows-msvc.tar.xz=8e5622917395ff50e53b237e7322f1faf2b64f0446c41ccaa0096e57a3e7de69 +dist/2024-11-27/cargo-beta-x86_64-unknown-freebsd.tar.gz=2734d099aa1ada79346213aec8cc7ebe40312df1dfb40a32d09ccd3b6622e025 +dist/2024-11-27/cargo-beta-x86_64-unknown-freebsd.tar.xz=642edcaf16dd74c0935d28ce9b37cf1c5ecb9c03bec30f6ff0e7476760ae7ca2 +dist/2024-11-27/cargo-beta-x86_64-unknown-illumos.tar.gz=4f28de38005de48db7126dcb698b748063341de41dc71175605301837a3f7336 +dist/2024-11-27/cargo-beta-x86_64-unknown-illumos.tar.xz=ce18692f99780ec09d01816277ee4e71785bdfbd7abb4375ba8d87c1b6905ffa +dist/2024-11-27/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=f1d692c3a1c280f34de167ef26af3c13a6d0a3b5ae4fb86b0a9f2178c3287a94 +dist/2024-11-27/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=21f477af2b49ec8809bf8bc7b4c4919c7d2ac57782b829f5a0d9ef1967c5d71a +dist/2024-11-27/cargo-beta-x86_64-unknown-linux-musl.tar.gz=4bed61be221c1347b1649f54222b27e2a3577b84816ce1099c9f0f461c6e9e5a +dist/2024-11-27/cargo-beta-x86_64-unknown-linux-musl.tar.xz=33f463209d50ca6b04a8953c87d2177a84d1729d635de9a7c9b1a711ccb5d751 +dist/2024-11-27/cargo-beta-x86_64-unknown-netbsd.tar.gz=ce46b5b2d767cc0d790d8fd21052ecfb787dffb4218a238a339fe5f1afd26d6f +dist/2024-11-27/cargo-beta-x86_64-unknown-netbsd.tar.xz=0afd0489cb4231edc5bc1ef24a43c3f1918f681f08c1207d184fefdb46416509 +dist/2024-11-27/clippy-beta-aarch64-apple-darwin.tar.gz=6e5f1a85dad2b899567369aceac0102943ab807dad7e218c273b7b4d6393dba7 +dist/2024-11-27/clippy-beta-aarch64-apple-darwin.tar.xz=f784ac4a6ab180675396adf8256ac2bf2d1e823bef106d1c6c59911a8360692c +dist/2024-11-27/clippy-beta-aarch64-pc-windows-msvc.tar.gz=22f1e9299a24aebaf9a32471ddc6cdbf856b455d059ca077170aecf5989f8772 +dist/2024-11-27/clippy-beta-aarch64-pc-windows-msvc.tar.xz=7f3fd047ed5aa85ea6ca2b0d6103f7530d7d070c93b0f212c9d1a6491f160cbc +dist/2024-11-27/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=f383ecb5cd654268f00be1f577572993c38e7386a1e1d18b864338e87c7b2b42 +dist/2024-11-27/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=b2043facf587f98a8f10a92ae129b7f608297709f4ac61d683b7c813cc65e41e +dist/2024-11-27/clippy-beta-aarch64-unknown-linux-musl.tar.gz=6678d45195bd2a7b27ed2d4bad3790e6b63e376da71d112b9333760ea375c40f +dist/2024-11-27/clippy-beta-aarch64-unknown-linux-musl.tar.xz=f6c77e80c9ea4e312fc2715a9f66ea9a2e6344e3f04ab96cc572e4c0e8c915db +dist/2024-11-27/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=be8c0dfde3f09bf476d6600b530aa498b01415015665429bebed8814c7568b73 +dist/2024-11-27/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=4315f7623dcf0a278cccb6c8b397a29f83f70ecb9b03588f61e383e5ebaa697d +dist/2024-11-27/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=c31ff694c68f28e0f462133e783a5d732cf9c539737fc8dbbfd01a53e9a456c3 +dist/2024-11-27/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=2553ae5596b8273d8a61ec66d2e20d0c9733c9f791ca5c56217c60884f0ccf9a +dist/2024-11-27/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=1842cf2c26ab474df47e74720c56997e270b37609f840ac50ab0b05064cb38fb +dist/2024-11-27/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=e882b1cc2814e3c97c33991fa0a80de62556ce8f4f88307f6338a90be32b045b +dist/2024-11-27/clippy-beta-i686-pc-windows-gnu.tar.gz=7c6e08b841f21e3b8953e51a6a9fd9df0c719e8defd7b1ab0660d8920fe72185 +dist/2024-11-27/clippy-beta-i686-pc-windows-gnu.tar.xz=137aec194877446fec994a233427db419bb4f2910151c456c3ec80d9329628e7 +dist/2024-11-27/clippy-beta-i686-pc-windows-msvc.tar.gz=52ba38277ac3f80d124fdc8dd1709b8c1115cecfc53fae4731da8615a63f78cb +dist/2024-11-27/clippy-beta-i686-pc-windows-msvc.tar.xz=548d3eb599334ab98791b8ba27decff8b0de98dfcffadc994ad38aad6255cff5 +dist/2024-11-27/clippy-beta-i686-unknown-linux-gnu.tar.gz=448071394d5e647e8da8f64cfbf85e8305d85ff9357dd24737523c95eb339ab3 +dist/2024-11-27/clippy-beta-i686-unknown-linux-gnu.tar.xz=e25daa6264cf5e0a7cbcfd827e27a8e276c29c88c86cc15977c1a1650d0303f9 +dist/2024-11-27/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=9f080cc937e7209ad83fdb8bf4b2cd7b080af83dbd9061229f154785e273bfec +dist/2024-11-27/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=7d537f66195c581ff51ce8f53c4687a762daf225c7f0ce76393953ab04b804e1 +dist/2024-11-27/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=2bd38261a9ef33ad687b3edcd33f283c32a493a80b56dbefc822c1116edb1f2f +dist/2024-11-27/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=7e63dff1d8abe517aefeb4b1976932d23a9a7ed5e4db2398d8ba2659301f639c +dist/2024-11-27/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=1495b2a49cfce014da72beb691e6c477d189ef34080acb1761b588d11b75d27a +dist/2024-11-27/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=75da94f1ade2ef48674b77ded595c69ee715f62f9d9dd96e72039e27807b7314 +dist/2024-11-27/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=2d6b826fb4d3d9b61ecd3aaffdd1334f766dd5a5fb0d8279e0de26d381c5cbdc +dist/2024-11-27/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=f5ceaca2651d6002f232f71809458ad912bb5f00030790e907ff7b0e12c9e0c1 +dist/2024-11-27/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=1a62f307197c6fd08fbeabef89f58842cfd59c6d62f530850592fe55852d61f7 +dist/2024-11-27/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=4c65fd6a5d74527391fbc7c242a2313e5290209f5a15763d74eeaa6cba0a0ed0 +dist/2024-11-27/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=8ab9f735a98de1949e65d51c3050b29ceba3ddc28167ba0180353253dc726392 +dist/2024-11-27/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=0367eb23a9349ebd829d59fe0a2638557c8e57205e48f66a701b238461385bf2 +dist/2024-11-27/clippy-beta-s390x-unknown-linux-gnu.tar.gz=ffe9100ec6b81b081d5f9d840bdf01c658790d7e6bc0674e5ebb6b28f79c2f7f +dist/2024-11-27/clippy-beta-s390x-unknown-linux-gnu.tar.xz=b19b1b28bb7ddf8cf977f102acb623f65d5117c44ab8b62cf197f2d3d33c15de +dist/2024-11-27/clippy-beta-x86_64-apple-darwin.tar.gz=d986de5c01bde3469693dea7cb4248155ee9791550aa179d601066d27e45afb1 +dist/2024-11-27/clippy-beta-x86_64-apple-darwin.tar.xz=8000e46ccc2598fdb770c69c68aeb18d94db9b2847d0509f7a9c51ef28714ba7 +dist/2024-11-27/clippy-beta-x86_64-pc-windows-gnu.tar.gz=c701581f28d885889ae5c845a7b34beebb04a4631c2740e9333b69390cfaf499 +dist/2024-11-27/clippy-beta-x86_64-pc-windows-gnu.tar.xz=fc285792e6f626e133edede613a9a9a90ee12191765e2f0beac642a3b3c9ca12 +dist/2024-11-27/clippy-beta-x86_64-pc-windows-msvc.tar.gz=91afdb71bdd54e5c04fc7c933dac06d5e769627e886e20eb712524e852a01966 +dist/2024-11-27/clippy-beta-x86_64-pc-windows-msvc.tar.xz=2ef7018c7319e3a299c5eddf36748d9d293ae43eaf54662d9855fd211eb4658c +dist/2024-11-27/clippy-beta-x86_64-unknown-freebsd.tar.gz=02234d4c47478112e01d51bc7dd48cd467293e1eeba55bd383d08bc7376c471d +dist/2024-11-27/clippy-beta-x86_64-unknown-freebsd.tar.xz=a3e6a0c7f31278866d97816c5ed434b1987e0bc5a89b24283e836402803c1388 +dist/2024-11-27/clippy-beta-x86_64-unknown-illumos.tar.gz=b238ab536ac963929884da4dc9bab43679e6fa9aba4251c73ab7e5cbe5d8eeb9 +dist/2024-11-27/clippy-beta-x86_64-unknown-illumos.tar.xz=797ea7a7643a8302e45347f21c4dc6bdee617c2a9d9ccef74ed525c7d2e9dd91 +dist/2024-11-27/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=d630a6b25a08af85d3d426e73d3231e018e0ab7176a5934572786147fbbf3823 +dist/2024-11-27/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=d0259a0112f452ee49b8c9bebd760ab8945e5bc3a0d57b1cdc2b8e24accd35c7 +dist/2024-11-27/clippy-beta-x86_64-unknown-linux-musl.tar.gz=5febe478e5040f0f74a14c23e78eed21b080900d875d6b447354945c07677a6f +dist/2024-11-27/clippy-beta-x86_64-unknown-linux-musl.tar.xz=552c35bbe76a83439e66cf9ccd522d97e43a8fe4f6aadbabd1f02c4b2c1814dd +dist/2024-11-27/clippy-beta-x86_64-unknown-netbsd.tar.gz=ff6db2d7b84e1b01c81e494de15ccd07f60fef6dc60fa46d47e128ebaba4022c +dist/2024-11-27/clippy-beta-x86_64-unknown-netbsd.tar.xz=b27f89b175bee3769dab1c2d0c54f17ff3efba2038f3b600f4077435c7fd21d3 +dist/2024-11-27/rustfmt-nightly-aarch64-apple-darwin.tar.gz=5b5015483d0a98e9dc715c3cc8c23598c02fc14ea6e5878790ae68f2f1c8ef46 +dist/2024-11-27/rustfmt-nightly-aarch64-apple-darwin.tar.xz=ce5706f0397a1b2fd9e17dbf34ccfbc3e8c87cc81c92b54b81fd33accc2b7c06 +dist/2024-11-27/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=3f5077c8743b5c4f233da7d0aa0aa13fc488ef0fa9da24b002bfa413d52dc845 +dist/2024-11-27/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=087eb30f24ba7d8ee42e28bce2a6cd75e5fb7ef5dca8a738ef23fac82ad59566 +dist/2024-11-27/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=28a716ef9c5318543559ab4c0c2d062b0deeab1ecec80d5d83ad5effb574f209 +dist/2024-11-27/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=99cf9ec4b7bea4281f64a613784350a8ac34e9b0387fed7eb26d6f8c21c83735 +dist/2024-11-27/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=a23c3de89603bd4d1035a267e6ee456c6de12efa4029d76ded3edf7c69285a15 +dist/2024-11-27/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=462dfd28b631b5a6d8277920cfa8037d8583cbf6a2e5c9159c492161013e820a +dist/2024-11-27/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=44af5b13726cab40865580df8bc05182a2359eae64e41a92f84790ef55ca6bdb +dist/2024-11-27/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=0a7c0b207e745d01194d96f0fbe2402273d630d4f1aa05001a5f5371c9585a2c +dist/2024-11-27/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=66e2fc688b8f746d15c0dce042f2a94e06c5b652d5e0b6534d9e992eec186784 +dist/2024-11-27/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=15a2e087f7b482fa8c027fe6e6fbaf846d784c8e917fed375048a297d5e13c45 +dist/2024-11-27/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=71788ea2544f8349ec548a2f150dca2afe80a49deb91c00c46484a5e3039742d +dist/2024-11-27/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=d9fa7b780b9d8b93549abf0a3f0e6f31cc8e1e991ddf682adf3b616fe2a1f0c8 +dist/2024-11-27/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=30924bad51ffa62f762d4c000f86ea3457b590f6397d65755c711ff7f77ac129 +dist/2024-11-27/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=14fff13942e6a65927776c49013249b2e75aa3a630667ecf49c9ba721e47bcb4 +dist/2024-11-27/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=02d82688bdf3bd3c261a4a6d4acfb07835e29ce262cdc3165ba849a6a8490bcc +dist/2024-11-27/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=2a19b55bb609542ec49dea87e3b67532e5d18df8be43d0ad775bb34f4f9f96a0 +dist/2024-11-27/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=d07ca0ddfb0dd89a9cc935b2b9662379bcc9503cb28a28d68c5165f787a7d762 +dist/2024-11-27/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=de8106801b1e49dfd8a4fffbfc2a4f949218eaa011ca2085953ebf2a5ea9b141 +dist/2024-11-27/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=309024f86e80a4568721b5bb61aa936e027accc251fa97acd5043b513b325576 +dist/2024-11-27/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=55bf234aa2ec7fd4c6a7179f779d790e7f62969967519bacfeae84db5cd29abe +dist/2024-11-27/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=4bf9571182e7ef40e76c7e5905fab8ac35269ace390f5007480b4951f80cfa3b +dist/2024-11-27/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=2a2cde80fcbf68768ba7a99cb059a0cdc9313ad0c934383dde9598d6147ef756 +dist/2024-11-27/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=b747fb16b15cff3f9368ce1a1f5cad0d2930bde5a609547a3afa2679d7ab8a1a +dist/2024-11-27/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=b861f8361ee806d83f38afbbbf312e0e5e4d8851e7048444c409de1a83484446 +dist/2024-11-27/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=ebe56700ad0948e4dcd9930730f7df8e01a5eefca1d1157fe12160d782e2a5c0 +dist/2024-11-27/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=5081c9b8677314464d8a3a50220809def18badb2269d2cd8b7106f3547b0e25a +dist/2024-11-27/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=2ed9094b538b6450371311b742f2d309a1f40b2b4c84deb9867059336b76d1b0 +dist/2024-11-27/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=d9d52d9b9f4da7a457d05dd4645885d092f170bd2f751a49b4ab3b88395a5248 +dist/2024-11-27/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=a2e51d381645c6bf18502ca72fe9f10ffd309281dae87ec16c5627f232f77e50 +dist/2024-11-27/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=c526efc054c33a08626b882eebadf887a9aaf8fd60a4adf6a146659a7c1ec8d7 +dist/2024-11-27/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=04e5b7c97b57ff7d967abb4f98374f0833108c04f6edf482b8b3fefbde340956 +dist/2024-11-27/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=1829afdebce1c3fe249f81958de68c765db18b431927e54fc42be37ea4ab8226 +dist/2024-11-27/rustfmt-nightly-x86_64-apple-darwin.tar.gz=d6cf138d02e50168f8ee4a89abb2a4a39e19458d060d7b46cf227bba1fd4c0d8 +dist/2024-11-27/rustfmt-nightly-x86_64-apple-darwin.tar.xz=e8185262c82c064c4bb9ae6f1d3072819410de9cfca943b77605012a546c254e +dist/2024-11-27/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=64d78f9f05a978b95b9e22a63bbb31dcf98152df5638f498a361a96d9d2b0c04 +dist/2024-11-27/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=c07041ab84364ace58a357c18b5c4dca037852e1159edabb02f4579ac6853b4a +dist/2024-11-27/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=7ef0122ccd3a0c77c917bd75e93358eb95d7e87d78a165c724e3f0cd90f8209c +dist/2024-11-27/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=d0d0566a0a50e1e9e7f4251cf207bde82d96c27016f0a0acc364754561ab4881 +dist/2024-11-27/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=e4854528c31316894339bfa97b07ec607e8956877c285778e555885ce9c8a068 +dist/2024-11-27/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=d79c9b352ed7b2f132f06dcdf360527502b2153beb09cca968a5ced521edcd39 +dist/2024-11-27/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=df76cbeae0a61506a29db22e8743d16fcd97ef2da216ea15bf4d6cd709814017 +dist/2024-11-27/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=103cbb30bbe92da6666d84fab53dd7fe8105c2ebe62eeab5f6609488e62a481b +dist/2024-11-27/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=5f3c61663a319d6162240192f387e10ab87e2a972062198082158a243b667d7f +dist/2024-11-27/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=221b45c3928b1c45fedbeea987ad80750d3f55fbc564cf3ccf910a68447ad725 +dist/2024-11-27/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=18eb24fd665ce1cc4ce66b37b19c22397bff9369963b127137780870c179228d +dist/2024-11-27/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=bcd09587a21ea10953a14521e9e0ba7b5100e8e15b6a10cc4e7bd359200d5279 +dist/2024-11-27/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=db712c5e1d21231770e12dc95f6bcbe2f1d04b9cde61bc7adf8b529b41773adf +dist/2024-11-27/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=43303e426752dcd15964416822cdce0e5f3012366a9b77f3d68e6011c7bacd0f +dist/2024-11-27/rustc-nightly-aarch64-apple-darwin.tar.gz=95d543a835b11cb5ccbf0578df1ce4e1846e4915622d23a36cc6e18e44e17f29 +dist/2024-11-27/rustc-nightly-aarch64-apple-darwin.tar.xz=db9e0c51c35c81c2ec8be0838f3231f7374917215792ffee159e3d7ffed855d8 +dist/2024-11-27/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=bf9b83d6418bf97caf2df70a8e8298cd8fecb7b950cdaaa2cecbec243ed57c74 +dist/2024-11-27/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=bb520da5b522fffb5a20eed4390990c2ab9d22eb4f77196535a84ae7a434c9f5 +dist/2024-11-27/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=4072d9ca2d617d09d394139c0b8608bb8b2b8b2b4fa450f13c41975a16a791c7 +dist/2024-11-27/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=3d75a8a534e86bb55b63f5b5b2df66ae47862cb7f3ecd1591a829435031d7279 +dist/2024-11-27/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=3cf05e90bc1f95e92cca4769f74055245234037009cf464df3062238c88bc2b6 +dist/2024-11-27/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=245ebb7886cfba64d667630ca8bd672520cfece0ccec3b916e3de0f26aeada52 +dist/2024-11-27/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=dadff4abd2f169f9aa1910d4ea247b7d1f767fca74238ad31485b73399ab6dda +dist/2024-11-27/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=ff97e1201e9a305673e8a9b740b7696cc4cb5e86bfaa3e137cd8e3e28cffd7a6 +dist/2024-11-27/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=0c411e0824140323f51600d387d52bd01f601f5539d6457815e950224a6d29a4 +dist/2024-11-27/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=dc5731a70c393f69555433d522cde8a52893bfb88beec519c1bbb03b2a0e060c +dist/2024-11-27/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=01ef2f07f1222fbf3e0cfc5b957c287fb886fd0bd08cbf18f90dc37fb0b63541 +dist/2024-11-27/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=d45042b3ea0c0ce6befea7bfdd731e890dbd1f47d1992fe8718a1363f9f18779 +dist/2024-11-27/rustc-nightly-i686-pc-windows-gnu.tar.gz=5437da4c0b73d203789829512d856a66c1697d95afb1ffeaa6347ad0f7c04672 +dist/2024-11-27/rustc-nightly-i686-pc-windows-gnu.tar.xz=a7cb4cb627d75de1ade9211d8ea489ada9ac76ed38909751861ef0cb729dcbcd +dist/2024-11-27/rustc-nightly-i686-pc-windows-msvc.tar.gz=fd6ee6fc171459092e5e8a012d9cfb7491313e021d1c38965605836b5b101b0a +dist/2024-11-27/rustc-nightly-i686-pc-windows-msvc.tar.xz=314c7cd558a3654db85d75b3ed71da7cfec3614e4a5f2c449dbc6663b64c7e3d +dist/2024-11-27/rustc-nightly-i686-unknown-linux-gnu.tar.gz=7a1118011b11befb7df2df57e4450c7611bb3503b3b3cfece9c9c7d4a304391d +dist/2024-11-27/rustc-nightly-i686-unknown-linux-gnu.tar.xz=2cb95208e77546bcce56d8d5646c3fb5e49ed711894926cb50903ba10431a36e +dist/2024-11-27/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=4a76c4493e5ba19aaf14947a6c2e28ebfc7f2da530f1441a9fdfa328e15ea4cf +dist/2024-11-27/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=9b361904c691e17fbf44d80c7f7789511db1d8f251d65ba9cf6fda7f06fd495f +dist/2024-11-27/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=e89dc76ab061ae23081aee1619fcbf4a94e3acefef6b9b149231f3e1c22f9ec1 +dist/2024-11-27/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=11266d557e6d1d9155e6f04f65e4815cfbfd9f8e1aaa47221030e3ff11b22f78 +dist/2024-11-27/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=30f2eae1b8694607a04c836f750b4b7c204e1e14e52ec37885b9a821c2c9646e +dist/2024-11-27/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=495316e70b26140c66b074e9d7f714ab949f422c2635cab784a5e133538e4bb9 +dist/2024-11-27/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=ca560c4fe28051573d54f512652ac9740a2d1111aeb8e36b004a6ff9c325925c +dist/2024-11-27/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=1191f15bb6da98b01b43f0e9d7f51c5c45d38e3c5be2b4ae5f7c0c8fd25e9a90 +dist/2024-11-27/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=5f85829aaab919fa4b2fa5ac843b87358e8da4797adbb6eeaed5be02666ce964 +dist/2024-11-27/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=7c671d366fec561f0b568bfb4b6a08a6071303077a60f76da1307453e51ebc36 +dist/2024-11-27/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=300307ab6cf88afc4312edaa510769e901598492deec4834176c6fc9f3eef6cb +dist/2024-11-27/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=6fcf91c8679f4963f7d510cc8afbc24a1070b25ea6d20d5d31ad78ea659da194 +dist/2024-11-27/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=ab905f6f3119648c83a2f37ebe1a55b7899a5ac6d10070e4dbbfb89762a369af +dist/2024-11-27/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=13688b6857c8b10f7fb497f07c969d406cb6b76869957b5138f4b20fcc5d7c5a +dist/2024-11-27/rustc-nightly-x86_64-apple-darwin.tar.gz=e6bb782014e34fafdc5dcf3aeb407eb636d822d346c5a8c6227cc45bc645561a +dist/2024-11-27/rustc-nightly-x86_64-apple-darwin.tar.xz=6016ae620deddc42d1d6b6134b0164dab45a204089754b73db41ec837aa88a84 +dist/2024-11-27/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=ed3a381858612e25cacfd89c08496e9d06378d593ccedea4217ad4fa1ab326d4 +dist/2024-11-27/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=4819bb9c25aa743de7ab7e93b10b30336a87f1f75e5122d578df2c83fbc59850 +dist/2024-11-27/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=404aac87c77871c80f83cd7c59390af9af704ee468f40eba68d224d23e2c84e9 +dist/2024-11-27/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=0e1e0d2454ad24fe1da2cce2dce425bc1167bbca68832da2476c7996c00ba612 +dist/2024-11-27/rustc-nightly-x86_64-unknown-freebsd.tar.gz=946d5bcc3ac0b83fd0b53b60290a6361b179f16ba2aa6a2467789ad520278792 +dist/2024-11-27/rustc-nightly-x86_64-unknown-freebsd.tar.xz=f3bd1a053399ec89dccaa7456da41d54a8e91deb5c628e4c502fdcf34c5fe780 +dist/2024-11-27/rustc-nightly-x86_64-unknown-illumos.tar.gz=c353588a38705b7ae050d4b9868b6c4d3527295edbfb25c115b22cda4912be1f +dist/2024-11-27/rustc-nightly-x86_64-unknown-illumos.tar.xz=a71d8b2b42f6cd522da237f99492ed59cd34ea8c86fc1e73c8854c8234e1c980 +dist/2024-11-27/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=5116b949572fd6c7b11a079d9453b15a4c48562bce22b26d82b7050da772789b +dist/2024-11-27/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=3635df40363273d44c6f8182f5f6a3a099ed55897bb764cab2565363cd31c1f4 +dist/2024-11-27/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=5233af0b907fb7b176d2b5fee07c486e92dcbbbab1d54a60d814a827befaa984 +dist/2024-11-27/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=c908cad6d28657f1fdcbe9d84ecb86f247c75134803dd5273ca24c6c68a58f37 +dist/2024-11-27/rustc-nightly-x86_64-unknown-netbsd.tar.gz=c799165c319218a2fb4cdc0ac8db87fc9e2992a8e402d984ea27938a5ad1c5af +dist/2024-11-27/rustc-nightly-x86_64-unknown-netbsd.tar.xz=ec12763fa5d4cc150f663361cd245c30835e05e3b1928898b1b7300de559468c \ No newline at end of file diff --git a/src/tools/cargo b/src/tools/cargo index 66221abdeca20..3908f64086a3d 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 66221abdeca2002d318fde6efff516aab091df0e +Subproject commit 3908f64086a3d7b9af8d87b4da2bd100776c3e61 diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md index dd3124ee9a3b6..61efaa3bf3e6d 100644 --- a/src/tools/clippy/CHANGELOG.md +++ b/src/tools/clippy/CHANGELOG.md @@ -6,11 +6,56 @@ document. ## Unreleased / Beta / In Rust Nightly -[0f8eabd6...master](https://github.com/rust-lang/rust-clippy/compare/0f8eabd6...master) +[aa0d5513...master](https://github.com/rust-lang/rust-clippy/compare/aa0d5513...master) + +## Rust 1.83 + +Current stable, released 2024-11-28 + +[View all 64 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-08-25T09%3A59%3A01Z..2024-10-03T13%3A42%3A56Z+base%3Amaster) + +### Important Change + +* Removed the implicit `cargo-clippy` feature set by Clippy as announced here: + + [#13246](https://github.com/rust-lang/rust-clippy/pull/13246) + +### New Lints + +* Added [`unused_trait_names`] to `restriction` + [#13322](https://github.com/rust-lang/rust-clippy/pull/13322) +* Added [`unnecessary_first_then_check`] to `complexity` + [#13421](https://github.com/rust-lang/rust-clippy/pull/13421) +* Added [`non_zero_suggestions`] to `restriction` + [#13167](https://github.com/rust-lang/rust-clippy/pull/13167) +* Added [`manual_is_power_of_two`] to `pedantic` + [#13327](https://github.com/rust-lang/rust-clippy/pull/13327) +* Added [`manual_div_ceil`] to `complexity` + [#12987](https://github.com/rust-lang/rust-clippy/pull/12987) +* Added [`zombie_processes`] to `suspicious` + [#11476](https://github.com/rust-lang/rust-clippy/pull/11476) +* Added [`used_underscore_items`] to `pedantic` + [#13294](https://github.com/rust-lang/rust-clippy/pull/13294) + +### Moves and Deprecations + +* Moved [`ref_option`] to `pedantic` (From `nursery`) + [#13469](https://github.com/rust-lang/rust-clippy/pull/13469) +* Moved [`manual_c_str_literals`] to `complexity` (From `pedantic`, now warn-by-default) + [#13263](https://github.com/rust-lang/rust-clippy/pull/13263) +* Moved [`empty_line_after_doc_comments`] to `suspicious` (From `nursery`, now warn-by-default) + [#13091](https://github.com/rust-lang/rust-clippy/pull/13091) +* Moved [`empty_line_after_outer_attr`] to `suspicious` (From `nursery`, now warn-by-default) + [#13091](https://github.com/rust-lang/rust-clippy/pull/13091) + +### Enhancements + +* [`missing_panics_doc`]: No longer lints in const environments + [#13382](https://github.com/rust-lang/rust-clippy/pull/13382) ## Rust 1.82 -Current stable, released 2024-10-17 +Released 2024-10-17 [View all 108 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-07-11T20%3A12%3A07Z..2024-08-24T20%3A55%3A35Z+base%3Amaster) @@ -5441,6 +5486,7 @@ Released 2018-09-13 [`disallowed_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_type [`disallowed_types`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types [`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression +[`doc_include_without_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_include_without_cfg [`doc_lazy_continuation`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_lazy_continuation [`doc_link_with_quotes`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_with_quotes [`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml index 50a2afbfc0720..77cb0006ff85b 100644 --- a/src/tools/clippy/Cargo.toml +++ b/src/tools/clippy/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "clippy" -version = "0.1.84" +# begin autogenerated version +version = "0.1.85" +# end autogenerated version description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" @@ -27,7 +29,7 @@ rustc_tools_util = "0.4.0" tempfile = { version = "3.3", optional = true } termize = "0.1" color-print = "0.3.4" -anstream = "0.6.0" +anstream = "0.6.18" [dev-dependencies] cargo_metadata = "0.18.1" diff --git a/src/tools/clippy/book/src/SUMMARY.md b/src/tools/clippy/book/src/SUMMARY.md index be13fcbe260fa..19328fdd3cd47 100644 --- a/src/tools/clippy/book/src/SUMMARY.md +++ b/src/tools/clippy/book/src/SUMMARY.md @@ -7,6 +7,7 @@ - [Configuration](configuration.md) - [Lint Configuration](lint_configuration.md) - [Clippy's Lints](lints.md) +- [Attributes for Crate Authors](attribs.md) - [Continuous Integration](continuous_integration/README.md) - [GitHub Actions](continuous_integration/github_actions.md) - [GitLab CI](continuous_integration/gitlab.md) diff --git a/src/tools/clippy/book/src/attribs.md b/src/tools/clippy/book/src/attribs.md new file mode 100644 index 0000000000000..cf99497bc0fcb --- /dev/null +++ b/src/tools/clippy/book/src/attribs.md @@ -0,0 +1,53 @@ +# Attributes for Crate Authors + +In some cases it is possible to extend Clippy coverage to 3rd party libraries. +To do this, Clippy provides attributes that can be applied to items in the 3rd party crate. + +## `#[clippy::format_args]` + +_Available since Clippy v1.84_ + +This attribute can be added to a macro that supports `format!`, `println!`, or similar syntax. +It tells Clippy that the macro is a formatting macro, and that the arguments to the macro +should be linted as if they were arguments to `format!`. Any lint that would apply to a +`format!` call will also apply to the macro call. The macro may have additional arguments +before the format string, and these will be ignored. + +### Example + +```rust +/// A macro that prints a message if a condition is true. +#[macro_export] +#[clippy::format_args] +macro_rules! print_if { + ($condition:expr, $($args:tt)+) => {{ + if $condition { + println!($($args)+) + } + }}; +} +``` + +## `#[clippy::has_significant_drop]` + +_Available since Clippy v1.60_ + +The `clippy::has_significant_drop` attribute can be added to types whose Drop impls have an important side effect, +such as unlocking a mutex, making it important for users to be able to accurately understand their lifetimes. +When a temporary is returned in a function call in a match scrutinee, its lifetime lasts until the end of the match +block, which may be surprising. + +### Example + +```rust +#[clippy::has_significant_drop] +struct CounterWrapper<'a> { + counter: &'a Counter, +} + +impl<'a> Drop for CounterWrapper<'a> { + fn drop(&mut self) { + self.counter.i.fetch_sub(1, Ordering::Relaxed); + } +} +``` diff --git a/src/tools/clippy/book/src/development/adding_lints.md b/src/tools/clippy/book/src/development/adding_lints.md index 963e02e5c1616..c07568697d02d 100644 --- a/src/tools/clippy/book/src/development/adding_lints.md +++ b/src/tools/clippy/book/src/development/adding_lints.md @@ -438,7 +438,7 @@ need to ensure that the MSRV configured for the project is >= the MSRV of the required Rust feature. If multiple features are required, just use the one with a lower MSRV. -First, add an MSRV alias for the required feature in [`clippy_config::msrvs`]. +First, add an MSRV alias for the required feature in [`clippy_utils::msrvs`]. This can be accessed later as `msrvs::STR_STRIP_PREFIX`, for example. ```rust @@ -517,7 +517,7 @@ define_Conf! { } ``` -[`clippy_config::msrvs`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_config/msrvs/index.html +[`clippy_utils::msrvs`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_config/msrvs/index.html Afterwards update the documentation for the book as described in [Adding configuration to a lint](#adding-configuration-to-a-lint). diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md index 670b5cbef8233..275d125096e95 100644 --- a/src/tools/clippy/book/src/lint_configuration.md +++ b/src/tools/clippy/book/src/lint_configuration.md @@ -895,7 +895,7 @@ The order of associated items in traits. ## `trivial-copy-size-limit` The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by -reference. By default there is no limit +reference. **Default Value:** `target_pointer_width * 2` diff --git a/src/tools/clippy/clippy_config/Cargo.toml b/src/tools/clippy/clippy_config/Cargo.toml index d21df202dcaba..3f18a0bc7d253 100644 --- a/src/tools/clippy/clippy_config/Cargo.toml +++ b/src/tools/clippy/clippy_config/Cargo.toml @@ -1,11 +1,15 @@ [package] name = "clippy_config" -version = "0.1.84" +# begin autogenerated version +version = "0.1.85" +# end autogenerated version edition = "2021" +publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +clippy_utils = { path = "../clippy_utils" } itertools = "0.12" serde = { version = "1.0", features = ["derive"] } toml = "0.7.3" diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs index 600d5b6e2c8d9..41b56b45d9aef 100644 --- a/src/tools/clippy/clippy_config/src/conf.rs +++ b/src/tools/clippy/clippy_config/src/conf.rs @@ -1,10 +1,10 @@ use crate::ClippyConfiguration; -use crate::msrvs::Msrv; use crate::types::{ DisallowedPath, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour, Rename, SourceItemOrdering, SourceItemOrderingCategory, SourceItemOrderingModuleItemGroupings, SourceItemOrderingModuleItemKind, SourceItemOrderingTraitAssocItemKind, SourceItemOrderingTraitAssocItemKinds, }; +use clippy_utils::msrvs::Msrv; use rustc_errors::Applicability; use rustc_session::Session; use rustc_span::edit_distance::edit_distance; @@ -181,7 +181,7 @@ macro_rules! define_Conf { )*) => { /// Clippy lint configuration pub struct Conf { - $($(#[doc = $doc])+ pub $name: $ty,)* + $($(#[cfg_attr(doc, doc = $doc)])+ pub $name: $ty,)* } mod defaults { @@ -678,7 +678,7 @@ define_Conf! { #[lints(arbitrary_source_item_ordering)] trait_assoc_item_kinds_order: SourceItemOrderingTraitAssocItemKinds = DEFAULT_TRAIT_ASSOC_ITEM_KINDS_ORDER.into(), /// The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by - /// reference. By default there is no limit + /// reference. #[default_text = "target_pointer_width * 2"] #[lints(trivially_copy_pass_by_ref)] trivial_copy_size_limit: Option = None, diff --git a/src/tools/clippy/clippy_config/src/lib.rs b/src/tools/clippy/clippy_config/src/lib.rs index 1c3f32c2514ca..5d6e8b875166c 100644 --- a/src/tools/clippy/clippy_config/src/lib.rs +++ b/src/tools/clippy/clippy_config/src/lib.rs @@ -13,18 +13,14 @@ rustc::untranslatable_diagnostic )] -extern crate rustc_ast; -extern crate rustc_attr; -#[allow(unused_extern_crates)] -extern crate rustc_driver; extern crate rustc_errors; +extern crate rustc_hir; +extern crate rustc_middle; extern crate rustc_session; extern crate rustc_span; -extern crate smallvec; mod conf; mod metadata; -pub mod msrvs; pub mod types; pub use conf::{Conf, get_configuration_metadata, lookup_conf_file, sanitize_explanation}; diff --git a/src/tools/clippy/clippy_config/src/types.rs b/src/tools/clippy/clippy_config/src/types.rs index fe5764241487e..c949db9109dee 100644 --- a/src/tools/clippy/clippy_config/src/types.rs +++ b/src/tools/clippy/clippy_config/src/types.rs @@ -1,3 +1,6 @@ +use clippy_utils::def_path_def_ids; +use rustc_hir::def_id::DefIdMap; +use rustc_middle::ty::TyCtxt; use serde::de::{self, Deserializer, Visitor}; use serde::{Deserialize, Serialize, ser}; use std::collections::HashMap; @@ -31,6 +34,18 @@ impl DisallowedPath { } } +/// Creates a map of disallowed items to the reason they were disallowed. +pub fn create_disallowed_map( + tcx: TyCtxt<'_>, + disallowed: &'static [DisallowedPath], +) -> DefIdMap<(&'static str, Option<&'static str>)> { + disallowed + .iter() + .map(|x| (x.path(), x.path().split("::").collect::>(), x.reason())) + .flat_map(|(name, path, reason)| def_path_def_ids(tcx, &path).map(move |id| (id, (name, reason)))) + .collect() +} + #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)] pub enum MatchLintBehaviour { AllTypes, diff --git a/src/tools/clippy/clippy_dev/Cargo.toml b/src/tools/clippy/clippy_dev/Cargo.toml index 952a8711fb4e4..d3a103eaf4c62 100644 --- a/src/tools/clippy/clippy_dev/Cargo.toml +++ b/src/tools/clippy/clippy_dev/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] aho-corasick = "1.0" +chrono = { version = "0.4.38", default-features = false, features = ["clock"] } clap = { version = "4.4", features = ["derive"] } indoc = "1.0" itertools = "0.12" diff --git a/src/tools/clippy/clippy_dev/src/dogfood.rs b/src/tools/clippy/clippy_dev/src/dogfood.rs index a0d57f5ab483f..75a4cbd2f92e0 100644 --- a/src/tools/clippy/clippy_dev/src/dogfood.rs +++ b/src/tools/clippy/clippy_dev/src/dogfood.rs @@ -1,4 +1,4 @@ -use crate::{clippy_project_root, exit_if_err}; +use crate::utils::{clippy_project_root, exit_if_err}; use std::process::Command; /// # Panics diff --git a/src/tools/clippy/clippy_dev/src/fmt.rs b/src/tools/clippy/clippy_dev/src/fmt.rs index 8c61c35533cf8..c667385928208 100644 --- a/src/tools/clippy/clippy_dev/src/fmt.rs +++ b/src/tools/clippy/clippy_dev/src/fmt.rs @@ -1,4 +1,4 @@ -use crate::clippy_project_root; +use crate::utils::clippy_project_root; use itertools::Itertools; use rustc_lexer::{TokenKind, tokenize}; use shell_escape::escape; diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs index ad385d5fbd29f..9280369c23b8f 100644 --- a/src/tools/clippy/clippy_dev/src/lib.rs +++ b/src/tools/clippy/clippy_dev/src/lib.rs @@ -14,69 +14,13 @@ extern crate rustc_driver; extern crate rustc_lexer; -use std::io; -use std::path::PathBuf; -use std::process::{self, ExitStatus}; - pub mod dogfood; pub mod fmt; pub mod lint; pub mod new_lint; +pub mod release; pub mod serve; pub mod setup; +pub mod sync; pub mod update_lints; - -#[cfg(not(windows))] -static CARGO_CLIPPY_EXE: &str = "cargo-clippy"; -#[cfg(windows)] -static CARGO_CLIPPY_EXE: &str = "cargo-clippy.exe"; - -/// Returns the path to the `cargo-clippy` binary -/// -/// # Panics -/// -/// Panics if the path of current executable could not be retrieved. -#[must_use] -pub fn cargo_clippy_path() -> PathBuf { - let mut path = std::env::current_exe().expect("failed to get current executable name"); - path.set_file_name(CARGO_CLIPPY_EXE); - path -} - -/// Returns the path to the Clippy project directory -/// -/// # Panics -/// -/// Panics if the current directory could not be retrieved, there was an error reading any of the -/// Cargo.toml files or ancestor directory is the clippy root directory -#[must_use] -pub fn clippy_project_root() -> PathBuf { - let current_dir = std::env::current_dir().unwrap(); - for path in current_dir.ancestors() { - let result = std::fs::read_to_string(path.join("Cargo.toml")); - if let Err(err) = &result { - if err.kind() == io::ErrorKind::NotFound { - continue; - } - } - - let content = result.unwrap(); - if content.contains("[package]\nname = \"clippy\"") { - return path.to_path_buf(); - } - } - panic!("error: Can't determine root of project. Please run inside a Clippy working dir."); -} - -/// # Panics -/// Panics if given command result was failed. -pub fn exit_if_err(status: io::Result) { - match status.expect("failed to run command").code() { - Some(0) => {}, - Some(n) => process::exit(n), - None => { - eprintln!("Killed by signal"); - process::exit(1); - }, - } -} +pub mod utils; diff --git a/src/tools/clippy/clippy_dev/src/lint.rs b/src/tools/clippy/clippy_dev/src/lint.rs index f308f5dfdfd83..125195397e6c1 100644 --- a/src/tools/clippy/clippy_dev/src/lint.rs +++ b/src/tools/clippy/clippy_dev/src/lint.rs @@ -1,4 +1,4 @@ -use crate::{cargo_clippy_path, exit_if_err}; +use crate::utils::{cargo_clippy_path, exit_if_err}; use std::process::{self, Command}; use std::{env, fs}; diff --git a/src/tools/clippy/clippy_dev/src/main.rs b/src/tools/clippy/clippy_dev/src/main.rs index fc15913354cd6..56ed60256f162 100644 --- a/src/tools/clippy/clippy_dev/src/main.rs +++ b/src/tools/clippy/clippy_dev/src/main.rs @@ -3,7 +3,7 @@ #![warn(rust_2018_idioms, unused_lifetimes)] use clap::{Args, Parser, Subcommand}; -use clippy_dev::{dogfood, fmt, lint, new_lint, serve, setup, update_lints}; +use clippy_dev::{dogfood, fmt, lint, new_lint, release, serve, setup, sync, update_lints, utils}; use std::convert::Infallible; fn main() { @@ -23,9 +23,9 @@ fn main() { if print_only { update_lints::print_lints(); } else if check { - update_lints::update(update_lints::UpdateMode::Check); + update_lints::update(utils::UpdateMode::Check); } else { - update_lints::update(update_lints::UpdateMode::Change); + update_lints::update(utils::UpdateMode::Change); } }, DevCommand::NewLint { @@ -35,7 +35,7 @@ fn main() { r#type, msrv, } => match new_lint::create(&pass, &name, &category, r#type.as_deref(), msrv) { - Ok(()) => update_lints::update(update_lints::UpdateMode::Change), + Ok(()) => update_lints::update(utils::UpdateMode::Change), Err(e) => eprintln!("Unable to create lint: {e}"), }, DevCommand::Setup(SetupCommand { subcommand }) => match subcommand { @@ -75,6 +75,12 @@ fn main() { uplift, } => update_lints::rename(&old_name, new_name.as_ref().unwrap_or(&old_name), uplift), DevCommand::Deprecate { name, reason } => update_lints::deprecate(&name, &reason), + DevCommand::Sync(SyncCommand { subcommand }) => match subcommand { + SyncSubcommand::UpdateNightly => sync::update_nightly(), + }, + DevCommand::Release(ReleaseCommand { subcommand }) => match subcommand { + ReleaseSubcommand::BumpVersion => release::bump_version(), + }, } } @@ -225,6 +231,10 @@ enum DevCommand { /// The reason for deprecation reason: String, }, + /// Sync between the rust repo and the Clippy repo + Sync(SyncCommand), + /// Manage Clippy releases + Release(ReleaseCommand), } #[derive(Args)] @@ -291,3 +301,29 @@ enum RemoveSubcommand { /// Remove the tasks added with 'cargo dev setup vscode-tasks' VscodeTasks, } + +#[derive(Args)] +struct SyncCommand { + #[command(subcommand)] + subcommand: SyncSubcommand, +} + +#[derive(Subcommand)] +enum SyncSubcommand { + #[command(name = "update_nightly")] + /// Update nightly version in rust-toolchain and `clippy_utils` + UpdateNightly, +} + +#[derive(Args)] +struct ReleaseCommand { + #[command(subcommand)] + subcommand: ReleaseSubcommand, +} + +#[derive(Subcommand)] +enum ReleaseSubcommand { + #[command(name = "bump_version")] + /// Bump the version in the Cargo.toml files + BumpVersion, +} diff --git a/src/tools/clippy/clippy_dev/src/new_lint.rs b/src/tools/clippy/clippy_dev/src/new_lint.rs index e15ba3397178a..24d1a53266a07 100644 --- a/src/tools/clippy/clippy_dev/src/new_lint.rs +++ b/src/tools/clippy/clippy_dev/src/new_lint.rs @@ -1,4 +1,4 @@ -use crate::clippy_project_root; +use crate::utils::{clippy_project_root, clippy_version}; use indoc::{formatdoc, writedoc}; use std::fmt; use std::fmt::Write as _; @@ -186,23 +186,8 @@ fn to_camel_case(name: &str) -> String { } pub(crate) fn get_stabilization_version() -> String { - fn parse_manifest(contents: &str) -> Option { - let version = contents - .lines() - .filter_map(|l| l.split_once('=')) - .find_map(|(k, v)| (k.trim() == "version").then(|| v.trim()))?; - let Some(("0", version)) = version.get(1..version.len() - 1)?.split_once('.') else { - return None; - }; - let (minor, patch) = version.split_once('.')?; - Some(format!( - "{}.{}.0", - minor.parse::().ok()?, - patch.parse::().ok()? - )) - } - let contents = fs::read_to_string("Cargo.toml").expect("Unable to read `Cargo.toml`"); - parse_manifest(&contents).expect("Unable to find package version in `Cargo.toml`") + let (minor, patch) = clippy_version(); + format!("{minor}.{patch}.0") } fn get_test_file_contents(lint_name: &str, msrv: bool) -> String { @@ -273,7 +258,7 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String { result.push_str(&if enable_msrv { formatdoc!( r" - use clippy_config::msrvs::{{self, Msrv}}; + use clippy_utils::msrvs::{{self, Msrv}}; use clippy_config::Conf; {pass_import} use rustc_lint::{{{context_import}, {pass_type}, LintContext}}; @@ -399,7 +384,7 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R let _: fmt::Result = writedoc!( lint_file_contents, r#" - use clippy_config::msrvs::{{self, Msrv}}; + use clippy_utils::msrvs::{{self, Msrv}}; use rustc_lint::{{{context_import}, LintContext}}; use super::{name_upper}; diff --git a/src/tools/clippy/clippy_dev/src/release.rs b/src/tools/clippy/clippy_dev/src/release.rs new file mode 100644 index 0000000000000..ac75516870103 --- /dev/null +++ b/src/tools/clippy/clippy_dev/src/release.rs @@ -0,0 +1,27 @@ +use std::fmt::Write; +use std::path::Path; + +use crate::utils::{UpdateMode, clippy_version, replace_region_in_file}; + +const CARGO_TOML_FILES: [&str; 4] = [ + "clippy_config/Cargo.toml", + "clippy_lints/Cargo.toml", + "clippy_utils/Cargo.toml", + "Cargo.toml", +]; + +pub fn bump_version() { + let (minor, mut patch) = clippy_version(); + patch += 1; + for file in &CARGO_TOML_FILES { + replace_region_in_file( + UpdateMode::Change, + Path::new(file), + "# begin autogenerated version\n", + "# end autogenerated version", + |res| { + writeln!(res, "version = \"0.{minor}.{patch}\"").unwrap(); + }, + ); + } +} diff --git a/src/tools/clippy/clippy_dev/src/sync.rs b/src/tools/clippy/clippy_dev/src/sync.rs new file mode 100644 index 0000000000000..3522d182e90ac --- /dev/null +++ b/src/tools/clippy/clippy_dev/src/sync.rs @@ -0,0 +1,33 @@ +use std::fmt::Write; +use std::path::Path; + +use chrono::offset::Utc; + +use crate::utils::{UpdateMode, replace_region_in_file}; + +pub fn update_nightly() { + // Update rust-toolchain nightly version + let date = Utc::now().format("%Y-%m-%d").to_string(); + replace_region_in_file( + UpdateMode::Change, + Path::new("rust-toolchain"), + "# begin autogenerated nightly\n", + "# end autogenerated nightly", + |res| { + writeln!(res, "channel = \"nightly-{date}\"").unwrap(); + }, + ); + + // Update clippy_utils nightly version + replace_region_in_file( + UpdateMode::Change, + Path::new("clippy_utils/README.md"), + "\n", + "", + |res| { + writeln!(res, "```").unwrap(); + writeln!(res, "nightly-{date}").unwrap(); + writeln!(res, "```").unwrap(); + }, + ); +} diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs index 795456ad3c56d..612d1c0ae1398 100644 --- a/src/tools/clippy/clippy_dev/src/update_lints.rs +++ b/src/tools/clippy/clippy_dev/src/update_lints.rs @@ -1,4 +1,4 @@ -use crate::clippy_project_root; +use crate::utils::{UpdateMode, clippy_project_root, exit_with_failure, replace_region_in_file}; use aho_corasick::AhoCorasickBuilder; use itertools::Itertools; use rustc_lexer::{LiteralKind, TokenKind, tokenize, unescape}; @@ -17,12 +17,6 @@ const GENERATED_FILE_COMMENT: &str = "// This file was generated by `cargo dev u const DOCS_LINK: &str = "https://rust-lang.github.io/rust-clippy/master/index.html"; -#[derive(Clone, Copy, PartialEq, Eq)] -pub enum UpdateMode { - Check, - Change, -} - /// Runs the `update_lints` command. /// /// This updates various generated values from the lint source code. @@ -511,14 +505,6 @@ fn process_file(path: impl AsRef, update_mode: UpdateMode, content: &str) } } -fn exit_with_failure() { - println!( - "Not all lints defined properly. \ - Please run `cargo dev update_lints` to make sure all lints are defined properly." - ); - std::process::exit(1); -} - /// Lint data parsed from the Clippy source code. #[derive(Clone, PartialEq, Eq, Debug)] struct Lint { @@ -851,61 +837,6 @@ fn remove_line_splices(s: &str) -> String { }); res } - -/// Replaces a region in a file delimited by two lines matching regexes. -/// -/// `path` is the relative path to the file on which you want to perform the replacement. -/// -/// See `replace_region_in_text` for documentation of the other options. -/// -/// # Panics -/// -/// Panics if the path could not read or then written -fn replace_region_in_file( - update_mode: UpdateMode, - path: &Path, - start: &str, - end: &str, - write_replacement: impl FnMut(&mut String), -) { - let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from `{}`: {e}", path.display())); - let new_contents = match replace_region_in_text(&contents, start, end, write_replacement) { - Ok(x) => x, - Err(delim) => panic!("Couldn't find `{delim}` in file `{}`", path.display()), - }; - - match update_mode { - UpdateMode::Check if contents != new_contents => exit_with_failure(), - UpdateMode::Check => (), - UpdateMode::Change => { - if let Err(e) = fs::write(path, new_contents.as_bytes()) { - panic!("Cannot write to `{}`: {e}", path.display()); - } - }, - } -} - -/// Replaces a region in a text delimited by two strings. Returns the new text if both delimiters -/// were found, or the missing delimiter if not. -fn replace_region_in_text<'a>( - text: &str, - start: &'a str, - end: &'a str, - mut write_replacement: impl FnMut(&mut String), -) -> Result { - let (text_start, rest) = text.split_once(start).ok_or(start)?; - let (_, text_end) = rest.split_once(end).ok_or(end)?; - - let mut res = String::with_capacity(text.len() + 4096); - res.push_str(text_start); - res.push_str(start); - write_replacement(&mut res); - res.push_str(end); - res.push_str(text_end); - - Ok(res) -} - fn try_rename_file(old_name: &Path, new_name: &Path) -> bool { match OpenOptions::new().create_new(true).write(true).open(new_name) { Ok(file) => drop(file), diff --git a/src/tools/clippy/clippy_dev/src/utils.rs b/src/tools/clippy/clippy_dev/src/utils.rs new file mode 100644 index 0000000000000..b87fcca13b1ce --- /dev/null +++ b/src/tools/clippy/clippy_dev/src/utils.rs @@ -0,0 +1,142 @@ +use std::path::{Path, PathBuf}; +use std::process::{self, ExitStatus}; +use std::{fs, io}; + +#[cfg(not(windows))] +static CARGO_CLIPPY_EXE: &str = "cargo-clippy"; +#[cfg(windows)] +static CARGO_CLIPPY_EXE: &str = "cargo-clippy.exe"; + +/// Returns the path to the `cargo-clippy` binary +/// +/// # Panics +/// +/// Panics if the path of current executable could not be retrieved. +#[must_use] +pub fn cargo_clippy_path() -> PathBuf { + let mut path = std::env::current_exe().expect("failed to get current executable name"); + path.set_file_name(CARGO_CLIPPY_EXE); + path +} + +/// Returns the path to the Clippy project directory +/// +/// # Panics +/// +/// Panics if the current directory could not be retrieved, there was an error reading any of the +/// Cargo.toml files or ancestor directory is the clippy root directory +#[must_use] +pub fn clippy_project_root() -> PathBuf { + let current_dir = std::env::current_dir().unwrap(); + for path in current_dir.ancestors() { + let result = fs::read_to_string(path.join("Cargo.toml")); + if let Err(err) = &result { + if err.kind() == io::ErrorKind::NotFound { + continue; + } + } + + let content = result.unwrap(); + if content.contains("[package]\nname = \"clippy\"") { + return path.to_path_buf(); + } + } + panic!("error: Can't determine root of project. Please run inside a Clippy working dir."); +} + +/// # Panics +/// Panics if given command result was failed. +pub fn exit_if_err(status: io::Result) { + match status.expect("failed to run command").code() { + Some(0) => {}, + Some(n) => process::exit(n), + None => { + eprintln!("Killed by signal"); + process::exit(1); + }, + } +} + +pub(crate) fn clippy_version() -> (u32, u32) { + fn parse_manifest(contents: &str) -> Option<(u32, u32)> { + let version = contents + .lines() + .filter_map(|l| l.split_once('=')) + .find_map(|(k, v)| (k.trim() == "version").then(|| v.trim()))?; + let Some(("0", version)) = version.get(1..version.len() - 1)?.split_once('.') else { + return None; + }; + let (minor, patch) = version.split_once('.')?; + Some((minor.parse().ok()?, patch.parse().ok()?)) + } + let contents = fs::read_to_string("Cargo.toml").expect("Unable to read `Cargo.toml`"); + parse_manifest(&contents).expect("Unable to find package version in `Cargo.toml`") +} + +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum UpdateMode { + Check, + Change, +} + +pub(crate) fn exit_with_failure() { + println!( + "Not all lints defined properly. \ + Please run `cargo dev update_lints` to make sure all lints are defined properly." + ); + process::exit(1); +} + +/// Replaces a region in a file delimited by two lines matching regexes. +/// +/// `path` is the relative path to the file on which you want to perform the replacement. +/// +/// See `replace_region_in_text` for documentation of the other options. +/// +/// # Panics +/// +/// Panics if the path could not read or then written +pub(crate) fn replace_region_in_file( + update_mode: UpdateMode, + path: &Path, + start: &str, + end: &str, + write_replacement: impl FnMut(&mut String), +) { + let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from `{}`: {e}", path.display())); + let new_contents = match replace_region_in_text(&contents, start, end, write_replacement) { + Ok(x) => x, + Err(delim) => panic!("Couldn't find `{delim}` in file `{}`", path.display()), + }; + + match update_mode { + UpdateMode::Check if contents != new_contents => exit_with_failure(), + UpdateMode::Check => (), + UpdateMode::Change => { + if let Err(e) = fs::write(path, new_contents.as_bytes()) { + panic!("Cannot write to `{}`: {e}", path.display()); + } + }, + } +} + +/// Replaces a region in a text delimited by two strings. Returns the new text if both delimiters +/// were found, or the missing delimiter if not. +pub(crate) fn replace_region_in_text<'a>( + text: &str, + start: &'a str, + end: &'a str, + mut write_replacement: impl FnMut(&mut String), +) -> Result { + let (text_start, rest) = text.split_once(start).ok_or(start)?; + let (_, text_end) = rest.split_once(end).ok_or(end)?; + + let mut res = String::with_capacity(text.len() + 4096); + res.push_str(text_start); + res.push_str(start); + write_replacement(&mut res); + res.push_str(end); + res.push_str(text_end); + + Ok(res) +} diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml index 63ea6faf60dbd..c1f8e82f69884 100644 --- a/src/tools/clippy/clippy_lints/Cargo.toml +++ b/src/tools/clippy/clippy_lints/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "clippy_lints" -version = "0.1.84" +# begin autogenerated version +version = "0.1.85" +# end autogenerated version description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/src/tools/clippy/clippy_lints/src/almost_complete_range.rs b/src/tools/clippy/clippy_lints/src/almost_complete_range.rs index 370f0c482fd54..2af5178920d9e 100644 --- a/src/tools/clippy/clippy_lints/src/almost_complete_range.rs +++ b/src/tools/clippy/clippy_lints/src/almost_complete_range.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{trim_span, walk_span_to_context}; use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits}; use rustc_errors::Applicability; diff --git a/src/tools/clippy/clippy_lints/src/approx_const.rs b/src/tools/clippy/clippy_lints/src/approx_const.rs index 4f8f091a09569..ebd35fd2b27fe 100644 --- a/src/tools/clippy/clippy_lints/src/approx_const.rs +++ b/src/tools/clippy/clippy_lints/src/approx_const.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::msrvs::{self, Msrv}; use rustc_ast::ast::{FloatTy, LitFloatType, LitKind}; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -91,7 +91,7 @@ impl ApproxConstant { let s = s.as_str(); if s.parse::().is_ok() { for &(constant, name, min_digits, msrv) in &KNOWN_CONSTS { - if is_approx_const(constant, s, min_digits) && msrv.map_or(true, |msrv| self.msrv.meets(msrv)) { + if is_approx_const(constant, s, min_digits) && msrv.is_none_or(|msrv| self.msrv.meets(msrv)) { span_lint_and_help( cx, APPROX_CONSTANT, diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs index 00626a37ef840..c8dd77d9578d7 100644 --- a/src/tools/clippy/clippy_lints/src/assigning_clones.rs +++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::mir::{PossibleBorrowerMap, enclosing_mir}; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::sugg::Sugg; use clippy_utils::{is_diag_trait_item, is_in_test, last_path_segment, local_is_initialized, path_to_local}; use rustc_errors::Applicability; @@ -100,13 +100,13 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones { // TODO: This check currently bails if the local variable has no initializer. // That is overly conservative - the lint should fire even if there was no initializer, // but the variable has been initialized before `lhs` was evaluated. - && path_to_local(lhs).map_or(true, |lhs| local_is_initialized(cx, lhs)) + && path_to_local(lhs).is_none_or(|lhs| local_is_initialized(cx, lhs)) && let Some(resolved_impl) = cx.tcx.impl_of_method(resolved_fn.def_id()) // Derived forms don't implement `clone_from`/`clone_into`. // See https://github.com/rust-lang/rust/pull/98445#issuecomment-1190681305 && !cx.tcx.is_builtin_derived(resolved_impl) // Don't suggest calling a function we're implementing. - && resolved_impl.as_local().map_or(true, |block_id| { + && resolved_impl.as_local().is_none_or(|block_id| { cx.tcx.hir().parent_owner_iter(e.hir_id).all(|(id, _)| id.def_id != block_id) }) && let resolved_assoc_items = cx.tcx.associated_items(resolved_impl) diff --git a/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs b/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs index abf924f7542e2..3a462018e3e04 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs @@ -1,6 +1,6 @@ use super::{Attribute, DEPRECATED_CFG_ATTR, DEPRECATED_CLIPPY_CFG_ATTR, unnecessary_clippy_cfg}; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use rustc_ast::AttrStyle; use rustc_errors::Applicability; use rustc_lint::EarlyContext; diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs index c29c9f08cf707..a9766597d50d7 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs @@ -13,7 +13,7 @@ mod useless_attribute; mod utils; use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; +use clippy_utils::msrvs::{self, Msrv}; use rustc_ast::{self as ast, Attribute, MetaItemInner, MetaItemKind}; use rustc_hir::{ImplItem, Item, TraitItem}; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; diff --git a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs index 6948cf560a539..2eb0566bf9a61 100644 --- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs +++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs @@ -1,6 +1,7 @@ use clippy_config::Conf; +use clippy_config::types::create_disallowed_map; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::{create_disallowed_map, match_def_path, paths}; +use clippy_utils::{match_def_path, paths}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, DefIdMap}; use rustc_lint::{LateContext, LateLintPass}; diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs index 896bd5fd03d5b..6eef0d42a550b 100644 --- a/src/tools/clippy/clippy_lints/src/booleans.rs +++ b/src/tools/clippy/clippy_lints/src/booleans.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; use clippy_utils::eq_expr_value; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::SpanRangeExt; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; use rustc_ast::ast::LitKind; diff --git a/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs b/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs index f2551a05b1a22..8892a9e6b6b08 100644 --- a/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs +++ b/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs @@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for BorrowDerefRef { && !addrof_target.span.from_expansion() && let ref_ty = cx.typeck_results().expr_ty(deref_target) && let ty::Ref(_, inner_ty, Mutability::Not) = ref_ty.kind() - && get_parent_expr(cx, e).map_or(true, |parent| { + && get_parent_expr(cx, e).is_none_or(|parent| { match parent.kind { // `*&*foo` should lint `deref_addrof` instead. ExprKind::Unary(UnOp::Deref, _) => is_lint_allowed(cx, DEREF_ADDROF, parent.hir_id), diff --git a/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs b/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs index 6714c053913c9..80514cb52e6e4 100644 --- a/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs +++ b/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs @@ -43,7 +43,7 @@ fn missing_warning(cx: &LateContext<'_>, package: &cargo_metadata::Package, fiel } fn is_empty_str>(value: Option<&T>) -> bool { - value.map_or(true, |s| s.as_ref().is_empty()) + value.is_none_or(|s| s.as_ref().is_empty()) } fn is_empty_vec(value: &[String]) -> bool { diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs b/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs index b7b63250864e6..ae433773193a8 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs @@ -1,5 +1,5 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::sugg::Sugg; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs index 84a44b14dde5b..4ad39d9160def 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs @@ -1,6 +1,6 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::is_in_const_context; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::SpanRangeExt; use clippy_utils::sugg::Sugg; use clippy_utils::ty::is_isize_or_usize; diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs index 40a1a9d1ce8fb..48e9f1d690eea 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs @@ -134,7 +134,7 @@ pub(super) fn check( }; let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx); - let cast_from_ptr_size = def.repr().int.map_or(true, |ty| matches!(ty, IntegerType::Pointer(_),)); + let cast_from_ptr_size = def.repr().int.is_none_or(|ty| matches!(ty, IntegerType::Pointer(_),)); let suffix = match (cast_from_ptr_size, is_isize_or_usize(cast_to)) { (_, false) if from_nbits > to_nbits => "", (false, true) if from_nbits > 64 => "", diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs index 285f0357112ba..030c2d322db6d 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs @@ -1,5 +1,5 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source; use rustc_ast::Mutability; use rustc_hir::{Expr, ExprKind, Node}; diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs index 1d89f6c75e188..c3bc5c0c9f2a9 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs @@ -1,5 +1,5 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs index 3acd4eca420e0..8b884399f9234 100644 --- a/src/tools/clippy/clippy_lints/src/casts/mod.rs +++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs @@ -24,8 +24,8 @@ mod utils; mod zero_ptr; use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::is_hir_ty_cfg_dependant; +use clippy_utils::msrvs::{self, Msrv}; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs index 46d67e615c73e..a138ade54aadd 100644 --- a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs @@ -1,5 +1,5 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; use rustc_errors::Applicability; diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs index 7518dd2435aee..945c05ee94365 100644 --- a/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs +++ b/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs @@ -1,5 +1,5 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::std_or_core; use clippy_utils::sugg::Sugg; use rustc_errors::Applicability; diff --git a/src/tools/clippy/clippy_lints/src/checked_conversions.rs b/src/tools/clippy/clippy_lints/src/checked_conversions.rs index f76e399517cfd..364f5c7dc7a08 100644 --- a/src/tools/clippy/clippy_lints/src/checked_conversions.rs +++ b/src/tools/clippy/clippy_lints/src/checked_conversions.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{SpanlessEq, is_in_const_context, is_integer_literal}; use rustc_errors::Applicability; diff --git a/src/tools/clippy/clippy_lints/src/copies.rs b/src/tools/clippy/clippy_lints/src/copies.rs index 3ecd36d3711f4..89808d38b9f39 100644 --- a/src/tools/clippy/clippy_lints/src/copies.rs +++ b/src/tools/clippy/clippy_lints/src/copies.rs @@ -212,7 +212,7 @@ fn lint_if_same_then_else(cx: &LateContext<'_>, conds: &[&Expr<'_>], blocks: &[& .array_windows::<2>() .enumerate() .fold(true, |all_eq, (i, &[lhs, rhs])| { - if eq.eq_block(lhs, rhs) && !contains_let(conds[i]) && conds.get(i + 1).map_or(true, |e| !contains_let(e)) { + if eq.eq_block(lhs, rhs) && !contains_let(conds[i]) && conds.get(i + 1).is_none_or(|e| !contains_let(e)) { span_lint_and_note( cx, IF_SAME_THEN_ELSE, @@ -470,7 +470,7 @@ fn scan_block_for_eq<'tcx>( b.stmts // the bounds check will catch the underflow .get(b.stmts.len().wrapping_sub(offset + 1)) - .map_or(true, |s| hash != hash_stmt(cx, s)) + .is_none_or(|s| hash != hash_stmt(cx, s)) }) }) .map_or(block.stmts.len() - start_end_eq, |(i, _)| i); diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs index dff60f76b746a..c4a0c8f186510 100644 --- a/src/tools/clippy/clippy_lints/src/declared_lints.rs +++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs @@ -135,6 +135,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::disallowed_names::DISALLOWED_NAMES_INFO, crate::disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS_INFO, crate::disallowed_types::DISALLOWED_TYPES_INFO, + crate::doc::DOC_INCLUDE_WITHOUT_CFG_INFO, crate::doc::DOC_LAZY_CONTINUATION_INFO, crate::doc::DOC_LINK_WITH_QUOTES_INFO, crate::doc::DOC_MARKDOWN_INFO, diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index fce7f9985ea1a..b1d192adff9a7 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -10,12 +10,12 @@ use core::mem; use rustc_ast::util::parser::{PREC_PREFIX, PREC_UNAMBIGUOUS}; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Applicability; +use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{Visitor, walk_ty}; use rustc_hir::{ self as hir, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, Pat, PatKind, Path, QPath, TyKind, UnOp, }; -use rustc_hir::def_id::DefId; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeckResults}; @@ -453,7 +453,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { )); } else if stability.is_deref_stable() // Auto-deref doesn't combine with other adjustments - && next_adjust.map_or(true, |a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_))) + && next_adjust.is_none_or(|a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_))) && iter.all(|a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_))) { self.state = Some((State::Borrow { mutability }, StateData { @@ -963,7 +963,7 @@ fn report<'tcx>( // expr_str (the suggestion) is never shown if is_final_ufcs is true, since it's // `expr.kind == ExprKind::Call`. Therefore, this is, afaik, always unnecessary. /* - expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence().order() < PREC_PREFIX { + expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence() < PREC_PREFIX { Cow::Owned(format!("({expr_str})")) } else { expr_str @@ -1003,7 +1003,7 @@ fn report<'tcx>( Node::Expr(e) => match e.kind { ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => (0, false), ExprKind::Call(..) => (PREC_UNAMBIGUOUS, matches!(expr.kind, ExprKind::Field(..))), - _ => (e.precedence().order(), false), + _ => (e.precedence(), false), }, _ => (0, false), }; @@ -1016,7 +1016,7 @@ fn report<'tcx>( ); let sugg = if !snip_is_macro - && (calls_field || expr.precedence().order() < precedence) + && (calls_field || expr.precedence() < precedence) && !has_enclosing_paren(&snip) && !is_in_tuple { @@ -1070,12 +1070,11 @@ fn report<'tcx>( let mut app = Applicability::MachineApplicable; let (snip, snip_is_macro) = snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app); - let sugg = - if !snip_is_macro && expr.precedence().order() < precedence && !has_enclosing_paren(&snip) { - format!("{prefix}({snip})") - } else { - format!("{prefix}{snip}") - }; + let sugg = if !snip_is_macro && expr.precedence() < precedence && !has_enclosing_paren(&snip) { + format!("{prefix}({snip})") + } else { + format!("{prefix}{snip}") + }; diag.span_suggestion(data.first_expr.span, "try", sugg, app); }, ); @@ -1158,7 +1157,7 @@ impl<'tcx> Dereferencing<'tcx> { }, Some(parent) if !parent.span.from_expansion() => { // Double reference might be needed at this point. - if parent.precedence().order() == PREC_UNAMBIGUOUS { + if parent.precedence() == PREC_UNAMBIGUOUS { // Parentheses would be needed here, don't lint. *outer_pat = None; } else { diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs index 767dda552bcd1..9569081ad0886 100644 --- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs +++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::indent_of; use clippy_utils::{is_default_equivalent, peel_blocks}; use rustc_errors::Applicability; @@ -132,17 +132,15 @@ fn check_struct<'tcx>( if should_emit { let struct_span = cx.tcx.def_span(adt_def.did()); + let suggestions = vec![ + (item.span, String::new()), // Remove the manual implementation + (struct_span.shrink_to_lo(), "#[derive(Default)]\n".to_string()), // Add the derive attribute + ]; + span_lint_and_then(cx, DERIVABLE_IMPLS, item.span, "this `impl` can be derived", |diag| { - diag.span_suggestion_hidden( - item.span, - "remove the manual implementation...", - String::new(), - Applicability::MachineApplicable, - ); - diag.span_suggestion( - struct_span.shrink_to_lo(), - "...and instead derive it", - "#[derive(Default)]\n".to_string(), + diag.multipart_suggestion( + "replace the manual implementation with a derive attribute", + suggestions, Applicability::MachineApplicable, ); }); @@ -161,23 +159,23 @@ fn check_enum<'tcx>(cx: &LateContext<'tcx>, item: &'tcx Item<'_>, func_expr: &Ex let indent_enum = indent_of(cx, enum_span).unwrap_or(0); let variant_span = cx.tcx.def_span(variant_def.def_id); let indent_variant = indent_of(cx, variant_span).unwrap_or(0); - span_lint_and_then(cx, DERIVABLE_IMPLS, item.span, "this `impl` can be derived", |diag| { - diag.span_suggestion_hidden( - item.span, - "remove the manual implementation...", - String::new(), - Applicability::MachineApplicable, - ); - diag.span_suggestion( + + let suggestions = vec![ + (item.span, String::new()), // Remove the manual implementation + ( enum_span.shrink_to_lo(), - "...and instead derive it...", - format!("#[derive(Default)]\n{indent}", indent = " ".repeat(indent_enum),), - Applicability::MachineApplicable, - ); - diag.span_suggestion( + format!("#[derive(Default)]\n{}", " ".repeat(indent_enum)), + ), // Add the derive attribute + ( variant_span.shrink_to_lo(), - "...and mark the default variant", - format!("#[default]\n{indent}", indent = " ".repeat(indent_variant),), + format!("#[default]\n{}", " ".repeat(indent_variant)), + ), // Mark the default variant + ]; + + span_lint_and_then(cx, DERIVABLE_IMPLS, item.span, "this `impl` can be derived", |diag| { + diag.multipart_suggestion( + "replace the manual implementation with a derive attribute and mark the default variant", + suggestions, Applicability::MachineApplicable, ); }); diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 3b6b3c89858bd..8125dab8adf6a 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -11,7 +11,6 @@ use rustc_hir::{ }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; -use rustc_middle::traits::Reveal; use rustc_middle::ty::{ self, ClauseKind, GenericArgKind, GenericParamDefKind, ParamEnv, TraitPredicate, Ty, TyCtxt, Upcast, }; @@ -506,18 +505,15 @@ fn typing_env_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId } } - let param_env = ParamEnv::new( - tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain( - params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { - ClauseKind::Trait(TraitPredicate { - trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]), - polarity: ty::PredicatePolarity::Positive, - }) - .upcast(tcx) - }), - )), - Reveal::UserFacing, - ); + let param_env = ParamEnv::new(tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain( + params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { + ClauseKind::Trait(TraitPredicate { + trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]), + polarity: ty::PredicatePolarity::Positive, + }) + .upcast(tcx) + }), + ))); ty::TypingEnv { typing_mode: ty::TypingMode::non_body_analysis(), param_env, diff --git a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs index bdd49bf8aa7cc..a0cb36f88dc05 100644 --- a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs +++ b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs @@ -1,5 +1,5 @@ use clippy_config::Conf; -use clippy_utils::create_disallowed_map; +use clippy_config::types::create_disallowed_map; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::macros::macro_backtrace; use rustc_data_structures::fx::FxHashSet; diff --git a/src/tools/clippy/clippy_lints/src/disallowed_methods.rs b/src/tools/clippy/clippy_lints/src/disallowed_methods.rs index 5a01d76a2a621..1e660b1957a44 100644 --- a/src/tools/clippy/clippy_lints/src/disallowed_methods.rs +++ b/src/tools/clippy/clippy_lints/src/disallowed_methods.rs @@ -1,5 +1,5 @@ use clippy_config::Conf; -use clippy_utils::create_disallowed_map; +use clippy_config::types::create_disallowed_map; use clippy_utils::diagnostics::span_lint_and_then; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefIdMap; diff --git a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs new file mode 100644 index 0000000000000..49978d4a65557 --- /dev/null +++ b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs @@ -0,0 +1,45 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_opt; +use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, AttrStyle, Attribute}; +use rustc_errors::Applicability; +use rustc_lint::LateContext; +use rustc_span::sym; + +use super::DOC_INCLUDE_WITHOUT_CFG; + +pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) { + for attr in attrs { + if !attr.span.from_expansion() + && let AttrKind::Normal(ref normal) = attr.kind + && normal.item.path == sym::doc + && let AttrArgs::Eq(_, AttrArgsEq::Hir(ref meta)) = normal.item.args + && !attr.span.contains(meta.span) + // Since the `include_str` is already expanded at this point, we can only take the + // whole attribute snippet and then modify for our suggestion. + && let Some(snippet) = snippet_opt(cx, attr.span) + // We cannot remove this because a `#[doc = include_str!("...")]` attribute can occupy + // several lines. + && let Some(start) = snippet.find('[') + && let Some(end) = snippet.rfind(']') + && let snippet = &snippet[start + 1..end] + // We check that the expansion actually comes from `include_str!` and not just from + // another macro. + && let Some(sub_snippet) = snippet.trim().strip_prefix("doc") + && let Some(sub_snippet) = sub_snippet.trim().strip_prefix("=") + && sub_snippet.trim().starts_with("include_str!") + { + span_lint_and_sugg( + cx, + DOC_INCLUDE_WITHOUT_CFG, + attr.span, + "included a file in documentation unconditionally", + "use `cfg_attr(doc, doc = \"...\")`", + format!( + "#{}[cfg_attr(doc, {snippet})]", + if attr.style == AttrStyle::Inner { "!" } else { "" } + ), + Applicability::MachineApplicable, + ); + } + } +} diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs index df7c37a192ad4..88ac871acf688 100644 --- a/src/tools/clippy/clippy_lints/src/doc/mod.rs +++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::lint_without_lint_pass)] + mod lazy_continuation; mod too_long_first_doc_paragraph; @@ -33,6 +35,7 @@ use std::ops::Range; use url::Url; mod empty_line_after; +mod include_in_doc_without_cfg; mod link_with_quotes; mod markdown; mod missing_headers; @@ -532,6 +535,35 @@ declare_clippy_lint! { "empty line after doc comments" } +declare_clippy_lint! { + /// ### What it does + /// Checks if included files in doc comments are included only for `cfg(doc)`. + /// + /// ### Why restrict this? + /// These files are not useful for compilation but will still be included. + /// Also, if any of these non-source code file is updated, it will trigger a + /// recompilation. + /// + /// ### Known problems + /// + /// Excluding this will currently result in the file being left out if + /// the item's docs are inlined from another crate. This may be fixed in a + /// future version of rustdoc. + /// + /// ### Example + /// ```ignore + /// #![doc = include_str!("some_file.md")] + /// ``` + /// Use instead: + /// ```no_run + /// #![cfg_attr(doc, doc = include_str!("some_file.md"))] + /// ``` + #[clippy::version = "1.84.0"] + pub DOC_INCLUDE_WITHOUT_CFG, + restriction, + "check if files included in documentation are behind `cfg(doc)`" +} + pub struct Documentation { valid_idents: FxHashSet, check_private_items: bool, @@ -561,6 +593,7 @@ impl_lint_pass!(Documentation => [ EMPTY_LINE_AFTER_OUTER_ATTR, EMPTY_LINE_AFTER_DOC_COMMENTS, TOO_LONG_FIRST_DOC_PARAGRAPH, + DOC_INCLUDE_WITHOUT_CFG, ]); impl<'tcx> LateLintPass<'tcx> for Documentation { @@ -690,6 +723,7 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet, attrs: &[ Some(("fake".into(), "fake".into())) } + include_in_doc_without_cfg::check(cx, attrs); if suspicious_doc_comments::check(cx, attrs) || empty_line_after::check(cx, attrs) || is_doc_hidden(attrs) { return None; } @@ -917,6 +951,7 @@ fn check_doc<'a, Events: Iterator, Range LateLintPass<'tcx> for ExcessiveBools { && fn_header.abi == Abi::Rust && fn_decl.inputs.len() as u64 > self.max_fn_params_bools && get_parent_as_impl(cx.tcx, cx.tcx.local_def_id_to_hir_id(def_id)) - .map_or(true, |impl_item| impl_item.of_trait.is_none()) + .is_none_or(|impl_item| impl_item.of_trait.is_none()) { check_fn_decl(cx, fn_decl, span, self.max_fn_params_bools); } diff --git a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs index 6ad879b9fe7ae..ae4b668006529 100644 --- a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs +++ b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs @@ -6,7 +6,7 @@ use rustc_errors::Applicability; use rustc_hir::intravisit::{Visitor, walk_impl_item, walk_item, walk_param_bound, walk_ty}; use rustc_hir::{ BodyId, ExprKind, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item, ItemKind, - PredicateOrigin, Ty, WherePredicate, + PredicateOrigin, Ty, WherePredicate, WherePredicateKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::nested_filter; @@ -205,12 +205,13 @@ impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> { } fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate<'tcx>) { - if let WherePredicate::BoundPredicate(predicate) = predicate { + let span = predicate.span; + if let WherePredicateKind::BoundPredicate(predicate) = predicate.kind { // Collect spans for any bounds on type parameters. if let Some((def_id, _)) = predicate.bounded_ty.peel_refs().as_generic_param() { match predicate.origin { PredicateOrigin::GenericParam => { - self.inline_bounds.insert(def_id, predicate.span); + self.inline_bounds.insert(def_id, span); }, PredicateOrigin::WhereClause => { self.where_bounds.insert(def_id); diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs index 4c043f8dc14b7..da5825b7ab21e 100644 --- a/src/tools/clippy/clippy_lints/src/format_args.rs +++ b/src/tools/clippy/clippy_lints/src/format_args.rs @@ -1,6 +1,5 @@ use arrayvec::ArrayVec; use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::is_diag_trait_item; use clippy_utils::macros::{ @@ -8,6 +7,7 @@ use clippy_utils::macros::{ format_placeholder_format_span, is_assert_macro, is_format_macro, is_panic, matching_root_macro_call, root_macro_call_first_node, }; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::SpanRangeExt; use clippy_utils::ty::{implements_trait, is_type_lang_item}; use itertools::Itertools; diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs index 14da0b515a51c..e43c311eb854e 100644 --- a/src/tools/clippy/clippy_lints/src/from_over_into.rs +++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs @@ -1,9 +1,9 @@ use std::ops::ControlFlow; use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::span_is_local; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::path_def_id; use clippy_utils::source::SpanRangeExt; use rustc_errors::Applicability; @@ -92,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto { |diag| { // If the target type is likely foreign mention the orphan rules as it's a common source of // confusion - if path_def_id(cx, target_ty.peel_refs()).map_or(true, |id| !id.is_local()) { + if path_def_id(cx, target_ty.peel_refs()).is_none_or(|id| !id.is_local()) { diag.help( "`impl From for Foreign` is allowed by the orphan rules, for more information see\n\ https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence" diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index cf08c16458bd5..bb2dc9995df7e 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -1,3 +1,5 @@ +use std::ops::ControlFlow; + use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::return_ty; use rustc_hir::intravisit::FnKind; @@ -5,7 +7,9 @@ use rustc_hir::{Body, FnDecl}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::print::PrintTraitRefExt; -use rustc_middle::ty::{self, AliasTy, ClauseKind, PredicateKind}; +use rustc_middle::ty::{ + self, AliasTy, Binder, ClauseKind, PredicateKind, Ty, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor, +}; use rustc_session::declare_lint_pass; use rustc_span::def_id::LocalDefId; use rustc_span::{Span, sym}; @@ -15,9 +19,16 @@ use rustc_trait_selection::traits::{self, FulfillmentError, ObligationCtxt}; declare_clippy_lint! { /// ### What it does /// This lint requires Future implementations returned from - /// functions and methods to implement the `Send` marker trait. It is mostly - /// used by library authors (public and internal) that target an audience where - /// multithreaded executors are likely to be used for running these Futures. + /// functions and methods to implement the `Send` marker trait, + /// ignoring type parameters. + /// + /// If a function is generic and its Future conditionally implements `Send` + /// based on a generic parameter then it is considered `Send` and no warning is emitted. + /// + /// This can be used by library authors (public and internal) to ensure + /// their functions are compatible with both multi-threaded runtimes that require `Send` futures, + /// as well as single-threaded runtimes where callers may choose `!Send` types + /// for generic parameters. /// /// ### Why is this bad? /// A Future implementation captures some state that it @@ -64,22 +75,46 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { return; } let ret_ty = return_ty(cx, cx.tcx.local_def_id_to_hir_id(fn_def_id).expect_owner()); - if let ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) = *ret_ty.kind() { + if let ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) = *ret_ty.kind() + && let Some(future_trait) = cx.tcx.lang_items().future_trait() + && let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send) + { let preds = cx.tcx.explicit_item_super_predicates(def_id); let is_future = preds.iter_instantiated_copied(cx.tcx, args).any(|(p, _)| { - p.as_trait_clause().is_some_and(|trait_pred| { - Some(trait_pred.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().future_trait() - }) + p.as_trait_clause() + .is_some_and(|trait_pred| trait_pred.skip_binder().trait_ref.def_id == future_trait) }); if is_future { - let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap(); let span = decl.output.span(); let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode()); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let cause = traits::ObligationCause::misc(span, fn_def_id); ocx.register_bound(cause, cx.param_env, ret_ty, send_trait); let send_errors = ocx.select_all_or_error(); - if !send_errors.is_empty() { + + // Allow errors that try to prove `Send` for types that "mention" a generic parameter at the "top + // level". + // For example, allow errors that `T: Send` can't be proven, but reject `Rc: Send` errors, + // which is always unconditionally `!Send` for any possible type `T`. + // + // We also allow associated type projections if the self type is either itself a projection or a + // type parameter. + // This is to prevent emitting warnings for e.g. holding a `::Output` across await + // points, where `Fut` is a type parameter. + + let is_send = send_errors.iter().all(|err| { + err.obligation + .predicate + .as_trait_clause() + .map(Binder::skip_binder) + .is_some_and(|pred| { + pred.def_id() == send_trait + && pred.self_ty().has_param() + && TyParamAtTopLevelVisitor.visit_ty(pred.self_ty()) == ControlFlow::Break(true) + }) + }); + + if !is_send { span_lint_and_then( cx, FUTURE_NOT_SEND, @@ -107,3 +142,15 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { } } } + +struct TyParamAtTopLevelVisitor; +impl<'tcx> TypeVisitor> for TyParamAtTopLevelVisitor { + type Result = ControlFlow; + fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { + match ty.kind() { + ty::Param(_) => ControlFlow::Break(true), + ty::Alias(ty::AliasTyKind::Projection, ty) => ty.visit_with(self), + _ => ControlFlow::Break(false), + } + } +} diff --git a/src/tools/clippy/clippy_lints/src/if_let_mutex.rs b/src/tools/clippy/clippy_lints/src/if_let_mutex.rs index ba80c099a0153..6444e99ae9cdd 100644 --- a/src/tools/clippy/clippy_lints/src/if_let_mutex.rs +++ b/src/tools/clippy/clippy_lints/src/if_let_mutex.rs @@ -7,6 +7,7 @@ use rustc_errors::Diag; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; +use rustc_span::edition::Edition::Edition2024; use rustc_span::sym; declare_clippy_lint! { @@ -14,6 +15,12 @@ declare_clippy_lint! { /// Checks for `Mutex::lock` calls in `if let` expression /// with lock calls in any of the else blocks. /// + /// ### Disabled starting in Edition 2024 + /// This lint is effectively disabled starting in + /// Edition 2024 as `if let ... else` scoping was reworked + /// such that this is no longer an issue. See + /// [Proposal: stabilize if_let_rescope for Edition 2024](https://github.com/rust-lang/rust/issues/131154) + /// /// ### Why is this bad? /// The Mutex lock remains held for the whole /// `if let ... else` block and deadlocks. @@ -45,6 +52,10 @@ declare_lint_pass!(IfLetMutex => [IF_LET_MUTEX]); impl<'tcx> LateLintPass<'tcx> for IfLetMutex { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { + if cx.tcx.sess.edition() >= Edition2024 { + return; + } + if let Some(higher::IfLet { let_expr, if_then, @@ -86,7 +97,7 @@ fn mutex_lock_call<'tcx>( && path.ident.as_str() == "lock" && let ty = cx.typeck_results().expr_ty(self_arg).peel_refs() && is_type_diagnostic_item(cx, ty, sym::Mutex) - && op_mutex.map_or(true, |op| eq_expr_value(cx, self_arg, op)) + && op_mutex.is_none_or(|op| eq_expr_value(cx, self_arg, op)) { ControlFlow::Break(self_arg) } else { diff --git a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs index d63c18c0edaab..3fc0a69652245 100644 --- a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs +++ b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::eager_or_lazy::switch_to_eager_eval; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::Sugg; use clippy_utils::{ diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs index 3b84b569c3edf..37481dc7feb7b 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_opt; use clippy_utils::{ SpanlessEq, higher, is_in_const_context, is_integer_literal, path_to_local, peel_blocks, peel_blocks_with_stmt, diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs index 65fdc93e0ed99..4427edb752e0e 100644 --- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs +++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs @@ -4,7 +4,7 @@ use rustc_errors::{Applicability, SuggestionStyle}; use rustc_hir::def_id::DefId; use rustc_hir::{ AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifiers, TyKind, - WherePredicate, + WherePredicateKind, }; use rustc_hir_analysis::lower_ty; use rustc_lint::{LateContext, LateLintPass}; @@ -324,7 +324,7 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) { impl<'tcx> LateLintPass<'tcx> for ImpliedBoundsInImpls { fn check_generics(&mut self, cx: &LateContext<'tcx>, generics: &rustc_hir::Generics<'tcx>) { for predicate in generics.predicates { - if let WherePredicate::BoundPredicate(predicate) = predicate + if let WherePredicateKind::BoundPredicate(predicate) = predicate.kind // In theory, the origin doesn't really matter, // we *could* also lint on explicit where clauses written out by the user, // not just impl trait desugared ones, but that contradicts with the lint name... diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs index 0b3a6ee1beaeb..f3467adacc55c 100644 --- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs +++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::Msrv; use clippy_utils::diagnostics::span_lint; use clippy_utils::is_in_test; +use clippy_utils::msrvs::Msrv; use rustc_attr::{StabilityLevel, StableSince}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::{Expr, ExprKind, HirId}; diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs index 96550c4d1cb95..c2030a5ab090b 100644 --- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs +++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs @@ -1,8 +1,8 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::IfLet; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::is_copy; use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; diff --git a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs index 66931a7f98c36..f4e41dc826b0f 100644 --- a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs +++ b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::Sugg; use clippy_utils::ty; 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 644365c9fe567..623b6b4fcc145 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -3,8 +3,8 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_errors::Applicability; use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty; +use rustc_middle::ty::layout::LayoutOf; use rustc_session::impl_lint_pass; use rustc_span::{BytePos, Pos, Span}; 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 e17d6213679a6..fb46bdcab6e1d 100644 --- a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs +++ b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{Msrv, NUMERIC_ASSOCIATED_CONSTANTS}; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::{get_parent_expr, is_from_proc_macro}; use hir::def_id::DefId; use rustc_errors::Applicability; @@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants { // 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 - && self.msrv.meets(NUMERIC_ASSOCIATED_CONSTANTS) + && self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS) && !in_external_macro(cx.sess(), item.span) && let Some(def_id) = path.res[0].opt_def_id() { @@ -138,7 +138,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants { return; }; - if self.msrv.meets(NUMERIC_ASSOCIATED_CONSTANTS) + if self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS) && !in_external_macro(cx.sess(), expr.span) && !is_from_proc_macro(cx, expr) { diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index ce0e1a24a7b52..35b14776e59f7 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; use clippy_utils::trait_ref_of_method; use itertools::Itertools; +use rustc_ast::visit::{try_visit, walk_list}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::Applicability; use rustc_hir::FnRetTy::Return; @@ -11,8 +12,9 @@ use rustc_hir::intravisit::{ }; use rustc_hir::{ BareFnTy, BodyId, FnDecl, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind, Generics, - Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, Node, PolyTraitRef, - PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate, lang_items, + HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, Node, PolyTraitRef, + PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WhereBoundPredicate, WherePredicate, + WherePredicateKind, lang_items, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; @@ -442,9 +444,9 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> { /// reason about elision. fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) -> bool { for predicate in generics.predicates { - match *predicate { - WherePredicate::RegionPredicate(..) => return true, - WherePredicate::BoundPredicate(ref pred) => { + match *predicate.kind { + WherePredicateKind::RegionPredicate(..) => return true, + WherePredicateKind::BoundPredicate(ref pred) => { // a predicate like F: Trait or F: for<'a> Trait<'a> let mut visitor = RefVisitor::new(cx); // walk the type F, it may not contain LT refs @@ -467,7 +469,7 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_ } } }, - WherePredicate::EqPredicate(ref pred) => { + WherePredicateKind::EqPredicate(ref pred) => { let mut visitor = RefVisitor::new(cx); walk_ty(&mut visitor, pred.lhs_ty); walk_ty(&mut visitor, pred.rhs_ty); @@ -483,6 +485,7 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_ struct Usage { lifetime: Lifetime, in_where_predicate: bool, + in_bounded_ty: bool, in_generics_arg: bool, } @@ -490,11 +493,15 @@ struct LifetimeChecker<'cx, 'tcx, F> { cx: &'cx LateContext<'tcx>, map: FxIndexMap>, where_predicate_depth: usize, + bounded_ty_depth: usize, generic_args_depth: usize, phantom: std::marker::PhantomData, } -impl<'cx, 'tcx, F> LifetimeChecker<'cx, 'tcx, F> { +impl<'cx, 'tcx, F> LifetimeChecker<'cx, 'tcx, F> +where + F: NestedFilter<'tcx>, +{ fn new(cx: &'cx LateContext<'tcx>, generics: &'tcx Generics<'_>) -> LifetimeChecker<'cx, 'tcx, F> { let map = generics .params @@ -510,10 +517,30 @@ impl<'cx, 'tcx, F> LifetimeChecker<'cx, 'tcx, F> { cx, map, where_predicate_depth: 0, + bounded_ty_depth: 0, generic_args_depth: 0, phantom: std::marker::PhantomData, } } + + // `visit_where_bound_predicate` is based on: + // https://github.com/rust-lang/rust/blob/864cee3ea383cc8254ba394ba355e648faa9cfa5/compiler/rustc_hir/src/intravisit.rs#L936-L939 + fn visit_where_bound_predicate( + &mut self, + hir_id: HirId, + bounded_ty: &'tcx Ty<'tcx>, + bounds: &'tcx [GenericBound<'tcx>], + bound_generic_params: &'tcx [GenericParam<'tcx>], + ) { + try_visit!(self.visit_id(hir_id)); + + self.bounded_ty_depth += 1; + try_visit!(self.visit_ty(bounded_ty)); + self.bounded_ty_depth -= 1; + + walk_list!(self, visit_param_bound, bounds); + walk_list!(self, visit_generic_param, bound_generic_params); + } } impl<'tcx, F> Visitor<'tcx> for LifetimeChecker<'_, 'tcx, F> @@ -531,6 +558,7 @@ where usages.push(Usage { lifetime: *lifetime, in_where_predicate: self.where_predicate_depth != 0, + in_bounded_ty: self.bounded_ty_depth != 0, in_generics_arg: self.generic_args_depth != 0, }); } @@ -538,7 +566,17 @@ where fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate<'tcx>) { self.where_predicate_depth += 1; - walk_where_predicate(self, predicate); + if let &WherePredicateKind::BoundPredicate(WhereBoundPredicate { + bounded_ty, + bounds, + bound_generic_params, + origin: _, + }) = predicate.kind + { + self.visit_where_bound_predicate(predicate.hir_id, bounded_ty, bounds, bound_generic_params); + } else { + walk_where_predicate(self, predicate); + } self.where_predicate_depth -= 1; } @@ -562,7 +600,7 @@ fn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>, for (def_id, usages) in checker.map { if usages .iter() - .all(|usage| usage.in_where_predicate && !usage.in_generics_arg) + .all(|usage| usage.in_where_predicate && !usage.in_bounded_ty && !usage.in_generics_arg) { span_lint( cx, @@ -589,7 +627,7 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<' for (&def_id, usages) in &checker.map { if usages .iter() - .all(|usage| usage.in_where_predicate && !usage.in_generics_arg) + .all(|usage| usage.in_where_predicate && !usage.in_bounded_ty && !usage.in_generics_arg) { span_lint( cx, @@ -605,8 +643,8 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<' // An `impl` lifetime is elidable if it satisfies the following conditions: // - It is used exactly once. -// - That single use is not in `GenericArgs` in a `WherePredicate`. (Note that `GenericArgs` are -// different from `GenericParam`s.) +// - That single use is not in a bounded type or `GenericArgs` in a `WherePredicate`. (Note that +// `GenericArgs` are different from `GenericParam`s.) fn report_elidable_impl_lifetimes<'tcx>( cx: &LateContext<'tcx>, impl_: &'tcx Impl<'_>, @@ -623,6 +661,7 @@ fn report_elidable_impl_lifetimes<'tcx>( } | Usage { lifetime, + in_bounded_ty: false, in_generics_arg: false, .. }, diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs index d999e1a058573..06cf901bfb231 100644 --- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs @@ -1,6 +1,6 @@ use super::EXPLICIT_ITER_LOOP; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::{ implements_trait, implements_trait_with_env, is_copy, is_type_lang_item, make_normalized_projection, @@ -29,7 +29,7 @@ pub(super) fn check( if !msrv.meets(msrvs::ARRAY_INTO_ITERATOR) { return; } - } else if count.try_to_target_usize(cx.tcx).map_or(true, |x| x > 32) && !msrv.meets(msrvs::ARRAY_IMPL_ANY_LEN) { + } else if count.try_to_target_usize(cx.tcx).is_none_or(|x| x > 32) && !msrv.meets(msrvs::ARRAY_IMPL_ANY_LEN) { return; } } @@ -181,7 +181,8 @@ fn is_ref_iterable<'tcx>( // Attempt to borrow let self_ty = Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, self_ty, mutbl); if implements_trait(cx, self_ty, trait_id, &[]) - && let Some(ty) = make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [self_ty]) + && let Some(ty) = + make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [self_ty]) && ty == res_ty { return Some((AdjustKind::borrow(mutbl), self_ty)); diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs index 17215621d2aa1..f3ca4a4a57152 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mod.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs @@ -23,8 +23,8 @@ mod while_let_loop; mod while_let_on_iterator; use clippy_config::Conf; -use clippy_config::msrvs::Msrv; use clippy_utils::higher; +use clippy_utils::msrvs::Msrv; use rustc_ast::Label; use rustc_hir::{Expr, ExprKind, LoopSource, Pat}; use rustc_lint::{LateContext, LateLintPass}; diff --git a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs index 70f76ced09a43..35dc8e9aa4e24 100644 --- a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs @@ -84,7 +84,7 @@ pub(super) fn check<'tcx>( if !prefix.is_empty() && ( // Precedence of internal expression is less than or equal to precedence of `&expr`. - arg_expression.precedence().order() <= PREC_PREFIX || is_range_literal(arg_expression) + arg_expression.precedence() <= PREC_PREFIX || is_range_literal(arg_expression) ) { arg_snip = format!("({arg_snip})").into(); diff --git a/src/tools/clippy/clippy_lints/src/manual_bits.rs b/src/tools/clippy/clippy_lints/src/manual_bits.rs index fd71167f814d2..c31656f8a05e4 100644 --- a/src/tools/clippy/clippy_lints/src/manual_bits.rs +++ b/src/tools/clippy/clippy_lints/src/manual_bits.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::get_parent_expr; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use rustc_ast::ast::LitKind; use rustc_data_structures::packed::Pu128; diff --git a/src/tools/clippy/clippy_lints/src/manual_clamp.rs b/src/tools/clippy/clippy_lints/src/manual_clamp.rs index 016ec7320a6ad..484a7ba256bda 100644 --- a/src/tools/clippy/clippy_lints/src/manual_clamp.rs +++ b/src/tools/clippy/clippy_lints/src/manual_clamp.rs @@ -1,8 +1,8 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::higher::If; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::implements_trait; use clippy_utils::visitors::is_const_evaluatable; diff --git a/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs b/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs index 4c171e6d890f9..bbb89bee8355d 100644 --- a/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs +++ b/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs @@ -1,6 +1,6 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::SpanlessEq; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; use rustc_ast::{BinOpKind, LitKind}; @@ -35,7 +35,7 @@ declare_clippy_lint! { /// let y: i32 = 4; /// let div = x.div_ceil(y); /// ``` - #[clippy::version = "1.81.0"] + #[clippy::version = "1.83.0"] pub MANUAL_DIV_CEIL, complexity, "manually reimplementing `div_ceil`" diff --git a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs index a269ea1139740..b12f575e81a34 100644 --- a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs +++ b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs @@ -1,7 +1,7 @@ -use clippy_config::msrvs::Msrv; -use clippy_config::{Conf, msrvs}; +use clippy_config::Conf; use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::SpanRangeExt; use clippy_utils::{is_from_proc_macro, path_to_local}; use rustc_errors::Applicability; diff --git a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs index 7a9c99637428a..7e092d11f1b47 100644 --- a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs +++ b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_hir_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::SpanRangeExt; use clippy_utils::visitors::{is_local_used, local_used_once}; use clippy_utils::{is_trait_method, path_to_local_id}; diff --git a/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs b/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs index dec8c5d85dec2..3f01f3cf30aea 100644 --- a/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs +++ b/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::matching_root_macro_call; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::sugg::Sugg; use clippy_utils::{higher, is_in_const_context, path_to_local, peel_ref_operators}; use rustc_ast::LitKind::{Byte, Char}; diff --git a/src/tools/clippy/clippy_lints/src/manual_is_power_of_two.rs b/src/tools/clippy/clippy_lints/src/manual_is_power_of_two.rs index a11d3e4624c78..4fee3bf7aa9f5 100644 --- a/src/tools/clippy/clippy_lints/src/manual_is_power_of_two.rs +++ b/src/tools/clippy/clippy_lints/src/manual_is_power_of_two.rs @@ -27,7 +27,7 @@ declare_clippy_lint! { /// let a: u32 = 4; /// let result = a.is_power_of_two(); /// ``` - #[clippy::version = "1.82.0"] + #[clippy::version = "1.83.0"] pub MANUAL_IS_POWER_OF_TWO, pedantic, "manually reimplementing `is_power_of_two`" diff --git a/src/tools/clippy/clippy_lints/src/manual_let_else.rs b/src/tools/clippy/clippy_lints/src/manual_let_else.rs index 17185df5d76fa..a70955a7c78da 100644 --- a/src/tools/clippy/clippy_lints/src/manual_let_else.rs +++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs @@ -1,11 +1,10 @@ use crate::question_mark::{QUESTION_MARK, QuestionMark}; -use clippy_config::msrvs; use clippy_config::types::MatchLintBehaviour; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::IfLetOrMatch; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::is_type_diagnostic_item; -use clippy_utils::{is_lint_allowed, is_never_expr, pat_and_expr_can_be_question_mark, peel_blocks}; +use clippy_utils::{is_lint_allowed, is_never_expr, msrvs, pat_and_expr_can_be_question_mark, peel_blocks}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatKind, QPath, Stmt, StmtKind}; diff --git a/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs b/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs index 85e99a92cf598..b7563a2508d0f 100644 --- a/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs +++ b/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::{is_trait_method, peel_hir_expr_refs}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; 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 25868ccae4003..00800231fe46e 100644 --- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::is_doc_hidden; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_indent; use itertools::Itertools; use rustc_ast::attr; diff --git a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs index 86293169ea28c..5e58054a98663 100644 --- a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs +++ b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{ConstEvalCtxt, FullInt}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use clippy_utils::{is_in_const_context, path_to_local}; use rustc_errors::Applicability; diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs index a60163be770d0..708980ac503d5 100644 --- a/src/tools/clippy/clippy_lints/src/manual_retain.rs +++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::SpanlessEq; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use clippy_utils::ty::{get_type_diagnostic_name, is_type_lang_item}; use rustc_errors::Applicability; diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs index 3f401eff6bdb9..79de41db3438b 100644 --- a/src/tools/clippy/clippy_lints/src/manual_strip.rs +++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use clippy_utils::usage::mutated_variables; use clippy_utils::{eq_expr_value, higher}; diff --git a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs index 50e6dfc6298dc..99a7b8c74be87 100644 --- a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs @@ -1,6 +1,6 @@ -use clippy_config::msrvs::Msrv; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::IfLetOrMatch; +use clippy_utils::msrvs::Msrv; use clippy_utils::source::snippet; use clippy_utils::visitors::is_local_used; use clippy_utils::{ @@ -72,14 +72,13 @@ fn check_arm<'tcx>( (Some(a), Some(b)) => SpanlessEq::new(cx).eq_expr(a, b), } // the binding must not be used in the if guard - && outer_guard.map_or( - true, + && outer_guard.is_none_or( |e| !is_local_used(cx, e, binding_id) ) // ...or anywhere in the inner expression && match inner { IfLetOrMatch::IfLet(_, _, body, els, _) => { - !is_local_used(cx, body, binding_id) && els.map_or(true, |e| !is_local_used(cx, e, binding_id)) + !is_local_used(cx, body, binding_id) && els.is_none_or(|e| !is_local_used(cx, e, binding_id)) }, IfLetOrMatch::Match(_, arms, ..) => !arms.iter().any(|arm| is_local_used(cx, arm, binding_id)), } diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs index d38560998a5a7..9c6df4d8ac0d9 100644 --- a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs +++ b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs @@ -117,7 +117,7 @@ where // it's being passed by value. let scrutinee = peel_hir_expr_refs(scrutinee).0; let (scrutinee_str, _) = snippet_with_context(cx, scrutinee.span, expr_ctxt, "..", &mut app); - let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence().order() < PREC_UNAMBIGUOUS { + let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence() < PREC_UNAMBIGUOUS { format!("({scrutinee_str})") } else { scrutinee_str.into() diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs index 28adcc2f22746..64969271764c4 100644 --- a/src/tools/clippy/clippy_lints/src/matches/mod.rs +++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs @@ -25,7 +25,7 @@ mod try_err; mod wild_in_or_pats; use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::walk_span_to_context; use clippy_utils::{higher, is_direct_expn_of, is_in_const_context, is_span_match, span_contains_cfg}; use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind}; diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs index 9e54475033c86..dfc0513add93f 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs @@ -1,6 +1,6 @@ -use clippy_config::msrvs::Msrv; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::matching_root_macro_call; +use clippy_utils::msrvs::Msrv; use clippy_utils::source::snippet; use clippy_utils::visitors::{for_each_expr_without_closures, is_local_used}; use clippy_utils::{is_in_const_context, path_to_local}; @@ -243,11 +243,6 @@ fn emit_redundant_guards<'tcx>( } /// Checks if the given `Expr` can also be represented as a `Pat`. -/// -/// All literals generally also work as patterns, however float literals are special. -/// They are currently (as of 2023/08/08) still allowed in patterns, but that will become -/// an error in the future, and rustc already actively warns against this (see rust#41620), -/// so we don't consider those as usable within patterns for linting purposes. fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { for_each_expr_without_closures(expr, |expr| { if match expr.kind { @@ -267,7 +262,7 @@ fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { | ExprKind::Tup(..) | ExprKind::Struct(..) | ExprKind::Unary(UnOp::Neg, _) => true, - ExprKind::Lit(lit) if !matches!(lit.node, LitKind::Float(..)) => true, + ExprKind::Lit(lit) if !matches!(lit.node, LitKind::CStr(..)) => true, _ => false, } { return ControlFlow::Continue(()); diff --git a/src/tools/clippy/clippy_lints/src/mem_replace.rs b/src/tools/clippy/clippy_lints/src/mem_replace.rs index 146748734cff4..5597cd85abc90 100644 --- a/src/tools/clippy/clippy_lints/src/mem_replace.rs +++ b/src/tools/clippy/clippy_lints/src/mem_replace.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::is_non_aggregate_primitive_type; diff --git a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs index c9604c7b2e2b6..1ee27d90d0545 100644 --- a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs +++ b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs @@ -30,7 +30,7 @@ pub(super) fn check( .type_dependent_def_id(expr.hir_id) .and_then(|id| cx.tcx.trait_of_item(id)) .zip(cx.tcx.lang_items().clone_trait()) - .map_or(true, |(x, y)| x != y) + .is_none_or(|(x, y)| x != y) { return; } diff --git a/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs b/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs index fa04f74eec107..2a0a9d3710dca 100644 --- a/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs +++ b/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs @@ -1,6 +1,6 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::is_trait_method; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::{get_iterator_item_ty, is_copy}; use rustc_errors::Applicability; use rustc_hir::Expr; diff --git a/src/tools/clippy/clippy_lints/src/methods/err_expect.rs b/src/tools/clippy/clippy_lints/src/methods/err_expect.rs index 3b1adb16b80e9..44b55570eead2 100644 --- a/src/tools/clippy/clippy_lints/src/methods/err_expect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/err_expect.rs @@ -1,6 +1,6 @@ use super::ERR_EXPECT; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::{has_debug_impl, is_type_diagnostic_item}; use rustc_errors::Applicability; use rustc_lint::LateContext; diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs index f94fe221833d9..3f89e59314874 100644 --- a/src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs +++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs @@ -1,6 +1,6 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; use clippy_utils::is_trait_method; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use rustc_errors::Applicability; use rustc_hir as hir; diff --git a/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs b/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs index 40b48ccca5d5d..d8bb9e377a0c8 100644 --- a/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs +++ b/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs @@ -1,7 +1,7 @@ use super::IS_DIGIT_ASCII_RADIX; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{ConstEvalCtxt, FullInt}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use rustc_errors::Applicability; use rustc_hir::Expr; diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs b/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs index 390dd24b5058d..299f6d1011239 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs @@ -1,6 +1,6 @@ use super::ITER_KV_MAP; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::pat_is_wild; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::is_type_diagnostic_item; diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs b/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs index 22f4748de70d3..7d5ebdedd0c30 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs @@ -1,6 +1,6 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::get_parent_expr; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use rustc_ast::{LitKind, StrStyle}; use rustc_errors::Applicability; diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs index 7aa13d8d5b6eb..865a42b65c624 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs @@ -1,5 +1,5 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{IntoSpan, SpanRangeExt}; use clippy_utils::ty::get_field_by_name; use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures}; diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs b/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs index c377abd62377a..90e502f244fa9 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs @@ -1,5 +1,5 @@ -use clippy_config::msrvs::{Msrv, OPTION_RESULT_IS_VARIANT_AND}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use clippy_utils::ty::is_type_diagnostic_item; use rustc_errors::Applicability; @@ -36,7 +36,7 @@ pub(super) fn check<'tcx>( } // 4. msrv doesn't meet `OPTION_RESULT_IS_VARIANT_AND` - if !msrv.meets(OPTION_RESULT_IS_VARIANT_AND) { + if !msrv.meets(msrvs::OPTION_RESULT_IS_VARIANT_AND) { return; } diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs b/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs index 31449d417701c..4a48d4b547ccc 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs @@ -1,5 +1,5 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::SpanRangeExt; use clippy_utils::ty::implements_trait; use clippy_utils::{is_from_proc_macro, is_trait_method}; diff --git a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs index d5594b21db5da..1252f7ccd357d 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs @@ -1,5 +1,5 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::{is_copy, is_type_diagnostic_item, should_call_clone_as_function}; use clippy_utils::{is_diag_trait_item, peel_blocks}; diff --git a/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs index 3226fa9cd3fa4..428da0cf107e5 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs @@ -1,5 +1,5 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::usage::mutated_variables; diff --git a/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs b/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs index fc656fd78ba2d..80703618a1131 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs @@ -1,6 +1,6 @@ use crate::methods::MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; use clippy_utils::{eager_or_lazy, higher, usage}; diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 795e041ffd9d8..7d1d5d69c9912 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -137,10 +137,10 @@ mod wrong_self_convention; mod zst_offset; use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::{span_lint, span_lint_and_help}; use clippy_utils::macros::FormatArgsStorage; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::{contains_ty_adt_constructor_opaque, implements_trait, is_copy, is_type_diagnostic_item}; use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, peel_blocks, return_ty}; pub use path_ends_with_ext::DEFAULT_ALLOWED_DOTFILES; @@ -4107,24 +4107,32 @@ declare_clippy_lint! { /// ### Why is this bad? /// Calls such as `opt.map_or(false, |val| val == 5)` are needlessly long and cumbersome, /// and can be reduced to, for example, `opt == Some(5)` assuming `opt` implements `PartialEq`. + /// Also, calls such as `opt.map_or(true, |val| val == 5)` can be reduced to + /// `opt.is_none_or(|val| val == 5)`. /// This lint offers readability and conciseness improvements. /// /// ### Example /// ```no_run - /// pub fn a(x: Option) -> bool { - /// x.map_or(false, |n| n == 5) + /// pub fn a(x: Option) -> (bool, bool) { + /// ( + /// x.map_or(false, |n| n == 5), + /// x.map_or(true, |n| n > 5), + /// ) /// } /// ``` /// Use instead: /// ```no_run - /// pub fn a(x: Option) -> bool { - /// x == Some(5) + /// pub fn a(x: Option) -> (bool, bool) { + /// ( + /// x == Some(5), + /// x.is_none_or(|n| n > 5), + /// ) /// } /// ``` - #[clippy::version = "1.75.0"] + #[clippy::version = "1.84.0"] pub UNNECESSARY_MAP_OR, style, - "reduce unnecessary pattern matching for constructs that implement `PartialEq`" + "reduce unnecessary calls to `.map_or(bool, …)`" } declare_clippy_lint! { @@ -4531,7 +4539,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { && method_config.output_type.matches(&sig.decl.output) // in case there is no first arg, since we already have checked the number of arguments // it's should be always true - && first_arg_ty_opt.map_or(true, |first_arg_ty| method_config + && first_arg_ty_opt.is_none_or(|first_arg_ty| method_config .self_kind.matches(cx, self_ty, first_arg_ty) ) && fn_header_equals(method_config.fn_header, sig.header) diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs index c00b9b368c43e..ea4984f83adb2 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -203,7 +203,8 @@ fn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool { fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: Ty<'tcx>) -> bool { if let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator) && let Some(into_iter_trait) = cx.tcx.get_diagnostic_item(sym::IntoIterator) - && let Some(iter_item_ty) = make_normalized_projection(cx.tcx, cx.typing_env(), iter_trait, sym::Item, [iter_ty]) + && let Some(iter_item_ty) = + make_normalized_projection(cx.tcx, cx.typing_env(), iter_trait, sym::Item, [iter_ty]) && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, sym::Item, [collect_ty]) && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions( cx.typing_env(), diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs index 998bdee01576d..8d97d1c72a6b9 100644 --- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs +++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs @@ -1,5 +1,5 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{path_to_local_id, peel_blocks}; diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs index 528e2204cf8f7..7c4dc4ffb2029 100644 --- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -1,5 +1,5 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::{is_copy, is_type_diagnostic_item}; use rustc_data_structures::fx::FxHashSet; diff --git a/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs b/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs index cfb823dbf5de4..febd7fd5cf2f4 100644 --- a/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs +++ b/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs @@ -1,6 +1,6 @@ use super::PATH_ENDS_WITH_EXT; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use clippy_utils::ty::is_type_diagnostic_item; use rustc_ast::{LitKind, StrStyle}; diff --git a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs index 1cee28e198617..c91be33b1cd09 100644 --- a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs +++ b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs @@ -1,6 +1,6 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use clippy_utils::usage::local_used_after_expr; use clippy_utils::visitors::{Descend, for_each_expr}; diff --git a/src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs b/src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs index cc0d432b799d6..cb719b34b1f0c 100644 --- a/src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs +++ b/src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs @@ -1,5 +1,5 @@ -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::SpanRangeExt; use clippy_utils::{is_from_proc_macro, is_trait_method, path_to_local}; use itertools::Itertools; diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs index bab439015c5f6..3de51bc661eb7 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -23,7 +23,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = arg.kind { let body = cx.tcx.hir().body(body); let arg_id = body.params[0].pat.hir_id; - let mutates_arg = mutated_variables(body.value, cx).map_or(true, |used_mutably| used_mutably.contains(&arg_id)); + let mutates_arg = mutated_variables(body.value, cx).is_none_or(|used_mutably| used_mutably.contains(&arg_id)); let (clone_or_copy_needed, _) = clone_or_copy_needed(cx, body.params[0].pat, body.value); let (mut found_mapping, mut found_filtering) = check_expression(cx, arg_id, body.value); diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs index adc27cd437f40..1199d28976107 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::eager_or_lazy::switch_to_eager_eval; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_opt; use clippy_utils::sugg::{Sugg, make_binop}; use clippy_utils::ty::{get_type_diagnostic_name, implements_trait}; @@ -60,7 +60,7 @@ pub(super) fn check<'a>( Some(_) | None => return, }; - let (sugg, method) = if let ExprKind::Closure(map_closure) = map.kind + let (sugg, method, applicability) = if let ExprKind::Closure(map_closure) = map.kind && let closure_body = cx.tcx.hir().body(map_closure.body) && let closure_body_value = closure_body.value.peel_blocks() && let ExprKind::Binary(op, l, r) = closure_body_value.kind @@ -100,7 +100,7 @@ pub(super) fn check<'a>( .maybe_par() .into_string(); - (binop, "a standard comparison") + (binop, "a standard comparison", Applicability::MaybeIncorrect) } else if !def_bool && msrv.meets(msrvs::OPTION_RESULT_IS_VARIANT_AND) && let Some(recv_callsite) = snippet_opt(cx, recv.span.source_callsite()) @@ -110,6 +110,18 @@ pub(super) fn check<'a>( ( format!("{recv_callsite}.{suggested_name}({span_callsite})",), suggested_name, + Applicability::MachineApplicable, + ) + } else if def_bool + && matches!(variant, Variant::Some) + && msrv.meets(msrvs::IS_NONE_OR) + && let Some(recv_callsite) = snippet_opt(cx, recv.span.source_callsite()) + && let Some(span_callsite) = snippet_opt(cx, map.span.source_callsite()) + { + ( + format!("{recv_callsite}.is_none_or({span_callsite})"), + "is_none_or", + Applicability::MachineApplicable, ) } else { return; @@ -123,9 +135,9 @@ pub(super) fn check<'a>( cx, UNNECESSARY_MAP_OR, expr.span, - "this `map_or` is redundant", + "this `map_or` can be simplified", format!("use {method} instead"), sugg, - Applicability::MaybeIncorrect, + applicability, ); } diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 84ea3554a358e..d19064fd57e3e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -1,7 +1,7 @@ use super::implicit_clone::is_clone_like; use super::unnecessary_iter_cloned::{self, is_into_iter}; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{SpanRangeExt, snippet}; use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, is_type_diagnostic_item, is_type_lang_item}; use clippy_utils::visitors::find_all_ret_expressions; diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs index 408dbef9cb16a..b856c929cf67b 100644 --- a/src/tools/clippy/clippy_lints/src/misc.rs +++ b/src/tools/clippy/clippy_lints/src/misc.rs @@ -114,7 +114,7 @@ declare_clippy_lint! { /// let _ = FooStruct{}; /// } /// ``` - #[clippy::version = "pre 1.29.0"] + #[clippy::version = "1.83.0"] pub USED_UNDERSCORE_ITEMS, pedantic, "using a item which is prefixed with an underscore" @@ -351,7 +351,7 @@ fn used_underscore_binding<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { /// `unused_variables`'s idea /// of what it means for an expression to be "used". fn is_used(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - get_parent_expr(cx, expr).map_or(true, |parent| match parent.kind { + get_parent_expr(cx, expr).is_none_or(|parent| match parent.kind { ExprKind::Assign(_, rhs, _) | ExprKind::AssignOp(_, _, rhs) => SpanlessEq::new(cx).eq_expr(rhs, expr), _ => is_used(cx, parent), }) diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs index eea0459e026e8..121c4326d6488 100644 --- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs +++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::qualify_min_const_fn::is_min_const_fn; use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, trait_ref_of_method}; use rustc_errors::Applicability; diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs index c2f524a635316..9a44a3c980c0e 100644 --- a/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs +++ b/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::macros::macro_backtrace; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::qualify_min_const_fn::is_min_const_fn; use clippy_utils::source::snippet; use clippy_utils::{fn_has_unsatisfiable_preds, peel_blocks}; diff --git a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs index d276e29bacecf..882ab2dda7aaa 100644 --- a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs +++ b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs @@ -1,5 +1,5 @@ use rustc_ast::visit::FnKind; -use rustc_ast::{NodeId, WherePredicate}; +use rustc_ast::{NodeId, WherePredicateKind}; use rustc_data_structures::fx::FxHashMap; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::declare_lint_pass; @@ -51,8 +51,8 @@ impl EarlyLintPass for MultipleBoundLocations { } } for clause in &generics.where_clause.predicates { - match clause { - WherePredicate::BoundPredicate(pred) => { + match &clause.kind { + WherePredicateKind::BoundPredicate(pred) => { if (!pred.bound_generic_params.is_empty() || !pred.bounds.is_empty()) && let Some(Some(bound_span)) = pred .bounded_ty @@ -62,14 +62,14 @@ impl EarlyLintPass for MultipleBoundLocations { emit_lint(cx, *bound_span, pred.bounded_ty.span); } }, - WherePredicate::RegionPredicate(pred) => { + WherePredicateKind::RegionPredicate(pred) => { if !pred.bounds.is_empty() && let Some(bound_span) = generic_params_with_bounds.get(&pred.lifetime.ident.name.as_str()) { emit_lint(cx, *bound_span, pred.lifetime.ident.span); } }, - WherePredicate::EqPredicate(_) => {}, + WherePredicateKind::EqPredicate(_) => {}, } } } diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index 9ebef531bc5cc..f69913ddbfd97 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::mir::{PossibleBorrowerMap, enclosing_mir, expr_local, local_assignments, used_exactly_once}; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::{implements_trait, is_copy}; use clippy_utils::{DefinedTy, ExprUseNode, expr_use_ctxt, peel_n_hir_expr_refs}; @@ -362,7 +362,7 @@ fn referent_used_exactly_once<'tcx>( let body_owner_local_def_id = cx.tcx.hir().enclosing_body_owner(reference.hir_id); if possible_borrowers .last() - .map_or(true, |&(local_def_id, _)| local_def_id != body_owner_local_def_id) + .is_none_or(|&(local_def_id, _)| local_def_id != body_owner_local_def_id) { possible_borrowers.push((body_owner_local_def_id, PossibleBorrowerMap::new(cx, mir))); } diff --git a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs index 852a0ce8c6d57..ad6313e391bd9 100644 --- a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs +++ b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_errors::Applicability; use rustc_hir::def_id::{DefId, DefIdMap}; -use rustc_hir::{BoundPolarity, GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, WherePredicate}; +use rustc_hir::{BoundPolarity, GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, WherePredicateKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{ClauseKind, PredicatePolarity}; use rustc_session::declare_lint_pass; @@ -52,7 +52,7 @@ fn type_param_bounds<'tcx>(generics: &'tcx Generics<'tcx>) -> impl Iterator LateLintPass<'tcx> for NeedlessPassByValue { && !is_copy(cx, ty) && ty.is_sized(cx.tcx, cx.typing_env()) && !allowed_traits.iter().any(|&t| { - implements_trait_with_env_from_iter( - cx.tcx, - cx.typing_env(), - ty, - t, - None, - [None::>] - ) + implements_trait_with_env_from_iter(cx.tcx, cx.typing_env(), ty, t, None, [None::< + ty::GenericArg<'tcx>, + >]) }) && !implements_borrow_trait && !all_borrowable_trait diff --git a/src/tools/clippy/clippy_lints/src/neg_multiply.rs b/src/tools/clippy/clippy_lints/src/neg_multiply.rs index f84d9fadb85c5..a0ba2aaf55236 100644 --- a/src/tools/clippy/clippy_lints/src/neg_multiply.rs +++ b/src/tools/clippy/clippy_lints/src/neg_multiply.rs @@ -58,7 +58,7 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) { { let mut applicability = Applicability::MachineApplicable; let (snip, from_macro) = snippet_with_context(cx, exp.span, span.ctxt(), "..", &mut applicability); - let suggestion = if !from_macro && exp.precedence().order() < PREC_PREFIX && !has_enclosing_paren(&snip) { + let suggestion = if !from_macro && exp.precedence() < PREC_PREFIX && !has_enclosing_paren(&snip) { format!("-({snip})") } else { format!("-{snip}") diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs index 74536028b5d46..8ecff9c3f9b36 100644 --- a/src/tools/clippy/clippy_lints/src/no_effect.rs +++ b/src/tools/clippy/clippy_lints/src/no_effect.rs @@ -238,7 +238,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { ExprKind::Struct(_, fields, ref base) => { !has_drop(cx, cx.typeck_results().expr_ty(expr)) && fields.iter().all(|field| has_no_effect(cx, field.expr)) - && base.as_ref().map_or(true, |base| has_no_effect(cx, base)) + && base.as_ref().is_none_or(|base| has_no_effect(cx, base)) }, ExprKind::Call(callee, args) => { if let ExprKind::Path(ref qpath) = callee.kind { diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 5416e00fe0cbf..5f253b9e5d5bd 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -278,7 +278,12 @@ impl<'tcx> NonCopyConst<'tcx> { fn is_value_unfrozen_expr(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool { let args = cx.typeck_results().node_args(hir_id); - let result = Self::const_eval_resolve(cx.tcx, cx.typing_env(), ty::UnevaluatedConst::new(def_id, args), DUMMY_SP); + let result = Self::const_eval_resolve( + cx.tcx, + cx.typing_env(), + ty::UnevaluatedConst::new(def_id, args), + DUMMY_SP, + ); Self::is_value_unfrozen_raw(cx, result, ty) } @@ -335,7 +340,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { // i.e. having an enum doesn't necessary mean a type has a frozen variant. // And, implementing it isn't a trivial task; it'll probably end up // re-implementing the trait predicate evaluation specific to `Freeze`. - && body_id_opt.map_or(true, |body_id| Self::is_value_unfrozen_poly(cx, body_id, normalized)) + && body_id_opt.is_none_or(|body_id| Self::is_value_unfrozen_poly(cx, body_id, normalized)) { lint(cx, Source::Assoc { item: trait_item.span }); } diff --git a/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs b/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs index aefb665b52e2f..f6ce1d1d58672 100644 --- a/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs +++ b/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs @@ -39,7 +39,7 @@ declare_clippy_lint! { /// let r2 = x % NonZeroU64::from(y); /// } /// ``` - #[clippy::version = "1.81.0"] + #[clippy::version = "1.83.0"] pub NON_ZERO_SUGGESTIONS, restriction, "suggests using `NonZero#` from `u#` or `i#` for more efficient and type-safe conversions" diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index 13b3d24070070..6de203e068b79 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs @@ -200,7 +200,7 @@ impl Params { if self .get_by_fn(param.fn_id, usage.idx) // If the parameter can't be found, then it's used for more than just recursion. - .map_or(true, |p| self.try_disable_lint_for_param(p, eval_stack)) + .is_none_or(|p| self.try_disable_lint_for_param(p, eval_stack)) { param.apply_lint.set(false); eval_stack.pop(); diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs index 0dcaec1c9a721..1315c3dfc127c 100644 --- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs +++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs @@ -27,7 +27,7 @@ pub(super) fn check<'tcx>( if let Some((_, lang_item)) = binop_traits(op.node) && let Some(trait_id) = cx.tcx.lang_items().get(lang_item) && let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id).def_id - && trait_ref_of_method(cx, parent_fn).map_or(true, |t| t.path.res.def_id() != trait_id) + && trait_ref_of_method(cx, parent_fn).is_none_or(|t| t.path.res.def_id() != trait_id) && implements_trait(cx, ty, trait_id, &[rty.into()]) { // Primitive types execute assign-ops right-to-left. Every other type is left-to-right. diff --git a/src/tools/clippy/clippy_lints/src/operators/bit_mask.rs b/src/tools/clippy/clippy_lints/src/operators/bit_mask.rs index 4414056a467ca..e87cfd103c301 100644 --- a/src/tools/clippy/clippy_lints/src/operators/bit_mask.rs +++ b/src/tools/clippy/clippy_lints/src/operators/bit_mask.rs @@ -1,5 +1,6 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint; +use clippy_utils::is_from_proc_macro; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::LateContext; use rustc_span::Span; @@ -35,9 +36,9 @@ fn invert_cmp(cmp: BinOpKind) -> BinOpKind { } } -fn check_compare(cx: &LateContext<'_>, bit_op: &Expr<'_>, cmp_op: BinOpKind, cmp_value: u128, span: Span) { +fn check_compare<'a>(cx: &LateContext<'a>, bit_op: &Expr<'a>, cmp_op: BinOpKind, cmp_value: u128, span: Span) { if let ExprKind::Binary(op, left, right) = &bit_op.kind { - if op.node != BinOpKind::BitAnd && op.node != BinOpKind::BitOr { + if op.node != BinOpKind::BitAnd && op.node != BinOpKind::BitOr || is_from_proc_macro(cx, bit_op) { return; } if let Some(mask) = fetch_int_literal(cx, right).or_else(|| fetch_int_literal(cx, left)) { diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index ecc095f385991..dec4c18a309ee 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -541,9 +541,7 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio .collect(); if let Some(args) = args && !args.is_empty() - && body.map_or(true, |body| { - sig.header.safety == Safety::Unsafe || contains_unsafe_block(cx, body.value) - }) + && body.is_none_or(|body| sig.header.safety == Safety::Unsafe || contains_unsafe_block(cx, body.value)) { span_lint_and_then( cx, diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs index f69cb9be4caee..4b96858d8f66f 100644 --- a/src/tools/clippy/clippy_lints/src/question_mark.rs +++ b/src/tools/clippy/clippy_lints/src/question_mark.rs @@ -1,9 +1,9 @@ use crate::manual_let_else::MANUAL_LET_ELSE; use crate::question_mark_used::QUESTION_MARK_USED; use clippy_config::Conf; -use clippy_config::msrvs::Msrv; use clippy_config::types::MatchLintBehaviour; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::Msrv; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; use clippy_utils::{ diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs index 21cd33672624f..1b0c0a4956f7e 100644 --- a/src/tools/clippy/clippy_lints/src/ranges.rs +++ b/src/tools/clippy/clippy_lints/src/ranges.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{SpanRangeExt, snippet, snippet_with_applicability}; use clippy_utils::sugg::Sugg; use clippy_utils::{get_parent_expr, higher, is_in_const_context, is_integer_const, path_to_local}; diff --git a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs index 313e4083256bc..3ade6bcee84d8 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs @@ -88,7 +88,7 @@ fn desugar_async_block<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Op cx.typeck_results() .closure_min_captures .get(def_id) - .map_or(true, |m| { + .is_none_or(|m| { m.values().all(|places| { places .iter() diff --git a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs index d0dbff081f905..347540e7344f9 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; use rustc_ast::ast::{Expr, ExprKind}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs index 0ac818c21d9b0..79baa914b0319 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs @@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing { let (expr_ty, expr_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(expr)); let (indexed_ty, indexed_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(indexed)); let parent_expr = get_parent_expr(cx, expr); - let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence().order() > PREC_PREFIX); + let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence() > PREC_PREFIX); if expr_ty == indexed_ty { if expr_ref_count > indexed_ref_count { diff --git a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs index b27bb2e78afed..06c854338066f 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use rustc_ast::ast::{ConstItem, Item, ItemKind, StaticItem, Ty, TyKind}; use rustc_errors::Applicability; diff --git a/src/tools/clippy/clippy_lints/src/single_call_fn.rs b/src/tools/clippy/clippy_lints/src/single_call_fn.rs index abe13a97c0d18..0176077c70e04 100644 --- a/src/tools/clippy/clippy_lints/src/single_call_fn.rs +++ b/src/tools/clippy/clippy_lints/src/single_call_fn.rs @@ -93,7 +93,7 @@ impl SingleCallFn { .tcx .hir() .maybe_body_owned_by(fn_def_id) - .map_or(true, |body| is_in_test_function(cx.tcx, body.value.hir_id)) + .is_none_or(|body| is_in_test_function(cx.tcx, body.value.hir_id)) || match cx.tcx.hir_node(fn_hir_id) { Node::Item(item) => is_from_proc_macro(cx, item), Node::ImplItem(item) => is_from_proc_macro(cx, item), diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs index 8dd9985879323..2941b9c39607a 100644 --- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs +++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::Msrv; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::is_from_proc_macro; +use clippy_utils::msrvs::Msrv; use rustc_attr::{StabilityLevel, StableSince}; use rustc_errors::Applicability; use rustc_hir::def::Res; diff --git a/src/tools/clippy/clippy_lints/src/string_patterns.rs b/src/tools/clippy/clippy_lints/src/string_patterns.rs index ba2ddac2ec339..0d85b1b858a4f 100644 --- a/src/tools/clippy/clippy_lints/src/string_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/string_patterns.rs @@ -1,10 +1,10 @@ use std::ops::ControlFlow; use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::eager_or_lazy::switch_to_eager_eval; use clippy_utils::macros::matching_root_macro_call; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::path_to_local_id; use clippy_utils::source::{snippet, str_literal_to_char_literal}; use clippy_utils::visitors::{Descend, for_each_expr}; 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 50a1577b28842..a1d92c3ac71f7 100644 --- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs +++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs @@ -56,9 +56,10 @@ 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 && let Some(last_field) = data.fields().last() - && let field_ty = cx - .tcx - .normalize_erasing_regions(cx.typing_env(), cx.tcx.type_of(last_field.def_id).instantiate_identity()) + && let field_ty = cx.tcx.normalize_erasing_regions( + cx.typing_env(), + cx.tcx.type_of(last_field.def_id).instantiate_identity(), + ) && let ty::Array(_, array_len) = *field_ty.kind() && let Some(0) = array_len.try_to_target_usize(cx.tcx) { diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs index 07bf4319ff0e8..99844beb8f00f 100644 --- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{SpanRangeExt, snippet, snippet_with_applicability}; use clippy_utils::{SpanlessEq, SpanlessHash, is_from_proc_macro}; use core::hash::{Hash, Hasher}; @@ -11,7 +11,7 @@ use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::{ BoundPolarity, GenericBound, Generics, Item, ItemKind, LangItem, Node, Path, PathSegment, PredicateOrigin, QPath, - TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicate, + TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicateKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; @@ -124,9 +124,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { let mut self_bounds_map = FxHashMap::default(); for predicate in item.generics.predicates { - if let WherePredicate::BoundPredicate(bound_predicate) = predicate + if let WherePredicateKind::BoundPredicate(bound_predicate) = predicate.kind && bound_predicate.origin != PredicateOrigin::ImplTrait - && !bound_predicate.span.from_expansion() + && !predicate.span.from_expansion() && let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind && let Some(PathSegment { res: Res::SelfTyParam { trait_: def_id }, @@ -268,10 +268,10 @@ impl TraitBounds { let mut map: UnhashMap, Vec<&GenericBound<'_>>> = UnhashMap::default(); let mut applicability = Applicability::MaybeIncorrect; for bound in generics.predicates { - if let WherePredicate::BoundPredicate(p) = bound + if let WherePredicateKind::BoundPredicate(p) = bound.kind && p.origin != PredicateOrigin::ImplTrait && p.bounds.len() as u64 <= self.max_trait_bounds - && !p.span.from_expansion() + && !bound.span.from_expansion() && let bounds = p .bounds .iter() @@ -295,7 +295,7 @@ impl TraitBounds { span_lint_and_help( cx, TYPE_REPETITION_IN_BOUNDS, - p.span, + bound.span, "this type has already been used as a bound predicate", None, hint_string, @@ -322,8 +322,8 @@ fn check_trait_bound_duplication<'tcx>(cx: &LateContext<'tcx>, generics: &'_ Gen .predicates .iter() .filter_map(|pred| { - if pred.in_where_clause() - && let WherePredicate::BoundPredicate(bound_predicate) = pred + if pred.kind.in_where_clause() + && let WherePredicateKind::BoundPredicate(bound_predicate) = pred.kind && let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind { return Some( @@ -347,10 +347,10 @@ fn check_trait_bound_duplication<'tcx>(cx: &LateContext<'tcx>, generics: &'_ Gen // | // compare trait bounds keyed by generic name and comparable trait to collected where // predicates eg. (T, Clone) - for predicate in generics.predicates.iter().filter(|pred| !pred.in_where_clause()) { - if let WherePredicate::BoundPredicate(bound_predicate) = predicate + for predicate in generics.predicates.iter().filter(|pred| !pred.kind.in_where_clause()) { + if let WherePredicateKind::BoundPredicate(bound_predicate) = predicate.kind && bound_predicate.origin != PredicateOrigin::ImplTrait - && !bound_predicate.span.from_expansion() + && !predicate.span.from_expansion() && let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind { let traits = rollup_traits(cx, bound_predicate.bounds, "these bounds contain repeated elements"); diff --git a/src/tools/clippy/clippy_lints/src/transmute/mod.rs b/src/tools/clippy/clippy_lints/src/transmute/mod.rs index 25fec9f688ca3..1cb0f837227df 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/mod.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/mod.rs @@ -20,8 +20,8 @@ mod utils; mod wrong_transmute; use clippy_config::Conf; -use clippy_config::msrvs::Msrv; use clippy_utils::is_in_const_context; +use clippy_utils::msrvs::Msrv; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs index 3507eb9a12480..f0b8abf9af664 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs @@ -1,6 +1,6 @@ use super::TRANSMUTE_FLOAT_TO_INT; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::sugg; use rustc_ast as ast; use rustc_errors::Applicability; diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs index c5c7ed6d398b9..e5b9aea6423a0 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs @@ -1,6 +1,6 @@ use super::TRANSMUTE_INT_TO_FLOAT; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::sugg; use rustc_errors::Applicability; use rustc_hir::Expr; diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs index a94cd27c7fd1d..6d828bad9b32d 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs @@ -1,6 +1,6 @@ use super::TRANSMUTE_NUM_TO_BYTES; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::sugg; use rustc_errors::Applicability; use rustc_hir::Expr; diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs index bf6700b1b6ba5..c4a2e20fa9d31 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs @@ -1,6 +1,6 @@ use super::TRANSMUTE_PTR_TO_PTR; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::sugg; use rustc_errors::Applicability; use rustc_hir::Expr; diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs index eaf927c0005fd..ef18633d945fa 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs @@ -1,6 +1,6 @@ use super::TRANSMUTE_PTR_TO_REF; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg; use rustc_errors::Applicability; diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs index fca332dba401a..8d71036084d3d 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs @@ -1,7 +1,7 @@ use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::sugg::Sugg; -use rustc_ast::ExprPrecedence; +use rustc_ast::util::parser::AssocOp; use rustc_errors::Applicability; use rustc_hir::{Expr, Node}; use rustc_hir_typeck::cast::check_cast; @@ -44,7 +44,8 @@ pub(super) fn check<'tcx>( }; if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id) - && parent.precedence().order() > ExprPrecedence::Cast.order() + && parent.precedence() + > i8::try_from(AssocOp::As.precedence()).expect("AssocOp always returns a precedence < 128") { sugg = format!("({sugg})"); } diff --git a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs index 07d0f59b91c1d..99a55f9fc357e 100644 --- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs +++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::visitors::for_each_local_use_after_expr; use clippy_utils::{is_from_proc_macro, path_to_local}; use itertools::Itertools; 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 0bba611116bbc..b79e59f857bbf 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -337,7 +337,7 @@ fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, span: Span) -> bool { .src .as_deref() .and_then(|src| src.get(file_pos.pos.to_usize()..)) - .map_or(true, |src| !src.starts_with("unsafe")) + .is_none_or(|src| !src.starts_with("unsafe")) } // Checks if any parent {expression, statement, block, local, const, static} diff --git a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs index 6eef582b4b28c..0702f6d1e74b2 100644 --- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs +++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs @@ -145,7 +145,7 @@ fn expr_needs_inferred_result<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) - } while let Some(id) = locals_to_check.pop() { if let Node::LetStmt(l) = cx.tcx.parent_hir_node(id) { - if !l.ty.map_or(true, |ty| matches!(ty.kind, TyKind::Infer)) { + if !l.ty.is_none_or(|ty| matches!(ty.kind, TyKind::Infer)) { return false; } if let Some(e) = l.init { diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs index c7c837de505e4..9d26bf930a1a9 100644 --- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs @@ -1,9 +1,9 @@ #![allow(clippy::wildcard_imports, clippy::enum_glob_use)] use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_maybe_qself, eq_pat, eq_path}; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::over; use rustc_ast::PatKind::*; use rustc_ast::mut_visit::*; 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 9fd6ebccd02f4..17ee5fc20ca2c 100644 --- a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs +++ b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::is_from_proc_macro; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_opt; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; 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 8de062a8fc153..c3843279ba2e8 100644 --- a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs +++ b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs @@ -93,7 +93,7 @@ fn check_ident(cx: &LateContext<'_>, ident: &Ident, hir_id: HirId, be_aggressive while let Some(c) = s.next() { r.push( if replace(&mut prev_upper, c.is_ascii_uppercase()) - && s.clone().next().map_or(true, |c| c.is_ascii_uppercase()) + && s.clone().next().is_none_or(|c| c.is_ascii_uppercase()) { c.to_ascii_lowercase() } else { diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs index f5cf4a586fd29..05c5be0300282 100644 --- a/src/tools/clippy/clippy_lints/src/use_self.rs +++ b/src/tools/clippy/clippy_lints/src/use_self.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::is_from_proc_macro; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::same_type_and_consts; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; @@ -94,7 +94,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { && let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args && parameters .as_ref() - .map_or(true, |params| params.parenthesized == GenericArgsParentheses::No) + .is_none_or(|params| params.parenthesized == GenericArgsParentheses::No) && !item.span.from_expansion() && !is_from_proc_macro(cx, item) // expensive, should be last check diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs index 96397375d5edb..a5fad68eea189 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs @@ -5,8 +5,8 @@ use rustc_hir as hir; use rustc_hir::Item; use rustc_hir::def::DefKind; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::FloatTy; use rustc_middle::ty::fast_reject::SimplifiedType; +use rustc_middle::ty::{self, FloatTy}; use rustc_session::declare_lint_pass; use rustc_span::symbol::Symbol; @@ -32,9 +32,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths { let mod_name = &cx.tcx.item_name(local_def_id.to_def_id()); if mod_name.as_str() == "paths" && let hir::ItemKind::Const(.., body_id) = item.kind - && let Some(Constant::Vec(path)) = - ConstEvalCtxt::with_env(cx.tcx, cx.tcx.param_env(item.owner_id), cx.tcx.typeck(item.owner_id)) - .eval_simple(cx.tcx.hir().body(body_id).value) + && let Some(Constant::Vec(path)) = ConstEvalCtxt::with_env( + cx.tcx, + ty::TypingEnv::post_analysis(cx.tcx, item.owner_id), + cx.tcx.typeck(item.owner_id), + ) + .eval_simple(cx.tcx.hir().body(body_id).value) && let Some(path) = path .iter() .map(|x| { diff --git a/src/tools/clippy/clippy_lints/src/vec.rs b/src/tools/clippy/clippy_lints/src/vec.rs index 9bcff9d7bcec7..ef1c46154d29a 100644 --- a/src/tools/clippy/clippy_lints/src/vec.rs +++ b/src/tools/clippy/clippy_lints/src/vec.rs @@ -2,9 +2,9 @@ use std::collections::BTreeMap; use std::ops::ControlFlow; use clippy_config::Conf; -use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint_hir_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::SpanRangeExt; use clippy_utils::ty::is_copy; use clippy_utils::visitors::for_each_local_use_after_expr; diff --git a/src/tools/clippy/clippy_lints/src/zombie_processes.rs b/src/tools/clippy/clippy_lints/src/zombie_processes.rs index 8d9241cc7d9a2..4a13c10166f86 100644 --- a/src/tools/clippy/clippy_lints/src/zombie_processes.rs +++ b/src/tools/clippy/clippy_lints/src/zombie_processes.rs @@ -35,7 +35,7 @@ declare_clippy_lint! { /// let mut child = Command::new("ls").spawn().expect("failed to execute child"); /// child.wait().expect("failed to wait on child"); /// ``` - #[clippy::version = "1.74.0"] + #[clippy::version = "1.83.0"] pub ZOMBIE_PROCESSES, suspicious, "not waiting on a spawned child process" diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml index d8d5733da1c94..945827c98c179 100644 --- a/src/tools/clippy/clippy_utils/Cargo.toml +++ b/src/tools/clippy/clippy_utils/Cargo.toml @@ -1,15 +1,22 @@ [package] name = "clippy_utils" -version = "0.1.84" +# begin autogenerated version +version = "0.1.85" +# end autogenerated version edition = "2021" -publish = false +description = "Helpful tools for writing lints, provided as they are used in Clippy" +repository = "https://github.com/rust-lang/rust-clippy" +readme = "README.md" +license = "MIT OR Apache-2.0" +keywords = ["clippy", "lint", "utils"] +categories = ["development-tools"] [dependencies] -clippy_config = { path = "../clippy_config" } arrayvec = { version = "0.7", default-features = false } itertools = "0.12" # FIXME(f16_f128): remove when no longer needed for parsing rustc_apfloat = "0.2.0" +serde = { version = "1.0", features = ["derive"] } [package.metadata.rust-analyzer] # This crate uses #[feature(rustc_private)] diff --git a/src/tools/clippy/clippy_utils/README.md b/src/tools/clippy/clippy_utils/README.md new file mode 100644 index 0000000000000..61476a82ba006 --- /dev/null +++ b/src/tools/clippy/clippy_utils/README.md @@ -0,0 +1,40 @@ +# `clippy-utils` + +Helpful tools for writing lints, provided as they are used in Clippy. + +## Usage + +This crate is only guaranteed to build with this `nightly` toolchain: + + +``` +nightly-2024-11-28 +``` + + +To use `clippy-utils` in your lint, add the following to your `Cargo.toml`: + +``` +clippy_utils = "0.1.XY" +``` + +`XY` is the version of the nightly toolchain above and can be determined with `rustc +nightly-YYYY-MM-DD -V`. + +## :warning: Stability :warning: + +No stability guarantees are made for this crate! Use at your own risk. + +Function signatures can change or be removed without replacement without any prior notice. + +## LICENSE + + + +Copyright 2014-2024 The Rust Project Developers + +Licensed under the Apache License, Version 2.0 +<[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)> or the MIT license +<[https://opensource.org/licenses/MIT](https://opensource.org/licenses/MIT)>, at your option. Files in the project may +not be copied, modified, or distributed except according to those terms. + + diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 0be6dc15a8e13..c90f4a6ebfe63 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -661,8 +661,8 @@ pub fn eq_generics(l: &Generics, r: &Generics) -> bool { } pub fn eq_where_predicate(l: &WherePredicate, r: &WherePredicate) -> bool { - use WherePredicate::*; - match (l, r) { + use WherePredicateKind::*; + match (&l.kind, &r.kind) { (BoundPredicate(l), BoundPredicate(r)) => { over(&l.bound_generic_params, &r.bound_generic_params, |l, r| { eq_generic_param(l, r) diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs index edc9c6ccdff84..b2a6657baad3e 100644 --- a/src/tools/clippy/clippy_utils/src/attrs.rs +++ b/src/tools/clippy/clippy_utils/src/attrs.rs @@ -27,7 +27,10 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, DeprecationStatus)] = &[ ("cyclomatic_complexity", DeprecationStatus::Replaced("cognitive_complexity")), ("dump", DeprecationStatus::None), ("msrv", DeprecationStatus::None), + // The following attributes are for the 3rd party crate authors. + // See book/src/attribs.md ("has_significant_drop", DeprecationStatus::None), + ("format_args", DeprecationStatus::None), ]; pub struct LimitStack { diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 52c986462899a..43ddf06730dd2 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -226,7 +226,7 @@ impl Constant<'_> { .zip(r) .zip(tys) .map(|((li, ri), cmp_type)| Self::partial_cmp(tcx, cmp_type, li, ri)) - .find(|r| r.map_or(true, |o| o != Ordering::Equal)) + .find(|r| r.is_none_or(|o| o != Ordering::Equal)) .unwrap_or_else(|| Some(l.len().cmp(&r.len()))), _ => None, }, @@ -236,7 +236,7 @@ impl Constant<'_> { }; iter::zip(l, r) .map(|(li, ri)| Self::partial_cmp(tcx, cmp_type, li, ri)) - .find(|r| r.map_or(true, |o| o != Ordering::Equal)) + .find(|r| r.is_none_or(|o| o != Ordering::Equal)) .unwrap_or_else(|| Some(l.len().cmp(&r.len()))) }, (Self::Repeat(lv, ls), Self::Repeat(rv, rs)) => { diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index ea866a78d87fe..8a88a24e924cd 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -545,7 +545,7 @@ impl HirEqInterExpr<'_, '_, '_> { fn eq_path_parameters(&mut self, left: &GenericArgs<'_>, right: &GenericArgs<'_>) -> bool { if left.parenthesized == right.parenthesized { over(left.args, right.args, |l, r| self.eq_generic_arg(l, r)) // FIXME(flip1995): may not work - && over(left.constraints, right.constraints, |l, r| self.eq_assoc_type_binding(l, r)) + && over(left.constraints, right.constraints, |l, r| self.eq_assoc_eq_constraint(l, r)) } else { false } @@ -602,12 +602,13 @@ impl HirEqInterExpr<'_, '_, '_> { } } - fn eq_assoc_type_binding(&mut self, left: &AssocItemConstraint<'_>, right: &AssocItemConstraint<'_>) -> bool { + /// Checks whether two constraints designate the same equality constraint (same name, and same + /// type or const). + fn eq_assoc_eq_constraint(&mut self, left: &AssocItemConstraint<'_>, right: &AssocItemConstraint<'_>) -> bool { + // TODO: this could be extended to check for identical associated item bound constraints left.ident.name == right.ident.name - && self.eq_ty( - left.ty().expect("expected assoc type binding"), - right.ty().expect("expected assoc type binding"), - ) + && (both_some_and(left.ty(), right.ty(), |l, r| self.eq_ty(l, r)) + || both_some_and(left.ct(), right.ct(), |l, r| self.eq_const_arg(l, r))) } fn check_ctxt(&mut self, left: SyntaxContext, right: SyntaxContext) -> bool { @@ -727,6 +728,11 @@ pub fn both(l: Option<&X>, r: Option<&X>, mut eq_fn: impl FnMut(&X, &X) -> bo .map_or_else(|| r.is_none(), |x| r.as_ref().is_some_and(|y| eq_fn(x, y))) } +/// Checks if the two `Option`s are both `Some` and pass the predicate function. +pub fn both_some_and(l: Option, r: Option, mut pred: impl FnMut(X, Y) -> bool) -> bool { + l.is_some_and(|l| r.is_some_and(|r| pred(l, r))) +} + /// Checks if two slices are equal as per `eq_fn`. pub fn over(left: &[X], right: &[X], mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool { left.len() == right.len() && left.iter().zip(right).all(|(x, y)| eq_fn(x, y)) diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 6408cc938cb86..434c26d687d7d 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -50,6 +50,7 @@ extern crate rustc_session; extern crate rustc_span; extern crate rustc_target; extern crate rustc_trait_selection; +extern crate smallvec; #[macro_use] pub mod sym_helper; @@ -65,6 +66,7 @@ pub mod higher; mod hir_utils; pub mod macros; pub mod mir; +pub mod msrvs; pub mod numeric_literal; pub mod paths; pub mod ptr; @@ -89,7 +91,6 @@ use std::hash::BuildHasherDefault; use std::iter::{once, repeat}; use std::sync::{Mutex, MutexGuard, OnceLock}; -use clippy_config::types::DisallowedPath; use itertools::Itertools; use rustc_ast::ast::{self, LitKind, RangeLimits}; use rustc_data_structures::fx::FxHashMap; @@ -97,7 +98,7 @@ use rustc_data_structures::packed::Pu128; use rustc_data_structures::unhash::UnhashMap; use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk}; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId, LocalModDefId}; +use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId}; use rustc_hir::definitions::{DefPath, DefPathData}; use rustc_hir::hir_id::{HirIdMap, HirIdSet}; use rustc_hir::intravisit::{FnKind, Visitor, walk_expr}; @@ -116,8 +117,8 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{ - self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgsRef, IntTy, - Ty, TyCtxt, TypeVisitableExt, UintTy, UpvarCapture, + self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgsRef, IntTy, Ty, TyCtxt, + TypeVisitableExt, UintTy, UpvarCapture, }; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::SourceMap; @@ -748,18 +749,6 @@ pub fn def_path_def_ids(tcx: TyCtxt<'_>, path: &[&str]) -> impl Iterator, - disallowed: &'static [DisallowedPath], -) -> DefIdMap<(&'static str, Option<&'static str>)> { - disallowed - .iter() - .map(|x| (x.path(), x.path().split("::").collect::>(), x.reason())) - .flat_map(|(name, path, reason)| def_path_def_ids(tcx, &path).map(move |id| (id, (name, reason)))) - .collect() -} - /// Convenience function to get the `DefId` of a trait by path. /// It could be a trait or trait alias. /// @@ -1581,7 +1570,7 @@ pub fn is_else_clause_in_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Option<&Path<'_>>) -> bool { let ty = cx.typeck_results().expr_ty(expr); if let Some(Range { start, end, limits }) = Range::hir(expr) { - let start_is_none_or_min = start.map_or(true, |start| { + let start_is_none_or_min = start.is_none_or(|start| { if let rustc_ty::Adt(_, subst) = ty.kind() && let bnd_ty = subst.type_at(0) && let Some(min_val) = bnd_ty.numeric_min_val(cx.tcx) @@ -1593,7 +1582,7 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti false } }); - let end_is_none_or_max = end.map_or(true, |end| match limits { + let end_is_none_or_max = end.is_none_or(|end| match limits { RangeLimits::Closed => { if let rustc_ty::Adt(_, subst) = ty.kind() && let bnd_ty = subst.type_at(0) @@ -2715,10 +2704,10 @@ pub enum DefinedTy<'tcx> { /// Used for function signatures, and constant and static values. The type is /// in the context of its definition site. We also track the `def_id` of its /// definition site. - /// + /// /// WARNING: As the `ty` in in the scope of the definition, not of the function /// using it, you must be very careful with how you use it. Using it in the wrong - /// scope easily results in ICEs. + /// scope easily results in ICEs. Mir { def_site_def_id: Option, ty: Binder<'tcx, Ty<'tcx>>, @@ -2844,7 +2833,7 @@ impl<'tcx> ExprUseNode<'tcx> { Self::ConstStatic(id) => Some(DefinedTy::Mir { def_site_def_id: Some(id.def_id.to_def_id()), ty: Binder::dummy(cx.tcx.type_of(id).instantiate_identity()), - }), + }), Self::Return(id) => { if let Node::Expr(Expr { kind: ExprKind::Closure(c), @@ -2857,7 +2846,10 @@ impl<'tcx> ExprUseNode<'tcx> { } } else { let ty = cx.tcx.fn_sig(id).instantiate_identity().output(); - Some(DefinedTy::Mir { def_site_def_id: Some(id.def_id.to_def_id()), ty }) + Some(DefinedTy::Mir { + def_site_def_id: Some(id.def_id.to_def_id()), + ty, + }) } }, Self::Field(field) => match get_parent_expr_for_hir(cx, field.hir_id) { @@ -2874,8 +2866,8 @@ impl<'tcx> ExprUseNode<'tcx> { .map(|f| (adt, f)) }) .map(|(adt, field_def)| DefinedTy::Mir { - def_site_def_id: Some(adt.did()), - ty: Binder::dummy(cx.tcx.type_of(field_def.did).instantiate_identity()), + def_site_def_id: Some(adt.did()), + ty: Binder::dummy(cx.tcx.type_of(field_def.did).instantiate_identity()), }), _ => None, }, @@ -2885,9 +2877,9 @@ impl<'tcx> ExprUseNode<'tcx> { Some(match hir_ty { Some(hir_ty) => DefinedTy::Hir(hir_ty), None => DefinedTy::Mir { - def_site_def_id: sig.predicates_id(), + def_site_def_id: sig.predicates_id(), ty, - } + }, }) }, Self::MethodArg(id, _, i) => { diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs index 9c4d19ac1f1dd..45beb146eb6ab 100644 --- a/src/tools/clippy/clippy_utils/src/macros.rs +++ b/src/tools/clippy/clippy_utils/src/macros.rs @@ -1,5 +1,6 @@ #![allow(clippy::similar_names)] // `expr` and `expn` +use crate::get_unique_attr; use crate::visitors::{Descend, for_each_expr_without_closures}; use arrayvec::ArrayVec; @@ -7,7 +8,7 @@ use rustc_ast::{FormatArgs, FormatArgument, FormatPlaceholder}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{Lrc, OnceLock}; use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath}; -use rustc_lint::LateContext; +use rustc_lint::{LateContext, LintContext}; use rustc_span::def_id::DefId; use rustc_span::hygiene::{self, MacroKind, SyntaxContext}; use rustc_span::{BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol, sym}; @@ -36,7 +37,9 @@ pub fn is_format_macro(cx: &LateContext<'_>, macro_def_id: DefId) -> bool { if let Some(name) = cx.tcx.get_diagnostic_name(macro_def_id) { FORMAT_MACRO_DIAG_ITEMS.contains(&name) } else { - false + // Allow users to tag any macro as being format!-like + // TODO: consider deleting FORMAT_MACRO_DIAG_ITEMS and using just this method + get_unique_attr(cx.sess(), cx.tcx.get_attrs_unchecked(macro_def_id), "format_args").is_some() } } @@ -93,7 +96,7 @@ pub fn expn_is_local(expn: ExpnId) -> bool { std::iter::once((expn, data)) .chain(backtrace) .find_map(|(_, data)| data.macro_def_id) - .map_or(true, DefId::is_local) + .is_none_or(DefId::is_local) } /// Returns an iterator of macro expansions that created the given span. diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs index 6b3078f52aff5..17e6558a41c45 100644 --- a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs +++ b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs @@ -2,7 +2,7 @@ use super::possible_origin::PossibleOriginVisitor; use super::transitive_relation::TransitiveRelation; use crate::ty::is_copy; use rustc_data_structures::fx::FxHashMap; -use rustc_index::bit_set::{BitSet, HybridBitSet}; +use rustc_index::bit_set::BitSet; use rustc_lint::LateContext; use rustc_middle::mir::visit::Visitor as _; use rustc_middle::mir::{self, Mutability}; @@ -21,14 +21,14 @@ struct PossibleBorrowerVisitor<'a, 'b, 'tcx> { possible_borrower: TransitiveRelation, body: &'b mir::Body<'tcx>, cx: &'a LateContext<'tcx>, - possible_origin: FxHashMap>, + possible_origin: FxHashMap>, } impl<'a, 'b, 'tcx> PossibleBorrowerVisitor<'a, 'b, 'tcx> { fn new( cx: &'a LateContext<'tcx>, body: &'b mir::Body<'tcx>, - possible_origin: FxHashMap>, + possible_origin: FxHashMap>, ) -> Self { Self { possible_borrower: TransitiveRelation::default(), @@ -119,7 +119,7 @@ impl<'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'_, '_, 'tcx> { let mut mutable_variables: Vec = mutable_borrowers .iter() .filter_map(|r| self.possible_origin.get(r)) - .flat_map(HybridBitSet::iter) + .flat_map(BitSet::iter) .collect(); if ContainsRegion.visit_ty(self.body.local_decls[*dest].ty).is_break() { @@ -171,7 +171,7 @@ fn rvalue_locals(rvalue: &mir::Rvalue<'_>, mut visit: impl FnMut(mir::Local)) { #[allow(clippy::module_name_repetitions)] pub struct PossibleBorrowerMap<'b, 'tcx> { /// Mapping `Local -> its possible borrowers` - pub map: FxHashMap>, + pub map: FxHashMap>, maybe_live: ResultsCursor<'b, 'tcx, MaybeStorageLive<'tcx>>, // Caches to avoid allocation of `BitSet` on every query pub bitset: (BitSet, BitSet), diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_origin.rs b/src/tools/clippy/clippy_utils/src/mir/possible_origin.rs index 4157b3f493066..47b93aad20c83 100644 --- a/src/tools/clippy/clippy_utils/src/mir/possible_origin.rs +++ b/src/tools/clippy/clippy_utils/src/mir/possible_origin.rs @@ -1,7 +1,7 @@ use super::transitive_relation::TransitiveRelation; use crate::ty::is_copy; use rustc_data_structures::fx::FxHashMap; -use rustc_index::bit_set::HybridBitSet; +use rustc_index::bit_set::BitSet; use rustc_lint::LateContext; use rustc_middle::mir; @@ -22,7 +22,7 @@ impl<'a, 'tcx> PossibleOriginVisitor<'a, 'tcx> { } } - pub fn into_map(self, cx: &LateContext<'tcx>) -> FxHashMap> { + pub fn into_map(self, cx: &LateContext<'tcx>) -> FxHashMap> { let mut map = FxHashMap::default(); for row in (1..self.body.local_decls.len()).map(mir::Local::from_usize) { if is_copy(cx, self.body.local_decls[row].ty) { diff --git a/src/tools/clippy/clippy_utils/src/mir/transitive_relation.rs b/src/tools/clippy/clippy_utils/src/mir/transitive_relation.rs index 7fe2960739fa2..74d1f60af71ce 100644 --- a/src/tools/clippy/clippy_utils/src/mir/transitive_relation.rs +++ b/src/tools/clippy/clippy_utils/src/mir/transitive_relation.rs @@ -1,5 +1,5 @@ use rustc_data_structures::fx::FxHashMap; -use rustc_index::bit_set::HybridBitSet; +use rustc_index::bit_set::BitSet; use rustc_middle::mir; #[derive(Default)] @@ -12,8 +12,8 @@ impl TransitiveRelation { self.relations.entry(a).or_default().push(b); } - pub fn reachable_from(&self, a: mir::Local, domain_size: usize) -> HybridBitSet { - let mut seen = HybridBitSet::new_empty(domain_size); + pub fn reachable_from(&self, a: mir::Local, domain_size: usize) -> BitSet { + let mut seen = BitSet::new_empty(domain_size); let mut stack = vec![a]; while let Some(u) = stack.pop() { if let Some(edges) = self.relations.get(&u) { diff --git a/src/tools/clippy/clippy_config/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs similarity index 98% rename from src/tools/clippy/clippy_config/src/msrvs.rs rename to src/tools/clippy/clippy_utils/src/msrvs.rs index 764ca8fb50ab4..1eb7d54e133d1 100644 --- a/src/tools/clippy/clippy_config/src/msrvs.rs +++ b/src/tools/clippy/clippy_utils/src/msrvs.rs @@ -121,7 +121,7 @@ impl Msrv { } pub fn meets(&self, required: RustcVersion) -> bool { - self.current().map_or(true, |msrv| msrv >= required) + self.current().is_none_or(|msrv| msrv >= required) } fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option { diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs index 11a98b02f337a..bb40a9430a7af 100644 --- a/src/tools/clippy/clippy_utils/src/paths.rs +++ b/src/tools/clippy/clippy_utils/src/paths.rs @@ -36,7 +36,7 @@ pub const CHILD_KILL: [&str; 4] = ["std", "process", "Child", "kill"]; pub const PANIC_ANY: [&str; 3] = ["std", "panic", "panic_any"]; // Paths in clippy itself -pub const MSRV: [&str; 3] = ["clippy_config", "msrvs", "Msrv"]; +pub const MSRV: [&str; 3] = ["clippy_utils", "msrvs", "Msrv"]; // Paths in external crates #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 345c46f944a5d..df3f10d6179a1 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -3,7 +3,7 @@ // of terminologies might not be relevant in the context of Clippy. Note that its behavior might // differ from the time of `rustc` even if the name stays the same. -use clippy_config::msrvs::{self, Msrv}; +use crate::msrvs::{self, Msrv}; use hir::LangItem; use rustc_attr::StableSince; use rustc_const_eval::check_consts::ConstCx; @@ -404,14 +404,12 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx> // FIXME(const_trait_impl, fee1-dead) revert to const destruct once it works again #[expect(unused)] fn is_ty_const_destruct_unused<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>) -> bool { - // Avoid selecting for simple cases, such as builtin types. - if ty::util::is_trivially_const_drop(ty) { - return true; + // If this doesn't need drop at all, then don't select `~const Destruct`. + if !ty.needs_drop(tcx, body.typing_env(tcx)) { + return false; } - - let (infcx, param_env) = - tcx.infer_ctxt().build_with_typing_env(body.typing_env(tcx)); + let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(body.typing_env(tcx)); // FIXME(const_trait_impl) constness let obligation = Obligation::new( tcx, diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 3498606dfd391..39c9d234a1a16 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -226,7 +226,14 @@ pub fn implements_trait<'tcx>( trait_id: DefId, args: &[GenericArg<'tcx>], ) -> bool { - implements_trait_with_env_from_iter(cx.tcx, cx.typing_env(), ty, trait_id, None, args.iter().map(|&x| Some(x))) + implements_trait_with_env_from_iter( + cx.tcx, + cx.typing_env(), + ty, + trait_id, + None, + args.iter().map(|&x| Some(x)), + ) } /// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context. @@ -575,7 +582,7 @@ pub fn same_type_and_consts<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { /// Checks if a given type looks safe to be uninitialized. pub fn is_uninit_value_valid_for_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - let typing_env = cx.typing_env().with_reveal_all_normalized(cx.tcx); + let typing_env = cx.typing_env().with_post_analysis_normalized(cx.tcx); cx.tcx .check_validity_requirement((ValidityRequirement::Uninit, typing_env.as_query_input(ty))) .unwrap_or_else(|_| is_uninit_value_valid_for_ty_fallback(cx, ty)) @@ -1262,7 +1269,8 @@ pub fn make_normalized_projection_with_regions<'tcx>( } let cause = ObligationCause::dummy(); let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); - match infcx.at(&cause, param_env) + match infcx + .at(&cause, param_env) .query_normalize(Ty::new_projection_from_args(tcx, ty.def_id, ty.args)) { Ok(ty) => Some(ty.value), @@ -1278,7 +1286,10 @@ pub fn make_normalized_projection_with_regions<'tcx>( pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { let cause = ObligationCause::dummy(); let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); - infcx.at(&cause, param_env).query_normalize(ty).map_or(ty, |ty| ty.value) + infcx + .at(&cause, param_env) + .query_normalize(ty) + .map_or(ty, |ty| ty.value) } /// Checks if the type is `core::mem::ManuallyDrop<_>` diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs index c8c25456f6965..37f729668925f 100644 --- a/src/tools/clippy/clippy_utils/src/usage.rs +++ b/src/tools/clippy/clippy_utils/src/usage.rs @@ -27,7 +27,7 @@ pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> } pub fn is_potentially_mutated<'tcx>(variable: HirId, expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> bool { - mutated_variables(expr, cx).map_or(true, |mutated| mutated.contains(&variable)) + mutated_variables(expr, cx).is_none_or(|mutated| mutated.contains(&variable)) } pub fn is_potentially_local_place(local_id: HirId, place: &Place<'_>) -> bool { diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain index e32e0cb360474..fb159ca2ae038 100644 --- a/src/tools/clippy/rust-toolchain +++ b/src/tools/clippy/rust-toolchain @@ -1,4 +1,6 @@ [toolchain] -channel = "nightly-2024-11-14" +# begin autogenerated nightly +channel = "nightly-2024-11-28" +# end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed index 9b5bf736f137c..928596d080913 100644 --- a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed +++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed @@ -8,8 +8,8 @@ extern crate rustc_lint; extern crate rustc_middle; #[macro_use] extern crate rustc_session; -use clippy_config::msrvs::Msrv; use clippy_utils::extract_msrv_attr; +use clippy_utils::msrvs::Msrv; use rustc_hir::Expr; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs index c5bde47e4ce8d..50b28648ccc9f 100644 --- a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs +++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs @@ -8,8 +8,8 @@ extern crate rustc_lint; extern crate rustc_middle; #[macro_use] extern crate rustc_session; -use clippy_config::msrvs::Msrv; use clippy_utils::extract_msrv_attr; +use clippy_utils::msrvs::Msrv; use rustc_hir::Expr; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; diff --git a/src/tools/clippy/tests/ui/crashes/ice-10645.rs b/src/tools/clippy/tests/ui/crashes/ice-10645.rs deleted file mode 100644 index 6e126aff7512e..0000000000000 --- a/src/tools/clippy/tests/ui/crashes/ice-10645.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@compile-flags: --cap-lints=warn -// https://github.com/rust-lang/rust-clippy/issues/10645 - -#![warn(clippy::future_not_send)] -pub async fn bar<'a, T: 'a>(_: T) {} - -fn main() {} diff --git a/src/tools/clippy/tests/ui/crashes/ice-10645.stderr b/src/tools/clippy/tests/ui/crashes/ice-10645.stderr deleted file mode 100644 index 0269072b88bc1..0000000000000 --- a/src/tools/clippy/tests/ui/crashes/ice-10645.stderr +++ /dev/null @@ -1,17 +0,0 @@ -warning: future cannot be sent between threads safely - --> tests/ui/crashes/ice-10645.rs:5:1 - | -LL | pub async fn bar<'a, T: 'a>(_: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `bar` is not `Send` - | -note: captured value is not `Send` - --> tests/ui/crashes/ice-10645.rs:5:29 - | -LL | pub async fn bar<'a, T: 'a>(_: T) {} - | ^ has type `T` which is not `Send` - = note: `T` doesn't implement `std::marker::Send` - = note: `-D clippy::future-not-send` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]` - -warning: 1 warning emitted - diff --git a/src/tools/clippy/tests/ui/derivable_impls.fixed b/src/tools/clippy/tests/ui/derivable_impls.fixed new file mode 100644 index 0000000000000..c85f384fd6eb9 --- /dev/null +++ b/src/tools/clippy/tests/ui/derivable_impls.fixed @@ -0,0 +1,295 @@ +#![allow(dead_code)] + +use std::collections::HashMap; + +#[derive(Default)] +struct FooDefault<'a> { + a: bool, + b: i32, + c: u64, + d: Vec, + e: FooND1, + f: FooND2, + g: HashMap, + h: (i32, Vec), + i: [Vec; 3], + j: [i32; 5], + k: Option, + l: &'a [i32], +} + + +#[derive(Default)] +struct TupleDefault(bool, i32, u64); + + +struct FooND1 { + a: bool, +} + +impl std::default::Default for FooND1 { + fn default() -> Self { + Self { a: true } + } +} + +struct FooND2 { + a: i32, +} + +impl std::default::Default for FooND2 { + fn default() -> Self { + Self { a: 5 } + } +} + +struct FooNDNew { + a: bool, +} + +impl FooNDNew { + fn new() -> Self { + Self { a: true } + } +} + +impl Default for FooNDNew { + fn default() -> Self { + Self::new() + } +} + +struct FooNDVec(Vec); + +impl Default for FooNDVec { + fn default() -> Self { + Self(vec![5, 12]) + } +} + +#[derive(Default)] +struct StrDefault<'a>(&'a str); + + +#[derive(Default)] +struct AlreadyDerived(i32, bool); + +macro_rules! mac { + () => { + 0 + }; + ($e:expr) => { + struct X(u32); + impl Default for X { + fn default() -> Self { + Self($e) + } + } + }; +} + +mac!(0); + +#[derive(Default)] +struct Y(u32); + +struct RustIssue26925 { + a: Option, +} + +// We should watch out for cases where a manual impl is needed because a +// derive adds different type bounds (https://github.com/rust-lang/rust/issues/26925). +// For example, a struct with Option does not require T: Default, but a derive adds +// that type bound anyways. So until #26925 get fixed we should disable lint +// for the following case +impl Default for RustIssue26925 { + fn default() -> Self { + Self { a: None } + } +} + +struct SpecializedImpl { + a: A, + b: B, +} + +impl Default for SpecializedImpl { + fn default() -> Self { + Self { + a: T::default(), + b: T::default(), + } + } +} + +#[derive(Default)] +struct WithoutSelfCurly { + a: bool, +} + + +#[derive(Default)] +struct WithoutSelfParan(bool); + + +// https://github.com/rust-lang/rust-clippy/issues/7655 + +pub struct SpecializedImpl2 { + v: Vec, +} + +impl Default for SpecializedImpl2 { + fn default() -> Self { + Self { v: Vec::new() } + } +} + +// https://github.com/rust-lang/rust-clippy/issues/7654 + +pub struct Color { + pub r: u8, + pub g: u8, + pub b: u8, +} + +/// `#000000` +impl Default for Color { + fn default() -> Self { + Color { r: 0, g: 0, b: 0 } + } +} + +pub struct Color2 { + pub r: u8, + pub g: u8, + pub b: u8, +} + +impl Default for Color2 { + /// `#000000` + fn default() -> Self { + Self { r: 0, g: 0, b: 0 } + } +} + +#[derive(Default)] +pub struct RepeatDefault1 { + a: [i8; 32], +} + + +pub struct RepeatDefault2 { + a: [i8; 33], +} + +impl Default for RepeatDefault2 { + fn default() -> Self { + RepeatDefault2 { a: [0; 33] } + } +} + +// https://github.com/rust-lang/rust-clippy/issues/7753 + +pub enum IntOrString { + Int(i32), + String(String), +} + +impl Default for IntOrString { + fn default() -> Self { + IntOrString::Int(0) + } +} + +#[derive(Default)] +pub enum SimpleEnum { + Foo, + #[default] + Bar, +} + + +pub enum NonExhaustiveEnum { + Foo, + #[non_exhaustive] + Bar, +} + +impl Default for NonExhaustiveEnum { + fn default() -> Self { + NonExhaustiveEnum::Bar + } +} + +// https://github.com/rust-lang/rust-clippy/issues/10396 + +#[derive(Default)] +struct DefaultType; + +struct GenericType { + t: T, +} + +impl Default for GenericType { + fn default() -> Self { + Self { t: Default::default() } + } +} + +struct InnerGenericType { + t: T, +} + +impl Default for InnerGenericType { + fn default() -> Self { + Self { t: Default::default() } + } +} + +struct OtherGenericType { + inner: InnerGenericType, +} + +impl Default for OtherGenericType { + fn default() -> Self { + Self { + inner: Default::default(), + } + } +} + +mod issue10158 { + pub trait T {} + + #[derive(Default)] + pub struct S {} + impl T for S {} + + pub struct Outer { + pub inner: Box, + } + + impl Default for Outer { + fn default() -> Self { + Outer { + // Box::::default() adjusts to Box + inner: Box::::default(), + } + } + } +} + +mod issue11368 { + pub struct A { + a: u32, + } + + impl Default for A { + #[track_caller] + fn default() -> Self { + Self { a: 0 } + } + } +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/derivable_impls.rs b/src/tools/clippy/tests/ui/derivable_impls.rs index 58f7771b6275b..21d73ba8b7778 100644 --- a/src/tools/clippy/tests/ui/derivable_impls.rs +++ b/src/tools/clippy/tests/ui/derivable_impls.rs @@ -1,7 +1,5 @@ #![allow(dead_code)] -//@no-rustfix: need to change the suggestion to a multipart suggestion - use std::collections::HashMap; struct FooDefault<'a> { diff --git a/src/tools/clippy/tests/ui/derivable_impls.stderr b/src/tools/clippy/tests/ui/derivable_impls.stderr index d3adfa60e10f0..c22569145bdb2 100644 --- a/src/tools/clippy/tests/ui/derivable_impls.stderr +++ b/src/tools/clippy/tests/ui/derivable_impls.stderr @@ -1,5 +1,5 @@ error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:22:1 + --> tests/ui/derivable_impls.rs:20:1 | LL | / impl std::default::Default for FooDefault<'_> { LL | | fn default() -> Self { @@ -12,15 +12,14 @@ LL | | } | = note: `-D clippy::derivable-impls` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::derivable_impls)]` - = help: remove the manual implementation... -help: ...and instead derive it +help: replace the manual implementation with a derive attribute | LL + #[derive(Default)] -LL | struct FooDefault<'a> { +LL ~ struct FooDefault<'a> { | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:43:1 + --> tests/ui/derivable_impls.rs:41:1 | LL | / impl std::default::Default for TupleDefault { LL | | fn default() -> Self { @@ -29,15 +28,14 @@ LL | | } LL | | } | |_^ | - = help: remove the manual implementation... -help: ...and instead derive it +help: replace the manual implementation with a derive attribute | LL + #[derive(Default)] -LL | struct TupleDefault(bool, i32, u64); +LL ~ struct TupleDefault(bool, i32, u64); | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:95:1 + --> tests/ui/derivable_impls.rs:93:1 | LL | / impl Default for StrDefault<'_> { LL | | fn default() -> Self { @@ -46,15 +44,14 @@ LL | | } LL | | } | |_^ | - = help: remove the manual implementation... -help: ...and instead derive it +help: replace the manual implementation with a derive attribute | LL + #[derive(Default)] -LL | struct StrDefault<'a>(&'a str); +LL ~ struct StrDefault<'a>(&'a str); | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:121:1 + --> tests/ui/derivable_impls.rs:119:1 | LL | / impl Default for Y { LL | | fn default() -> Self { @@ -63,15 +60,14 @@ LL | | } LL | | } | |_^ | - = help: remove the manual implementation... -help: ...and instead derive it +help: replace the manual implementation with a derive attribute | LL + #[derive(Default)] -LL | struct Y(u32); +LL ~ struct Y(u32); | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:160:1 + --> tests/ui/derivable_impls.rs:158:1 | LL | / impl Default for WithoutSelfCurly { LL | | fn default() -> Self { @@ -80,15 +76,14 @@ LL | | } LL | | } | |_^ | - = help: remove the manual implementation... -help: ...and instead derive it +help: replace the manual implementation with a derive attribute | LL + #[derive(Default)] -LL | struct WithoutSelfCurly { +LL ~ struct WithoutSelfCurly { | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:168:1 + --> tests/ui/derivable_impls.rs:166:1 | LL | / impl Default for WithoutSelfParan { LL | | fn default() -> Self { @@ -97,15 +92,14 @@ LL | | } LL | | } | |_^ | - = help: remove the manual implementation... -help: ...and instead derive it +help: replace the manual implementation with a derive attribute | LL + #[derive(Default)] -LL | struct WithoutSelfParan(bool); +LL ~ struct WithoutSelfParan(bool); | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:218:1 + --> tests/ui/derivable_impls.rs:216:1 | LL | / impl Default for RepeatDefault1 { LL | | fn default() -> Self { @@ -114,15 +108,14 @@ LL | | } LL | | } | |_^ | - = help: remove the manual implementation... -help: ...and instead derive it +help: replace the manual implementation with a derive attribute | LL + #[derive(Default)] -LL | pub struct RepeatDefault1 { +LL ~ pub struct RepeatDefault1 { | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:252:1 + --> tests/ui/derivable_impls.rs:250:1 | LL | / impl Default for SimpleEnum { LL | | fn default() -> Self { @@ -131,14 +124,11 @@ LL | | } LL | | } | |_^ | - = help: remove the manual implementation... -help: ...and instead derive it... +help: replace the manual implementation with a derive attribute and mark the default variant | LL + #[derive(Default)] -LL | pub enum SimpleEnum { - | -help: ...and mark the default variant - | +LL ~ pub enum SimpleEnum { +LL | Foo, LL ~ #[default] LL ~ Bar, | diff --git a/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.fixed b/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.fixed new file mode 100644 index 0000000000000..d4ae810d73855 --- /dev/null +++ b/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.fixed @@ -0,0 +1,40 @@ +#![warn(clippy::doc_include_without_cfg)] +// Should not lint. +#![doc(html_playground_url = "https://playground.example.com/")] +#![cfg_attr(doc, doc = include_str!("../approx_const.rs"))] //~ doc_include_without_cfg +// Should not lint. +#![cfg_attr(feature = "whatever", doc = include_str!("../approx_const.rs"))] +#![cfg_attr(doc, doc = include_str!("../approx_const.rs"))] +#![doc = "some doc"] +//! more doc + +macro_rules! man_link { + ($a:literal, $b:literal) => { + concat!($a, $b) + }; +} + +// Should not lint! +macro_rules! tst { + ($(#[$attr:meta])*) => { + $(#[$attr])* + fn blue() { + println!("Hello, world!"); + } + } +} + +tst! { + /// This is a test with no included file +} + +#[cfg_attr(doc, doc = include_str!("../approx_const.rs"))] //~ doc_include_without_cfg +// Should not lint. +#[doc = man_link!("bla", "blob")] +#[cfg_attr(feature = "whatever", doc = include_str!("../approx_const.rs"))] +#[cfg_attr(doc, doc = include_str!("../approx_const.rs"))] +#[doc = "some doc"] +/// more doc +fn main() { + // test code goes here +} diff --git a/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.rs b/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.rs new file mode 100644 index 0000000000000..c82f6bf20356a --- /dev/null +++ b/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.rs @@ -0,0 +1,40 @@ +#![warn(clippy::doc_include_without_cfg)] +// Should not lint. +#![doc(html_playground_url = "https://playground.example.com/")] +#![doc = include_str!("../approx_const.rs")] //~ doc_include_without_cfg +// Should not lint. +#![cfg_attr(feature = "whatever", doc = include_str!("../approx_const.rs"))] +#![cfg_attr(doc, doc = include_str!("../approx_const.rs"))] +#![doc = "some doc"] +//! more doc + +macro_rules! man_link { + ($a:literal, $b:literal) => { + concat!($a, $b) + }; +} + +// Should not lint! +macro_rules! tst { + ($(#[$attr:meta])*) => { + $(#[$attr])* + fn blue() { + println!("Hello, world!"); + } + } +} + +tst! { + /// This is a test with no included file +} + +#[doc = include_str!("../approx_const.rs")] //~ doc_include_without_cfg +// Should not lint. +#[doc = man_link!("bla", "blob")] +#[cfg_attr(feature = "whatever", doc = include_str!("../approx_const.rs"))] +#[cfg_attr(doc, doc = include_str!("../approx_const.rs"))] +#[doc = "some doc"] +/// more doc +fn main() { + // test code goes here +} diff --git a/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.stderr b/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.stderr new file mode 100644 index 0000000000000..17ea53c7c318a --- /dev/null +++ b/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.stderr @@ -0,0 +1,17 @@ +error: included a file in documentation unconditionally + --> tests/ui/doc/doc_include_without_cfg.rs:4:1 + | +LL | #![doc = include_str!("../approx_const.rs")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `cfg_attr(doc, doc = "...")`: `#![cfg_attr(doc, doc = include_str!("../approx_const.rs"))]` + | + = note: `-D clippy::doc-include-without-cfg` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::doc_include_without_cfg)]` + +error: included a file in documentation unconditionally + --> tests/ui/doc/doc_include_without_cfg.rs:31:1 + | +LL | #[doc = include_str!("../approx_const.rs")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `cfg_attr(doc, doc = "...")`: `#[cfg_attr(doc, doc = include_str!("../approx_const.rs"))]` + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs index 17d2ed9f50cfc..aa964af3fc2db 100644 --- a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs +++ b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs @@ -134,4 +134,11 @@ struct Human<'a> { pub name: &'a str, } +// https://github.com/rust-lang/rust-clippy/issues/13578 +mod issue_13578 { + pub trait Foo {} + + impl<'a, T: 'a> Foo for Option where &'a T: Foo {} +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/format_args_unfixable.rs b/src/tools/clippy/tests/ui/format_args_unfixable.rs index f04715f4f0182..7590de3751a8e 100644 --- a/src/tools/clippy/tests/ui/format_args_unfixable.rs +++ b/src/tools/clippy/tests/ui/format_args_unfixable.rs @@ -119,3 +119,32 @@ fn test2() { format!("something failed at {}", Location::caller()) ); } + +#[clippy::format_args] +macro_rules! usr_println { + ($target:expr, $($args:tt)*) => {{ + if $target { + println!($($args)*) + } + }}; +} + +fn user_format() { + let error = Error::new(ErrorKind::Other, "bad thing"); + let x = 'x'; + + usr_println!(true, "error: {}", format!("boom at {}", Location::caller())); + //~^ ERROR: `format!` in `usr_println!` args + usr_println!(true, "{}: {}", error, format!("boom at {}", Location::caller())); + //~^ ERROR: `format!` in `usr_println!` args + usr_println!(true, "{:?}: {}", error, format!("boom at {}", Location::caller())); + //~^ ERROR: `format!` in `usr_println!` args + usr_println!(true, "{{}}: {}", format!("boom at {}", Location::caller())); + //~^ ERROR: `format!` in `usr_println!` args + usr_println!(true, r#"error: "{}""#, format!("boom at {}", Location::caller())); + //~^ ERROR: `format!` in `usr_println!` args + usr_println!(true, "error: {}", format!(r#"boom at "{}""#, Location::caller())); + //~^ ERROR: `format!` in `usr_println!` args + usr_println!(true, "error: {}", format!("boom at {} {0}", Location::caller())); + //~^ ERROR: `format!` in `usr_println!` args +} diff --git a/src/tools/clippy/tests/ui/format_args_unfixable.stderr b/src/tools/clippy/tests/ui/format_args_unfixable.stderr index 20cd0bb8c5541..1b4b683fd6c62 100644 --- a/src/tools/clippy/tests/ui/format_args_unfixable.stderr +++ b/src/tools/clippy/tests/ui/format_args_unfixable.stderr @@ -174,5 +174,68 @@ LL | panic!("error: {}", format!("something failed at {}", Location::caller( = help: combine the `format!(..)` arguments with the outer `panic!(..)` call = help: or consider changing `format!` to `format_args!` -error: aborting due to 18 previous errors +error: `format!` in `usr_println!` args + --> tests/ui/format_args_unfixable.rs:136:5 + | +LL | usr_println!(true, "error: {}", format!("boom at {}", Location::caller())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call + = help: or consider changing `format!` to `format_args!` + +error: `format!` in `usr_println!` args + --> tests/ui/format_args_unfixable.rs:138:5 + | +LL | usr_println!(true, "{}: {}", error, format!("boom at {}", Location::caller())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call + = help: or consider changing `format!` to `format_args!` + +error: `format!` in `usr_println!` args + --> tests/ui/format_args_unfixable.rs:140:5 + | +LL | usr_println!(true, "{:?}: {}", error, format!("boom at {}", Location::caller())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call + = help: or consider changing `format!` to `format_args!` + +error: `format!` in `usr_println!` args + --> tests/ui/format_args_unfixable.rs:142:5 + | +LL | usr_println!(true, "{{}}: {}", format!("boom at {}", Location::caller())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call + = help: or consider changing `format!` to `format_args!` + +error: `format!` in `usr_println!` args + --> tests/ui/format_args_unfixable.rs:144:5 + | +LL | usr_println!(true, r#"error: "{}""#, format!("boom at {}", Location::caller())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call + = help: or consider changing `format!` to `format_args!` + +error: `format!` in `usr_println!` args + --> tests/ui/format_args_unfixable.rs:146:5 + | +LL | usr_println!(true, "error: {}", format!(r#"boom at "{}""#, Location::caller())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call + = help: or consider changing `format!` to `format_args!` + +error: `format!` in `usr_println!` args + --> tests/ui/format_args_unfixable.rs:148:5 + | +LL | usr_println!(true, "error: {}", format!("boom at {} {0}", Location::caller())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call + = help: or consider changing `format!` to `format_args!` + +error: aborting due to 25 previous errors diff --git a/src/tools/clippy/tests/ui/future_not_send.rs b/src/tools/clippy/tests/ui/future_not_send.rs index 9274340b5caa5..626ee6de9e4fb 100644 --- a/src/tools/clippy/tests/ui/future_not_send.rs +++ b/src/tools/clippy/tests/ui/future_not_send.rs @@ -1,6 +1,7 @@ #![warn(clippy::future_not_send)] use std::cell::Cell; +use std::future::Future; use std::rc::Rc; use std::sync::Arc; @@ -63,6 +64,22 @@ where t } +async fn maybe_send_generic_future(t: T) -> T { + async { true }.await; + t +} + +async fn maybe_send_generic_future2 Fut, Fut: Future>(f: F) { + async { true }.await; + let res = f(); + async { true }.await; +} + +async fn generic_future_always_unsend(_: Rc) { + //~^ ERROR: future cannot be sent between threads safely + async { true }.await; +} + async fn generic_future_send(t: T) where T: Send, @@ -71,7 +88,6 @@ where } async fn unclear_future(t: T) {} -//~^ ERROR: future cannot be sent between threads safely fn main() { let rc = Rc::new([1, 2, 3]); diff --git a/src/tools/clippy/tests/ui/future_not_send.stderr b/src/tools/clippy/tests/ui/future_not_send.stderr index 67677d6367aaa..3807c74701368 100644 --- a/src/tools/clippy/tests/ui/future_not_send.stderr +++ b/src/tools/clippy/tests/ui/future_not_send.stderr @@ -1,11 +1,11 @@ error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:7:1 + --> tests/ui/future_not_send.rs:8:1 | LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> tests/ui/future_not_send.rs:9:20 + --> tests/ui/future_not_send.rs:10:20 | LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { | -- has type `std::rc::Rc<[u8]>` which is not `Send` @@ -14,7 +14,7 @@ LL | async { true }.await | ^^^^^ await occurs here, with `rc` maybe used later = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` - --> tests/ui/future_not_send.rs:7:39 + --> tests/ui/future_not_send.rs:8:39 | LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { | ^^^^ has type `&std::cell::Cell` which is not `Send`, because `std::cell::Cell` is not `Sync` @@ -23,13 +23,13 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:12:1 + --> tests/ui/future_not_send.rs:13:1 | LL | pub async fn public_future(rc: Rc<[u8]>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> tests/ui/future_not_send.rs:14:20 + --> tests/ui/future_not_send.rs:15:20 | LL | pub async fn public_future(rc: Rc<[u8]>) { | -- has type `std::rc::Rc<[u8]>` which is not `Send` @@ -39,45 +39,45 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:21:1 + --> tests/ui/future_not_send.rs:22:1 | LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future2` is not `Send` | note: captured value is not `Send` - --> tests/ui/future_not_send.rs:21:26 + --> tests/ui/future_not_send.rs:22:26 | LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { | ^^ has type `std::rc::Rc<[u8]>` which is not `Send` = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` - --> tests/ui/future_not_send.rs:21:40 + --> tests/ui/future_not_send.rs:22:40 | LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { | ^^^^ has type `&std::cell::Cell` which is not `Send`, because `std::cell::Cell` is not `Sync` = note: `std::cell::Cell` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:26:1 + --> tests/ui/future_not_send.rs:27:1 | LL | pub async fn public_future2(rc: Rc<[u8]>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future2` is not `Send` | note: captured value is not `Send` - --> tests/ui/future_not_send.rs:26:29 + --> tests/ui/future_not_send.rs:27:29 | LL | pub async fn public_future2(rc: Rc<[u8]>) {} | ^^ has type `std::rc::Rc<[u8]>` which is not `Send` = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:38:5 + --> tests/ui/future_not_send.rs:39:5 | LL | async fn private_future(&self) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> tests/ui/future_not_send.rs:40:24 + --> tests/ui/future_not_send.rs:41:24 | LL | async fn private_future(&self) -> usize { | ----- has type `&Dummy` which is not `Send` @@ -87,20 +87,20 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:44:5 + --> tests/ui/future_not_send.rs:45:5 | LL | pub async fn public_future(&self) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` | note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` - --> tests/ui/future_not_send.rs:44:32 + --> tests/ui/future_not_send.rs:45:32 | LL | pub async fn public_future(&self) { | ^^^^^ has type `&Dummy` which is not `Send`, because `Dummy` is not `Sync` = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:55:1 + --> tests/ui/future_not_send.rs:56:1 | LL | / async fn generic_future(t: T) -> T LL | | @@ -109,7 +109,7 @@ LL | | T: Send, | |____________^ future returned by `generic_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> tests/ui/future_not_send.rs:61:20 + --> tests/ui/future_not_send.rs:62:20 | LL | let rt = &t; | -- has type `&T` which is not `Send` @@ -118,17 +118,20 @@ LL | async { true }.await; = note: `T` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:73:1 + --> tests/ui/future_not_send.rs:78:1 | -LL | async fn unclear_future(t: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `unclear_future` is not `Send` +LL | async fn generic_future_always_unsend(_: Rc) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `generic_future_always_unsend` is not `Send` | -note: captured value is not `Send` - --> tests/ui/future_not_send.rs:73:28 +note: future is not `Send` as this value is used across an await + --> tests/ui/future_not_send.rs:80:20 | -LL | async fn unclear_future(t: T) {} - | ^ has type `T` which is not `Send` - = note: `T` doesn't implement `std::marker::Send` +LL | async fn generic_future_always_unsend(_: Rc) { + | - has type `std::rc::Rc` which is not `Send` +LL | +LL | async { true }.await; + | ^^^^^ await occurs here, with `_` maybe used later + = note: `std::rc::Rc` doesn't implement `std::marker::Send` error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui/if_let_mutex.stderr b/src/tools/clippy/tests/ui/if_let_mutex.edition2021.stderr similarity index 94% rename from src/tools/clippy/tests/ui/if_let_mutex.stderr rename to src/tools/clippy/tests/ui/if_let_mutex.edition2021.stderr index 45df4ac4d6795..984d6adbb2a4e 100644 --- a/src/tools/clippy/tests/ui/if_let_mutex.stderr +++ b/src/tools/clippy/tests/ui/if_let_mutex.edition2021.stderr @@ -1,5 +1,5 @@ error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock - --> tests/ui/if_let_mutex.rs:11:5 + --> tests/ui/if_let_mutex.rs:16:5 | LL | if let Err(locked) = m.lock() { | ^ - this Mutex will remain locked for the entire `if let`-block... @@ -19,7 +19,7 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::if_let_mutex)]` error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock - --> tests/ui/if_let_mutex.rs:24:5 + --> tests/ui/if_let_mutex.rs:29:5 | LL | if let Some(locked) = m.lock().unwrap().deref() { | ^ - this Mutex will remain locked for the entire `if let`-block... @@ -37,7 +37,7 @@ LL | | }; = help: move the lock call outside of the `if let ...` expression error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock - --> tests/ui/if_let_mutex.rs:46:5 + --> tests/ui/if_let_mutex.rs:51:5 | LL | if let Ok(i) = mutex.lock() { | ^ ----- this Mutex will remain locked for the entire `if let`-block... @@ -54,7 +54,7 @@ LL | | }; = help: move the lock call outside of the `if let ...` expression error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock - --> tests/ui/if_let_mutex.rs:55:5 + --> tests/ui/if_let_mutex.rs:60:5 | LL | if let Ok(_) = m1.lock() { | ^ -- this Mutex will remain locked for the entire `if let`-block... diff --git a/src/tools/clippy/tests/ui/if_let_mutex.rs b/src/tools/clippy/tests/ui/if_let_mutex.rs index bb0eadfca1c7a..80eee29398907 100644 --- a/src/tools/clippy/tests/ui/if_let_mutex.rs +++ b/src/tools/clippy/tests/ui/if_let_mutex.rs @@ -1,3 +1,8 @@ +//@ compile-flags: -Zunstable-options + +//@revisions: edition2021 edition2024 +//@[edition2021] edition:2021 +//@[edition2024] edition:2024 #![warn(clippy::if_let_mutex)] #![allow(clippy::redundant_pattern_matching)] @@ -9,7 +14,7 @@ fn do_stuff(_: T) {} fn if_let() { let m = Mutex::new(1_u8); if let Err(locked) = m.lock() { - //~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d + //~[edition2021]^ if_let_mutex do_stuff(locked); } else { let lock = m.lock().unwrap(); @@ -22,7 +27,7 @@ fn if_let() { fn if_let_option() { let m = Mutex::new(Some(0_u8)); if let Some(locked) = m.lock().unwrap().deref() { - //~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d + //~[edition2021]^ if_let_mutex do_stuff(locked); } else { let lock = m.lock().unwrap(); @@ -44,7 +49,7 @@ fn if_let_different_mutex() { fn mutex_ref(mutex: &Mutex) { if let Ok(i) = mutex.lock() { - //~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d + //~[edition2021]^ if_let_mutex do_stuff(i); } else { let _x = mutex.lock(); diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed index 754fe061c4aea..014fbb85c7a33 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed @@ -1,6 +1,6 @@ #![warn(clippy::missing_const_for_fn)] #![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)] -#![feature(const_trait_impl, abi_vectorcall)] +#![feature(const_trait_impl)] use std::mem::transmute; @@ -211,8 +211,4 @@ mod extern_fn { //~^ ERROR: this could be a `const fn` const extern "system-unwind" fn system_unwind() {} //~^ ERROR: this could be a `const fn` - pub const extern "vectorcall" fn std_call() {} - //~^ ERROR: this could be a `const fn` - pub const extern "vectorcall-unwind" fn std_call_unwind() {} - //~^ ERROR: this could be a `const fn` } diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs index 460be0733e035..4f7c2cbcf0b42 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs @@ -1,6 +1,6 @@ #![warn(clippy::missing_const_for_fn)] #![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)] -#![feature(const_trait_impl, abi_vectorcall)] +#![feature(const_trait_impl)] use std::mem::transmute; @@ -211,8 +211,4 @@ mod extern_fn { //~^ ERROR: this could be a `const fn` extern "system-unwind" fn system_unwind() {} //~^ ERROR: this could be a `const fn` - pub extern "vectorcall" fn std_call() {} - //~^ ERROR: this could be a `const fn` - pub extern "vectorcall-unwind" fn std_call_unwind() {} - //~^ ERROR: this could be a `const fn` } diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr index d553c52255653..cc7dfd0888d04 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -316,27 +316,5 @@ help: make the function `const` LL | const extern "system-unwind" fn system_unwind() {} | +++++ -error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:214:5 - | -LL | pub extern "vectorcall" fn std_call() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: make the function `const` - | -LL | pub const extern "vectorcall" fn std_call() {} - | +++++ - -error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:216:5 - | -LL | pub extern "vectorcall-unwind" fn std_call_unwind() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: make the function `const` - | -LL | pub const extern "vectorcall-unwind" fn std_call_unwind() {} - | +++++ - -error: aborting due to 26 previous errors +error: aborting due to 24 previous errors diff --git a/src/tools/clippy/tests/ui/missing_doc_crate.rs b/src/tools/clippy/tests/ui/missing_doc_crate.rs index e00c7fbfed157..fdb23af279df5 100644 --- a/src/tools/clippy/tests/ui/missing_doc_crate.rs +++ b/src/tools/clippy/tests/ui/missing_doc_crate.rs @@ -1,4 +1,5 @@ #![warn(clippy::missing_docs_in_private_items)] +#![allow(clippy::doc_include_without_cfg)] #![doc = include_str!("../../README.md")] fn main() {} diff --git a/src/tools/clippy/tests/ui/redundant_guards.fixed b/src/tools/clippy/tests/ui/redundant_guards.fixed index ed4b1c219150e..ff7b233f004ec 100644 --- a/src/tools/clippy/tests/ui/redundant_guards.fixed +++ b/src/tools/clippy/tests/ui/redundant_guards.fixed @@ -1,6 +1,6 @@ //@aux-build:proc_macros.rs #![feature(if_let_guard)] -#![allow(clippy::no_effect, unused, clippy::single_match)] +#![allow(clippy::no_effect, unused, clippy::single_match, invalid_nan_comparisons)] #![warn(clippy::redundant_guards)] #[macro_use] @@ -19,15 +19,24 @@ struct FloatWrapper(f32); fn issue11304() { match 0.1 { - x if x == 0.0 => todo!(), + 0.0 => todo!(), + // Pattern matching NAN is illegal + x if x == f64::NAN => todo!(), _ => todo!(), } match FloatWrapper(0.1) { - x if x == FloatWrapper(0.0) => todo!(), + FloatWrapper(0.0) => todo!(), _ => todo!(), } } +fn issue13681() { + match c"hi" { + x if x == c"hi" => (), + _ => (), + } +} + fn main() { let c = C(1, 2); match c { diff --git a/src/tools/clippy/tests/ui/redundant_guards.rs b/src/tools/clippy/tests/ui/redundant_guards.rs index adbc4ed16cd7b..b4d4ef5b170d7 100644 --- a/src/tools/clippy/tests/ui/redundant_guards.rs +++ b/src/tools/clippy/tests/ui/redundant_guards.rs @@ -1,6 +1,6 @@ //@aux-build:proc_macros.rs #![feature(if_let_guard)] -#![allow(clippy::no_effect, unused, clippy::single_match)] +#![allow(clippy::no_effect, unused, clippy::single_match, invalid_nan_comparisons)] #![warn(clippy::redundant_guards)] #[macro_use] @@ -20,6 +20,8 @@ struct FloatWrapper(f32); fn issue11304() { match 0.1 { x if x == 0.0 => todo!(), + // Pattern matching NAN is illegal + x if x == f64::NAN => todo!(), _ => todo!(), } match FloatWrapper(0.1) { @@ -28,6 +30,13 @@ fn issue11304() { } } +fn issue13681() { + match c"hi" { + x if x == c"hi" => (), + _ => (), + } +} + fn main() { let c = C(1, 2); match c { diff --git a/src/tools/clippy/tests/ui/redundant_guards.stderr b/src/tools/clippy/tests/ui/redundant_guards.stderr index fd12e08328231..7512546450b2f 100644 --- a/src/tools/clippy/tests/ui/redundant_guards.stderr +++ b/src/tools/clippy/tests/ui/redundant_guards.stderr @@ -1,19 +1,43 @@ error: redundant guard - --> tests/ui/redundant_guards.rs:34:20 + --> tests/ui/redundant_guards.rs:22:14 | -LL | C(x, y) if let 1 = y => .., - | ^^^^^^^^^ +LL | x if x == 0.0 => todo!(), + | ^^^^^^^^ | = note: `-D clippy::redundant-guards` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::redundant_guards)]` help: try | +LL - x if x == 0.0 => todo!(), +LL + 0.0 => todo!(), + | + +error: redundant guard + --> tests/ui/redundant_guards.rs:28:14 + | +LL | x if x == FloatWrapper(0.0) => todo!(), + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - x if x == FloatWrapper(0.0) => todo!(), +LL + FloatWrapper(0.0) => todo!(), + | + +error: redundant guard + --> tests/ui/redundant_guards.rs:43:20 + | +LL | C(x, y) if let 1 = y => .., + | ^^^^^^^^^ + | +help: try + | LL - C(x, y) if let 1 = y => .., LL + C(x, 1) => .., | error: redundant guard - --> tests/ui/redundant_guards.rs:40:20 + --> tests/ui/redundant_guards.rs:49:20 | LL | Some(x) if matches!(x, Some(1) if true) => .., | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,7 +48,7 @@ LL | Some(Some(1)) if true => .., | ~~~~~~~ ~~~~~~~ error: redundant guard - --> tests/ui/redundant_guards.rs:41:20 + --> tests/ui/redundant_guards.rs:50:20 | LL | Some(x) if matches!(x, Some(1)) => { | ^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +60,7 @@ LL + Some(Some(1)) => { | error: redundant guard - --> tests/ui/redundant_guards.rs:45:20 + --> tests/ui/redundant_guards.rs:54:20 | LL | Some(x) if let Some(1) = x => .., | ^^^^^^^^^^^^^^^ @@ -48,7 +72,7 @@ LL + Some(Some(1)) => .., | error: redundant guard - --> tests/ui/redundant_guards.rs:46:20 + --> tests/ui/redundant_guards.rs:55:20 | LL | Some(x) if x == Some(2) => .., | ^^^^^^^^^^^^ @@ -60,7 +84,7 @@ LL + Some(Some(2)) => .., | error: redundant guard - --> tests/ui/redundant_guards.rs:47:20 + --> tests/ui/redundant_guards.rs:56:20 | LL | Some(x) if Some(2) == x => .., | ^^^^^^^^^^^^ @@ -72,7 +96,7 @@ LL + Some(Some(2)) => .., | error: redundant guard - --> tests/ui/redundant_guards.rs:72:20 + --> tests/ui/redundant_guards.rs:81:20 | LL | B { e } if matches!(e, Some(A(2))) => .., | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,7 +108,7 @@ LL + B { e: Some(A(2)) } => .., | error: redundant guard - --> tests/ui/redundant_guards.rs:109:20 + --> tests/ui/redundant_guards.rs:118:20 | LL | E::A(y) if y == "not from an or pattern" => {}, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -96,7 +120,7 @@ LL + E::A("not from an or pattern") => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:116:14 + --> tests/ui/redundant_guards.rs:125:14 | LL | x if matches!(x, Some(0)) => .., | ^^^^^^^^^^^^^^^^^^^^ @@ -108,7 +132,7 @@ LL + Some(0) => .., | error: redundant guard - --> tests/ui/redundant_guards.rs:123:14 + --> tests/ui/redundant_guards.rs:132:14 | LL | i if i == -1 => {}, | ^^^^^^^ @@ -120,7 +144,7 @@ LL + -1 => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:124:14 + --> tests/ui/redundant_guards.rs:133:14 | LL | i if i == 1 => {}, | ^^^^^^ @@ -132,7 +156,7 @@ LL + 1 => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:186:28 + --> tests/ui/redundant_guards.rs:195:28 | LL | Some(ref x) if x == &1 => {}, | ^^^^^^^ @@ -144,7 +168,7 @@ LL + Some(1) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:187:28 + --> tests/ui/redundant_guards.rs:196:28 | LL | Some(ref x) if &1 == x => {}, | ^^^^^^^ @@ -156,7 +180,7 @@ LL + Some(1) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:188:28 + --> tests/ui/redundant_guards.rs:197:28 | LL | Some(ref x) if let &2 = x => {}, | ^^^^^^^^^^ @@ -168,7 +192,7 @@ LL + Some(2) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:189:28 + --> tests/ui/redundant_guards.rs:198:28 | LL | Some(ref x) if matches!(x, &3) => {}, | ^^^^^^^^^^^^^^^ @@ -180,7 +204,7 @@ LL + Some(3) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:209:32 + --> tests/ui/redundant_guards.rs:218:32 | LL | B { ref c, .. } if c == &1 => {}, | ^^^^^^^ @@ -192,7 +216,7 @@ LL + B { c: 1, .. } => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:210:32 + --> tests/ui/redundant_guards.rs:219:32 | LL | B { ref c, .. } if &1 == c => {}, | ^^^^^^^ @@ -204,7 +228,7 @@ LL + B { c: 1, .. } => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:211:32 + --> tests/ui/redundant_guards.rs:220:32 | LL | B { ref c, .. } if let &1 = c => {}, | ^^^^^^^^^^ @@ -216,7 +240,7 @@ LL + B { c: 1, .. } => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:212:32 + --> tests/ui/redundant_guards.rs:221:32 | LL | B { ref c, .. } if matches!(c, &1) => {}, | ^^^^^^^^^^^^^^^ @@ -228,7 +252,7 @@ LL + B { c: 1, .. } => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:222:26 + --> tests/ui/redundant_guards.rs:231:26 | LL | Some(Some(x)) if x.is_empty() => {}, | ^^^^^^^^^^^^ @@ -240,7 +264,7 @@ LL + Some(Some("")) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:233:26 + --> tests/ui/redundant_guards.rs:242:26 | LL | Some(Some(x)) if x.is_empty() => {}, | ^^^^^^^^^^^^ @@ -252,7 +276,7 @@ LL + Some(Some([])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:238:26 + --> tests/ui/redundant_guards.rs:247:26 | LL | Some(Some(x)) if x.is_empty() => {}, | ^^^^^^^^^^^^ @@ -264,7 +288,7 @@ LL + Some(Some([])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:249:26 + --> tests/ui/redundant_guards.rs:258:26 | LL | Some(Some(x)) if x.starts_with(&[]) => {}, | ^^^^^^^^^^^^^^^^^^ @@ -276,7 +300,7 @@ LL + Some(Some([..])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:254:26 + --> tests/ui/redundant_guards.rs:263:26 | LL | Some(Some(x)) if x.starts_with(&[1]) => {}, | ^^^^^^^^^^^^^^^^^^^ @@ -288,7 +312,7 @@ LL + Some(Some([1, ..])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:259:26 + --> tests/ui/redundant_guards.rs:268:26 | LL | Some(Some(x)) if x.starts_with(&[1, 2]) => {}, | ^^^^^^^^^^^^^^^^^^^^^^ @@ -300,7 +324,7 @@ LL + Some(Some([1, 2, ..])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:264:26 + --> tests/ui/redundant_guards.rs:273:26 | LL | Some(Some(x)) if x.ends_with(&[1, 2]) => {}, | ^^^^^^^^^^^^^^^^^^^^ @@ -312,7 +336,7 @@ LL + Some(Some([.., 1, 2])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:286:18 + --> tests/ui/redundant_guards.rs:295:18 | LL | y if y.is_empty() => {}, | ^^^^^^^^^^^^ @@ -324,7 +348,7 @@ LL + "" => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:305:22 + --> tests/ui/redundant_guards.rs:314:22 | LL | y if y.is_empty() => {}, | ^^^^^^^^^^^^ @@ -335,5 +359,5 @@ LL - y if y.is_empty() => {}, LL + "" => {}, | -error: aborting due to 28 previous errors +error: aborting due to 30 previous errors diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed index 779431303aed2..708512793d50a 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed @@ -1,6 +1,6 @@ #![deny(clippy::trait_duplication_in_bounds)] #![allow(unused)] -#![feature(const_trait_impl)] +#![feature(associated_const_equality, const_trait_impl)] use std::any::Any; @@ -179,3 +179,19 @@ fn main() { let _x: fn(_) = f::<()>; let _x: fn(_) = f::; } + +// #13706 +fn assoc_tys_bounds() +where + T: Iterator + Iterator, +{ +} +trait AssocConstTrait { + const ASSOC: usize; +} +fn assoc_const_args() +where + T: AssocConstTrait, + //~^ trait_duplication_in_bounds +{ +} diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs index 3e974dc0a8f27..12db6b65a7aed 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs @@ -1,6 +1,6 @@ #![deny(clippy::trait_duplication_in_bounds)] #![allow(unused)] -#![feature(const_trait_impl)] +#![feature(associated_const_equality, const_trait_impl)] use std::any::Any; @@ -179,3 +179,19 @@ fn main() { let _x: fn(_) = f::<()>; let _x: fn(_) = f::; } + +// #13706 +fn assoc_tys_bounds() +where + T: Iterator + Iterator, +{ +} +trait AssocConstTrait { + const ASSOC: usize; +} +fn assoc_const_args() +where + T: AssocConstTrait + AssocConstTrait, + //~^ trait_duplication_in_bounds +{ +} diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr index 0dd508e474507..83c06eaccd4e8 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr @@ -70,5 +70,11 @@ error: these where clauses contain repeated elements LL | T: IntoIterator + IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `IntoIterator` -error: aborting due to 11 previous errors +error: these where clauses contain repeated elements + --> tests/ui/trait_duplication_in_bounds.rs:194:8 + | +LL | T: AssocConstTrait + AssocConstTrait, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `AssocConstTrait` + +error: aborting due to 12 previous errors diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.fixed b/src/tools/clippy/tests/ui/uninlined_format_args.fixed index 3f5b0e52ece0a..111a2e1987c83 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args.fixed +++ b/src/tools/clippy/tests/ui/uninlined_format_args.fixed @@ -257,8 +257,6 @@ fn tester2() { my_concat!("{}", local_i32); my_good_macro!("{}", local_i32); my_good_macro!("{}", local_i32,); - - // FIXME: Broken false positives, currently unhandled my_bad_macro!("{}", local_i32); my_bad_macro2!("{}", local_i32); used_twice! { @@ -267,3 +265,22 @@ fn tester2() { local_i32, }; } + +#[clippy::format_args] +macro_rules! usr_println { + ($target:expr, $($args:tt)*) => {{ + if $target { + println!($($args)*) + } + }}; +} + +fn user_format() { + let local_i32 = 1; + let local_f64 = 2.0; + + usr_println!(true, "val='{local_i32}'"); + usr_println!(true, "{local_i32}"); + usr_println!(true, "{local_i32:#010x}"); + usr_println!(true, "{local_f64:.1}"); +} diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.rs b/src/tools/clippy/tests/ui/uninlined_format_args.rs index b311aa4912cd7..81fe24765674b 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args.rs +++ b/src/tools/clippy/tests/ui/uninlined_format_args.rs @@ -262,8 +262,6 @@ fn tester2() { my_concat!("{}", local_i32); my_good_macro!("{}", local_i32); my_good_macro!("{}", local_i32,); - - // FIXME: Broken false positives, currently unhandled my_bad_macro!("{}", local_i32); my_bad_macro2!("{}", local_i32); used_twice! { @@ -272,3 +270,22 @@ fn tester2() { local_i32, }; } + +#[clippy::format_args] +macro_rules! usr_println { + ($target:expr, $($args:tt)*) => {{ + if $target { + println!($($args)*) + } + }}; +} + +fn user_format() { + let local_i32 = 1; + let local_f64 = 2.0; + + usr_println!(true, "val='{}'", local_i32); + usr_println!(true, "{}", local_i32); + usr_println!(true, "{:#010x}", local_i32); + usr_println!(true, "{:.1}", local_f64); +} diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.stderr b/src/tools/clippy/tests/ui/uninlined_format_args.stderr index 5a7ff3bc4f5aa..77961fea2c534 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args.stderr +++ b/src/tools/clippy/tests/ui/uninlined_format_args.stderr @@ -845,5 +845,53 @@ LL - println!("expand='{}'", local_i32); LL + println!("expand='{local_i32}'"); | -error: aborting due to 71 previous errors +error: variables can be used directly in the `format!` string + --> tests/ui/uninlined_format_args.rs:287:5 + | +LL | usr_println!(true, "val='{}'", local_i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: change this to + | +LL - usr_println!(true, "val='{}'", local_i32); +LL + usr_println!(true, "val='{local_i32}'"); + | + +error: variables can be used directly in the `format!` string + --> tests/ui/uninlined_format_args.rs:288:5 + | +LL | usr_println!(true, "{}", local_i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: change this to + | +LL - usr_println!(true, "{}", local_i32); +LL + usr_println!(true, "{local_i32}"); + | + +error: variables can be used directly in the `format!` string + --> tests/ui/uninlined_format_args.rs:289:5 + | +LL | usr_println!(true, "{:#010x}", local_i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: change this to + | +LL - usr_println!(true, "{:#010x}", local_i32); +LL + usr_println!(true, "{local_i32:#010x}"); + | + +error: variables can be used directly in the `format!` string + --> tests/ui/uninlined_format_args.rs:290:5 + | +LL | usr_println!(true, "{:.1}", local_f64); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: change this to + | +LL - usr_println!(true, "{:.1}", local_f64); +LL + usr_println!(true, "{local_f64:.1}"); + | + +error: aborting due to 75 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.fixed b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed index 2d932a70e9d94..70b78ceca502f 100644 --- a/src/tools/clippy/tests/ui/unnecessary_map_or.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed @@ -23,10 +23,9 @@ fn main() { let _ = Ok::, i32>(vec![5]).is_ok_and(|n| n == [5]); let _ = (Ok::(5) == Ok(5)); let _ = (Some(5) == Some(5)).then(|| 1); + let _ = Some(5).is_none_or(|n| n == 5); + let _ = Some(5).is_none_or(|n| 5 == n); - // shouldnt trigger - let _ = Some(5).map_or(true, |n| n == 5); - let _ = Some(5).map_or(true, |n| 5 == n); macro_rules! x { () => { Some(1) @@ -51,10 +50,21 @@ fn main() { let r: Result = Ok(3); let _ = r.is_ok_and(|x| x == 7); + // lint constructs that are not comparaisons as well + let func = |_x| true; + let r: Result = Ok(3); + let _ = r.is_ok_and(func); + let _ = Some(5).is_some_and(func); + let _ = Some(5).is_none_or(func); + #[derive(PartialEq)] struct S2; let r: Result = Ok(4); let _ = (r == Ok(8)); + + // do not lint `Result::map_or(true, …)` + let r: Result = Ok(4); + let _ = r.map_or(true, |x| x == 8); } #[clippy::msrv = "1.69.0"] @@ -62,3 +72,9 @@ fn msrv_1_69() { // is_some_and added in 1.70.0 let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 }); } + +#[clippy::msrv = "1.81.0"] +fn msrv_1_81() { + // is_none_or added in 1.82.0 + let _ = Some(5).map_or(true, |n| n == if 2 > 1 { n } else { 0 }); +} diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.rs b/src/tools/clippy/tests/ui/unnecessary_map_or.rs index 4a9d69be1e9dc..5075771597719 100644 --- a/src/tools/clippy/tests/ui/unnecessary_map_or.rs +++ b/src/tools/clippy/tests/ui/unnecessary_map_or.rs @@ -26,10 +26,9 @@ fn main() { let _ = Ok::, i32>(vec![5]).map_or(false, |n| n == [5]); let _ = Ok::(5).map_or(false, |n| n == 5); let _ = Some(5).map_or(false, |n| n == 5).then(|| 1); - - // shouldnt trigger let _ = Some(5).map_or(true, |n| n == 5); let _ = Some(5).map_or(true, |n| 5 == n); + macro_rules! x { () => { Some(1) @@ -54,10 +53,21 @@ fn main() { let r: Result = Ok(3); let _ = r.map_or(false, |x| x == 7); + // lint constructs that are not comparaisons as well + let func = |_x| true; + let r: Result = Ok(3); + let _ = r.map_or(false, func); + let _ = Some(5).map_or(false, func); + let _ = Some(5).map_or(true, func); + #[derive(PartialEq)] struct S2; let r: Result = Ok(4); let _ = r.map_or(false, |x| x == 8); + + // do not lint `Result::map_or(true, …)` + let r: Result = Ok(4); + let _ = r.map_or(true, |x| x == 8); } #[clippy::msrv = "1.69.0"] @@ -65,3 +75,9 @@ fn msrv_1_69() { // is_some_and added in 1.70.0 let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 }); } + +#[clippy::msrv = "1.81.0"] +fn msrv_1_81() { + // is_none_or added in 1.82.0 + let _ = Some(5).map_or(true, |n| n == if 2 > 1 { n } else { 0 }); +} diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr index 299a4e5da7aad..890abb0122885 100644 --- a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr @@ -1,4 +1,4 @@ -error: this `map_or` is redundant +error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:12:13 | LL | let _ = Some(5).map_or(false, |n| n == 5); @@ -7,13 +7,13 @@ LL | let _ = Some(5).map_or(false, |n| n == 5); = note: `-D clippy::unnecessary-map-or` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_or)]` -error: this `map_or` is redundant +error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:13:13 | LL | let _ = Some(5).map_or(true, |n| n != 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Some(5) != Some(5))` -error: this `map_or` is redundant +error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:14:13 | LL | let _ = Some(5).map_or(false, |n| { @@ -23,7 +23,7 @@ LL | | n == 5 LL | | }); | |______^ help: use a standard comparison instead: `(Some(5) == Some(5))` -error: this `map_or` is redundant +error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:18:13 | LL | let _ = Some(5).map_or(false, |n| { @@ -41,59 +41,89 @@ LL + 6 >= 5 LL ~ }); | -error: this `map_or` is redundant +error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:22:13 | LL | let _ = Some(vec![5]).map_or(false, |n| n == [5]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(vec![5]).is_some_and(|n| n == [5])` -error: this `map_or` is redundant +error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:23:13 | LL | let _ = Some(vec![1]).map_or(false, |n| vec![2] == n); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(vec![1]).is_some_and(|n| vec![2] == n)` -error: this `map_or` is redundant +error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:24:13 | LL | let _ = Some(5).map_or(false, |n| n == n); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(5).is_some_and(|n| n == n)` -error: this `map_or` is redundant +error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:25:13 | LL | let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(5).is_some_and(|n| n == if 2 > 1 { n } else { 0 })` -error: this `map_or` is redundant +error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:26:13 | LL | let _ = Ok::, i32>(vec![5]).map_or(false, |n| n == [5]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_ok_and instead: `Ok::, i32>(vec![5]).is_ok_and(|n| n == [5])` -error: this `map_or` is redundant +error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:27:13 | LL | let _ = Ok::(5).map_or(false, |n| n == 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Ok::(5) == Ok(5))` -error: this `map_or` is redundant +error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:28:13 | LL | let _ = Some(5).map_or(false, |n| n == 5).then(|| 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Some(5) == Some(5))` -error: this `map_or` is redundant - --> tests/ui/unnecessary_map_or.rs:55:13 +error: this `map_or` can be simplified + --> tests/ui/unnecessary_map_or.rs:29:13 + | +LL | let _ = Some(5).map_or(true, |n| n == 5); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_none_or instead: `Some(5).is_none_or(|n| n == 5)` + +error: this `map_or` can be simplified + --> tests/ui/unnecessary_map_or.rs:30:13 + | +LL | let _ = Some(5).map_or(true, |n| 5 == n); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_none_or instead: `Some(5).is_none_or(|n| 5 == n)` + +error: this `map_or` can be simplified + --> tests/ui/unnecessary_map_or.rs:54:13 | LL | let _ = r.map_or(false, |x| x == 7); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_ok_and instead: `r.is_ok_and(|x| x == 7)` -error: this `map_or` is redundant +error: this `map_or` can be simplified + --> tests/ui/unnecessary_map_or.rs:59:13 + | +LL | let _ = r.map_or(false, func); + | ^^^^^^^^^^^^^^^^^^^^^ help: use is_ok_and instead: `r.is_ok_and(func)` + +error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:60:13 | +LL | let _ = Some(5).map_or(false, func); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(5).is_some_and(func)` + +error: this `map_or` can be simplified + --> tests/ui/unnecessary_map_or.rs:61:13 + | +LL | let _ = Some(5).map_or(true, func); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_none_or instead: `Some(5).is_none_or(func)` + +error: this `map_or` can be simplified + --> tests/ui/unnecessary_map_or.rs:66:13 + | LL | let _ = r.map_or(false, |x| x == 8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(r == Ok(8))` -error: aborting due to 13 previous errors +error: aborting due to 18 previous errors diff --git a/src/tools/clippy/tests/ui/unused_format_specs.1.fixed b/src/tools/clippy/tests/ui/unused_format_specs.1.fixed index b7d1cce287016..157c2b08d3cfa 100644 --- a/src/tools/clippy/tests/ui/unused_format_specs.1.fixed +++ b/src/tools/clippy/tests/ui/unused_format_specs.1.fixed @@ -33,3 +33,38 @@ fn should_not_lint() { let args = format_args!(""); println!("{args}"); } + +#[clippy::format_args] +macro_rules! usr_println { + ($target:expr, $($args:tt)*) => {{ + if $target { + println!($($args)*) + } + }}; +} + +fn should_lint_user() { + // prints `.`, not ` .` + usr_println!(true, "{:5}.", format!("")); + //~^ ERROR: format specifiers have no effect on `format_args!()` + //prints `abcde`, not `abc` + usr_println!(true, "{:.3}", format!("abcde")); + //~^ ERROR: format specifiers have no effect on `format_args!()` + + usr_println!(true, "{}.", format_args_from_macro!()); + //~^ ERROR: format specifiers have no effect on `format_args!()` + + let args = format_args!(""); + usr_println!(true, "{args}"); + //~^ ERROR: format specifiers have no effect on `format_args!()` +} + +fn should_not_lint_user() { + usr_println!(true, "{}", format_args!("")); + // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use + // debug formatting so allow it + usr_println!(true, "{:?}", format_args!("")); + + let args = format_args!(""); + usr_println!(true, "{args}"); +} diff --git a/src/tools/clippy/tests/ui/unused_format_specs.2.fixed b/src/tools/clippy/tests/ui/unused_format_specs.2.fixed index 94bb6b7036bde..92c7b951f3caf 100644 --- a/src/tools/clippy/tests/ui/unused_format_specs.2.fixed +++ b/src/tools/clippy/tests/ui/unused_format_specs.2.fixed @@ -33,3 +33,38 @@ fn should_not_lint() { let args = format_args!(""); println!("{args}"); } + +#[clippy::format_args] +macro_rules! usr_println { + ($target:expr, $($args:tt)*) => {{ + if $target { + println!($($args)*) + } + }}; +} + +fn should_lint_user() { + // prints `.`, not ` .` + usr_println!(true, "{}.", format_args!("")); + //~^ ERROR: format specifiers have no effect on `format_args!()` + //prints `abcde`, not `abc` + usr_println!(true, "{}", format_args!("abcde")); + //~^ ERROR: format specifiers have no effect on `format_args!()` + + usr_println!(true, "{}.", format_args_from_macro!()); + //~^ ERROR: format specifiers have no effect on `format_args!()` + + let args = format_args!(""); + usr_println!(true, "{args}"); + //~^ ERROR: format specifiers have no effect on `format_args!()` +} + +fn should_not_lint_user() { + usr_println!(true, "{}", format_args!("")); + // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use + // debug formatting so allow it + usr_println!(true, "{:?}", format_args!("")); + + let args = format_args!(""); + usr_println!(true, "{args}"); +} diff --git a/src/tools/clippy/tests/ui/unused_format_specs.rs b/src/tools/clippy/tests/ui/unused_format_specs.rs index 2c85e3711493e..a5df4d8a86683 100644 --- a/src/tools/clippy/tests/ui/unused_format_specs.rs +++ b/src/tools/clippy/tests/ui/unused_format_specs.rs @@ -33,3 +33,38 @@ fn should_not_lint() { let args = format_args!(""); println!("{args}"); } + +#[clippy::format_args] +macro_rules! usr_println { + ($target:expr, $($args:tt)*) => {{ + if $target { + println!($($args)*) + } + }}; +} + +fn should_lint_user() { + // prints `.`, not ` .` + usr_println!(true, "{:5}.", format_args!("")); + //~^ ERROR: format specifiers have no effect on `format_args!()` + //prints `abcde`, not `abc` + usr_println!(true, "{:.3}", format_args!("abcde")); + //~^ ERROR: format specifiers have no effect on `format_args!()` + + usr_println!(true, "{:5}.", format_args_from_macro!()); + //~^ ERROR: format specifiers have no effect on `format_args!()` + + let args = format_args!(""); + usr_println!(true, "{args:5}"); + //~^ ERROR: format specifiers have no effect on `format_args!()` +} + +fn should_not_lint_user() { + usr_println!(true, "{}", format_args!("")); + // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use + // debug formatting so allow it + usr_println!(true, "{:?}", format_args!("")); + + let args = format_args!(""); + usr_println!(true, "{args}"); +} diff --git a/src/tools/clippy/tests/ui/unused_format_specs.stderr b/src/tools/clippy/tests/ui/unused_format_specs.stderr index 2b5c81c63d600..df61d59130ef5 100644 --- a/src/tools/clippy/tests/ui/unused_format_specs.stderr +++ b/src/tools/clippy/tests/ui/unused_format_specs.stderr @@ -58,5 +58,63 @@ LL - println!("{args:5}"); LL + println!("{args}"); | -error: aborting due to 4 previous errors +error: format specifiers have no effect on `format_args!()` + --> tests/ui/unused_format_specs.rs:48:25 + | +LL | usr_println!(true, "{:5}.", format_args!("")); + | ^^^^ + | +help: for the width to apply consider using `format!()` + | +LL | usr_println!(true, "{:5}.", format!("")); + | ~~~~~~ +help: if the current behavior is intentional, remove the format specifiers + | +LL - usr_println!(true, "{:5}.", format_args!("")); +LL + usr_println!(true, "{}.", format_args!("")); + | + +error: format specifiers have no effect on `format_args!()` + --> tests/ui/unused_format_specs.rs:51:25 + | +LL | usr_println!(true, "{:.3}", format_args!("abcde")); + | ^^^^^ + | +help: for the precision to apply consider using `format!()` + | +LL | usr_println!(true, "{:.3}", format!("abcde")); + | ~~~~~~ +help: if the current behavior is intentional, remove the format specifiers + | +LL - usr_println!(true, "{:.3}", format_args!("abcde")); +LL + usr_println!(true, "{}", format_args!("abcde")); + | + +error: format specifiers have no effect on `format_args!()` + --> tests/ui/unused_format_specs.rs:54:25 + | +LL | usr_println!(true, "{:5}.", format_args_from_macro!()); + | ^^^^ + | + = help: for the width to apply consider using `format!()` +help: if the current behavior is intentional, remove the format specifiers + | +LL - usr_println!(true, "{:5}.", format_args_from_macro!()); +LL + usr_println!(true, "{}.", format_args_from_macro!()); + | + +error: format specifiers have no effect on `format_args!()` + --> tests/ui/unused_format_specs.rs:58:25 + | +LL | usr_println!(true, "{args:5}"); + | ^^^^^^^^ + | + = help: for the width to apply consider using `format!()` +help: if the current behavior is intentional, remove the format specifiers + | +LL - usr_println!(true, "{args:5}"); +LL + usr_println!(true, "{args}"); + | + +error: aborting due to 8 previous errors diff --git a/src/tools/collect-license-metadata/src/main.rs b/src/tools/collect-license-metadata/src/main.rs index dce36bb17b600..08a30d0b8994f 100644 --- a/src/tools/collect-license-metadata/src/main.rs +++ b/src/tools/collect-license-metadata/src/main.rs @@ -4,7 +4,7 @@ mod reuse; use std::path::PathBuf; -use anyhow::Error; +use anyhow::{Context, Error}; use crate::licenses::LicensesInterner; @@ -12,10 +12,12 @@ use crate::licenses::LicensesInterner; /// /// You should probably let `bootstrap` execute this program instead of running it directly. /// -/// Run `x.py run collect-license-metadata` +/// * Run `x.py run collect-license-metadata` to re-regenerate the file. +/// * Run `x.py test collect-license-metadata` to check if the file you have is correct. fn main() -> Result<(), Error> { let reuse_exe: PathBuf = std::env::var_os("REUSE_EXE").expect("Missing REUSE_EXE").into(); let dest: PathBuf = std::env::var_os("DEST").expect("Missing DEST").into(); + let only_check = std::env::var_os("ONLY_CHECK").is_some(); let mut interner = LicensesInterner::new(); let paths = crate::reuse::collect(&reuse_exe, &mut interner)?; @@ -23,15 +25,32 @@ fn main() -> Result<(), Error> { let mut tree = crate::path_tree::build(paths); tree.simplify(); - if let Some(parent) = dest.parent() { - std::fs::create_dir_all(parent)?; + let output = serde_json::json!({ + "files": crate::path_tree::expand_interned_licenses(tree, &interner) + }); + + if only_check { + println!("loading existing license information"); + let existing = std::fs::read_to_string(&dest).with_context(|| { + format!("Failed to read existing license JSON at {}", dest.display()) + })?; + let existing_json: serde_json::Value = + serde_json::from_str(&existing).with_context(|| { + format!("Failed to read existing license JSON at {}", dest.display()) + })?; + if existing_json != output { + eprintln!("The existing {} file is out of date.", dest.display()); + eprintln!("Run ./x run collect-license-metadata to update it."); + anyhow::bail!("The existing {} file doesn't match what REUSE reports.", dest.display()); + } + println!("license information matches"); + } else { + if let Some(parent) = dest.parent() { + std::fs::create_dir_all(parent)?; + } + std::fs::write(&dest, &serde_json::to_vec_pretty(&output)?)?; + println!("license information written to {}", dest.display()); } - std::fs::write( - &dest, - &serde_json::to_vec_pretty(&serde_json::json!({ - "files": crate::path_tree::expand_interned_licenses(tree, &interner), - }))?, - )?; Ok(()) } diff --git a/src/tools/collect-license-metadata/src/reuse.rs b/src/tools/collect-license-metadata/src/reuse.rs index e5ee8f0da5ef9..dbe46781b7c5b 100644 --- a/src/tools/collect-license-metadata/src/reuse.rs +++ b/src/tools/collect-license-metadata/src/reuse.rs @@ -10,10 +10,10 @@ pub(crate) fn collect( reuse_exe: &Path, interner: &mut LicensesInterner, ) -> Result, Error> { - eprintln!("gathering license information from REUSE"); + println!("gathering license information from REUSE (this might take a minute...)"); let start = Instant::now(); let raw = &obtain_spdx_document(reuse_exe)?; - eprintln!("finished gathering the license information from REUSE in {:.2?}", start.elapsed()); + println!("finished gathering the license information from REUSE in {:.2?}", start.elapsed()); let document = spdx_rs::parsers::spdx_from_tag_value(&raw)?; diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index bdd0b80b3957c..952533e904c5a 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -214,8 +214,8 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-x86_64-unknown-linux-gnu", "pp-exact", "pretty-compare-only", - "pretty-expanded", "pretty-mode", + "proc-macro", "reference", "regex-error-pattern", "remap-src-base", diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 3539e85ba632b..fe4c5fdd8b51c 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -124,8 +124,6 @@ pub struct TestProps { // a proc-macro and needs `#![crate_type = "proc-macro"]`. This ensures // that the aux file is compiled as a `proc-macro` and not as a `dylib`. pub no_prefer_dynamic: bool, - // Run -Zunpretty expanded when running pretty printing tests - pub pretty_expanded: bool, // Which pretty mode are we testing with, default to 'normal' pub pretty_mode: String, // Only compare pretty output and don't try compiling @@ -218,12 +216,12 @@ mod directives { pub const DONT_CHECK_COMPILER_STDOUT: &'static str = "dont-check-compiler-stdout"; pub const DONT_CHECK_COMPILER_STDERR: &'static str = "dont-check-compiler-stderr"; pub const NO_PREFER_DYNAMIC: &'static str = "no-prefer-dynamic"; - pub const PRETTY_EXPANDED: &'static str = "pretty-expanded"; pub const PRETTY_MODE: &'static str = "pretty-mode"; pub const PRETTY_COMPARE_ONLY: &'static str = "pretty-compare-only"; pub const AUX_BIN: &'static str = "aux-bin"; pub const AUX_BUILD: &'static str = "aux-build"; pub const AUX_CRATE: &'static str = "aux-crate"; + pub const PROC_MACRO: &'static str = "proc-macro"; pub const AUX_CODEGEN_BACKEND: &'static str = "aux-codegen-backend"; pub const EXEC_ENV: &'static str = "exec-env"; pub const RUSTC_ENV: &'static str = "rustc-env"; @@ -278,7 +276,6 @@ impl TestProps { dont_check_compiler_stderr: false, compare_output_lines_by_subset: false, no_prefer_dynamic: false, - pretty_expanded: false, pretty_mode: "normal".to_string(), pretty_compare_only: false, forbid_output: vec![], @@ -425,7 +422,6 @@ impl TestProps { &mut self.dont_check_compiler_stderr, ); config.set_name_directive(ln, NO_PREFER_DYNAMIC, &mut self.no_prefer_dynamic); - config.set_name_directive(ln, PRETTY_EXPANDED, &mut self.pretty_expanded); if let Some(m) = config.parse_name_value_directive(ln, PRETTY_MODE) { self.pretty_mode = m; diff --git a/src/tools/compiletest/src/header/auxiliary.rs b/src/tools/compiletest/src/header/auxiliary.rs index 6f6538ce196d4..0e1f3a785f87f 100644 --- a/src/tools/compiletest/src/header/auxiliary.rs +++ b/src/tools/compiletest/src/header/auxiliary.rs @@ -4,7 +4,7 @@ use std::iter; use crate::common::Config; -use crate::header::directives::{AUX_BIN, AUX_BUILD, AUX_CODEGEN_BACKEND, AUX_CRATE}; +use crate::header::directives::{AUX_BIN, AUX_BUILD, AUX_CODEGEN_BACKEND, AUX_CRATE, PROC_MACRO}; /// Properties parsed from `aux-*` test directives. #[derive(Clone, Debug, Default)] @@ -17,6 +17,8 @@ pub(crate) struct AuxProps { /// Similar to `builds`, but a list of NAME=somelib.rs of dependencies /// to build and pass with the `--extern` flag. pub(crate) crates: Vec<(String, String)>, + /// Same as `builds`, but for proc-macros. + pub(crate) proc_macros: Vec, /// Similar to `builds`, but also uses the resulting dylib as a /// `-Zcodegen-backend` when compiling the test file. pub(crate) codegen_backend: Option, @@ -26,12 +28,13 @@ impl AuxProps { /// Yields all of the paths (relative to `./auxiliary/`) that have been /// specified in `aux-*` directives for this test. pub(crate) fn all_aux_path_strings(&self) -> impl Iterator { - let Self { builds, bins, crates, codegen_backend } = self; + let Self { builds, bins, crates, proc_macros, codegen_backend } = self; iter::empty() .chain(builds.iter().map(String::as_str)) .chain(bins.iter().map(String::as_str)) .chain(crates.iter().map(|(_, path)| path.as_str())) + .chain(proc_macros.iter().map(String::as_str)) .chain(codegen_backend.iter().map(String::as_str)) } } @@ -39,13 +42,15 @@ impl AuxProps { /// If the given test directive line contains an `aux-*` directive, parse it /// and update [`AuxProps`] accordingly. pub(super) fn parse_and_update_aux(config: &Config, ln: &str, aux: &mut AuxProps) { - if !ln.starts_with("aux-") { + if !(ln.starts_with("aux-") || ln.starts_with("proc-macro")) { return; } config.push_name_value_directive(ln, AUX_BUILD, &mut aux.builds, |r| r.trim().to_string()); config.push_name_value_directive(ln, AUX_BIN, &mut aux.bins, |r| r.trim().to_string()); config.push_name_value_directive(ln, AUX_CRATE, &mut aux.crates, parse_aux_crate); + config + .push_name_value_directive(ln, PROC_MACRO, &mut aux.proc_macros, |r| r.trim().to_string()); if let Some(r) = config.parse_name_value_directive(ln, AUX_CODEGEN_BACKEND) { aux.codegen_backend = Some(r.trim().to_owned()); } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index bc80c8246ad0f..93e5980f1f5fb 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -102,7 +102,7 @@ fn get_lib_name(name: &str, aux_type: AuxType) -> Option { // In this case, the only path we can pass // with '--extern-meta' is the '.rlib' file AuxType::Lib => Some(format!("lib{name}.rlib")), - AuxType::Dylib => Some(dylib_name(name)), + AuxType::Dylib | AuxType::ProcMacro => Some(dylib_name(name)), } } @@ -1097,7 +1097,9 @@ impl<'test> TestCx<'test> { } fn has_aux_dir(&self) -> bool { - !self.props.aux.builds.is_empty() || !self.props.aux.crates.is_empty() + !self.props.aux.builds.is_empty() + || !self.props.aux.crates.is_empty() + || !self.props.aux.proc_macros.is_empty() } fn aux_output_dir(&self) -> PathBuf { @@ -1118,31 +1120,48 @@ impl<'test> TestCx<'test> { fn build_all_auxiliary(&self, of: &TestPaths, aux_dir: &Path, rustc: &mut Command) { for rel_ab in &self.props.aux.builds { - self.build_auxiliary(of, rel_ab, &aux_dir, false /* is_bin */); + self.build_auxiliary(of, rel_ab, &aux_dir, None); } for rel_ab in &self.props.aux.bins { - self.build_auxiliary(of, rel_ab, &aux_dir, true /* is_bin */); + self.build_auxiliary(of, rel_ab, &aux_dir, Some(AuxType::Bin)); } + let path_to_crate_name = |path: &str| -> String { + path.rsplit_once('/') + .map_or(path, |(_, tail)| tail) + .trim_end_matches(".rs") + .replace('-', "_") + }; + + let add_extern = + |rustc: &mut Command, aux_name: &str, aux_path: &str, aux_type: AuxType| { + let lib_name = get_lib_name(&path_to_crate_name(aux_path), aux_type); + if let Some(lib_name) = lib_name { + rustc.arg("--extern").arg(format!( + "{}={}/{}", + aux_name, + aux_dir.display(), + lib_name + )); + } + }; + for (aux_name, aux_path) in &self.props.aux.crates { - let aux_type = self.build_auxiliary(of, &aux_path, &aux_dir, false /* is_bin */); - let lib_name = - get_lib_name(&aux_path.trim_end_matches(".rs").replace('-', "_"), aux_type); - if let Some(lib_name) = lib_name { - rustc.arg("--extern").arg(format!( - "{}={}/{}", - aux_name, - aux_dir.display(), - lib_name - )); - } + let aux_type = self.build_auxiliary(of, &aux_path, &aux_dir, None); + add_extern(rustc, aux_name, aux_path, aux_type); + } + + for proc_macro in &self.props.aux.proc_macros { + self.build_auxiliary(of, proc_macro, &aux_dir, Some(AuxType::ProcMacro)); + let crate_name = path_to_crate_name(proc_macro); + add_extern(rustc, &crate_name, proc_macro, AuxType::ProcMacro); } // Build any `//@ aux-codegen-backend`, and pass the resulting library // to `-Zcodegen-backend` when compiling the test file. if let Some(aux_file) = &self.props.aux.codegen_backend { - let aux_type = self.build_auxiliary(of, aux_file, aux_dir, false); + let aux_type = self.build_auxiliary(of, aux_file, aux_dir, None); if let Some(lib_name) = get_lib_name(aux_file.trim_end_matches(".rs"), aux_type) { let lib_path = aux_dir.join(&lib_name); rustc.arg(format!("-Zcodegen-backend={}", lib_path.display())); @@ -1209,17 +1228,23 @@ impl<'test> TestCx<'test> { } /// Builds an aux dependency. + /// + /// If `aux_type` is `None`, then this will determine the aux-type automatically. fn build_auxiliary( &self, of: &TestPaths, source_path: &str, aux_dir: &Path, - is_bin: bool, + aux_type: Option, ) -> AuxType { let aux_testpaths = self.compute_aux_test_paths(of, source_path); - let aux_props = self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config); + let mut aux_props = + self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config); + if aux_type == Some(AuxType::ProcMacro) { + aux_props.force_host = true; + } let mut aux_dir = aux_dir.to_path_buf(); - if is_bin { + if aux_type == Some(AuxType::Bin) { // On unix, the binary of `auxiliary/foo.rs` will be named // `auxiliary/foo` which clashes with the _dir_ `auxiliary/foo`, so // put bins in a `bin` subfolder. @@ -1250,8 +1275,12 @@ impl<'test> TestCx<'test> { aux_rustc.env_remove(key); } - let (aux_type, crate_type) = if is_bin { + let (aux_type, crate_type) = if aux_type == Some(AuxType::Bin) { (AuxType::Bin, Some("bin")) + } else if aux_type == Some(AuxType::ProcMacro) { + (AuxType::ProcMacro, Some("proc-macro")) + } else if aux_type.is_some() { + panic!("aux_type {aux_type:?} not expected"); } else if aux_props.no_prefer_dynamic { (AuxType::Dylib, None) } else if self.config.target.contains("emscripten") @@ -1287,6 +1316,11 @@ impl<'test> TestCx<'test> { aux_rustc.args(&["--crate-type", crate_type]); } + if aux_type == AuxType::ProcMacro { + // For convenience, but this only works on 2018. + aux_rustc.args(&["--extern", "proc_macro"]); + } + aux_rustc.arg("-L").arg(&aux_dir); let auxres = aux_cx.compose_and_run( @@ -2768,8 +2802,10 @@ enum LinkToAux { No, } +#[derive(Debug, PartialEq)] enum AuxType { Bin, Lib, Dylib, + ProcMacro, } diff --git a/src/tools/compiletest/src/runtest/pretty.rs b/src/tools/compiletest/src/runtest/pretty.rs index 40e767e84ef39..e3b07f1d63d1e 100644 --- a/src/tools/compiletest/src/runtest/pretty.rs +++ b/src/tools/compiletest/src/runtest/pretty.rs @@ -84,21 +84,5 @@ impl TestCx<'_> { if !proc_res.status.success() { self.fatal_proc_rec("pretty-printed source does not typecheck", &proc_res); } - - if !self.props.pretty_expanded { - return; - } - - // additionally, run `-Zunpretty=expanded` and try to build it. - let proc_res = self.print_source(ReadFrom::Path, "expanded"); - if !proc_res.status.success() { - self.fatal_proc_rec("pretty-printing (expanded) failed", &proc_res); - } - - let ProcRes { stdout: expanded_src, .. } = proc_res; - let proc_res = self.typecheck_source(expanded_src); - if !proc_res.status.success() { - self.fatal_proc_rec("pretty-printed source (expanded) does not typecheck", &proc_res); - } } } diff --git a/src/tools/generate-copyright/src/cargo_metadata.rs b/src/tools/generate-copyright/src/cargo_metadata.rs index 31b18c3dc1035..420579372acb0 100644 --- a/src/tools/generate-copyright/src/cargo_metadata.rs +++ b/src/tools/generate-copyright/src/cargo_metadata.rs @@ -45,21 +45,20 @@ pub struct PackageMetadata { /// Use `cargo metadata` and `cargo vendor` to get a list of dependencies and their license data. /// -/// This will involve running `cargo vendor` into `${BUILD}/vendor` so we can +/// This will involve running `cargo vendor` into `vendor_path` so we can /// grab the license files. /// /// Any dependency with a path beginning with `root_path` is ignored, as we /// assume `reuse` has covered it already. pub fn get_metadata_and_notices( cargo: &Path, - dest: &Path, + vendor_path: &Path, root_path: &Path, manifest_paths: &[&Path], ) -> Result, Error> { let mut output = get_metadata(cargo, root_path, manifest_paths)?; // Now do a cargo-vendor and grab everything - let vendor_path = dest.join("vendor"); println!("Vendoring deps into {}...", vendor_path.display()); run_cargo_vendor(cargo, &vendor_path, manifest_paths)?; diff --git a/src/tools/generate-copyright/src/main.rs b/src/tools/generate-copyright/src/main.rs index afa75d0d67140..f83d16d0cabf3 100644 --- a/src/tools/generate-copyright/src/main.rs +++ b/src/tools/generate-copyright/src/main.rs @@ -6,13 +6,6 @@ use rinja::Template; mod cargo_metadata; -#[derive(Template)] -#[template(path = "COPYRIGHT.html")] -struct CopyrightTemplate { - in_tree: Node, - dependencies: BTreeMap, -} - /// The entry point to the binary. /// /// You should probably let `bootstrap` execute this program instead of running it directly. @@ -20,49 +13,97 @@ struct CopyrightTemplate { /// Run `x.py run generate-copyright` fn main() -> Result<(), Error> { let dest_file = env_path("DEST")?; + let libstd_dest_file = env_path("DEST_LIBSTD")?; let out_dir = env_path("OUT_DIR")?; let cargo = env_path("CARGO")?; let license_metadata = env_path("LICENSE_METADATA")?; - let collected_tree_metadata: Metadata = - serde_json::from_slice(&std::fs::read(&license_metadata)?)?; - let root_path = std::path::absolute(".")?; - let workspace_paths = [ - Path::new("./Cargo.toml"), - Path::new("./src/tools/cargo/Cargo.toml"), - Path::new("./library/Cargo.toml"), - ]; - let mut collected_cargo_metadata = - cargo_metadata::get_metadata_and_notices(&cargo, &out_dir, &root_path, &workspace_paths)?; - let stdlib_set = - cargo_metadata::get_metadata(&cargo, &root_path, &[Path::new("./library/std/Cargo.toml")])?; + // Scan Cargo dependencies + let mut collected_cargo_metadata = + cargo_metadata::get_metadata_and_notices(&cargo, &out_dir.join("vendor"), &root_path, &[ + Path::new("./Cargo.toml"), + Path::new("./src/tools/cargo/Cargo.toml"), + Path::new("./library/Cargo.toml"), + ])?; + + let library_collected_cargo_metadata = cargo_metadata::get_metadata_and_notices( + &cargo, + &out_dir.join("library-vendor"), + &root_path, + &[Path::new("./library/Cargo.toml")], + )?; for (key, value) in collected_cargo_metadata.iter_mut() { - value.is_in_libstd = Some(stdlib_set.contains_key(key)); + value.is_in_libstd = Some(library_collected_cargo_metadata.contains_key(key)); } + // Load JSON output by reuse + let collected_tree_metadata: Metadata = + serde_json::from_slice(&std::fs::read(&license_metadata)?)?; + + // Find libstd sub-set + let library_collected_tree_metadata = Metadata { + files: collected_tree_metadata + .files + .trim_clone(&Path::new("./library"), &Path::new(".")) + .unwrap(), + }; + + // Output main file let template = CopyrightTemplate { in_tree: collected_tree_metadata.files, dependencies: collected_cargo_metadata, }; - let output = template.render()?; - + // Git stores text files with \n, but this file may contain \r\n in files + // copied from dependencies. Normalise them before we write them out, for + // consistency. + let output = output.replace("\r\n", "\n"); std::fs::write(&dest_file, output)?; + // Output libstd subset file + let template = LibraryCopyrightTemplate { + in_tree: library_collected_tree_metadata.files, + dependencies: library_collected_cargo_metadata, + }; + let output = template.render()?; + // Git stores text files with \n, but this file may contain \r\n in files + // copied from dependencies. Normalise them before we write them out, for + // consistency. + let output = output.replace("\r\n", "\n"); + std::fs::write(&libstd_dest_file, output)?; + Ok(()) } +/// The HTML template for the toolchain copyright file +#[derive(Template)] +#[template(path = "COPYRIGHT.html")] +struct CopyrightTemplate { + in_tree: Node, + dependencies: BTreeMap, +} + +/// The HTML template for the library copyright file +#[derive(Template)] +#[template(path = "COPYRIGHT-library.html")] +struct LibraryCopyrightTemplate { + in_tree: Node, + dependencies: BTreeMap, +} + /// Describes a tree of metadata for our filesystem tree -#[derive(serde::Deserialize)] +/// +/// Must match the JSON emitted by the `CollectLicenseMetadata` bootstrap tool. +#[derive(serde::Deserialize, Clone, Debug, PartialEq, Eq)] struct Metadata { files: Node, } /// Describes one node in our metadata tree -#[derive(serde::Deserialize, rinja::Template)] +#[derive(serde::Deserialize, rinja::Template, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "kebab-case", tag = "type")] #[template(path = "Node.html")] pub(crate) enum Node { @@ -72,8 +113,74 @@ pub(crate) enum Node { Group { files: Vec, directories: Vec, license: License }, } +impl Node { + /// Clone, this node, but only if the path to the item is within the match path + fn trim_clone(&self, match_path: &Path, parent_path: &Path) -> Option { + match self { + Node::Root { children } => { + let mut filtered_children = Vec::new(); + for node in children { + if let Some(child_node) = node.trim_clone(match_path, parent_path) { + filtered_children.push(child_node); + } + } + if filtered_children.is_empty() { + None + } else { + Some(Node::Root { children: filtered_children }) + } + } + Node::Directory { name, children, license } => { + let child_name = parent_path.join(name); + if !(child_name.starts_with(match_path) || match_path.starts_with(&child_name)) { + return None; + } + let mut filtered_children = Vec::new(); + for node in children { + if let Some(child_node) = node.trim_clone(match_path, &child_name) { + filtered_children.push(child_node); + } + } + Some(Node::Directory { + name: name.clone(), + children: filtered_children, + license: license.clone(), + }) + } + Node::File { name, license } => { + let child_name = parent_path.join(name); + if !(child_name.starts_with(match_path) || match_path.starts_with(&child_name)) { + return None; + } + Some(Node::File { name: name.clone(), license: license.clone() }) + } + Node::Group { files, directories, license } => { + let mut filtered_child_files = Vec::new(); + for child in files { + let child_name = parent_path.join(child); + if child_name.starts_with(match_path) || match_path.starts_with(&child_name) { + filtered_child_files.push(child.clone()); + } + } + let mut filtered_child_dirs = Vec::new(); + for child in directories { + let child_name = parent_path.join(child); + if child_name.starts_with(match_path) || match_path.starts_with(&child_name) { + filtered_child_dirs.push(child.clone()); + } + } + Some(Node::Group { + files: filtered_child_files, + directories: filtered_child_dirs, + license: license.clone(), + }) + } + } + } +} + /// A License has an SPDX license name and a list of copyright holders. -#[derive(serde::Deserialize)] +#[derive(serde::Deserialize, Clone, Debug, PartialEq, Eq)] struct License { spdx: String, copyright: Vec, diff --git a/src/tools/generate-copyright/templates/COPYRIGHT-library.html b/src/tools/generate-copyright/templates/COPYRIGHT-library.html new file mode 100644 index 0000000000000..2c1eba741db0a --- /dev/null +++ b/src/tools/generate-copyright/templates/COPYRIGHT-library.html @@ -0,0 +1,53 @@ + + + + + Copyright notices for The Rust Standard Library + + + +

Copyright notices for The Rust Standard Library

+ +

This file describes the copyright and licensing information for the Rust +Standard Library source code within The Rust Project git tree, and the +third-party dependencies used when building the Rust Standard Library.

+ +

Table of Contents

+ + +

In-tree files

+ +

The following licenses cover the in-tree source files that were used in this +release:

+ +{{ in_tree|safe }} + +

Out-of-tree dependencies

+ +

The following licenses cover the out-of-tree crates that were used in the +Rust Standard Library in this release:

+ +{% for (key, value) in dependencies %} +

📦 {{key.name}}-{{key.version}}

+

URL: https://crates.io/crates/{{ key.name }}/{{ key.version }}

+

Authors: {{ value.authors|join(", ") }}

+

License: {{ value.license }}

+ {% let len = value.notices.len() %} + {% if len > 0 %} +

Notices: + {% for (notice_name, notice_text) in value.notices %} +

+ {{ notice_name }} +
+{{ notice_text }}
+                
+
+ {% endfor %} +

+ {% endif %} +{% endfor %} + + \ No newline at end of file diff --git a/src/tools/miri/.cargo/config.toml b/src/tools/miri/.cargo/config.toml deleted file mode 100644 index 42e7c2c48189a..0000000000000 --- a/src/tools/miri/.cargo/config.toml +++ /dev/null @@ -1,9 +0,0 @@ -[unstable] -profile-rustflags = true - -# Add back the containing directory of the packages we have to refer to using --manifest-path. -# Per-package profiles avoid adding this to build dependencies. -[profile.dev.package."cargo-miri"] -rustflags = ["--remap-path-prefix", "=cargo-miri"] -[profile.dev.package."miri-script"] -rustflags = ["--remap-path-prefix", "=miri-script"] diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index a73fefaaf3499..9a683ae68fd71 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -548,6 +548,7 @@ Definite bugs found: * [Incorrect offset computation for highly-aligned types in `portable-atomic-util`](https://github.com/taiki-e/portable-atomic/pull/138) * [Occasional memory leak in `std::mpsc` channels](https://github.com/rust-lang/rust/issues/121582) (original code in [crossbeam](https://github.com/crossbeam-rs/crossbeam/pull/1084)) * [Weak-memory-induced memory leak in Windows thread-local storage](https://github.com/rust-lang/rust/pull/124281) +* [A bug in the new `RwLock::downgrade` implementation](https://rust-lang.zulipchat.com/#narrow/channel/269128-miri/topic/Miri.20error.20library.20test) (caught by Miri before it landed in the Rust repo) Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment): diff --git a/src/tools/miri/miri b/src/tools/miri/miri index 5d07ad9e249d6..ac1a7211c4ef8 100755 --- a/src/tools/miri/miri +++ b/src/tools/miri/miri @@ -1,13 +1,15 @@ #!/usr/bin/env bash set -e # We want to call the binary directly, so we need to know where it ends up. -MIRI_SCRIPT_TARGET_DIR="$(dirname "$0")"/miri-script/target +ROOT_DIR="$(dirname "$0")" +MIRI_SCRIPT_TARGET_DIR="$ROOT_DIR"/miri-script/target # If stdout is not a terminal and we are not on CI, assume that we are being invoked by RA, and use JSON output. if ! [ -t 1 ] && [ -z "$CI" ]; then MESSAGE_FORMAT="--message-format=json" fi -# We need a nightly toolchain, for the `profile-rustflags` cargo feature. -cargo +nightly build $CARGO_EXTRA_FLAGS --manifest-path "$(dirname "$0")"/miri-script/Cargo.toml \ +# We need a nightly toolchain, for `-Zroot-dir`. +cargo +nightly build $CARGO_EXTRA_FLAGS --manifest-path "$ROOT_DIR"/miri-script/Cargo.toml \ + -Zroot-dir="$ROOT_DIR" \ -q --target-dir "$MIRI_SCRIPT_TARGET_DIR" $MESSAGE_FORMAT || \ ( echo "Failed to build miri-script. Is the 'nightly' toolchain installed?"; exit 1 ) # Instead of doing just `cargo run --manifest-path .. $@`, we invoke miri-script binary directly. Invoking `cargo run` goes through diff --git a/src/tools/miri/miri-script/src/util.rs b/src/tools/miri/miri-script/src/util.rs index e6e85747d4d5f..cf6529d8373ed 100644 --- a/src/tools/miri/miri-script/src/util.rs +++ b/src/tools/miri/miri-script/src/util.rs @@ -105,7 +105,7 @@ impl MiriEnv { // Get extra flags for cargo. let cargo_extra_flags = std::env::var("CARGO_EXTRA_FLAGS").unwrap_or_default(); - let cargo_extra_flags = flagsplit(&cargo_extra_flags); + let mut cargo_extra_flags = flagsplit(&cargo_extra_flags); if cargo_extra_flags.iter().any(|a| a == "--release" || a.starts_with("--profile")) { // This makes binaries end up in different paths, let's not do that. eprintln!( @@ -113,6 +113,8 @@ impl MiriEnv { ); std::process::exit(1); } + // Also set `-Zroot-dir` for cargo, to print diagnostics relative to the miri dir. + cargo_extra_flags.push(format!("-Zroot-dir={}", miri_dir.display())); Ok(MiriEnv { miri_dir, toolchain, sh, sysroot, cargo_extra_flags, libdir }) } diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index bec28af6257fa..effed0cd180d1 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -668959740f97e7a22ae340742886d330ab63950f +2d0ea7956c45de6e421fd579e2ded27be405dec6 diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 357c50889c422..c61c62c73dad2 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -73,51 +73,47 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { fn after_analysis<'tcx>( &mut self, _: &rustc_interface::interface::Compiler, - queries: &'tcx rustc_interface::Queries<'tcx>, + tcx: TyCtxt<'tcx>, ) -> Compilation { - queries.global_ctxt().unwrap().enter(|tcx| { - if tcx.sess.dcx().has_errors_or_delayed_bugs().is_some() { - tcx.dcx().fatal("miri cannot be run on programs that fail compilation"); - } + if tcx.sess.dcx().has_errors_or_delayed_bugs().is_some() { + tcx.dcx().fatal("miri cannot be run on programs that fail compilation"); + } - let early_dcx = EarlyDiagCtxt::new(tcx.sess.opts.error_format); - init_late_loggers(&early_dcx, tcx); - if !tcx.crate_types().contains(&CrateType::Executable) { - tcx.dcx().fatal("miri only makes sense on bin crates"); - } + let early_dcx = EarlyDiagCtxt::new(tcx.sess.opts.error_format); + init_late_loggers(&early_dcx, tcx); + if !tcx.crate_types().contains(&CrateType::Executable) { + tcx.dcx().fatal("miri only makes sense on bin crates"); + } - let (entry_def_id, entry_type) = entry_fn(tcx); - let mut config = self.miri_config.clone(); + let (entry_def_id, entry_type) = entry_fn(tcx); + let mut config = self.miri_config.clone(); - // Add filename to `miri` arguments. - config.args.insert(0, tcx.sess.io.input.filestem().to_string()); + // Add filename to `miri` arguments. + config.args.insert(0, tcx.sess.io.input.filestem().to_string()); - // Adjust working directory for interpretation. - if let Some(cwd) = env::var_os("MIRI_CWD") { - env::set_current_dir(cwd).unwrap(); - } + // Adjust working directory for interpretation. + if let Some(cwd) = env::var_os("MIRI_CWD") { + env::set_current_dir(cwd).unwrap(); + } - if tcx.sess.opts.optimize != OptLevel::No { - tcx.dcx().warn("Miri does not support optimizations: the opt-level is ignored. The only effect \ + if tcx.sess.opts.optimize != OptLevel::No { + tcx.dcx().warn("Miri does not support optimizations: the opt-level is ignored. The only effect \ of selecting a Cargo profile that enables optimizations (such as --release) is to apply \ its remaining settings, such as whether debug assertions and overflow checks are enabled."); - } - if tcx.sess.mir_opt_level() > 0 { - tcx.dcx().warn("You have explicitly enabled MIR optimizations, overriding Miri's default \ + } + if tcx.sess.mir_opt_level() > 0 { + tcx.dcx().warn("You have explicitly enabled MIR optimizations, overriding Miri's default \ which is to completely disable them. Any optimizations may hide UB that Miri would \ otherwise detect, and it is not necessarily possible to predict what kind of UB will \ be missed. If you are enabling optimizations to make Miri run faster, we advise using \ cfg(miri) to shrink your workload instead. The performance benefit of enabling MIR \ optimizations is usually marginal at best."); - } + } - if let Some(return_code) = miri::eval_entry(tcx, entry_def_id, entry_type, config) { - std::process::exit( - i32::try_from(return_code).expect("Return value was too large!"), - ); - } - tcx.dcx().abort_if_errors(); - }); + if let Some(return_code) = miri::eval_entry(tcx, entry_def_id, entry_type, config) { + std::process::exit(i32::try_from(return_code).expect("Return value was too large!")); + } + tcx.dcx().abort_if_errors(); Compilation::Stop } @@ -193,20 +189,18 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { fn after_analysis<'tcx>( &mut self, _: &rustc_interface::interface::Compiler, - queries: &'tcx rustc_interface::Queries<'tcx>, + tcx: TyCtxt<'tcx>, ) -> Compilation { - queries.global_ctxt().unwrap().enter(|tcx| { - if self.target_crate { - // cargo-miri has patched the compiler flags to make these into check-only builds, - // but we are still emulating regular rustc builds, which would perform post-mono - // const-eval during collection. So let's also do that here, even if we might be - // running with `--emit=metadata`. In particular this is needed to make - // `compile_fail` doc tests trigger post-mono errors. - // In general `collect_and_partition_mono_items` is not safe to call in check-only - // builds, but we are setting `-Zalways-encode-mir` which avoids those issues. - let _ = tcx.collect_and_partition_mono_items(()); - } - }); + if self.target_crate { + // cargo-miri has patched the compiler flags to make these into check-only builds, + // but we are still emulating regular rustc builds, which would perform post-mono + // const-eval during collection. So let's also do that here, even if we might be + // running with `--emit=metadata`. In particular this is needed to make + // `compile_fail` doc tests trigger post-mono errors. + // In general `collect_and_partition_mono_items` is not safe to call in check-only + // builds, but we are setting `-Zalways-encode-mir` which avoids those issues. + let _ = tcx.collect_and_partition_mono_items(()); + } Compilation::Continue } } diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index 02e8261a6ed90..ef4034cc0c11e 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -1,6 +1,7 @@ use std::cell::RefCell; use std::collections::VecDeque; use std::collections::hash_map::Entry; +use std::default::Default; use std::ops::Not; use std::rc::Rc; use std::time::Duration; @@ -46,8 +47,6 @@ macro_rules! declare_id { } pub(super) use declare_id; -declare_id!(MutexId); - /// The mutex state. #[derive(Default, Debug)] struct Mutex { @@ -61,6 +60,21 @@ struct Mutex { clock: VClock, } +#[derive(Default, Clone, Debug)] +pub struct MutexRef(Rc>); + +impl MutexRef { + fn new() -> Self { + MutexRef(Rc::new(RefCell::new(Mutex::default()))) + } +} + +impl VisitProvenance for MutexRef { + fn visit_provenance(&self, _visit: &mut VisitWith<'_>) { + // Mutex contains no provenance. + } +} + declare_id!(RwLockId); /// The read-write lock state. @@ -144,7 +158,6 @@ struct FutexWaiter { /// The state of all synchronization objects. #[derive(Default, Debug)] pub struct SynchronizationObjects { - mutexes: IndexVec, rwlocks: IndexVec, condvars: IndexVec, pub(super) init_onces: IndexVec, @@ -155,17 +168,17 @@ impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} pub(super) trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { fn condvar_reacquire_mutex( &mut self, - mutex: MutexId, + mutex_ref: &MutexRef, retval: Scalar, dest: MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - if this.mutex_is_locked(mutex) { - assert_ne!(this.mutex_get_owner(mutex), this.active_thread()); - this.mutex_enqueue_and_block(mutex, Some((retval, dest))); + if this.mutex_is_locked(mutex_ref) { + assert_ne!(this.mutex_get_owner(mutex_ref), this.active_thread()); + this.mutex_enqueue_and_block(mutex_ref, Some((retval, dest))); } else { // We can have it right now! - this.mutex_lock(mutex); + this.mutex_lock(mutex_ref); // Don't forget to write the return value. this.write_scalar(retval, &dest)?; } @@ -174,10 +187,9 @@ pub(super) trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } impl SynchronizationObjects { - pub fn mutex_create(&mut self) -> MutexId { - self.mutexes.push(Default::default()) + pub fn mutex_create(&mut self) -> MutexRef { + MutexRef::new() } - pub fn rwlock_create(&mut self) -> RwLockId { self.rwlocks.push(Default::default()) } @@ -209,12 +221,16 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Helper for lazily initialized `alloc_extra.sync` data: /// this forces an immediate init. - fn lazy_sync_init( - &mut self, + /// Return a reference to the data in the machine state. + fn lazy_sync_init<'a, T: 'static>( + &'a mut self, primitive: &MPlaceTy<'tcx>, init_offset: Size, data: T, - ) -> InterpResult<'tcx> { + ) -> InterpResult<'tcx, &'a T> + where + 'tcx: 'a, + { let this = self.eval_context_mut(); let (alloc, offset, _) = this.ptr_get_alloc_id(primitive.ptr(), 0)?; @@ -227,7 +243,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &init_field, AtomicWriteOrd::Relaxed, )?; - interp_ok(()) + interp_ok(this.get_alloc_extra(alloc)?.get_sync::(offset).unwrap()) } /// Helper for lazily initialized `alloc_extra.sync` data: @@ -235,13 +251,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// - If yes, fetches the data from `alloc_extra.sync`, or calls `missing_data` if that fails /// and stores that in `alloc_extra.sync`. /// - Otherwise, calls `new_data` to initialize the primitive. - fn lazy_sync_get_data( - &mut self, + /// + /// Return a reference to the data in the machine state. + fn lazy_sync_get_data<'a, T: 'static>( + &'a mut self, primitive: &MPlaceTy<'tcx>, init_offset: Size, missing_data: impl FnOnce() -> InterpResult<'tcx, T>, new_data: impl FnOnce(&mut MiriInterpCx<'tcx>) -> InterpResult<'tcx, T>, - ) -> InterpResult<'tcx, T> { + ) -> InterpResult<'tcx, &'a T> + where + 'tcx: 'a, + { let this = self.eval_context_mut(); // Check if this is already initialized. Needs to be atomic because we can race with another @@ -265,17 +286,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // or else it has been moved illegally. let (alloc, offset, _) = this.ptr_get_alloc_id(primitive.ptr(), 0)?; let (alloc_extra, _machine) = this.get_alloc_extra_mut(alloc)?; - if let Some(data) = alloc_extra.get_sync::(offset) { - interp_ok(*data) - } else { + // Due to borrow checker reasons, we have to do the lookup twice. + if alloc_extra.get_sync::(offset).is_none() { let data = missing_data()?; alloc_extra.sync.insert(offset, Box::new(data)); - interp_ok(data) } + interp_ok(alloc_extra.get_sync::(offset).unwrap()) } else { let data = new_data(this)?; - this.lazy_sync_init(primitive, init_offset, data)?; - interp_ok(data) + this.lazy_sync_init(primitive, init_offset, data) } } @@ -311,23 +330,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { #[inline] /// Get the id of the thread that currently owns this lock. - fn mutex_get_owner(&mut self, id: MutexId) -> ThreadId { - let this = self.eval_context_ref(); - this.machine.sync.mutexes[id].owner.unwrap() + fn mutex_get_owner(&self, mutex_ref: &MutexRef) -> ThreadId { + mutex_ref.0.borrow().owner.unwrap() } #[inline] /// Check if locked. - fn mutex_is_locked(&self, id: MutexId) -> bool { - let this = self.eval_context_ref(); - this.machine.sync.mutexes[id].owner.is_some() + fn mutex_is_locked(&self, mutex_ref: &MutexRef) -> bool { + mutex_ref.0.borrow().owner.is_some() } /// Lock by setting the mutex owner and increasing the lock count. - fn mutex_lock(&mut self, id: MutexId) { + fn mutex_lock(&mut self, mutex_ref: &MutexRef) { let this = self.eval_context_mut(); let thread = this.active_thread(); - let mutex = &mut this.machine.sync.mutexes[id]; + let mut mutex = mutex_ref.0.borrow_mut(); if let Some(current_owner) = mutex.owner { assert_eq!(thread, current_owner, "mutex already locked by another thread"); assert!( @@ -347,9 +364,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// count. If the lock count reaches 0, release the lock and potentially /// give to a new owner. If the lock was not locked by the current thread, /// return `None`. - fn mutex_unlock(&mut self, id: MutexId) -> InterpResult<'tcx, Option> { + fn mutex_unlock(&mut self, mutex_ref: &MutexRef) -> InterpResult<'tcx, Option> { let this = self.eval_context_mut(); - let mutex = &mut this.machine.sync.mutexes[id]; + let mut mutex = mutex_ref.0.borrow_mut(); interp_ok(if let Some(current_owner) = mutex.owner { // Mutex is locked. if current_owner != this.machine.threads.active_thread() { @@ -367,8 +384,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { mutex.clock.clone_from(clock) }); } - if let Some(thread) = this.machine.sync.mutexes[id].queue.pop_front() { - this.unblock_thread(thread, BlockReason::Mutex(id))?; + let thread_id = mutex.queue.pop_front(); + // We need to drop our mutex borrow before unblock_thread + // because it will be borrowed again in the unblock callback. + drop(mutex); + if thread_id.is_some() { + this.unblock_thread(thread_id.unwrap(), BlockReason::Mutex)?; } } Some(old_lock_count) @@ -385,24 +406,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { #[inline] fn mutex_enqueue_and_block( &mut self, - id: MutexId, + mutex_ref: &MutexRef, retval_dest: Option<(Scalar, MPlaceTy<'tcx>)>, ) { let this = self.eval_context_mut(); - assert!(this.mutex_is_locked(id), "queing on unlocked mutex"); + assert!(this.mutex_is_locked(mutex_ref), "queuing on unlocked mutex"); let thread = this.active_thread(); - this.machine.sync.mutexes[id].queue.push_back(thread); + mutex_ref.0.borrow_mut().queue.push_back(thread); + let mutex_ref = mutex_ref.clone(); this.block_thread( - BlockReason::Mutex(id), + BlockReason::Mutex, None, callback!( @capture<'tcx> { - id: MutexId, + mutex_ref: MutexRef, retval_dest: Option<(Scalar, MPlaceTy<'tcx>)>, } @unblock = |this| { - assert!(!this.mutex_is_locked(id)); - this.mutex_lock(id); + assert!(!this.mutex_is_locked(&mutex_ref)); + this.mutex_lock(&mutex_ref); if let Some((retval, dest)) = retval_dest { this.write_scalar(retval, &dest)?; @@ -623,14 +645,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn condvar_wait( &mut self, condvar: CondvarId, - mutex: MutexId, + mutex_ref: MutexRef, timeout: Option<(TimeoutClock, TimeoutAnchor, Duration)>, retval_succ: Scalar, retval_timeout: Scalar, dest: MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - if let Some(old_locked_count) = this.mutex_unlock(mutex)? { + if let Some(old_locked_count) = this.mutex_unlock(&mutex_ref)? { if old_locked_count != 1 { throw_unsup_format!( "awaiting a condvar on a mutex acquired multiple times is not supported" @@ -650,7 +672,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { callback!( @capture<'tcx> { condvar: CondvarId, - mutex: MutexId, + mutex_ref: MutexRef, retval_succ: Scalar, retval_timeout: Scalar, dest: MPlaceTy<'tcx>, @@ -665,7 +687,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Try to acquire the mutex. // The timeout only applies to the first wait (until the signal), not for mutex acquisition. - this.condvar_reacquire_mutex(mutex, retval_succ, dest) + this.condvar_reacquire_mutex(&mutex_ref, retval_succ, dest) } @timeout = |this| { // We have to remove the waiter from the queue again. @@ -673,7 +695,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let waiters = &mut this.machine.sync.condvars[condvar].waiters; waiters.retain(|waiter| *waiter != thread); // Now get back the lock. - this.condvar_reacquire_mutex(mutex, retval_timeout, dest) + this.condvar_reacquire_mutex(&mutex_ref, retval_timeout, dest) } ), ); diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index e6a3ae897c23b..59e2fdd428504 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -113,6 +113,11 @@ impl ThreadId { self.0 } + /// Create a new thread id from a `u32` without checking if this thread exists. + pub fn new_unchecked(id: u32) -> Self { + Self(id) + } + pub const MAIN_THREAD: ThreadId = ThreadId(0); } @@ -141,7 +146,7 @@ pub enum BlockReason { /// Waiting for time to pass. Sleep, /// Blocked on a mutex. - Mutex(MutexId), + Mutex, /// Blocked on a condition variable. Condvar(CondvarId), /// Blocked on a reader-writer lock. @@ -152,6 +157,8 @@ pub enum BlockReason { InitOnce(InitOnceId), /// Blocked on epoll. Epoll, + /// Blocked on eventfd. + Eventfd, } /// The state of a thread. diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 63591474120db..41b7be37c37d3 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -195,7 +195,7 @@ pub fn prune_stacktrace<'tcx>( // This len check ensures that we don't somehow remove every frame, as doing so breaks // the primary error message. while stacktrace.len() > 1 - && stacktrace.last().map_or(false, |frame| !machine.is_local(frame)) + && stacktrace.last().is_some_and(|frame| !machine.is_local(frame)) { stacktrace.pop(); } diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 85591a0b37022..1df1d08802a82 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -270,12 +270,8 @@ pub fn create_ecx<'tcx>( ) -> InterpResult<'tcx, InterpCx<'tcx, MiriMachine<'tcx>>> { let typing_env = ty::TypingEnv::fully_monomorphized(); let layout_cx = LayoutCx::new(tcx, typing_env); - let mut ecx = InterpCx::new( - tcx, - rustc_span::DUMMY_SP, - typing_env, - MiriMachine::new(config, layout_cx) - ); + let mut ecx = + InterpCx::new(tcx, rustc_span::DUMMY_SP, typing_env, MiriMachine::new(config, layout_cx)); // Some parts of initialization require a full `InterpCx`. MiriMachine::late_init(&mut ecx, config, { diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 4b34f1686a01a..b57ce4e070c38 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -116,8 +116,7 @@ pub fn resolve_path<'tcx>( /// Gets the layout of a type at a path. #[track_caller] pub fn path_ty_layout<'tcx>(cx: &impl LayoutOf<'tcx>, path: &[&str]) -> TyAndLayout<'tcx> { - let ty = resolve_path(cx.tcx(), path, Namespace::TypeNS) - .ty(cx.tcx(), cx.typing_env()); + let ty = resolve_path(cx.tcx(), path, Namespace::TypeNS).ty(cx.tcx(), cx.typing_env()); cx.layout_of(ty).to_result().ok().unwrap() } @@ -1009,7 +1008,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_ref(); fn float_to_int_inner<'tcx, F: rustc_apfloat::Float>( - this: &MiriInterpCx<'tcx>, + ecx: &MiriInterpCx<'tcx>, src: F, cast_to: TyAndLayout<'tcx>, round: rustc_apfloat::Round, @@ -1029,7 +1028,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Nothing else _ => span_bug!( - this.cur_span(), + ecx.cur_span(), "attempted float-to-int conversion with non-int output type {}", cast_to.ty, ), diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index 272dca1594ed9..9eebbc5d3631e 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -218,20 +218,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; - // Using host floats (but it's fine, these operations do not have guaranteed precision). - let f_host = f.to_host(); + // Using host floats except for sqrt (but it's fine, these operations do not have + // guaranteed precision). let res = match intrinsic_name { - "sinf32" => f_host.sin(), - "cosf32" => f_host.cos(), - "sqrtf32" => f_host.sqrt(), // FIXME Using host floats, this should use full-precision soft-floats - "expf32" => f_host.exp(), - "exp2f32" => f_host.exp2(), - "logf32" => f_host.ln(), - "log10f32" => f_host.log10(), - "log2f32" => f_host.log2(), + "sinf32" => f.to_host().sin().to_soft(), + "cosf32" => f.to_host().cos().to_soft(), + "sqrtf32" => math::sqrt(f), + "expf32" => f.to_host().exp().to_soft(), + "exp2f32" => f.to_host().exp2().to_soft(), + "logf32" => f.to_host().ln().to_soft(), + "log10f32" => f.to_host().log10().to_soft(), + "log2f32" => f.to_host().log2().to_soft(), _ => bug!(), }; - let res = res.to_soft(); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } @@ -247,20 +246,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f64()?; - // Using host floats (but it's fine, these operations do not have guaranteed precision). - let f_host = f.to_host(); + // Using host floats except for sqrt (but it's fine, these operations do not have + // guaranteed precision). let res = match intrinsic_name { - "sinf64" => f_host.sin(), - "cosf64" => f_host.cos(), - "sqrtf64" => f_host.sqrt(), // FIXME Using host floats, this should use full-precision soft-floats - "expf64" => f_host.exp(), - "exp2f64" => f_host.exp2(), - "logf64" => f_host.ln(), - "log10f64" => f_host.log10(), - "log2f64" => f_host.log2(), + "sinf64" => f.to_host().sin().to_soft(), + "cosf64" => f.to_host().cos().to_soft(), + "sqrtf64" => math::sqrt(f), + "expf64" => f.to_host().exp().to_soft(), + "exp2f64" => f.to_host().exp2().to_soft(), + "logf64" => f.to_host().ln().to_soft(), + "log10f64" => f.to_host().log10().to_soft(), + "log2f64" => f.to_host().log2().to_soft(), _ => bug!(), }; - let res = res.to_soft(); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs index d5c417e723142..075b6f35e0ee0 100644 --- a/src/tools/miri/src/intrinsics/simd.rs +++ b/src/tools/miri/src/intrinsics/simd.rs @@ -104,42 +104,39 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let ty::Float(float_ty) = op.layout.ty.kind() else { span_bug!(this.cur_span(), "{} operand is not a float", intrinsic_name) }; - // Using host floats (but it's fine, these operations do not have guaranteed precision). + // Using host floats except for sqrt (but it's fine, these operations do not + // have guaranteed precision). match float_ty { FloatTy::F16 => unimplemented!("f16_f128"), FloatTy::F32 => { let f = op.to_scalar().to_f32()?; - let f_host = f.to_host(); let res = match host_op { - "fsqrt" => f_host.sqrt(), // FIXME Using host floats, this should use full-precision soft-floats - "fsin" => f_host.sin(), - "fcos" => f_host.cos(), - "fexp" => f_host.exp(), - "fexp2" => f_host.exp2(), - "flog" => f_host.ln(), - "flog2" => f_host.log2(), - "flog10" => f_host.log10(), + "fsqrt" => math::sqrt(f), + "fsin" => f.to_host().sin().to_soft(), + "fcos" => f.to_host().cos().to_soft(), + "fexp" => f.to_host().exp().to_soft(), + "fexp2" => f.to_host().exp2().to_soft(), + "flog" => f.to_host().ln().to_soft(), + "flog2" => f.to_host().log2().to_soft(), + "flog10" => f.to_host().log10().to_soft(), _ => bug!(), }; - let res = res.to_soft(); let res = this.adjust_nan(res, &[f]); Scalar::from(res) } FloatTy::F64 => { let f = op.to_scalar().to_f64()?; - let f_host = f.to_host(); let res = match host_op { - "fsqrt" => f_host.sqrt(), - "fsin" => f_host.sin(), - "fcos" => f_host.cos(), - "fexp" => f_host.exp(), - "fexp2" => f_host.exp2(), - "flog" => f_host.ln(), - "flog2" => f_host.log2(), - "flog10" => f_host.log10(), + "fsqrt" => math::sqrt(f), + "fsin" => f.to_host().sin().to_soft(), + "fcos" => f.to_host().cos().to_soft(), + "fexp" => f.to_host().exp().to_soft(), + "fexp2" => f.to_host().exp2().to_soft(), + "flog" => f.to_host().ln().to_soft(), + "flog2" => f.to_host().log2().to_soft(), + "flog10" => f.to_host().log10().to_soft(), _ => bug!(), }; - let res = res.to_soft(); let res = this.adjust_nan(res, &[f]); Scalar::from(res) } diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index f903ccbc25a74..85c896563dabf 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -83,6 +83,7 @@ mod eval; mod helpers; mod intrinsics; mod machine; +mod math; mod mono_hash_map; mod operator; mod provenance_gc; @@ -122,7 +123,7 @@ pub use crate::concurrency::data_race::{ }; pub use crate::concurrency::init_once::{EvalContextExt as _, InitOnceId}; pub use crate::concurrency::sync::{ - CondvarId, EvalContextExt as _, MutexId, RwLockId, SynchronizationObjects, + CondvarId, EvalContextExt as _, MutexRef, RwLockId, SynchronizationObjects, }; pub use crate::concurrency::thread::{ BlockReason, EvalContextExt as _, StackEmptyCallback, ThreadId, ThreadManager, TimeoutAnchor, diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 7b03aed476383..814dc6d2b01f7 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -732,20 +732,20 @@ impl<'tcx> MiriMachine<'tcx> { } pub(crate) fn late_init( - this: &mut MiriInterpCx<'tcx>, + ecx: &mut MiriInterpCx<'tcx>, config: &MiriConfig, on_main_stack_empty: StackEmptyCallback<'tcx>, ) -> InterpResult<'tcx> { - EnvVars::init(this, config)?; - MiriMachine::init_extern_statics(this)?; - ThreadManager::init(this, on_main_stack_empty); + EnvVars::init(ecx, config)?; + MiriMachine::init_extern_statics(ecx)?; + ThreadManager::init(ecx, on_main_stack_empty); interp_ok(()) } - pub(crate) fn add_extern_static(this: &mut MiriInterpCx<'tcx>, name: &str, ptr: Pointer) { + pub(crate) fn add_extern_static(ecx: &mut MiriInterpCx<'tcx>, name: &str, ptr: Pointer) { // This got just allocated, so there definitely is a pointer here. let ptr = ptr.into_pointer_or_addr().unwrap(); - this.machine.extern_statics.try_insert(Symbol::intern(name), ptr).unwrap(); + ecx.machine.extern_statics.try_insert(Symbol::intern(name), ptr).unwrap(); } pub(crate) fn communicate(&self) -> bool { diff --git a/src/tools/miri/src/math.rs b/src/tools/miri/src/math.rs new file mode 100644 index 0000000000000..ed3d2d55678e2 --- /dev/null +++ b/src/tools/miri/src/math.rs @@ -0,0 +1,164 @@ +use rand::Rng as _; +use rand::distributions::Distribution as _; +use rustc_apfloat::Float as _; +use rustc_apfloat::ieee::IeeeFloat; + +/// Disturbes a floating-point result by a relative error on the order of (-2^scale, 2^scale). +pub(crate) fn apply_random_float_error( + ecx: &mut crate::MiriInterpCx<'_>, + val: F, + err_scale: i32, +) -> F { + let rng = ecx.machine.rng.get_mut(); + // Generate a random integer in the range [0, 2^PREC). + let dist = rand::distributions::Uniform::new(0, 1 << F::PRECISION); + let err = F::from_u128(dist.sample(rng)) + .value + .scalbn(err_scale.strict_sub(F::PRECISION.try_into().unwrap())); + // give it a random sign + let err = if rng.gen::() { -err } else { err }; + // multiple the value with (1+err) + (val * (F::from_u128(1).value + err).value).value +} + +pub(crate) fn sqrt(x: IeeeFloat) -> IeeeFloat { + match x.category() { + // preserve zero sign + rustc_apfloat::Category::Zero => x, + // propagate NaN + rustc_apfloat::Category::NaN => x, + // sqrt of negative number is NaN + _ if x.is_negative() => IeeeFloat::NAN, + // sqrt(∞) = ∞ + rustc_apfloat::Category::Infinity => IeeeFloat::INFINITY, + rustc_apfloat::Category::Normal => { + // Floating point precision, excluding the integer bit + let prec = i32::try_from(S::PRECISION).unwrap() - 1; + + // x = 2^(exp - prec) * mant + // where mant is an integer with prec+1 bits + // mant is a u128, which should be large enough for the largest prec (112 for f128) + let mut exp = x.ilogb(); + let mut mant = x.scalbn(prec - exp).to_u128(128).value; + + if exp % 2 != 0 { + // Make exponent even, so it can be divided by 2 + exp -= 1; + mant <<= 1; + } + + // Bit-by-bit (base-2 digit-by-digit) sqrt of mant. + // mant is treated here as a fixed point number with prec fractional bits. + // mant will be shifted left by one bit to have an extra fractional bit, which + // will be used to determine the rounding direction. + + // res is the truncated sqrt of mant, where one bit is added at each iteration. + let mut res = 0u128; + // rem is the remainder with the current res + // rem_i = 2^i * ((mant<<1) - res_i^2) + // starting with res = 0, rem = mant<<1 + let mut rem = mant << 1; + // s_i = 2*res_i + let mut s = 0u128; + // d is used to iterate over bits, from high to low (d_i = 2^(-i)) + let mut d = 1u128 << (prec + 1); + + // For iteration j=i+1, we need to find largest b_j = 0 or 1 such that + // (res_i + b_j * 2^(-j))^2 <= mant<<1 + // Expanding (a + b)^2 = a^2 + b^2 + 2*a*b: + // res_i^2 + (b_j * 2^(-j))^2 + 2 * res_i * b_j * 2^(-j) <= mant<<1 + // And rearranging the terms: + // b_j^2 * 2^(-j) + 2 * res_i * b_j <= 2^j * (mant<<1 - res_i^2) + // b_j^2 * 2^(-j) + 2 * res_i * b_j <= rem_i + + while d != 0 { + // Probe b_j^2 * 2^(-j) + 2 * res_i * b_j <= rem_i with b_j = 1: + // t = 2*res_i + 2^(-j) + let t = s + d; + if rem >= t { + // b_j should be 1, so make res_j = res_i + 2^(-j) and adjust rem + res += d; + s += d + d; + rem -= t; + } + // Adjust rem for next iteration + rem <<= 1; + // Shift iterator + d >>= 1; + } + + // Remove extra fractional bit from result, rounding to nearest. + // If the last bit is 0, then the nearest neighbor is definitely the lower one. + // If the last bit is 1, it sounds like this may either be a tie (if there's + // infinitely many 0s after this 1), or the nearest neighbor is the upper one. + // However, since square roots are either exact or irrational, and an exact root + // would lead to the last "extra" bit being 0, we can exclude a tie in this case. + // We therefore always round up if the last bit is 1. When the last bit is 0, + // adding 1 will not do anything since the shift will discard it. + res = (res + 1) >> 1; + + // Build resulting value with res as mantissa and exp/2 as exponent + IeeeFloat::from_u128(res).value.scalbn(exp / 2 - prec) + } + } +} + +#[cfg(test)] +mod tests { + use rustc_apfloat::ieee::{DoubleS, HalfS, IeeeFloat, QuadS, SingleS}; + + use super::sqrt; + + #[test] + fn test_sqrt() { + #[track_caller] + fn test(x: &str, expected: &str) { + let x: IeeeFloat = x.parse().unwrap(); + let expected: IeeeFloat = expected.parse().unwrap(); + let result = sqrt(x); + assert_eq!(result, expected); + } + + fn exact_tests() { + test::("0", "0"); + test::("1", "1"); + test::("1.5625", "1.25"); + test::("2.25", "1.5"); + test::("4", "2"); + test::("5.0625", "2.25"); + test::("9", "3"); + test::("16", "4"); + test::("25", "5"); + test::("36", "6"); + test::("49", "7"); + test::("64", "8"); + test::("81", "9"); + test::("100", "10"); + + test::("0.5625", "0.75"); + test::("0.25", "0.5"); + test::("0.0625", "0.25"); + test::("0.00390625", "0.0625"); + } + + exact_tests::(); + exact_tests::(); + exact_tests::(); + exact_tests::(); + + test::("2", "1.4142135"); + test::("2", "1.4142135623730951"); + + test::("1.1", "1.0488088"); + test::("1.1", "1.0488088481701516"); + + test::("2.2", "1.4832398"); + test::("2.2", "1.4832396974191326"); + + test::("1.22101e-40", "1.10499205e-20"); + test::("1.22101e-310", "1.1049932126488395e-155"); + + test::("3.4028235e38", "1.8446743e19"); + test::("1.7976931348623157e308", "1.3407807929942596e154"); + } +} diff --git a/src/tools/miri/src/provenance_gc.rs b/src/tools/miri/src/provenance_gc.rs index 6042a9eb2eb52..b3d715db9cd63 100644 --- a/src/tools/miri/src/provenance_gc.rs +++ b/src/tools/miri/src/provenance_gc.rs @@ -195,10 +195,10 @@ impl LiveAllocs<'_, '_> { } } -fn remove_unreachable_tags<'tcx>(this: &mut MiriInterpCx<'tcx>, tags: FxHashSet) { +fn remove_unreachable_tags<'tcx>(ecx: &mut MiriInterpCx<'tcx>, tags: FxHashSet) { // Avoid iterating all allocations if there's no borrow tracker anyway. - if this.machine.borrow_tracker.is_some() { - this.memory.alloc_map().iter(|it| { + if ecx.machine.borrow_tracker.is_some() { + ecx.memory.alloc_map().iter(|it| { for (_id, (_kind, alloc)) in it { alloc.extra.borrow_tracker.as_ref().unwrap().remove_unreachable_tags(&tags); } @@ -206,16 +206,16 @@ fn remove_unreachable_tags<'tcx>(this: &mut MiriInterpCx<'tcx>, tags: FxHashSet< } } -fn remove_unreachable_allocs<'tcx>(this: &mut MiriInterpCx<'tcx>, allocs: FxHashSet) { - let allocs = LiveAllocs { ecx: this, collected: allocs }; - this.machine.allocation_spans.borrow_mut().retain(|id, _| allocs.is_live(*id)); - this.machine.symbolic_alignment.borrow_mut().retain(|id, _| allocs.is_live(*id)); - this.machine.alloc_addresses.borrow_mut().remove_unreachable_allocs(&allocs); - if let Some(borrow_tracker) = &this.machine.borrow_tracker { +fn remove_unreachable_allocs<'tcx>(ecx: &mut MiriInterpCx<'tcx>, allocs: FxHashSet) { + let allocs = LiveAllocs { ecx, collected: allocs }; + ecx.machine.allocation_spans.borrow_mut().retain(|id, _| allocs.is_live(*id)); + ecx.machine.symbolic_alignment.borrow_mut().retain(|id, _| allocs.is_live(*id)); + ecx.machine.alloc_addresses.borrow_mut().remove_unreachable_allocs(&allocs); + if let Some(borrow_tracker) = &ecx.machine.borrow_tracker { borrow_tracker.borrow_mut().remove_unreachable_allocs(&allocs); } // Clean up core (non-Miri-specific) state. - this.remove_unreachable_allocs(&allocs.collected); + ecx.remove_unreachable_allocs(&allocs.collected); } impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs index 5559ea2750b3b..f0aebfe169378 100644 --- a/src/tools/miri/src/shims/extern_static.rs +++ b/src/tools/miri/src/shims/extern_static.rs @@ -4,13 +4,13 @@ use crate::*; impl<'tcx> MiriMachine<'tcx> { fn alloc_extern_static( - this: &mut MiriInterpCx<'tcx>, + ecx: &mut MiriInterpCx<'tcx>, name: &str, val: ImmTy<'tcx>, ) -> InterpResult<'tcx> { - let place = this.allocate(val.layout, MiriMemoryKind::ExternStatic.into())?; - this.write_immediate(*val, &place)?; - Self::add_extern_static(this, name, place.ptr()); + let place = ecx.allocate(val.layout, MiriMemoryKind::ExternStatic.into())?; + ecx.write_immediate(*val, &place)?; + Self::add_extern_static(ecx, name, place.ptr()); interp_ok(()) } @@ -18,72 +18,69 @@ impl<'tcx> MiriMachine<'tcx> { /// Most of them are for weak symbols, which we all set to null (indicating that the /// symbol is not supported, and triggering fallback code which ends up calling /// some other shim that we do support). - fn null_ptr_extern_statics( - this: &mut MiriInterpCx<'tcx>, - names: &[&str], - ) -> InterpResult<'tcx> { + fn null_ptr_extern_statics(ecx: &mut MiriInterpCx<'tcx>, names: &[&str]) -> InterpResult<'tcx> { for name in names { - let val = ImmTy::from_int(0, this.machine.layouts.usize); - Self::alloc_extern_static(this, name, val)?; + let val = ImmTy::from_int(0, ecx.machine.layouts.usize); + Self::alloc_extern_static(ecx, name, val)?; } interp_ok(()) } /// Extern statics that are initialized with function pointers to the symbols of the same name. fn weak_symbol_extern_statics( - this: &mut MiriInterpCx<'tcx>, + ecx: &mut MiriInterpCx<'tcx>, names: &[&str], ) -> InterpResult<'tcx> { for name in names { - assert!(this.is_dyn_sym(name), "{name} is not a dynamic symbol"); - let layout = this.machine.layouts.const_raw_ptr; - let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str(name))); - let val = ImmTy::from_scalar(Scalar::from_pointer(ptr, this), layout); - Self::alloc_extern_static(this, name, val)?; + assert!(ecx.is_dyn_sym(name), "{name} is not a dynamic symbol"); + let layout = ecx.machine.layouts.const_raw_ptr; + let ptr = ecx.fn_ptr(FnVal::Other(DynSym::from_str(name))); + let val = ImmTy::from_scalar(Scalar::from_pointer(ptr, ecx), layout); + Self::alloc_extern_static(ecx, name, val)?; } interp_ok(()) } /// Sets up the "extern statics" for this machine. - pub fn init_extern_statics(this: &mut MiriInterpCx<'tcx>) -> InterpResult<'tcx> { + pub fn init_extern_statics(ecx: &mut MiriInterpCx<'tcx>) -> InterpResult<'tcx> { // "__rust_no_alloc_shim_is_unstable" - let val = ImmTy::from_int(0, this.machine.layouts.u8); // always 0, value does not matter - Self::alloc_extern_static(this, "__rust_no_alloc_shim_is_unstable", val)?; + let val = ImmTy::from_int(0, ecx.machine.layouts.u8); // always 0, value does not matter + Self::alloc_extern_static(ecx, "__rust_no_alloc_shim_is_unstable", val)?; // "__rust_alloc_error_handler_should_panic" - let val = this.tcx.sess.opts.unstable_opts.oom.should_panic(); - let val = ImmTy::from_int(val, this.machine.layouts.u8); - Self::alloc_extern_static(this, "__rust_alloc_error_handler_should_panic", val)?; + 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)?; - if this.target_os_is_unix() { + if ecx.target_os_is_unix() { // "environ" is mandated by POSIX. - let environ = this.machine.env_vars.unix().environ(); - Self::add_extern_static(this, "environ", environ); + let environ = ecx.machine.env_vars.unix().environ(); + Self::add_extern_static(ecx, "environ", environ); } - match this.tcx.sess.target.os.as_ref() { + match ecx.tcx.sess.target.os.as_ref() { "linux" => { - Self::null_ptr_extern_statics(this, &[ + Self::null_ptr_extern_statics(ecx, &[ "__cxa_thread_atexit_impl", "__clock_gettime64", ])?; - Self::weak_symbol_extern_statics(this, &["getrandom", "statx"])?; + Self::weak_symbol_extern_statics(ecx, &["getrandom", "statx"])?; } "freebsd" => { - Self::null_ptr_extern_statics(this, &["__cxa_thread_atexit_impl"])?; + Self::null_ptr_extern_statics(ecx, &["__cxa_thread_atexit_impl"])?; } "android" => { - Self::null_ptr_extern_statics(this, &["bsd_signal"])?; - Self::weak_symbol_extern_statics(this, &["signal", "getrandom"])?; + Self::null_ptr_extern_statics(ecx, &["bsd_signal"])?; + Self::weak_symbol_extern_statics(ecx, &["signal", "getrandom"])?; } "windows" => { // "_tls_used" // This is some obscure hack that is part of the Windows TLS story. It's a `u8`. - let val = ImmTy::from_int(0, this.machine.layouts.u8); - Self::alloc_extern_static(this, "_tls_used", val)?; + let val = ImmTy::from_int(0, ecx.machine.layouts.u8); + Self::alloc_extern_static(ecx, "_tls_used", val)?; } "illumos" | "solaris" => { - Self::weak_symbol_extern_statics(this, &["pthread_setname_np"])?; + Self::weak_symbol_extern_statics(ecx, &["pthread_setname_np"])?; } _ => {} // No "extern statics" supported on this target } diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index b74491a2f8e62..4dc857ef30b49 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -496,14 +496,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Rust allocation "__rust_alloc" | "miri_alloc" => { - let default = |this: &mut MiriInterpCx<'tcx>| { + 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. - let [size, align] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; - let size = this.read_target_usize(size)?; - let align = this.read_target_usize(align)?; + let [size, align] = ecx.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let size = ecx.read_target_usize(size)?; + let align = ecx.read_target_usize(align)?; - this.check_rustc_alloc_request(size, align)?; + ecx.check_rustc_alloc_request(size, align)?; let memory_kind = match link_name.as_str() { "__rust_alloc" => MiriMemoryKind::Rust, @@ -511,13 +511,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { _ => unreachable!(), }; - let ptr = this.allocate_ptr( + let ptr = ecx.allocate_ptr( Size::from_bytes(size), Align::from_bytes(align).unwrap(), memory_kind.into(), )?; - this.write_pointer(ptr, dest) + ecx.write_pointer(ptr, dest) }; match link_name.as_str() { @@ -555,14 +555,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { }); } "__rust_dealloc" | "miri_dealloc" => { - let default = |this: &mut MiriInterpCx<'tcx>| { + let default = |ecx: &mut MiriInterpCx<'tcx>| { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. let [ptr, old_size, align] = - this.check_shim(abi, ExternAbi::Rust, link_name, args)?; - let ptr = this.read_pointer(ptr)?; - let old_size = this.read_target_usize(old_size)?; - let align = this.read_target_usize(align)?; + ecx.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let ptr = ecx.read_pointer(ptr)?; + let old_size = ecx.read_target_usize(old_size)?; + let align = ecx.read_target_usize(align)?; let memory_kind = match link_name.as_str() { "__rust_dealloc" => MiriMemoryKind::Rust, @@ -571,7 +571,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { }; // No need to check old_size/align; we anyway check that they match the allocation. - this.deallocate_ptr( + ecx.deallocate_ptr( ptr, Some((Size::from_bytes(old_size), Align::from_bytes(align).unwrap())), memory_kind.into(), diff --git a/src/tools/miri/src/shims/unix/android/thread.rs b/src/tools/miri/src/shims/unix/android/thread.rs index 093b7405ccda6..f8a0b3a85a2f2 100644 --- a/src/tools/miri/src/shims/unix/android/thread.rs +++ b/src/tools/miri/src/shims/unix/android/thread.rs @@ -8,7 +8,7 @@ use crate::*; const TASK_COMM_LEN: usize = 16; pub fn prctl<'tcx>( - this: &mut MiriInterpCx<'tcx>, + ecx: &mut MiriInterpCx<'tcx>, link_name: Symbol, abi: ExternAbi, args: &[OpTy<'tcx>], @@ -16,41 +16,41 @@ pub fn prctl<'tcx>( ) -> InterpResult<'tcx> { // We do not use `check_shim` here because `prctl` is variadic. The argument // count is checked bellow. - this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; + ecx.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; // FIXME: Use constants once https://github.com/rust-lang/libc/pull/3941 backported to the 0.2 branch. let pr_set_name = 15; let pr_get_name = 16; let [op] = check_min_arg_count("prctl", args)?; - let res = match this.read_scalar(op)?.to_i32()? { + let res = match ecx.read_scalar(op)?.to_i32()? { op if op == pr_set_name => { let [_, name] = check_min_arg_count("prctl(PR_SET_NAME, ...)", args)?; - let name = this.read_scalar(name)?; - let thread = this.pthread_self()?; + let name = ecx.read_scalar(name)?; + let thread = ecx.pthread_self()?; // The Linux kernel silently truncates long names. // https://www.man7.org/linux/man-pages/man2/PR_SET_NAME.2const.html let res = - this.pthread_setname_np(thread, name, TASK_COMM_LEN, /* truncate */ true)?; + ecx.pthread_setname_np(thread, name, TASK_COMM_LEN, /* truncate */ true)?; assert_eq!(res, ThreadNameResult::Ok); Scalar::from_u32(0) } op if op == pr_get_name => { let [_, name] = check_min_arg_count("prctl(PR_GET_NAME, ...)", args)?; - let name = this.read_scalar(name)?; - let thread = this.pthread_self()?; - let len = Scalar::from_target_usize(TASK_COMM_LEN as u64, this); - this.check_ptr_access( - name.to_pointer(this)?, + let name = ecx.read_scalar(name)?; + let thread = ecx.pthread_self()?; + let len = Scalar::from_target_usize(TASK_COMM_LEN as u64, ecx); + ecx.check_ptr_access( + name.to_pointer(ecx)?, Size::from_bytes(TASK_COMM_LEN), CheckInAllocMsg::MemoryAccessTest, )?; - let res = this.pthread_getname_np(thread, name, len, /* truncate*/ false)?; + let res = ecx.pthread_getname_np(thread, name, len, /* truncate*/ false)?; assert_eq!(res, ThreadNameResult::Ok); Scalar::from_u32(0) } op => throw_unsup_format!("Miri does not support `prctl` syscall with op={}", op), }; - this.write_scalar(res, dest)?; + ecx.write_scalar(res, dest)?; interp_ok(()) } diff --git a/src/tools/miri/src/shims/unix/linux/eventfd.rs b/src/tools/miri/src/shims/unix/linux/eventfd.rs index 35bc933885cd2..63b7d37b13e1f 100644 --- a/src/tools/miri/src/shims/unix/linux/eventfd.rs +++ b/src/tools/miri/src/shims/unix/linux/eventfd.rs @@ -4,7 +4,7 @@ use std::io; use std::io::ErrorKind; use crate::concurrency::VClock; -use crate::shims::unix::fd::FileDescriptionRef; +use crate::shims::unix::fd::{FileDescriptionRef, WeakFileDescriptionRef}; use crate::shims::unix::linux::epoll::{EpollReadyEvents, EvalContextExt as _}; use crate::shims::unix::*; use crate::*; @@ -26,6 +26,10 @@ struct Event { counter: Cell, is_nonblock: bool, clock: RefCell, + /// A list of thread ids blocked on eventfd::read. + blocked_read_tid: RefCell>, + /// A list of thread ids blocked on eventfd::write. + blocked_write_tid: RefCell>, } impl FileDescription for Event { @@ -72,31 +76,8 @@ impl FileDescription for Event { // eventfd read at the size of u64. let buf_place = ecx.ptr_to_mplace_unaligned(ptr, ty); - // Block when counter == 0. - let counter = self.counter.get(); - if counter == 0 { - if self.is_nonblock { - return ecx.set_last_error_and_return(ErrorKind::WouldBlock, dest); - } - - throw_unsup_format!("eventfd: blocking is unsupported"); - } else { - // Synchronize with all prior `write` calls to this FD. - ecx.acquire_clock(&self.clock.borrow()); - - // Give old counter value to userspace, and set counter value to 0. - ecx.write_int(counter, &buf_place)?; - self.counter.set(0); - - // When any of the event happened, we check and update the status of all supported event - // types for current file description. - ecx.check_and_update_readiness(self_ref)?; - - // Tell userspace how many bytes we wrote. - ecx.write_int(buf_place.layout.size.bytes(), dest)?; - } - - interp_ok(()) + let weak_eventfd = self_ref.downgrade(); + eventfd_read(buf_place, dest, weak_eventfd, ecx) } /// A write call adds the 8-byte integer value supplied in @@ -127,7 +108,7 @@ impl FileDescription for Event { return ecx.set_last_error_and_return(ErrorKind::InvalidInput, dest); } - // Read the user supplied value from the pointer. + // Read the user-supplied value from the pointer. let buf_place = ecx.ptr_to_mplace_unaligned(ptr, ty); let num = ecx.read_scalar(&buf_place)?.to_u64()?; @@ -137,27 +118,8 @@ impl FileDescription for Event { } // If the addition does not let the counter to exceed the maximum value, update the counter. // Else, block. - match self.counter.get().checked_add(num) { - Some(new_count @ 0..=MAX_COUNTER) => { - // Future `read` calls will synchronize with this write, so update the FD clock. - ecx.release_clock(|clock| { - self.clock.borrow_mut().join(clock); - }); - self.counter.set(new_count); - } - None | Some(u64::MAX) => - if self.is_nonblock { - return ecx.set_last_error_and_return(ErrorKind::WouldBlock, dest); - } else { - throw_unsup_format!("eventfd: blocking is unsupported"); - }, - }; - // When any of the event happened, we check and update the status of all supported event - // types for current file description. - ecx.check_and_update_readiness(self_ref)?; - - // Return how many bytes we read. - ecx.write_int(buf_place.layout.size.bytes(), dest) + let weak_eventfd = self_ref.downgrade(); + eventfd_write(num, buf_place, dest, weak_eventfd, ecx) } } @@ -217,8 +179,151 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { counter: Cell::new(val.into()), is_nonblock, clock: RefCell::new(VClock::default()), + blocked_read_tid: RefCell::new(Vec::new()), + blocked_write_tid: RefCell::new(Vec::new()), }); interp_ok(Scalar::from_i32(fd_value)) } } + +/// Block thread if the value addition will exceed u64::MAX -1, +/// else just add the user-supplied value to current counter. +fn eventfd_write<'tcx>( + num: u64, + buf_place: MPlaceTy<'tcx>, + dest: &MPlaceTy<'tcx>, + weak_eventfd: WeakFileDescriptionRef, + ecx: &mut MiriInterpCx<'tcx>, +) -> InterpResult<'tcx> { + let Some(eventfd_ref) = weak_eventfd.upgrade() else { + throw_unsup_format!("eventfd FD got closed while blocking.") + }; + + // Since we pass the weak file description ref, it is guaranteed to be + // an eventfd file description. + let eventfd = eventfd_ref.downcast::().unwrap(); + + match eventfd.counter.get().checked_add(num) { + Some(new_count @ 0..=MAX_COUNTER) => { + // Future `read` calls will synchronize with this write, so update the FD clock. + ecx.release_clock(|clock| { + eventfd.clock.borrow_mut().join(clock); + }); + + // When this function is called, the addition is guaranteed to not exceed u64::MAX - 1. + eventfd.counter.set(new_count); + + // When any of the event happened, we check and update the status of all supported event + // types for current file description. + ecx.check_and_update_readiness(&eventfd_ref)?; + + // Unblock *all* threads previously blocked on `read`. + // We need to take out the blocked thread ids and unblock them together, + // because `unblock_threads` may block them again and end up re-adding the + // thread to the blocked list. + let waiting_threads = std::mem::take(&mut *eventfd.blocked_read_tid.borrow_mut()); + // FIXME: We can randomize the order of unblocking. + for thread_id in waiting_threads { + ecx.unblock_thread(thread_id, BlockReason::Eventfd)?; + } + + // Return how many bytes we wrote. + return ecx.write_int(buf_place.layout.size.bytes(), dest); + } + None | Some(u64::MAX) => { + if eventfd.is_nonblock { + return ecx.set_last_error_and_return(ErrorKind::WouldBlock, dest); + } + + let dest = dest.clone(); + + eventfd.blocked_write_tid.borrow_mut().push(ecx.active_thread()); + + ecx.block_thread( + BlockReason::Eventfd, + None, + callback!( + @capture<'tcx> { + num: u64, + buf_place: MPlaceTy<'tcx>, + dest: MPlaceTy<'tcx>, + weak_eventfd: WeakFileDescriptionRef, + } + @unblock = |this| { + eventfd_write(num, buf_place, &dest, weak_eventfd, this) + } + ), + ); + } + }; + interp_ok(()) +} + +/// Block thread if the current counter is 0, +/// else just return the current counter value to the caller and set the counter to 0. +fn eventfd_read<'tcx>( + buf_place: MPlaceTy<'tcx>, + dest: &MPlaceTy<'tcx>, + weak_eventfd: WeakFileDescriptionRef, + ecx: &mut MiriInterpCx<'tcx>, +) -> InterpResult<'tcx> { + let Some(eventfd_ref) = weak_eventfd.upgrade() else { + throw_unsup_format!("eventfd FD got closed while blocking.") + }; + + // Since we pass the weak file description ref to the callback function, it is guaranteed to be + // an eventfd file description. + let eventfd = eventfd_ref.downcast::().unwrap(); + + // Block when counter == 0. + let counter = eventfd.counter.replace(0); + + if counter == 0 { + if eventfd.is_nonblock { + return ecx.set_last_error_and_return(ErrorKind::WouldBlock, dest); + } + let dest = dest.clone(); + + eventfd.blocked_read_tid.borrow_mut().push(ecx.active_thread()); + + ecx.block_thread( + BlockReason::Eventfd, + None, + callback!( + @capture<'tcx> { + buf_place: MPlaceTy<'tcx>, + dest: MPlaceTy<'tcx>, + weak_eventfd: WeakFileDescriptionRef, + } + @unblock = |this| { + eventfd_read(buf_place, &dest, weak_eventfd, this) + } + ), + ); + } else { + // Synchronize with all prior `write` calls to this FD. + ecx.acquire_clock(&eventfd.clock.borrow()); + + // Give old counter value to userspace, and set counter value to 0. + ecx.write_int(counter, &buf_place)?; + + // When any of the events happened, we check and update the status of all supported event + // types for current file description. + ecx.check_and_update_readiness(&eventfd_ref)?; + + // Unblock *all* threads previously blocked on `write`. + // We need to take out the blocked thread ids and unblock them together, + // because `unblock_threads` may block them again and end up re-adding the + // thread to the blocked list. + let waiting_threads = std::mem::take(&mut *eventfd.blocked_write_tid.borrow_mut()); + // FIXME: We can randomize the order of unblocking. + for thread_id in waiting_threads { + ecx.unblock_thread(thread_id, BlockReason::Eventfd)?; + } + + // Tell userspace how many bytes we read. + return ecx.write_int(buf_place.layout.size.bytes(), dest); + } + interp_ok(()) +} diff --git a/src/tools/miri/src/shims/unix/linux/sync.rs b/src/tools/miri/src/shims/unix/linux/sync.rs index 01b011d35046e..51124fb2a003b 100644 --- a/src/tools/miri/src/shims/unix/linux/sync.rs +++ b/src/tools/miri/src/shims/unix/linux/sync.rs @@ -9,7 +9,7 @@ struct LinuxFutex { /// Implementation of the SYS_futex syscall. /// `args` is the arguments *including* the syscall number. pub fn futex<'tcx>( - this: &mut MiriInterpCx<'tcx>, + ecx: &mut MiriInterpCx<'tcx>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { @@ -26,19 +26,19 @@ pub fn futex<'tcx>( // The first three arguments (after the syscall number itself) are the same to all futex operations: // (int *addr, int op, int val). // We checked above that these definitely exist. - let addr = this.read_pointer(addr)?; - let op = this.read_scalar(op)?.to_i32()?; - let val = this.read_scalar(val)?.to_i32()?; + let addr = ecx.read_pointer(addr)?; + let op = ecx.read_scalar(op)?.to_i32()?; + let val = ecx.read_scalar(val)?.to_i32()?; // This is a vararg function so we have to bring our own type for this pointer. - let addr = this.ptr_to_mplace(addr, this.machine.layouts.i32); + let addr = ecx.ptr_to_mplace(addr, ecx.machine.layouts.i32); - let futex_private = this.eval_libc_i32("FUTEX_PRIVATE_FLAG"); - let futex_wait = this.eval_libc_i32("FUTEX_WAIT"); - let futex_wait_bitset = this.eval_libc_i32("FUTEX_WAIT_BITSET"); - let futex_wake = this.eval_libc_i32("FUTEX_WAKE"); - let futex_wake_bitset = this.eval_libc_i32("FUTEX_WAKE_BITSET"); - let futex_realtime = this.eval_libc_i32("FUTEX_CLOCK_REALTIME"); + let futex_private = ecx.eval_libc_i32("FUTEX_PRIVATE_FLAG"); + let futex_wait = ecx.eval_libc_i32("FUTEX_WAIT"); + let futex_wait_bitset = ecx.eval_libc_i32("FUTEX_WAIT_BITSET"); + let futex_wake = ecx.eval_libc_i32("FUTEX_WAKE"); + let futex_wake_bitset = ecx.eval_libc_i32("FUTEX_WAKE_BITSET"); + let futex_realtime = ecx.eval_libc_i32("FUTEX_CLOCK_REALTIME"); // FUTEX_PRIVATE enables an optimization that stops it from working across processes. // Miri doesn't support that anyway, so we ignore that flag. @@ -57,9 +57,9 @@ pub fn futex<'tcx>( let (timeout, bitset) = if wait_bitset { let [_, _, _, _, timeout, uaddr2, bitset] = check_min_arg_count("`syscall(SYS_futex, FUTEX_WAIT_BITSET, ...)`", args)?; - let _timeout = this.read_pointer(timeout)?; - let _uaddr2 = this.read_pointer(uaddr2)?; - (timeout, this.read_scalar(bitset)?.to_u32()?) + let _timeout = ecx.read_pointer(timeout)?; + let _uaddr2 = ecx.read_pointer(uaddr2)?; + (timeout, ecx.read_scalar(bitset)?.to_u32()?) } else { let [_, _, _, _, timeout] = check_min_arg_count("`syscall(SYS_futex, FUTEX_WAIT, ...)`", args)?; @@ -67,21 +67,21 @@ pub fn futex<'tcx>( }; if bitset == 0 { - return this.set_last_error_and_return(LibcError("EINVAL"), dest); + return ecx.set_last_error_and_return(LibcError("EINVAL"), dest); } - let timeout = this.deref_pointer_as(timeout, this.libc_ty_layout("timespec"))?; - let timeout = if this.ptr_is_null(timeout.ptr())? { + let timeout = ecx.deref_pointer_as(timeout, ecx.libc_ty_layout("timespec"))?; + let timeout = if ecx.ptr_is_null(timeout.ptr())? { None } else { - let duration = match this.read_timespec(&timeout)? { + let duration = match ecx.read_timespec(&timeout)? { Some(duration) => duration, None => { - return this.set_last_error_and_return(LibcError("EINVAL"), dest); + return ecx.set_last_error_and_return(LibcError("EINVAL"), dest); } }; let timeout_clock = if op & futex_realtime == futex_realtime { - this.check_no_isolation( + ecx.check_no_isolation( "`futex` syscall with `op=FUTEX_WAIT` and non-null timeout with `FUTEX_CLOCK_REALTIME`", )?; TimeoutClock::RealTime @@ -139,36 +139,36 @@ pub fn futex<'tcx>( // // Thankfully, preemptions cannot happen inside a Miri shim, so we do not need to // do anything special to guarantee fence-load-comparison atomicity. - this.atomic_fence(AtomicFenceOrd::SeqCst)?; + ecx.atomic_fence(AtomicFenceOrd::SeqCst)?; // Read an `i32` through the pointer, regardless of any wrapper types. // It's not uncommon for `addr` to be passed as another type than `*mut i32`, such as `*const AtomicI32`. // We do an acquire read -- it only seems reasonable that if we observe a value here, we // actually establish an ordering with that value. - let futex_val = this.read_scalar_atomic(&addr, AtomicReadOrd::Acquire)?.to_i32()?; + let futex_val = ecx.read_scalar_atomic(&addr, AtomicReadOrd::Acquire)?.to_i32()?; if val == futex_val { // The value still matches, so we block the thread and make it wait for FUTEX_WAKE. // This cannot fail since we already did an atomic acquire read on that pointer. // Acquire reads are only allowed on mutable memory. - let futex_ref = this + let futex_ref = ecx .get_sync_or_init(addr.ptr(), |_| LinuxFutex { futex: Default::default() }) .unwrap() .futex .clone(); - this.futex_wait( + ecx.futex_wait( futex_ref, bitset, timeout, - Scalar::from_target_isize(0, this), // retval_succ - Scalar::from_target_isize(-1, this), // retval_timeout + Scalar::from_target_isize(0, ecx), // retval_succ + Scalar::from_target_isize(-1, ecx), // retval_timeout dest.clone(), LibcError("ETIMEDOUT"), // errno_timeout ); } else { // The futex value doesn't match the expected value, so we return failure // right away without sleeping: -1 and errno set to EAGAIN. - return this.set_last_error_and_return(LibcError("EAGAIN"), dest); + return ecx.set_last_error_and_return(LibcError("EAGAIN"), dest); } } // FUTEX_WAKE: (int *addr, int op = FUTEX_WAKE, int val) @@ -179,42 +179,42 @@ pub fn futex<'tcx>( // Same as FUTEX_WAKE, but allows you to specify a bitset to select which threads to wake up. op if op == futex_wake || op == futex_wake_bitset => { let Some(futex_ref) = - this.get_sync_or_init(addr.ptr(), |_| LinuxFutex { futex: Default::default() }) + ecx.get_sync_or_init(addr.ptr(), |_| LinuxFutex { futex: Default::default() }) else { // No AllocId, or no live allocation at that AllocId. // Return an error code. (That seems nicer than silently doing something non-intuitive.) // This means that if an address gets reused by a new allocation, // we'll use an independent futex queue for this... that seems acceptable. - return this.set_last_error_and_return(LibcError("EFAULT"), dest); + return ecx.set_last_error_and_return(LibcError("EFAULT"), dest); }; let futex_ref = futex_ref.futex.clone(); let bitset = if op == futex_wake_bitset { let [_, _, _, _, timeout, uaddr2, bitset] = check_min_arg_count("`syscall(SYS_futex, FUTEX_WAKE_BITSET, ...)`", args)?; - let _timeout = this.read_pointer(timeout)?; - let _uaddr2 = this.read_pointer(uaddr2)?; - this.read_scalar(bitset)?.to_u32()? + let _timeout = ecx.read_pointer(timeout)?; + let _uaddr2 = ecx.read_pointer(uaddr2)?; + ecx.read_scalar(bitset)?.to_u32()? } else { u32::MAX }; if bitset == 0 { - return this.set_last_error_and_return(LibcError("EINVAL"), dest); + return ecx.set_last_error_and_return(LibcError("EINVAL"), dest); } // Together with the SeqCst fence in futex_wait, this makes sure that futex_wait // will see the latest value on addr which could be changed by our caller // before doing the syscall. - this.atomic_fence(AtomicFenceOrd::SeqCst)?; + ecx.atomic_fence(AtomicFenceOrd::SeqCst)?; let mut n = 0; #[expect(clippy::arithmetic_side_effects)] for _ in 0..val { - if this.futex_wake(&futex_ref, bitset)? { + if ecx.futex_wake(&futex_ref, bitset)? { n += 1; } else { break; } } - this.write_scalar(Scalar::from_target_isize(n, this), dest)?; + ecx.write_scalar(Scalar::from_target_isize(n, ecx), dest)?; } op => throw_unsup_format!("Miri does not support `futex` syscall with op={}", op), } diff --git a/src/tools/miri/src/shims/unix/linux/syscall.rs b/src/tools/miri/src/shims/unix/linux/syscall.rs index 0d7032adab43e..9f6935f096be4 100644 --- a/src/tools/miri/src/shims/unix/linux/syscall.rs +++ b/src/tools/miri/src/shims/unix/linux/syscall.rs @@ -7,7 +7,7 @@ use crate::shims::unix::linux::sync::futex; use crate::*; pub fn syscall<'tcx>( - this: &mut MiriInterpCx<'tcx>, + ecx: &mut MiriInterpCx<'tcx>, link_name: Symbol, abi: ExternAbi, args: &[OpTy<'tcx>], @@ -15,18 +15,18 @@ pub fn syscall<'tcx>( ) -> InterpResult<'tcx> { // We do not use `check_shim` here because `syscall` is variadic. The argument // count is checked bellow. - this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; + ecx.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; // The syscall variadic function is legal to call with more arguments than needed, // extra arguments are simply ignored. The important check is that when we use an // argument, we have to also check all arguments *before* it to ensure that they // have the right type. - let sys_getrandom = this.eval_libc("SYS_getrandom").to_target_usize(this)?; - let sys_futex = this.eval_libc("SYS_futex").to_target_usize(this)?; - let sys_eventfd2 = this.eval_libc("SYS_eventfd2").to_target_usize(this)?; + let sys_getrandom = ecx.eval_libc("SYS_getrandom").to_target_usize(ecx)?; + let sys_futex = ecx.eval_libc("SYS_futex").to_target_usize(ecx)?; + let sys_eventfd2 = ecx.eval_libc("SYS_eventfd2").to_target_usize(ecx)?; let [op] = check_min_arg_count("syscall", args)?; - match this.read_target_usize(op)? { + match ecx.read_target_usize(op)? { // `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)` // is called if a `HashMap` is created the regular way (e.g. HashMap). num if num == sys_getrandom => { @@ -34,25 +34,25 @@ pub fn syscall<'tcx>( // The first argument is the syscall id, so skip over it. let [_, ptr, len, flags] = check_min_arg_count("syscall(SYS_getrandom, ...)", args)?; - let ptr = this.read_pointer(ptr)?; - let len = this.read_target_usize(len)?; + let ptr = ecx.read_pointer(ptr)?; + let len = ecx.read_target_usize(len)?; // The only supported flags are GRND_RANDOM and GRND_NONBLOCK, // neither of which have any effect on our current PRNG. // See for a discussion of argument sizes. - let _flags = this.read_scalar(flags)?.to_i32()?; + let _flags = ecx.read_scalar(flags)?.to_i32()?; - this.gen_random(ptr, len)?; - this.write_scalar(Scalar::from_target_usize(len, this), dest)?; + ecx.gen_random(ptr, len)?; + ecx.write_scalar(Scalar::from_target_usize(len, ecx), dest)?; } // `futex` is used by some synchronization primitives. num if num == sys_futex => { - futex(this, args, dest)?; + futex(ecx, args, dest)?; } num if num == sys_eventfd2 => { let [_, initval, flags] = check_min_arg_count("syscall(SYS_evetfd2, ...)", args)?; - let result = this.eventfd(initval, flags)?; - this.write_int(result.to_i32()?, dest)?; + let result = ecx.eventfd(initval, flags)?; + ecx.write_int(result.to_i32()?, dest)?; } num => { throw_unsup_format!("syscall: unsupported syscall number {num}"); diff --git a/src/tools/miri/src/shims/unix/macos/sync.rs b/src/tools/miri/src/shims/unix/macos/sync.rs index ffc8c2227380d..f66a57ae7061c 100644 --- a/src/tools/miri/src/shims/unix/macos/sync.rs +++ b/src/tools/miri/src/shims/unix/macos/sync.rs @@ -14,18 +14,21 @@ use rustc_abi::Size; use crate::*; -#[derive(Copy, Clone)] +#[derive(Clone)] enum MacOsUnfairLock { Poisoned, - Active { id: MutexId }, + Active { mutex_ref: MutexRef }, } impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { - fn os_unfair_lock_get_data( - &mut self, + fn os_unfair_lock_get_data<'a>( + &'a mut self, lock_ptr: &OpTy<'tcx>, - ) -> InterpResult<'tcx, MacOsUnfairLock> { + ) -> InterpResult<'tcx, &'a MacOsUnfairLock> + where + 'tcx: 'a, + { let this = self.eval_context_mut(); let lock = this.deref_pointer(lock_ptr)?; this.lazy_sync_get_data( @@ -42,8 +45,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(MacOsUnfairLock::Poisoned) }, |ecx| { - let id = ecx.machine.sync.mutex_create(); - interp_ok(MacOsUnfairLock::Active { id }) + let mutex_ref = ecx.machine.sync.mutex_create(); + interp_ok(MacOsUnfairLock::Active { mutex_ref }) }, ) } @@ -54,7 +57,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn os_unfair_lock_lock(&mut self, lock_op: &OpTy<'tcx>) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let MacOsUnfairLock::Active { id } = this.os_unfair_lock_get_data(lock_op)? else { + let MacOsUnfairLock::Active { mutex_ref } = this.os_unfair_lock_get_data(lock_op)? else { // Trying to get a poisoned lock. Just block forever... this.block_thread( BlockReason::Sleep, @@ -68,18 +71,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); return interp_ok(()); }; + let mutex_ref = mutex_ref.clone(); - if this.mutex_is_locked(id) { - if this.mutex_get_owner(id) == this.active_thread() { + if this.mutex_is_locked(&mutex_ref) { + if this.mutex_get_owner(&mutex_ref) == this.active_thread() { // Matching the current macOS implementation: abort on reentrant locking. throw_machine_stop!(TerminationInfo::Abort( "attempted to lock an os_unfair_lock that is already locked by the current thread".to_owned() )); } - this.mutex_enqueue_and_block(id, None); + this.mutex_enqueue_and_block(&mutex_ref, None); } else { - this.mutex_lock(id); + this.mutex_lock(&mutex_ref); } interp_ok(()) @@ -92,18 +96,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let MacOsUnfairLock::Active { id } = this.os_unfair_lock_get_data(lock_op)? else { + let MacOsUnfairLock::Active { mutex_ref } = this.os_unfair_lock_get_data(lock_op)? else { // Trying to get a poisoned lock. That never works. this.write_scalar(Scalar::from_bool(false), dest)?; return interp_ok(()); }; + let mutex_ref = mutex_ref.clone(); - if this.mutex_is_locked(id) { + if this.mutex_is_locked(&mutex_ref) { // Contrary to the blocking lock function, this does not check for // reentrancy. this.write_scalar(Scalar::from_bool(false), dest)?; } else { - this.mutex_lock(id); + this.mutex_lock(&mutex_ref); this.write_scalar(Scalar::from_bool(true), dest)?; } @@ -113,15 +118,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn os_unfair_lock_unlock(&mut self, lock_op: &OpTy<'tcx>) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let MacOsUnfairLock::Active { id } = this.os_unfair_lock_get_data(lock_op)? else { + let MacOsUnfairLock::Active { mutex_ref } = this.os_unfair_lock_get_data(lock_op)? else { // The lock is poisoned, who knows who owns it... we'll pretend: someone else. throw_machine_stop!(TerminationInfo::Abort( "attempted to unlock an os_unfair_lock not owned by the current thread".to_owned() )); }; + let mutex_ref = mutex_ref.clone(); // Now, unlock. - if this.mutex_unlock(id)?.is_none() { + if this.mutex_unlock(&mutex_ref)?.is_none() { // Matching the current macOS implementation: abort. throw_machine_stop!(TerminationInfo::Abort( "attempted to unlock an os_unfair_lock not owned by the current thread".to_owned() @@ -130,7 +136,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // If the lock is not locked by anyone now, it went quer. // Reset to zero so that it can be moved and initialized again for the next phase. - if !this.mutex_is_locked(id) { + if !this.mutex_is_locked(&mutex_ref) { let lock_place = this.deref_pointer_as(lock_op, this.machine.layouts.u32)?; this.write_scalar_atomic(Scalar::from_u32(0), &lock_place, AtomicWriteOrd::Relaxed)?; } @@ -141,13 +147,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn os_unfair_lock_assert_owner(&mut self, lock_op: &OpTy<'tcx>) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let MacOsUnfairLock::Active { id } = this.os_unfair_lock_get_data(lock_op)? else { + let MacOsUnfairLock::Active { mutex_ref } = this.os_unfair_lock_get_data(lock_op)? else { // The lock is poisoned, who knows who owns it... we'll pretend: someone else. throw_machine_stop!(TerminationInfo::Abort( "called os_unfair_lock_assert_owner on an os_unfair_lock not owned by the current thread".to_owned() )); }; - if !this.mutex_is_locked(id) || this.mutex_get_owner(id) != this.active_thread() { + let mutex_ref = mutex_ref.clone(); + + if !this.mutex_is_locked(&mutex_ref) + || this.mutex_get_owner(&mutex_ref) != this.active_thread() + { throw_machine_stop!(TerminationInfo::Abort( "called os_unfair_lock_assert_owner on an os_unfair_lock not owned by the current thread".to_owned() )); @@ -161,11 +171,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn os_unfair_lock_assert_not_owner(&mut self, lock_op: &OpTy<'tcx>) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let MacOsUnfairLock::Active { id } = this.os_unfair_lock_get_data(lock_op)? else { + let MacOsUnfairLock::Active { mutex_ref } = this.os_unfair_lock_get_data(lock_op)? else { // The lock is poisoned, who knows who owns it... we'll pretend: someone else. return interp_ok(()); }; - if this.mutex_is_locked(id) && this.mutex_get_owner(id) == this.active_thread() { + let mutex_ref = mutex_ref.clone(); + + if this.mutex_is_locked(&mutex_ref) + && this.mutex_get_owner(&mutex_ref) == this.active_thread() + { throw_machine_stop!(TerminationInfo::Abort( "called os_unfair_lock_assert_not_owner on an os_unfair_lock owned by the current thread".to_owned() )); @@ -173,7 +187,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // If the lock is not locked by anyone now, it went quer. // Reset to zero so that it can be moved and initialized again for the next phase. - if !this.mutex_is_locked(id) { + if !this.mutex_is_locked(&mutex_ref) { let lock_place = this.deref_pointer_as(lock_op, this.machine.layouts.u32)?; this.write_scalar_atomic(Scalar::from_u32(0), &lock_place, AtomicWriteOrd::Relaxed)?; } diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index 850626d89ac15..416cf020dcc99 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -116,9 +116,9 @@ enum MutexKind { ErrorCheck, } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone)] struct PthreadMutex { - id: MutexId, + mutex_ref: MutexRef, kind: MutexKind, } @@ -175,19 +175,20 @@ fn mutex_create<'tcx>( ) -> InterpResult<'tcx, PthreadMutex> { let mutex = ecx.deref_pointer(mutex_ptr)?; let id = ecx.machine.sync.mutex_create(); - let data = PthreadMutex { id, kind }; - ecx.lazy_sync_init(&mutex, mutex_init_offset(ecx)?, data)?; + let data = PthreadMutex { mutex_ref: id, kind }; + ecx.lazy_sync_init(&mutex, mutex_init_offset(ecx)?, data.clone())?; interp_ok(data) } -/// Returns the `MutexId` of the mutex stored at `mutex_op`. -/// -/// `mutex_get_id` will also check if the mutex has been moved since its first use and -/// return an error if it has. +/// Returns the mutex data stored at the address that `mutex_ptr` points to. +/// Will raise an error if the mutex has been moved since its first use. fn mutex_get_data<'tcx, 'a>( ecx: &'a mut MiriInterpCx<'tcx>, mutex_ptr: &OpTy<'tcx>, -) -> InterpResult<'tcx, PthreadMutex> { +) -> InterpResult<'tcx, &'a PthreadMutex> +where + 'tcx: 'a, +{ let mutex = ecx.deref_pointer(mutex_ptr)?; ecx.lazy_sync_get_data( &mutex, @@ -196,7 +197,7 @@ fn mutex_get_data<'tcx, 'a>( |ecx| { let kind = mutex_kind_from_static_initializer(ecx, &mutex)?; let id = ecx.machine.sync.mutex_create(); - interp_ok(PthreadMutex { id, kind }) + interp_ok(PthreadMutex { mutex_ref: id, kind }) }, ) } @@ -261,10 +262,13 @@ fn rwlock_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size interp_ok(offset) } -fn rwlock_get_data<'tcx>( - ecx: &mut MiriInterpCx<'tcx>, +fn rwlock_get_data<'tcx, 'a>( + ecx: &'a mut MiriInterpCx<'tcx>, rwlock_ptr: &OpTy<'tcx>, -) -> InterpResult<'tcx, PthreadRwLock> { +) -> InterpResult<'tcx, &'a PthreadRwLock> +where + 'tcx: 'a, +{ let rwlock = ecx.deref_pointer(rwlock_ptr)?; ecx.lazy_sync_get_data( &rwlock, @@ -391,10 +395,13 @@ fn cond_create<'tcx>( interp_ok(data) } -fn cond_get_data<'tcx>( - ecx: &mut MiriInterpCx<'tcx>, +fn cond_get_data<'tcx, 'a>( + ecx: &'a mut MiriInterpCx<'tcx>, cond_ptr: &OpTy<'tcx>, -) -> InterpResult<'tcx, PthreadCondvar> { +) -> InterpResult<'tcx, &'a PthreadCondvar> +where + 'tcx: 'a, +{ let cond = ecx.deref_pointer(cond_ptr)?; ecx.lazy_sync_get_data( &cond, @@ -500,12 +507,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let mutex = mutex_get_data(this, mutex_op)?; + let mutex = mutex_get_data(this, mutex_op)?.clone(); - let ret = if this.mutex_is_locked(mutex.id) { - let owner_thread = this.mutex_get_owner(mutex.id); + let ret = if this.mutex_is_locked(&mutex.mutex_ref) { + let owner_thread = this.mutex_get_owner(&mutex.mutex_ref); if owner_thread != this.active_thread() { - this.mutex_enqueue_and_block(mutex.id, Some((Scalar::from_i32(0), dest.clone()))); + this.mutex_enqueue_and_block( + &mutex.mutex_ref, + Some((Scalar::from_i32(0), dest.clone())), + ); return interp_ok(()); } else { // Trying to acquire the same mutex again. @@ -517,14 +527,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { MutexKind::Normal => throw_machine_stop!(TerminationInfo::Deadlock), MutexKind::ErrorCheck => this.eval_libc_i32("EDEADLK"), MutexKind::Recursive => { - this.mutex_lock(mutex.id); + this.mutex_lock(&mutex.mutex_ref); 0 } } } } else { // The mutex is unlocked. Let's lock it. - this.mutex_lock(mutex.id); + this.mutex_lock(&mutex.mutex_ref); 0 }; this.write_scalar(Scalar::from_i32(ret), dest)?; @@ -534,10 +544,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn pthread_mutex_trylock(&mut self, mutex_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - let mutex = mutex_get_data(this, mutex_op)?; + let mutex = mutex_get_data(this, mutex_op)?.clone(); - interp_ok(Scalar::from_i32(if this.mutex_is_locked(mutex.id) { - let owner_thread = this.mutex_get_owner(mutex.id); + interp_ok(Scalar::from_i32(if this.mutex_is_locked(&mutex.mutex_ref) { + let owner_thread = this.mutex_get_owner(&mutex.mutex_ref); if owner_thread != this.active_thread() { this.eval_libc_i32("EBUSY") } else { @@ -545,14 +555,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { MutexKind::Default | MutexKind::Normal | MutexKind::ErrorCheck => this.eval_libc_i32("EBUSY"), MutexKind::Recursive => { - this.mutex_lock(mutex.id); + this.mutex_lock(&mutex.mutex_ref); 0 } } } } else { // The mutex is unlocked. Let's lock it. - this.mutex_lock(mutex.id); + this.mutex_lock(&mutex.mutex_ref); 0 })) } @@ -560,9 +570,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn pthread_mutex_unlock(&mut self, mutex_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - let mutex = mutex_get_data(this, mutex_op)?; + let mutex = mutex_get_data(this, mutex_op)?.clone(); - if let Some(_old_locked_count) = this.mutex_unlock(mutex.id)? { + if let Some(_old_locked_count) = this.mutex_unlock(&mutex.mutex_ref)? { // The mutex was locked by the current thread. interp_ok(Scalar::from_i32(0)) } else { @@ -588,10 +598,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); // Reading the field also has the side-effect that we detect double-`destroy` - // since we make the field unint below. - let mutex = mutex_get_data(this, mutex_op)?; + // since we make the field uninit below. + let mutex = mutex_get_data(this, mutex_op)?.clone(); - if this.mutex_is_locked(mutex.id) { + if this.mutex_is_locked(&mutex.mutex_ref) { throw_ub_format!("destroyed a locked mutex"); } @@ -696,7 +706,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); // Reading the field also has the side-effect that we detect double-`destroy` - // since we make the field unint below. + // since we make the field uninit below. let id = rwlock_get_data(this, rwlock_op)?.id; if this.rwlock_is_locked(id) { @@ -821,12 +831,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let data = cond_get_data(this, cond_op)?; - let mutex_id = mutex_get_data(this, mutex_op)?.id; + let data = *cond_get_data(this, cond_op)?; + let mutex_ref = mutex_get_data(this, mutex_op)?.mutex_ref.clone(); this.condvar_wait( data.id, - mutex_id, + mutex_ref, None, // no timeout Scalar::from_i32(0), Scalar::from_i32(0), // retval_timeout -- unused @@ -845,8 +855,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let data = cond_get_data(this, cond_op)?; - let mutex_id = mutex_get_data(this, mutex_op)?.id; + let data = *cond_get_data(this, cond_op)?; + let mutex_ref = mutex_get_data(this, mutex_op)?.mutex_ref.clone(); // Extract the timeout. let duration = match this @@ -869,7 +879,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.condvar_wait( data.id, - mutex_id, + mutex_ref, Some((timeout_clock, TimeoutAnchor::Absolute, duration)), Scalar::from_i32(0), this.eval_libc("ETIMEDOUT"), // retval_timeout @@ -883,7 +893,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); // Reading the field also has the side-effect that we detect double-`destroy` - // since we make the field unint below. + // since we make the field uninit below. let id = cond_get_data(this, cond_op)?.id; if this.condvar_is_awaited(id) { throw_ub_format!("destroying an awaited conditional variable"); diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 504efed3cfd53..a1fad6f9af4b7 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -7,6 +7,7 @@ use rustc_span::Symbol; use self::shims::windows::handle::{Handle, PseudoHandle}; use crate::shims::os_str::bytes_to_os_str; +use crate::shims::windows::handle::HandleError; use crate::shims::windows::*; use crate::*; @@ -381,6 +382,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Return success (`1`). this.write_int(1, dest)?; } + "TlsFree" => { + let [key] = this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let key = u128::from(this.read_scalar(key)?.to_u32()?); + this.machine.tls.delete_tls_key(key)?; + + // Return success (`1`). + this.write_int(1, dest)?; + } // Access to command-line arguments "GetCommandLineW" => { @@ -488,7 +497,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let thread_id = this.CreateThread(security, stacksize, start, arg, flags, thread)?; - this.write_scalar(Handle::Thread(thread_id.to_u32()).to_scalar(this), dest)?; + this.write_scalar(Handle::Thread(thread_id).to_scalar(this), dest)?; } "WaitForSingleObject" => { let [handle, timeout] = @@ -513,10 +522,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let handle = this.read_scalar(handle)?; let name = this.read_wide_str(this.read_pointer(name)?)?; - let thread = match Handle::from_scalar(handle, this)? { - Some(Handle::Thread(thread)) => this.thread_id_try_from(thread), - Some(Handle::Pseudo(PseudoHandle::CurrentThread)) => Ok(this.active_thread()), - _ => this.invalid_handle("SetThreadDescription")?, + let thread = match Handle::try_from_scalar(handle, this)? { + Ok(Handle::Thread(thread)) => Ok(thread), + Ok(Handle::Pseudo(PseudoHandle::CurrentThread)) => Ok(this.active_thread()), + Ok(_) | Err(HandleError::InvalidHandle) => + this.invalid_handle("SetThreadDescription")?, + Err(HandleError::ThreadNotFound(e)) => Err(e), }; let res = match thread { Ok(thread) => { @@ -536,10 +547,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let handle = this.read_scalar(handle)?; let name_ptr = this.deref_pointer(name_ptr)?; // the pointer where we should store the ptr to the name - let thread = match Handle::from_scalar(handle, this)? { - Some(Handle::Thread(thread)) => this.thread_id_try_from(thread), - Some(Handle::Pseudo(PseudoHandle::CurrentThread)) => Ok(this.active_thread()), - _ => this.invalid_handle("GetThreadDescription")?, + let thread = match Handle::try_from_scalar(handle, this)? { + Ok(Handle::Thread(thread)) => Ok(thread), + Ok(Handle::Pseudo(PseudoHandle::CurrentThread)) => Ok(this.active_thread()), + Ok(_) | Err(HandleError::InvalidHandle) => + this.invalid_handle("GetThreadDescription")?, + Err(HandleError::ThreadNotFound(e)) => Err(e), }; let (name, res) = match thread { Ok(thread) => { diff --git a/src/tools/miri/src/shims/windows/handle.rs b/src/tools/miri/src/shims/windows/handle.rs index b40c00efeddf4..3d872b65a6376 100644 --- a/src/tools/miri/src/shims/windows/handle.rs +++ b/src/tools/miri/src/shims/windows/handle.rs @@ -2,6 +2,7 @@ use std::mem::variant_count; use rustc_abi::HasDataLayout; +use crate::concurrency::thread::ThreadNotFound; use crate::*; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -14,7 +15,7 @@ pub enum PseudoHandle { pub enum Handle { Null, Pseudo(PseudoHandle), - Thread(u32), + Thread(ThreadId), } impl PseudoHandle { @@ -34,6 +35,14 @@ impl PseudoHandle { } } +/// Errors that can occur when constructing a [`Handle`] from a Scalar. +pub enum HandleError { + /// There is no thread with the given ID. + ThreadNotFound(ThreadNotFound), + /// Can't convert scalar to handle because it is structurally invalid. + InvalidHandle, +} + impl Handle { const NULL_DISCRIMINANT: u32 = 0; const PSEUDO_DISCRIMINANT: u32 = 1; @@ -51,7 +60,7 @@ impl Handle { match self { Self::Null => 0, Self::Pseudo(pseudo_handle) => pseudo_handle.value(), - Self::Thread(thread) => thread, + Self::Thread(thread) => thread.to_u32(), } } @@ -95,7 +104,7 @@ impl Handle { match discriminant { Self::NULL_DISCRIMINANT if data == 0 => Some(Self::Null), Self::PSEUDO_DISCRIMINANT => Some(Self::Pseudo(PseudoHandle::from_value(data)?)), - Self::THREAD_DISCRIMINANT => Some(Self::Thread(data)), + Self::THREAD_DISCRIMINANT => Some(Self::Thread(ThreadId::new_unchecked(data))), _ => None, } } @@ -126,10 +135,14 @@ impl Handle { Scalar::from_target_isize(signed_handle.into(), cx) } - pub fn from_scalar<'tcx>( + /// Convert a scalar into a structured `Handle`. + /// Structurally invalid handles return [`HandleError::InvalidHandle`]. + /// If the handle is structurally valid but semantically invalid, e.g. a for non-existent thread + /// ID, returns [`HandleError::ThreadNotFound`]. + pub fn try_from_scalar<'tcx>( handle: Scalar, - cx: &impl HasDataLayout, - ) -> InterpResult<'tcx, Option> { + cx: &MiriInterpCx<'tcx>, + ) -> InterpResult<'tcx, Result> { let sign_extended_handle = handle.to_target_isize(cx)?; #[expect(clippy::cast_sign_loss)] // we want to lose the sign @@ -137,10 +150,20 @@ impl Handle { signed_handle as u32 } else { // if a handle doesn't fit in an i32, it isn't valid. - return interp_ok(None); + return interp_ok(Err(HandleError::InvalidHandle)); }; - interp_ok(Self::from_packed(handle)) + match Self::from_packed(handle) { + Some(Self::Thread(thread)) => { + // validate the thread id + match cx.machine.threads.thread_id_try_from(thread.to_u32()) { + Ok(id) => interp_ok(Ok(Self::Thread(id))), + Err(e) => interp_ok(Err(HandleError::ThreadNotFound(e))), + } + } + Some(handle) => interp_ok(Ok(handle)), + None => interp_ok(Err(HandleError::InvalidHandle)), + } } } @@ -158,14 +181,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); let handle = this.read_scalar(handle_op)?; - let ret = match Handle::from_scalar(handle, this)? { - Some(Handle::Thread(thread)) => { - if let Ok(thread) = this.thread_id_try_from(thread) { - this.detach_thread(thread, /*allow_terminated_joined*/ true)?; - this.eval_windows("c", "TRUE") - } else { - this.invalid_handle("CloseHandle")? - } + let ret = match Handle::try_from_scalar(handle, this)? { + Ok(Handle::Thread(thread)) => { + this.detach_thread(thread, /*allow_terminated_joined*/ true)?; + this.eval_windows("c", "TRUE") } _ => this.invalid_handle("CloseHandle")?, }; diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index b03dedea146c4..a394e0430bcd0 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -20,10 +20,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Windows sync primitives are pointer sized. // We only use the first 4 bytes for the id. - fn init_once_get_data( - &mut self, + fn init_once_get_data<'a>( + &'a mut self, init_once_ptr: &OpTy<'tcx>, - ) -> InterpResult<'tcx, WindowsInitOnce> { + ) -> InterpResult<'tcx, &'a WindowsInitOnce> + where + 'tcx: 'a, + { let this = self.eval_context_mut(); let init_once = this.deref_pointer(init_once_ptr)?; diff --git a/src/tools/miri/src/shims/windows/thread.rs b/src/tools/miri/src/shims/windows/thread.rs index 7af15fc647ce3..efc1c2286bcbc 100644 --- a/src/tools/miri/src/shims/windows/thread.rs +++ b/src/tools/miri/src/shims/windows/thread.rs @@ -65,15 +65,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let handle = this.read_scalar(handle_op)?; let timeout = this.read_scalar(timeout_op)?.to_u32()?; - let thread = match Handle::from_scalar(handle, this)? { - Some(Handle::Thread(thread)) => - match this.thread_id_try_from(thread) { - Ok(thread) => thread, - Err(_) => this.invalid_handle("WaitForSingleObject")?, - }, + let thread = match Handle::try_from_scalar(handle, this)? { + Ok(Handle::Thread(thread)) => thread, // Unlike on posix, the outcome of joining the current thread is not documented. // On current Windows, it just deadlocks. - Some(Handle::Pseudo(PseudoHandle::CurrentThread)) => this.active_thread(), + Ok(Handle::Pseudo(PseudoHandle::CurrentThread)) => this.active_thread(), _ => this.invalid_handle("WaitForSingleObject")?, }; diff --git a/src/tools/miri/src/shims/x86/aesni.rs b/src/tools/miri/src/shims/x86/aesni.rs index 33b1f27713ca9..4c6c1cefeb1df 100644 --- a/src/tools/miri/src/shims/x86/aesni.rs +++ b/src/tools/miri/src/shims/x86/aesni.rs @@ -132,7 +132,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Performs an AES round (given by `f`) on each 128-bit word of // `state` with the corresponding 128-bit key of `key`. fn aes_round<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, state: &OpTy<'tcx>, key: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, @@ -145,21 +145,20 @@ fn aes_round<'tcx>( assert_eq!(dest.layout.size.bytes() % 16, 0); let len = dest.layout.size.bytes() / 16; - let u128_array_layout = - this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u128, len))?; + let u128_array_layout = ecx.layout_of(Ty::new_array(ecx.tcx.tcx, ecx.tcx.types.u128, len))?; - let state = state.transmute(u128_array_layout, this)?; - let key = key.transmute(u128_array_layout, this)?; - let dest = dest.transmute(u128_array_layout, this)?; + let state = state.transmute(u128_array_layout, ecx)?; + let key = key.transmute(u128_array_layout, ecx)?; + let dest = dest.transmute(u128_array_layout, ecx)?; for i in 0..len { - let state = this.read_scalar(&this.project_index(&state, i)?)?.to_u128()?; - let key = this.read_scalar(&this.project_index(&key, i)?)?.to_u128()?; - let dest = this.project_index(&dest, i)?; + let state = ecx.read_scalar(&ecx.project_index(&state, i)?)?.to_u128()?; + let key = ecx.read_scalar(&ecx.project_index(&key, i)?)?.to_u128()?; + let dest = ecx.project_index(&dest, i)?; let res = f(state, key); - this.write_scalar(Scalar::from_u128(res), &dest)?; + ecx.write_scalar(Scalar::from_u128(res), &dest)?; } interp_ok(()) diff --git a/src/tools/miri/src/shims/x86/gfni.rs b/src/tools/miri/src/shims/x86/gfni.rs index 7b92d422cc535..92010345f55dd 100644 --- a/src/tools/miri/src/shims/x86/gfni.rs +++ b/src/tools/miri/src/shims/x86/gfni.rs @@ -75,21 +75,21 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// If `inverse` is set, then the inverse transformation with respect to the reduction polynomial /// x^8 + x^4 + x^3 + x + 1 is performed instead. fn affine_transform<'tcx>( - this: &mut MiriInterpCx<'tcx>, + ecx: &mut MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, imm8: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, inverse: bool, ) -> InterpResult<'tcx, ()> { - let (left, left_len) = this.project_to_simd(left)?; - let (right, right_len) = this.project_to_simd(right)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (left, left_len) = ecx.project_to_simd(left)?; + let (right, right_len) = ecx.project_to_simd(right)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; assert_eq!(dest_len, right_len); assert_eq!(dest_len, left_len); - let imm8 = this.read_scalar(imm8)?.to_u8()?; + let imm8 = ecx.read_scalar(imm8)?.to_u8()?; // Each 8x8 bit matrix gets multiplied with eight bit vectors. // Therefore, the iteration is done in chunks of eight. @@ -98,13 +98,13 @@ fn affine_transform<'tcx>( let mut matrix = [0u8; 8]; for j in 0..8 { matrix[usize::try_from(j).unwrap()] = - this.read_scalar(&this.project_index(&right, i.wrapping_add(j))?)?.to_u8()?; + ecx.read_scalar(&ecx.project_index(&right, i.wrapping_add(j))?)?.to_u8()?; } // Multiply the matrix with the vector and perform the addition. for j in 0..8 { let index = i.wrapping_add(j); - let left = this.read_scalar(&this.project_index(&left, index)?)?.to_u8()?; + let left = ecx.read_scalar(&ecx.project_index(&left, index)?)?.to_u8()?; let left = if inverse { TABLE[usize::from(left)] } else { left }; let mut res = 0; @@ -124,8 +124,8 @@ fn affine_transform<'tcx>( // Perform the addition. res ^= imm8; - let dest = this.project_index(&dest, index)?; - this.write_scalar(Scalar::from_u8(res), &dest)?; + let dest = ecx.project_index(&dest, index)?; + ecx.write_scalar(Scalar::from_u8(res), &dest)?; } } diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 433e9e966f2a2..3e02a4b363769 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -1,4 +1,3 @@ -use rand::Rng as _; use rustc_abi::{ExternAbi, Size}; use rustc_apfloat::Float; use rustc_apfloat::ieee::Single; @@ -226,7 +225,7 @@ impl FloatBinOp { /// Convert from the `imm` argument used to specify the comparison /// operation in intrinsics such as `llvm.x86.sse.cmp.ss`. fn cmp_from_imm<'tcx>( - this: &crate::MiriInterpCx<'tcx>, + ecx: &crate::MiriInterpCx<'tcx>, imm: i8, intrinsic: Symbol, ) -> InterpResult<'tcx, Self> { @@ -260,7 +259,7 @@ impl FloatBinOp { }; // When bit 3 is 1 (only possible in AVX), unord is toggled. if imm & 0b1000 != 0 { - this.expect_target_feature_for_intrinsic(intrinsic, "avx")?; + ecx.expect_target_feature_for_intrinsic(intrinsic, "avx")?; unord = !unord; } interp_ok(Self::Cmp { gt, lt, eq, unord }) @@ -327,28 +326,28 @@ fn bin_op_float<'tcx, F: rustc_apfloat::Float>( /// Performs `which` operation on the first component of `left` and `right` /// and copies the other components from `left`. The result is stored in `dest`. fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, which: FloatBinOp, left: &OpTy<'tcx>, right: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (left, left_len) = this.project_to_simd(left)?; - let (right, right_len) = this.project_to_simd(right)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (left, left_len) = ecx.project_to_simd(left)?; + let (right, right_len) = ecx.project_to_simd(right)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; assert_eq!(dest_len, left_len); assert_eq!(dest_len, right_len); let res0 = bin_op_float::( which, - &this.read_immediate(&this.project_index(&left, 0)?)?, - &this.read_immediate(&this.project_index(&right, 0)?)?, + &ecx.read_immediate(&ecx.project_index(&left, 0)?)?, + &ecx.read_immediate(&ecx.project_index(&right, 0)?)?, )?; - this.write_scalar(res0, &this.project_index(&dest, 0)?)?; + ecx.write_scalar(res0, &ecx.project_index(&dest, 0)?)?; for i in 1..dest_len { - this.copy_op(&this.project_index(&left, i)?, &this.project_index(&dest, i)?)?; + ecx.copy_op(&ecx.project_index(&left, i)?, &ecx.project_index(&dest, i)?)?; } interp_ok(()) @@ -357,26 +356,26 @@ fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>( /// Performs `which` operation on each component of `left` and /// `right`, storing the result is stored in `dest`. fn bin_op_simd_float_all<'tcx, F: rustc_apfloat::Float>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, which: FloatBinOp, left: &OpTy<'tcx>, right: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (left, left_len) = this.project_to_simd(left)?; - let (right, right_len) = this.project_to_simd(right)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (left, left_len) = ecx.project_to_simd(left)?; + let (right, right_len) = ecx.project_to_simd(right)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; assert_eq!(dest_len, left_len); assert_eq!(dest_len, right_len); for i in 0..dest_len { - let left = this.read_immediate(&this.project_index(&left, i)?)?; - let right = this.read_immediate(&this.project_index(&right, i)?)?; - let dest = this.project_index(&dest, i)?; + let left = ecx.read_immediate(&ecx.project_index(&left, i)?)?; + let right = ecx.read_immediate(&ecx.project_index(&right, i)?)?; + let dest = ecx.project_index(&dest, i)?; let res = bin_op_float::(which, &left, &right)?; - this.write_scalar(res, &dest)?; + ecx.write_scalar(res, &dest)?; } interp_ok(()) @@ -398,7 +397,7 @@ enum FloatUnaryOp { /// Performs `which` scalar operation on `op` and returns the result. fn unary_op_f32<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, which: FloatUnaryOp, op: &ImmTy<'tcx>, ) -> InterpResult<'tcx, Scalar> { @@ -408,56 +407,38 @@ fn unary_op_f32<'tcx>( let div = (Single::from_u128(1).value / op).value; // Apply a relative error with a magnitude on the order of 2^-12 to simulate the // inaccuracy of RCP. - let res = apply_random_float_error(this, div, -12); + let res = math::apply_random_float_error(ecx, div, -12); interp_ok(Scalar::from_f32(res)) } FloatUnaryOp::Rsqrt => { - let op = op.to_scalar().to_u32()?; - // FIXME using host floats - let sqrt = Single::from_bits(f32::from_bits(op).sqrt().to_bits().into()); - let rsqrt = (Single::from_u128(1).value / sqrt).value; + let op = op.to_scalar().to_f32()?; + let rsqrt = (Single::from_u128(1).value / math::sqrt(op)).value; // Apply a relative error with a magnitude on the order of 2^-12 to simulate the // inaccuracy of RSQRT. - let res = apply_random_float_error(this, rsqrt, -12); + let res = math::apply_random_float_error(ecx, rsqrt, -12); interp_ok(Scalar::from_f32(res)) } } } -/// Disturbes a floating-point result by a relative error on the order of (-2^scale, 2^scale). -#[expect(clippy::arithmetic_side_effects)] // floating point arithmetic cannot panic -fn apply_random_float_error( - this: &mut crate::MiriInterpCx<'_>, - val: F, - err_scale: i32, -) -> F { - let rng = this.machine.rng.get_mut(); - // generates rand(0, 2^64) * 2^(scale - 64) = rand(0, 1) * 2^scale - let err = F::from_u128(rng.gen::().into()).value.scalbn(err_scale.strict_sub(64)); - // give it a random sign - let err = if rng.gen::() { -err } else { err }; - // multiple the value with (1+err) - (val * (F::from_u128(1).value + err).value).value -} - /// Performs `which` operation on the first component of `op` and copies /// the other components. The result is stored in `dest`. fn unary_op_ss<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, which: FloatUnaryOp, op: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (op, op_len) = this.project_to_simd(op)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (op, op_len) = ecx.project_to_simd(op)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; assert_eq!(dest_len, op_len); - let res0 = unary_op_f32(this, which, &this.read_immediate(&this.project_index(&op, 0)?)?)?; - this.write_scalar(res0, &this.project_index(&dest, 0)?)?; + let res0 = unary_op_f32(ecx, which, &ecx.read_immediate(&ecx.project_index(&op, 0)?)?)?; + ecx.write_scalar(res0, &ecx.project_index(&dest, 0)?)?; for i in 1..dest_len { - this.copy_op(&this.project_index(&op, i)?, &this.project_index(&dest, i)?)?; + ecx.copy_op(&ecx.project_index(&op, i)?, &ecx.project_index(&dest, i)?)?; } interp_ok(()) @@ -466,22 +447,22 @@ fn unary_op_ss<'tcx>( /// Performs `which` operation on each component of `op`, storing the /// result is stored in `dest`. fn unary_op_ps<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, which: FloatUnaryOp, op: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (op, op_len) = this.project_to_simd(op)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (op, op_len) = ecx.project_to_simd(op)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; assert_eq!(dest_len, op_len); for i in 0..dest_len { - let op = this.read_immediate(&this.project_index(&op, i)?)?; - let dest = this.project_index(&dest, i)?; + let op = ecx.read_immediate(&ecx.project_index(&op, i)?)?; + let dest = ecx.project_index(&dest, i)?; - let res = unary_op_f32(this, which, &op)?; - this.write_scalar(res, &dest)?; + let res = unary_op_f32(ecx, which, &op)?; + ecx.write_scalar(res, &dest)?; } interp_ok(()) @@ -503,14 +484,14 @@ enum ShiftOp { /// For arithmetic right-shifts, when right is larger than BITS - 1, the sign /// bit is copied to all bits. fn shift_simd_by_scalar<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, which: ShiftOp, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (left, left_len) = this.project_to_simd(left)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (left, left_len) = ecx.project_to_simd(left)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; assert_eq!(dest_len, left_len); // `right` may have a different length, and we only care about its @@ -520,11 +501,11 @@ fn shift_simd_by_scalar<'tcx>( // by checked_{shl,shr} (u32). // It is ok to saturate the value to u32::MAX because any value // above BITS - 1 will produce the same result. - let shift = u32::try_from(extract_first_u64(this, right)?).unwrap_or(u32::MAX); + let shift = u32::try_from(extract_first_u64(ecx, right)?).unwrap_or(u32::MAX); for i in 0..dest_len { - let left = this.read_scalar(&this.project_index(&left, i)?)?; - let dest = this.project_index(&dest, i)?; + let left = ecx.read_scalar(&ecx.project_index(&left, i)?)?; + let dest = ecx.project_index(&dest, i)?; let res = match which { ShiftOp::Left => { @@ -547,7 +528,7 @@ fn shift_simd_by_scalar<'tcx>( Scalar::from_int(res, dest.layout.size) } }; - this.write_scalar(res, &dest)?; + ecx.write_scalar(res, &dest)?; } interp_ok(()) @@ -559,23 +540,23 @@ fn shift_simd_by_scalar<'tcx>( /// For arithmetic right-shifts, when right is larger than BITS - 1, the sign /// bit is copied to all bits. fn shift_simd_by_simd<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, which: ShiftOp, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (left, left_len) = this.project_to_simd(left)?; - let (right, right_len) = this.project_to_simd(right)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (left, left_len) = ecx.project_to_simd(left)?; + let (right, right_len) = ecx.project_to_simd(right)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; assert_eq!(dest_len, left_len); assert_eq!(dest_len, right_len); for i in 0..dest_len { - let left = this.read_scalar(&this.project_index(&left, i)?)?; - let right = this.read_scalar(&this.project_index(&right, i)?)?; - let dest = this.project_index(&dest, i)?; + let left = ecx.read_scalar(&ecx.project_index(&left, i)?)?; + let right = ecx.read_scalar(&ecx.project_index(&right, i)?)?; + let dest = ecx.project_index(&dest, i)?; // It is ok to saturate the value to u32::MAX because any value // above BITS - 1 will produce the same result. @@ -602,7 +583,7 @@ fn shift_simd_by_simd<'tcx>( Scalar::from_int(res, dest.layout.size) } }; - this.write_scalar(res, &dest)?; + ecx.write_scalar(res, &dest)?; } interp_ok(()) @@ -611,44 +592,44 @@ fn shift_simd_by_simd<'tcx>( /// Takes a 128-bit vector, transmutes it to `[u64; 2]` and extracts /// the first value. fn extract_first_u64<'tcx>( - this: &crate::MiriInterpCx<'tcx>, + ecx: &crate::MiriInterpCx<'tcx>, op: &OpTy<'tcx>, ) -> InterpResult<'tcx, u64> { // Transmute vector to `[u64; 2]` - let array_layout = this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u64, 2))?; - let op = op.transmute(array_layout, this)?; + let array_layout = ecx.layout_of(Ty::new_array(ecx.tcx.tcx, ecx.tcx.types.u64, 2))?; + let op = op.transmute(array_layout, ecx)?; // Get the first u64 from the array - this.read_scalar(&this.project_index(&op, 0)?)?.to_u64() + ecx.read_scalar(&ecx.project_index(&op, 0)?)?.to_u64() } // Rounds the first element of `right` according to `rounding` // and copies the remaining elements from `left`. fn round_first<'tcx, F: rustc_apfloat::Float>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, rounding: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (left, left_len) = this.project_to_simd(left)?; - let (right, right_len) = this.project_to_simd(right)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (left, left_len) = ecx.project_to_simd(left)?; + let (right, right_len) = ecx.project_to_simd(right)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; assert_eq!(dest_len, left_len); assert_eq!(dest_len, right_len); - let rounding = rounding_from_imm(this.read_scalar(rounding)?.to_i32()?)?; + let rounding = rounding_from_imm(ecx.read_scalar(rounding)?.to_i32()?)?; - let op0: F = this.read_scalar(&this.project_index(&right, 0)?)?.to_float()?; + let op0: F = ecx.read_scalar(&ecx.project_index(&right, 0)?)?.to_float()?; let res = op0.round_to_integral(rounding).value; - this.write_scalar( + ecx.write_scalar( Scalar::from_uint(res.to_bits(), Size::from_bits(F::BITS)), - &this.project_index(&dest, 0)?, + &ecx.project_index(&dest, 0)?, )?; for i in 1..dest_len { - this.copy_op(&this.project_index(&left, i)?, &this.project_index(&dest, i)?)?; + ecx.copy_op(&ecx.project_index(&left, i)?, &ecx.project_index(&dest, i)?)?; } interp_ok(()) @@ -656,24 +637,24 @@ fn round_first<'tcx, F: rustc_apfloat::Float>( // Rounds all elements of `op` according to `rounding`. fn round_all<'tcx, F: rustc_apfloat::Float>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, op: &OpTy<'tcx>, rounding: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (op, op_len) = this.project_to_simd(op)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (op, op_len) = ecx.project_to_simd(op)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; assert_eq!(dest_len, op_len); - let rounding = rounding_from_imm(this.read_scalar(rounding)?.to_i32()?)?; + let rounding = rounding_from_imm(ecx.read_scalar(rounding)?.to_i32()?)?; for i in 0..dest_len { - let op: F = this.read_scalar(&this.project_index(&op, i)?)?.to_float()?; + let op: F = ecx.read_scalar(&ecx.project_index(&op, i)?)?.to_float()?; let res = op.round_to_integral(rounding).value; - this.write_scalar( + ecx.write_scalar( Scalar::from_uint(res.to_bits(), Size::from_bits(F::BITS)), - &this.project_index(&dest, i)?, + &ecx.project_index(&dest, i)?, )?; } @@ -708,31 +689,31 @@ fn rounding_from_imm<'tcx>(rounding: i32) -> InterpResult<'tcx, rustc_apfloat::R /// If `op` has more elements than `dest`, extra elements are ignored. If `op` /// has less elements than `dest`, the rest is filled with zeros. fn convert_float_to_int<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, op: &OpTy<'tcx>, rnd: rustc_apfloat::Round, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (op, op_len) = this.project_to_simd(op)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (op, op_len) = ecx.project_to_simd(op)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; // Output must be *signed* integers. - assert!(matches!(dest.layout.field(this, 0).ty.kind(), ty::Int(_))); + assert!(matches!(dest.layout.field(ecx, 0).ty.kind(), ty::Int(_))); for i in 0..op_len.min(dest_len) { - let op = this.read_immediate(&this.project_index(&op, i)?)?; - let dest = this.project_index(&dest, i)?; + let op = ecx.read_immediate(&ecx.project_index(&op, i)?)?; + let dest = ecx.project_index(&dest, i)?; - let res = this.float_to_int_checked(&op, dest.layout, rnd)?.unwrap_or_else(|| { + let res = ecx.float_to_int_checked(&op, dest.layout, rnd)?.unwrap_or_else(|| { // Fallback to minimum according to SSE/AVX semantics. ImmTy::from_int(dest.layout.size.signed_int_min(), dest.layout) }); - this.write_immediate(*res, &dest)?; + ecx.write_immediate(*res, &dest)?; } // Fill remainder with zeros for i in op_len..dest_len { - let dest = this.project_index(&dest, i)?; - this.write_scalar(Scalar::from_int(0, dest.layout.size), &dest)?; + let dest = ecx.project_index(&dest, i)?; + ecx.write_scalar(Scalar::from_int(0, dest.layout.size), &dest)?; } interp_ok(()) @@ -743,26 +724,26 @@ fn convert_float_to_int<'tcx>( /// In case of overflow (when the operand is the minimum value), the operation /// will wrap around. fn int_abs<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, op: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (op, op_len) = this.project_to_simd(op)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (op, op_len) = ecx.project_to_simd(op)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; assert_eq!(op_len, dest_len); - let zero = ImmTy::from_int(0, op.layout.field(this, 0)); + let zero = ImmTy::from_int(0, op.layout.field(ecx, 0)); for i in 0..dest_len { - let op = this.read_immediate(&this.project_index(&op, i)?)?; - let dest = this.project_index(&dest, i)?; + let op = ecx.read_immediate(&ecx.project_index(&op, i)?)?; + let dest = ecx.project_index(&dest, i)?; - let lt_zero = this.binary_op(mir::BinOp::Lt, &op, &zero)?; + let lt_zero = ecx.binary_op(mir::BinOp::Lt, &op, &zero)?; let res = - if lt_zero.to_scalar().to_bool()? { this.unary_op(mir::UnOp::Neg, &op)? } else { op }; + if lt_zero.to_scalar().to_bool()? { ecx.unary_op(mir::UnOp::Neg, &op)? } else { op }; - this.write_immediate(*res, &dest)?; + ecx.write_immediate(*res, &dest)?; } interp_ok(()) @@ -776,25 +757,25 @@ fn int_abs<'tcx>( /// * The third element is the `op` vector split into chunks, i.e, it's /// type is `[[T; M]; N]` where `T` is the element type of `op`. fn split_simd_to_128bit_chunks<'tcx, P: Projectable<'tcx, Provenance>>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, op: &P, ) -> InterpResult<'tcx, (u64, u64, P)> { let simd_layout = op.layout(); - let (simd_len, element_ty) = simd_layout.ty.simd_size_and_type(this.tcx.tcx); + let (simd_len, element_ty) = simd_layout.ty.simd_size_and_type(ecx.tcx.tcx); assert_eq!(simd_layout.size.bits() % 128, 0); let num_chunks = simd_layout.size.bits() / 128; let items_per_chunk = simd_len.strict_div(num_chunks); // Transmute to `[[T; items_per_chunk]; num_chunks]` - let chunked_layout = this + let chunked_layout = ecx .layout_of(Ty::new_array( - this.tcx.tcx, - Ty::new_array(this.tcx.tcx, element_ty, items_per_chunk), + ecx.tcx.tcx, + Ty::new_array(ecx.tcx.tcx, element_ty, items_per_chunk), num_chunks, )) .unwrap(); - let chunked_op = op.transmute(chunked_layout, this)?; + let chunked_op = op.transmute(chunked_layout, ecx)?; interp_ok((num_chunks, items_per_chunk, chunked_op)) } @@ -809,7 +790,7 @@ fn split_simd_to_128bit_chunks<'tcx, P: Projectable<'tcx, Provenance>>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn horizontal_bin_op<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, which: mir::BinOp, saturating: bool, left: &OpTy<'tcx>, @@ -819,15 +800,15 @@ fn horizontal_bin_op<'tcx>( assert_eq!(left.layout, dest.layout); assert_eq!(right.layout, dest.layout); - let (num_chunks, items_per_chunk, left) = split_simd_to_128bit_chunks(this, left)?; - let (_, _, right) = split_simd_to_128bit_chunks(this, right)?; - let (_, _, dest) = split_simd_to_128bit_chunks(this, dest)?; + let (num_chunks, items_per_chunk, left) = split_simd_to_128bit_chunks(ecx, left)?; + let (_, _, right) = split_simd_to_128bit_chunks(ecx, right)?; + let (_, _, dest) = split_simd_to_128bit_chunks(ecx, dest)?; let middle = items_per_chunk / 2; for i in 0..num_chunks { - let left = this.project_index(&left, i)?; - let right = this.project_index(&right, i)?; - let dest = this.project_index(&dest, i)?; + let left = ecx.project_index(&left, i)?; + let right = ecx.project_index(&right, i)?; + let dest = ecx.project_index(&dest, i)?; for j in 0..items_per_chunk { // `j` is the index in `dest` @@ -835,16 +816,16 @@ fn horizontal_bin_op<'tcx>( let (k, src) = if j < middle { (j, &left) } else { (j.strict_sub(middle), &right) }; // `base_i` is the index of the first item of the 2-item chunk in `src` let base_i = k.strict_mul(2); - let lhs = this.read_immediate(&this.project_index(src, base_i)?)?; - let rhs = this.read_immediate(&this.project_index(src, base_i.strict_add(1))?)?; + let lhs = ecx.read_immediate(&ecx.project_index(src, base_i)?)?; + let rhs = ecx.read_immediate(&ecx.project_index(src, base_i.strict_add(1))?)?; let res = if saturating { - Immediate::from(this.saturating_arith(which, &lhs, &rhs)?) + Immediate::from(ecx.saturating_arith(which, &lhs, &rhs)?) } else { - *this.binary_op(which, &lhs, &rhs)? + *ecx.binary_op(which, &lhs, &rhs)? }; - this.write_immediate(res, &this.project_index(&dest, j)?)?; + ecx.write_immediate(res, &ecx.project_index(&dest, j)?)?; } } @@ -860,7 +841,7 @@ fn horizontal_bin_op<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit blocks of `left` and `right`). fn conditional_dot_product<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, imm: &OpTy<'tcx>, @@ -869,20 +850,20 @@ fn conditional_dot_product<'tcx>( assert_eq!(left.layout, dest.layout); assert_eq!(right.layout, dest.layout); - let (num_chunks, items_per_chunk, left) = split_simd_to_128bit_chunks(this, left)?; - let (_, _, right) = split_simd_to_128bit_chunks(this, right)?; - let (_, _, dest) = split_simd_to_128bit_chunks(this, dest)?; + let (num_chunks, items_per_chunk, left) = split_simd_to_128bit_chunks(ecx, left)?; + let (_, _, right) = split_simd_to_128bit_chunks(ecx, right)?; + let (_, _, dest) = split_simd_to_128bit_chunks(ecx, dest)?; - let element_layout = left.layout.field(this, 0).field(this, 0); + let element_layout = left.layout.field(ecx, 0).field(ecx, 0); assert!(items_per_chunk <= 4); // `imm` is a `u8` for SSE4.1 or an `i32` for AVX :/ - let imm = this.read_scalar(imm)?.to_uint(imm.layout.size)?; + let imm = ecx.read_scalar(imm)?.to_uint(imm.layout.size)?; for i in 0..num_chunks { - let left = this.project_index(&left, i)?; - let right = this.project_index(&right, i)?; - let dest = this.project_index(&dest, i)?; + let left = ecx.project_index(&left, i)?; + let right = ecx.project_index(&right, i)?; + let dest = ecx.project_index(&dest, i)?; // Calculate dot product // Elements are floating point numbers, but we can use `from_int` @@ -890,22 +871,22 @@ fn conditional_dot_product<'tcx>( let mut sum = ImmTy::from_int(0u8, element_layout); for j in 0..items_per_chunk { if imm & (1 << j.strict_add(4)) != 0 { - let left = this.read_immediate(&this.project_index(&left, j)?)?; - let right = this.read_immediate(&this.project_index(&right, j)?)?; + let left = ecx.read_immediate(&ecx.project_index(&left, j)?)?; + let right = ecx.read_immediate(&ecx.project_index(&right, j)?)?; - let mul = this.binary_op(mir::BinOp::Mul, &left, &right)?; - sum = this.binary_op(mir::BinOp::Add, &sum, &mul)?; + let mul = ecx.binary_op(mir::BinOp::Mul, &left, &right)?; + sum = ecx.binary_op(mir::BinOp::Add, &sum, &mul)?; } } // Write to destination (conditioned to imm) for j in 0..items_per_chunk { - let dest = this.project_index(&dest, j)?; + let dest = ecx.project_index(&dest, j)?; if imm & (1 << j) != 0 { - this.write_immediate(*sum, &dest)?; + ecx.write_immediate(*sum, &dest)?; } else { - this.write_scalar(Scalar::from_int(0u8, element_layout.size), &dest)?; + ecx.write_scalar(Scalar::from_int(0u8, element_layout.size), &dest)?; } } } @@ -918,25 +899,25 @@ fn conditional_dot_product<'tcx>( /// The first is true when all the bits of `op & mask` are zero. /// The second is true when `(op & mask) == mask` fn test_bits_masked<'tcx>( - this: &crate::MiriInterpCx<'tcx>, + ecx: &crate::MiriInterpCx<'tcx>, op: &OpTy<'tcx>, mask: &OpTy<'tcx>, ) -> InterpResult<'tcx, (bool, bool)> { assert_eq!(op.layout, mask.layout); - let (op, op_len) = this.project_to_simd(op)?; - let (mask, mask_len) = this.project_to_simd(mask)?; + let (op, op_len) = ecx.project_to_simd(op)?; + let (mask, mask_len) = ecx.project_to_simd(mask)?; assert_eq!(op_len, mask_len); let mut all_zero = true; let mut masked_set = true; for i in 0..op_len { - let op = this.project_index(&op, i)?; - let mask = this.project_index(&mask, i)?; + let op = ecx.project_index(&op, i)?; + let mask = ecx.project_index(&mask, i)?; - let op = this.read_scalar(&op)?.to_uint(op.layout.size)?; - let mask = this.read_scalar(&mask)?.to_uint(mask.layout.size)?; + let op = ecx.read_scalar(&op)?.to_uint(op.layout.size)?; + let mask = ecx.read_scalar(&mask)?.to_uint(mask.layout.size)?; all_zero &= (op & mask) == 0; masked_set &= (op & mask) == mask; } @@ -949,27 +930,27 @@ fn test_bits_masked<'tcx>( /// The first is true when the highest bit of each element of `op & mask` is zero. /// The second is true when the highest bit of each element of `!op & mask` is zero. fn test_high_bits_masked<'tcx>( - this: &crate::MiriInterpCx<'tcx>, + ecx: &crate::MiriInterpCx<'tcx>, op: &OpTy<'tcx>, mask: &OpTy<'tcx>, ) -> InterpResult<'tcx, (bool, bool)> { assert_eq!(op.layout, mask.layout); - let (op, op_len) = this.project_to_simd(op)?; - let (mask, mask_len) = this.project_to_simd(mask)?; + let (op, op_len) = ecx.project_to_simd(op)?; + let (mask, mask_len) = ecx.project_to_simd(mask)?; assert_eq!(op_len, mask_len); - let high_bit_offset = op.layout.field(this, 0).size.bits().strict_sub(1); + let high_bit_offset = op.layout.field(ecx, 0).size.bits().strict_sub(1); let mut direct = true; let mut negated = true; for i in 0..op_len { - let op = this.project_index(&op, i)?; - let mask = this.project_index(&mask, i)?; + let op = ecx.project_index(&op, i)?; + let mask = ecx.project_index(&mask, i)?; - let op = this.read_scalar(&op)?.to_uint(op.layout.size)?; - let mask = this.read_scalar(&mask)?.to_uint(mask.layout.size)?; + let op = ecx.read_scalar(&op)?.to_uint(op.layout.size)?; + let mask = ecx.read_scalar(&mask)?.to_uint(mask.layout.size)?; direct &= (op & mask) >> high_bit_offset == 0; negated &= (!op & mask) >> high_bit_offset == 0; } @@ -980,30 +961,30 @@ fn test_high_bits_masked<'tcx>( /// Conditionally loads from `ptr` according the high bit of each /// element of `mask`. `ptr` does not need to be aligned. fn mask_load<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, ptr: &OpTy<'tcx>, mask: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (mask, mask_len) = this.project_to_simd(mask)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (mask, mask_len) = ecx.project_to_simd(mask)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; assert_eq!(dest_len, mask_len); - let mask_item_size = mask.layout.field(this, 0).size; + let mask_item_size = mask.layout.field(ecx, 0).size; let high_bit_offset = mask_item_size.bits().strict_sub(1); - let ptr = this.read_pointer(ptr)?; + let ptr = ecx.read_pointer(ptr)?; for i in 0..dest_len { - let mask = this.project_index(&mask, i)?; - let dest = this.project_index(&dest, i)?; + let mask = ecx.project_index(&mask, i)?; + let dest = ecx.project_index(&dest, i)?; - if this.read_scalar(&mask)?.to_uint(mask_item_size)? >> high_bit_offset != 0 { - let ptr = ptr.wrapping_offset(dest.layout.size * i, &this.tcx); + if ecx.read_scalar(&mask)?.to_uint(mask_item_size)? >> high_bit_offset != 0 { + let ptr = ptr.wrapping_offset(dest.layout.size * i, &ecx.tcx); // Unaligned copy, which is what we want. - this.mem_copy(ptr, dest.ptr(), dest.layout.size, /*nonoverlapping*/ true)?; + ecx.mem_copy(ptr, dest.ptr(), dest.layout.size, /*nonoverlapping*/ true)?; } else { - this.write_scalar(Scalar::from_int(0, dest.layout.size), &dest)?; + ecx.write_scalar(Scalar::from_int(0, dest.layout.size), &dest)?; } } @@ -1013,31 +994,31 @@ fn mask_load<'tcx>( /// Conditionally stores into `ptr` according the high bit of each /// element of `mask`. `ptr` does not need to be aligned. fn mask_store<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, ptr: &OpTy<'tcx>, mask: &OpTy<'tcx>, value: &OpTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (mask, mask_len) = this.project_to_simd(mask)?; - let (value, value_len) = this.project_to_simd(value)?; + let (mask, mask_len) = ecx.project_to_simd(mask)?; + let (value, value_len) = ecx.project_to_simd(value)?; assert_eq!(value_len, mask_len); - let mask_item_size = mask.layout.field(this, 0).size; + let mask_item_size = mask.layout.field(ecx, 0).size; let high_bit_offset = mask_item_size.bits().strict_sub(1); - let ptr = this.read_pointer(ptr)?; + let ptr = ecx.read_pointer(ptr)?; for i in 0..value_len { - let mask = this.project_index(&mask, i)?; - let value = this.project_index(&value, i)?; + let mask = ecx.project_index(&mask, i)?; + let value = ecx.project_index(&value, i)?; - if this.read_scalar(&mask)?.to_uint(mask_item_size)? >> high_bit_offset != 0 { + if ecx.read_scalar(&mask)?.to_uint(mask_item_size)? >> high_bit_offset != 0 { // *Non-inbounds* pointer arithmetic to compute the destination. // (That's why we can't use a place projection.) - let ptr = ptr.wrapping_offset(value.layout.size * i, &this.tcx); + let ptr = ptr.wrapping_offset(value.layout.size * i, &ecx.tcx); // Deref the pointer *unaligned*, and do the copy. - let dest = this.ptr_to_mplace_unaligned(ptr, value.layout); - this.copy_op(&value, &dest)?; + let dest = ecx.ptr_to_mplace_unaligned(ptr, value.layout); + ecx.copy_op(&value, &dest)?; } } @@ -1056,7 +1037,7 @@ fn mask_store<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn mpsadbw<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, imm: &OpTy<'tcx>, @@ -1065,13 +1046,13 @@ fn mpsadbw<'tcx>( assert_eq!(left.layout, right.layout); assert_eq!(left.layout.size, dest.layout.size); - let (num_chunks, op_items_per_chunk, left) = split_simd_to_128bit_chunks(this, left)?; - let (_, _, right) = split_simd_to_128bit_chunks(this, right)?; - let (_, dest_items_per_chunk, dest) = split_simd_to_128bit_chunks(this, dest)?; + let (num_chunks, op_items_per_chunk, left) = split_simd_to_128bit_chunks(ecx, left)?; + let (_, _, right) = split_simd_to_128bit_chunks(ecx, right)?; + let (_, dest_items_per_chunk, dest) = split_simd_to_128bit_chunks(ecx, dest)?; assert_eq!(op_items_per_chunk, dest_items_per_chunk.strict_mul(2)); - let imm = this.read_scalar(imm)?.to_uint(imm.layout.size)?; + let imm = ecx.read_scalar(imm)?.to_uint(imm.layout.size)?; // Bit 2 of `imm` specifies the offset for indices of `left`. // The offset is 0 when the bit is 0 or 4 when the bit is 1. let left_offset = u64::try_from((imm >> 2) & 1).unwrap().strict_mul(4); @@ -1080,23 +1061,23 @@ fn mpsadbw<'tcx>( let right_offset = u64::try_from(imm & 0b11).unwrap().strict_mul(4); for i in 0..num_chunks { - let left = this.project_index(&left, i)?; - let right = this.project_index(&right, i)?; - let dest = this.project_index(&dest, i)?; + let left = ecx.project_index(&left, i)?; + let right = ecx.project_index(&right, i)?; + let dest = ecx.project_index(&dest, i)?; for j in 0..dest_items_per_chunk { let left_offset = left_offset.strict_add(j); let mut res: u16 = 0; for k in 0..4 { - let left = this - .read_scalar(&this.project_index(&left, left_offset.strict_add(k))?)? + let left = ecx + .read_scalar(&ecx.project_index(&left, left_offset.strict_add(k))?)? .to_u8()?; - let right = this - .read_scalar(&this.project_index(&right, right_offset.strict_add(k))?)? + let right = ecx + .read_scalar(&ecx.project_index(&right, right_offset.strict_add(k))?)? .to_u8()?; res = res.strict_add(left.abs_diff(right).into()); } - this.write_scalar(Scalar::from_u16(res), &this.project_index(&dest, j)?)?; + ecx.write_scalar(Scalar::from_u16(res), &ecx.project_index(&dest, j)?)?; } } @@ -1111,22 +1092,22 @@ fn mpsadbw<'tcx>( /// /// fn pmulhrsw<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (left, left_len) = this.project_to_simd(left)?; - let (right, right_len) = this.project_to_simd(right)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (left, left_len) = ecx.project_to_simd(left)?; + let (right, right_len) = ecx.project_to_simd(right)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; assert_eq!(dest_len, left_len); assert_eq!(dest_len, right_len); for i in 0..dest_len { - let left = this.read_scalar(&this.project_index(&left, i)?)?.to_i16()?; - let right = this.read_scalar(&this.project_index(&right, i)?)?.to_i16()?; - let dest = this.project_index(&dest, i)?; + let left = ecx.read_scalar(&ecx.project_index(&left, i)?)?.to_i16()?; + let right = ecx.read_scalar(&ecx.project_index(&right, i)?)?.to_i16()?; + let dest = ecx.project_index(&dest, i)?; let res = (i32::from(left).strict_mul(right.into()) >> 14).strict_add(1) >> 1; @@ -1135,7 +1116,7 @@ fn pmulhrsw<'tcx>( #[expect(clippy::cast_possible_truncation)] let res = res as i16; - this.write_scalar(Scalar::from_i16(res), &dest)?; + ecx.write_scalar(Scalar::from_i16(res), &dest)?; } interp_ok(()) @@ -1152,7 +1133,7 @@ fn pmulhrsw<'tcx>( /// /// fn pclmulqdq<'tcx>( - this: &mut MiriInterpCx<'tcx>, + ecx: &mut MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, imm8: &OpTy<'tcx>, @@ -1166,14 +1147,14 @@ fn pclmulqdq<'tcx>( // Transmute the input into arrays of `[u64; len]`. // Transmute the output into an array of `[u128, len / 2]`. - let src_layout = this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u64, len))?; - let dest_layout = this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u128, len / 2))?; + let src_layout = ecx.layout_of(Ty::new_array(ecx.tcx.tcx, ecx.tcx.types.u64, len))?; + let dest_layout = ecx.layout_of(Ty::new_array(ecx.tcx.tcx, ecx.tcx.types.u128, len / 2))?; - let left = left.transmute(src_layout, this)?; - let right = right.transmute(src_layout, this)?; - let dest = dest.transmute(dest_layout, this)?; + let left = left.transmute(src_layout, ecx)?; + let right = right.transmute(src_layout, ecx)?; + let dest = dest.transmute(dest_layout, ecx)?; - let imm8 = this.read_scalar(imm8)?.to_u8()?; + let imm8 = ecx.read_scalar(imm8)?.to_u8()?; for i in 0..(len / 2) { let lo = i.strict_mul(2); @@ -1181,11 +1162,11 @@ fn pclmulqdq<'tcx>( // select the 64-bit integer from left that the user specified (low or high) let index = if (imm8 & 0x01) == 0 { lo } else { hi }; - let left = this.read_scalar(&this.project_index(&left, index)?)?.to_u64()?; + let left = ecx.read_scalar(&ecx.project_index(&left, index)?)?.to_u64()?; // select the 64-bit integer from right that the user specified (low or high) let index = if (imm8 & 0x10) == 0 { lo } else { hi }; - let right = this.read_scalar(&this.project_index(&right, index)?)?.to_u64()?; + let right = ecx.read_scalar(&ecx.project_index(&right, index)?)?.to_u64()?; // Perform carry-less multiplication. // @@ -1203,8 +1184,8 @@ fn pclmulqdq<'tcx>( } } - let dest = this.project_index(&dest, i)?; - this.write_scalar(Scalar::from_u128(result), &dest)?; + let dest = ecx.project_index(&dest, i)?; + ecx.write_scalar(Scalar::from_u128(result), &dest)?; } interp_ok(()) @@ -1218,7 +1199,7 @@ fn pclmulqdq<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn pack_generic<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, @@ -1227,28 +1208,28 @@ fn pack_generic<'tcx>( assert_eq!(left.layout, right.layout); assert_eq!(left.layout.size, dest.layout.size); - let (num_chunks, op_items_per_chunk, left) = split_simd_to_128bit_chunks(this, left)?; - let (_, _, right) = split_simd_to_128bit_chunks(this, right)?; - let (_, dest_items_per_chunk, dest) = split_simd_to_128bit_chunks(this, dest)?; + let (num_chunks, op_items_per_chunk, left) = split_simd_to_128bit_chunks(ecx, left)?; + let (_, _, right) = split_simd_to_128bit_chunks(ecx, right)?; + let (_, dest_items_per_chunk, dest) = split_simd_to_128bit_chunks(ecx, dest)?; assert_eq!(dest_items_per_chunk, op_items_per_chunk.strict_mul(2)); for i in 0..num_chunks { - let left = this.project_index(&left, i)?; - let right = this.project_index(&right, i)?; - let dest = this.project_index(&dest, i)?; + let left = ecx.project_index(&left, i)?; + let right = ecx.project_index(&right, i)?; + let dest = ecx.project_index(&dest, i)?; for j in 0..op_items_per_chunk { - let left = this.read_scalar(&this.project_index(&left, j)?)?; - let right = this.read_scalar(&this.project_index(&right, j)?)?; - let left_dest = this.project_index(&dest, j)?; - let right_dest = this.project_index(&dest, j.strict_add(op_items_per_chunk))?; + let left = ecx.read_scalar(&ecx.project_index(&left, j)?)?; + let right = ecx.read_scalar(&ecx.project_index(&right, j)?)?; + let left_dest = ecx.project_index(&dest, j)?; + let right_dest = ecx.project_index(&dest, j.strict_add(op_items_per_chunk))?; let left_res = f(left)?; let right_res = f(right)?; - this.write_scalar(left_res, &left_dest)?; - this.write_scalar(right_res, &right_dest)?; + ecx.write_scalar(left_res, &left_dest)?; + ecx.write_scalar(right_res, &right_dest)?; } } @@ -1262,12 +1243,12 @@ fn pack_generic<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn packsswb<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - pack_generic(this, left, right, dest, |op| { + pack_generic(ecx, left, right, dest, |op| { let op = op.to_i16()?; let res = i8::try_from(op).unwrap_or(if op < 0 { i8::MIN } else { i8::MAX }); interp_ok(Scalar::from_i8(res)) @@ -1281,12 +1262,12 @@ fn packsswb<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn packuswb<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - pack_generic(this, left, right, dest, |op| { + pack_generic(ecx, left, right, dest, |op| { let op = op.to_i16()?; let res = u8::try_from(op).unwrap_or(if op < 0 { 0 } else { u8::MAX }); interp_ok(Scalar::from_u8(res)) @@ -1300,12 +1281,12 @@ fn packuswb<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn packssdw<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - pack_generic(this, left, right, dest, |op| { + pack_generic(ecx, left, right, dest, |op| { let op = op.to_i32()?; let res = i16::try_from(op).unwrap_or(if op < 0 { i16::MIN } else { i16::MAX }); interp_ok(Scalar::from_i16(res)) @@ -1319,12 +1300,12 @@ fn packssdw<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn packusdw<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - pack_generic(this, left, right, dest, |op| { + pack_generic(ecx, left, right, dest, |op| { let op = op.to_i32()?; let res = u16::try_from(op).unwrap_or(if op < 0 { 0 } else { u16::MAX }); interp_ok(Scalar::from_u16(res)) @@ -1336,27 +1317,27 @@ fn packusdw<'tcx>( /// is written to the corresponding output element. /// In other words, multiplies `left` with `right.signum()`. fn psign<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx>, right: &OpTy<'tcx>, dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, ()> { - let (left, left_len) = this.project_to_simd(left)?; - let (right, right_len) = this.project_to_simd(right)?; - let (dest, dest_len) = this.project_to_simd(dest)?; + let (left, left_len) = ecx.project_to_simd(left)?; + let (right, right_len) = ecx.project_to_simd(right)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; assert_eq!(dest_len, left_len); assert_eq!(dest_len, right_len); for i in 0..dest_len { - let dest = this.project_index(&dest, i)?; - let left = this.read_immediate(&this.project_index(&left, i)?)?; - let right = this.read_scalar(&this.project_index(&right, i)?)?.to_int(dest.layout.size)?; + let dest = ecx.project_index(&dest, i)?; + let left = ecx.read_immediate(&ecx.project_index(&left, i)?)?; + let right = ecx.read_scalar(&ecx.project_index(&right, i)?)?.to_int(dest.layout.size)?; let res = - this.binary_op(mir::BinOp::Mul, &left, &ImmTy::from_int(right.signum(), dest.layout))?; + ecx.binary_op(mir::BinOp::Mul, &left, &ImmTy::from_int(right.signum(), dest.layout))?; - this.write_immediate(*res, &dest)?; + ecx.write_immediate(*res, &dest)?; } interp_ok(()) @@ -1366,7 +1347,7 @@ fn psign<'tcx>( /// of `op` and returns both the sum and the overflow bit. `op` is expected to be /// either one of `mir::BinOp::AddWithOverflow` and `mir::BinOp::SubWithOverflow`. fn carrying_add<'tcx>( - this: &mut crate::MiriInterpCx<'tcx>, + ecx: &mut crate::MiriInterpCx<'tcx>, cb_in: &OpTy<'tcx>, a: &OpTy<'tcx>, b: &OpTy<'tcx>, @@ -1374,13 +1355,13 @@ fn carrying_add<'tcx>( ) -> InterpResult<'tcx, (ImmTy<'tcx>, Scalar)> { assert!(op == mir::BinOp::AddWithOverflow || op == mir::BinOp::SubWithOverflow); - let cb_in = this.read_scalar(cb_in)?.to_u8()? != 0; - let a = this.read_immediate(a)?; - let b = this.read_immediate(b)?; + let cb_in = ecx.read_scalar(cb_in)?.to_u8()? != 0; + let a = ecx.read_immediate(a)?; + let b = ecx.read_immediate(b)?; - let (sum, overflow1) = this.binary_op(op, &a, &b)?.to_pair(this); + let (sum, overflow1) = ecx.binary_op(op, &a, &b)?.to_pair(ecx); let (sum, overflow2) = - this.binary_op(op, &sum, &ImmTy::from_uint(cb_in, a.layout))?.to_pair(this); + ecx.binary_op(op, &sum, &ImmTy::from_uint(cb_in, a.layout))?.to_pair(ecx); let cb_out = overflow1.to_scalar().to_bool()? | overflow2.to_scalar().to_bool()?; interp_ok((sum, Scalar::from_u8(cb_out.into()))) diff --git a/src/tools/miri/src/shims/x86/sha.rs b/src/tools/miri/src/shims/x86/sha.rs index 964204127d92c..f18ff1ec253b8 100644 --- a/src/tools/miri/src/shims/x86/sha.rs +++ b/src/tools/miri/src/shims/x86/sha.rs @@ -23,27 +23,27 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Prefix should have already been checked. let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sha").unwrap(); - fn read<'c>(this: &mut MiriInterpCx<'c>, reg: &OpTy<'c>) -> InterpResult<'c, [u32; 4]> { + fn read<'c>(ecx: &mut MiriInterpCx<'c>, reg: &OpTy<'c>) -> InterpResult<'c, [u32; 4]> { let mut res = [0; 4]; // We reverse the order because x86 is little endian but the copied implementation uses // big endian. for (i, dst) in res.iter_mut().rev().enumerate() { - let projected = &this.project_index(reg, i.try_into().unwrap())?; - *dst = this.read_scalar(projected)?.to_u32()? + let projected = &ecx.project_index(reg, i.try_into().unwrap())?; + *dst = ecx.read_scalar(projected)?.to_u32()? } interp_ok(res) } fn write<'c>( - this: &mut MiriInterpCx<'c>, + ecx: &mut MiriInterpCx<'c>, dest: &MPlaceTy<'c>, val: [u32; 4], ) -> InterpResult<'c, ()> { // We reverse the order because x86 is little endian but the copied implementation uses // big endian. for (i, part) in val.into_iter().rev().enumerate() { - let projected = &this.project_index(dest, i.try_into().unwrap())?; - this.write_scalar(Scalar::from_u32(part), projected)?; + let projected = &ecx.project_index(dest, i.try_into().unwrap())?; + ecx.write_scalar(Scalar::from_u32(part), projected)?; } interp_ok(()) } diff --git a/src/tools/miri/src/shims/x86/sse42.rs b/src/tools/miri/src/shims/x86/sse42.rs index cc7cfab504195..0b058a9911e2a 100644 --- a/src/tools/miri/src/shims/x86/sse42.rs +++ b/src/tools/miri/src/shims/x86/sse42.rs @@ -70,7 +70,7 @@ const USE_SIGNED: u8 = 2; /// For more information, see the Intel Software Developer's Manual, Vol. 2b, Chapter 4.1. #[expect(clippy::arithmetic_side_effects)] fn compare_strings<'tcx>( - this: &mut MiriInterpCx<'tcx>, + ecx: &mut MiriInterpCx<'tcx>, str1: &OpTy<'tcx>, str2: &OpTy<'tcx>, len: Option<(u64, u64)>, @@ -80,8 +80,8 @@ fn compare_strings<'tcx>( let (len1, len2) = if let Some(t) = len { t } else { - let len1 = implicit_len(this, str1, imm)?.unwrap_or(default_len); - let len2 = implicit_len(this, str2, imm)?.unwrap_or(default_len); + let len1 = implicit_len(ecx, str1, imm)?.unwrap_or(default_len); + let len2 = implicit_len(ecx, str2, imm)?.unwrap_or(default_len); (len1, len2) }; @@ -90,12 +90,12 @@ fn compare_strings<'tcx>( 0 => { // Equal any: Checks which characters of `str2` are inside `str1`. for i in 0..len2 { - let ch2 = this.read_immediate(&this.project_index(str2, i)?)?; + let ch2 = ecx.read_immediate(&ecx.project_index(str2, i)?)?; for j in 0..len1 { - let ch1 = this.read_immediate(&this.project_index(str1, j)?)?; + let ch1 = ecx.read_immediate(&ecx.project_index(str1, j)?)?; - let eq = this.binary_op(mir::BinOp::Eq, &ch1, &ch2)?; + let eq = ecx.binary_op(mir::BinOp::Eq, &ch1, &ch2)?; if eq.to_scalar().to_bool()? { result |= 1 << i; break; @@ -119,9 +119,9 @@ fn compare_strings<'tcx>( for i in 0..len2 { for j in (0..len1).step_by(2) { - let ch2 = get_ch(this.read_scalar(&this.project_index(str2, i)?)?)?; - let ch1_1 = get_ch(this.read_scalar(&this.project_index(str1, j)?)?)?; - let ch1_2 = get_ch(this.read_scalar(&this.project_index(str1, j + 1)?)?)?; + let ch2 = get_ch(ecx.read_scalar(&ecx.project_index(str2, i)?)?)?; + let ch1_1 = get_ch(ecx.read_scalar(&ecx.project_index(str1, j)?)?)?; + let ch1_2 = get_ch(ecx.read_scalar(&ecx.project_index(str1, j + 1)?)?)?; if ch1_1 <= ch2 && ch2 <= ch1_2 { result |= 1 << i; @@ -135,9 +135,9 @@ fn compare_strings<'tcx>( result ^= (1 << len1.max(len2)) - 1; for i in 0..len1.min(len2) { - let ch1 = this.read_immediate(&this.project_index(str1, i)?)?; - let ch2 = this.read_immediate(&this.project_index(str2, i)?)?; - let eq = this.binary_op(mir::BinOp::Eq, &ch1, &ch2)?; + let ch1 = ecx.read_immediate(&ecx.project_index(str1, i)?)?; + let ch2 = ecx.read_immediate(&ecx.project_index(str2, i)?)?; + let eq = ecx.binary_op(mir::BinOp::Eq, &ch1, &ch2)?; result |= i32::from(eq.to_scalar().to_bool()?) << i; } } @@ -159,9 +159,9 @@ fn compare_strings<'tcx>( if k >= default_len { break; } else { - let ch1 = this.read_immediate(&this.project_index(str1, j)?)?; - let ch2 = this.read_immediate(&this.project_index(str2, k)?)?; - let ne = this.binary_op(mir::BinOp::Ne, &ch1, &ch2)?; + let ch1 = ecx.read_immediate(&ecx.project_index(str1, j)?)?; + let ch2 = ecx.read_immediate(&ecx.project_index(str2, k)?)?; + let ne = ecx.binary_op(mir::BinOp::Ne, &ch1, &ch2)?; if ne.to_scalar().to_bool()? { result &= !(1 << i); @@ -198,16 +198,16 @@ fn compare_strings<'tcx>( /// corresponding to the x86 128-bit integer SIMD type. fn deconstruct_args<'tcx>( unprefixed_name: &str, - this: &mut MiriInterpCx<'tcx>, + ecx: &mut MiriInterpCx<'tcx>, link_name: Symbol, abi: ExternAbi, args: &[OpTy<'tcx>], ) -> InterpResult<'tcx, (OpTy<'tcx>, OpTy<'tcx>, Option<(u64, u64)>, u8)> { - let array_layout_fn = |this: &mut MiriInterpCx<'tcx>, imm: u8| { + let array_layout_fn = |ecx: &mut MiriInterpCx<'tcx>, imm: u8| { if imm & USE_WORDS != 0 { - this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u16, 8)) + ecx.layout_of(Ty::new_array(ecx.tcx.tcx, ecx.tcx.types.u16, 8)) } else { - this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u8, 16)) + ecx.layout_of(Ty::new_array(ecx.tcx.tcx, ecx.tcx.types.u8, 16)) } }; @@ -223,26 +223,26 @@ fn deconstruct_args<'tcx>( if is_explicit { let [str1, len1, str2, len2, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; - let imm = this.read_scalar(imm)?.to_u8()?; + ecx.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let imm = ecx.read_scalar(imm)?.to_u8()?; let default_len = default_len::(imm); - let len1 = u64::from(this.read_scalar(len1)?.to_u32()?.min(default_len)); - let len2 = u64::from(this.read_scalar(len2)?.to_u32()?.min(default_len)); + let len1 = u64::from(ecx.read_scalar(len1)?.to_u32()?.min(default_len)); + let len2 = u64::from(ecx.read_scalar(len2)?.to_u32()?.min(default_len)); - let array_layout = array_layout_fn(this, imm)?; - let str1 = str1.transmute(array_layout, this)?; - let str2 = str2.transmute(array_layout, this)?; + let array_layout = array_layout_fn(ecx, imm)?; + let str1 = str1.transmute(array_layout, ecx)?; + let str2 = str2.transmute(array_layout, ecx)?; interp_ok((str1, str2, Some((len1, len2)), imm)) } else { let [str1, str2, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; - let imm = this.read_scalar(imm)?.to_u8()?; + ecx.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let imm = ecx.read_scalar(imm)?.to_u8()?; - let array_layout = array_layout_fn(this, imm)?; - let str1 = str1.transmute(array_layout, this)?; - let str2 = str2.transmute(array_layout, this)?; + let array_layout = array_layout_fn(ecx, imm)?; + let str1 = str1.transmute(array_layout, ecx)?; + let str2 = str2.transmute(array_layout, ecx)?; interp_ok((str1, str2, None, imm)) } @@ -251,16 +251,16 @@ fn deconstruct_args<'tcx>( /// Calculate the c-style string length for a given string `str`. /// The string is either a length 16 array of bytes a length 8 array of two-byte words. fn implicit_len<'tcx>( - this: &mut MiriInterpCx<'tcx>, + ecx: &mut MiriInterpCx<'tcx>, str: &OpTy<'tcx>, imm: u8, ) -> InterpResult<'tcx, Option> { let mut result = None; - let zero = ImmTy::from_int(0, str.layout.field(this, 0)); + let zero = ImmTy::from_int(0, str.layout.field(ecx, 0)); for i in 0..default_len::(imm) { - let ch = this.read_immediate(&this.project_index(str, i)?)?; - let is_zero = this.binary_op(mir::BinOp::Eq, &ch, &zero)?; + let ch = ecx.read_immediate(&ecx.project_index(str, i)?)?; + let is_zero = ecx.binary_op(mir::BinOp::Eq, &ch, &zero)?; if is_zero.to_scalar().to_bool()? { result = Some(i); break; diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.rs b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.rs new file mode 100644 index 0000000000000..65d29b2c6bad1 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.rs @@ -0,0 +1,65 @@ +//@only-target: linux +//~^ERROR: deadlocked +//~^^ERROR: deadlocked +//@compile-flags: -Zmiri-preemption-rate=0 +//@error-in-other-file: deadlock + +use std::thread; + +// Test the behaviour of a thread being blocked on an eventfd read, get unblocked, and then +// get blocked again. + +// The expected execution is +// 1. Thread 1 blocks. +// 2. Thread 2 blocks. +// 3. Thread 3 unblocks both thread 1 and thread 2. +// 4. Thread 1 reads. +// 5. Thread 2's `read` deadlocked. + +fn main() { + // eventfd write will block when EFD_NONBLOCK flag is clear + // and the addition caused counter to exceed u64::MAX - 1. + let flags = libc::EFD_CLOEXEC; + let fd = unsafe { libc::eventfd(0, flags) }; + + let thread1 = thread::spawn(move || { + thread::park(); + let mut buf: [u8; 8] = [0; 8]; + // This read will block initially. + let res: i64 = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 8).try_into().unwrap() }; + assert_eq!(res, 8); + let counter = u64::from_ne_bytes(buf); + assert_eq!(counter, 1_u64); + }); + + let thread2 = thread::spawn(move || { + thread::park(); + let mut buf: [u8; 8] = [0; 8]; + // This read will block initially, then get unblocked by thread3, then get blocked again + // because the `read` in thread1 executes first and set the counter to 0 again. + let res: i64 = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 8).try_into().unwrap() }; + //~^ERROR: deadlocked + assert_eq!(res, 8); + let counter = u64::from_ne_bytes(buf); + assert_eq!(counter, 1_u64); + }); + + let thread3 = thread::spawn(move || { + thread::park(); + let sized_8_data = 1_u64.to_ne_bytes(); + // Write 1 to the counter, so both thread1 and thread2 will unblock. + let res: i64 = unsafe { + libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() + }; + // Make sure that write is successful. + assert_eq!(res, 8); + }); + + thread1.thread().unpark(); + thread2.thread().unpark(); + thread3.thread().unpark(); + + thread1.join().unwrap(); + thread2.join().unwrap(); + thread3.join().unwrap(); +} diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr new file mode 100644 index 0000000000000..bb235345c5ed1 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr @@ -0,0 +1,41 @@ +error: deadlock: the evaluated program deadlocked + --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + | +LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; + | ^ the evaluated program deadlocked + | + = note: BACKTRACE: + = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC +note: inside `main` + --> tests/fail-dep/libc/eventfd_block_read_twice.rs:LL:CC + | +LL | thread2.join().unwrap(); + | ^^^^^^^^^^^^^^ + +error: deadlock: the evaluated program deadlocked + | + = note: the evaluated program deadlocked + = note: (no span available) + = note: BACKTRACE on thread `unnamed-ID`: + +error: deadlock: the evaluated program deadlocked + --> tests/fail-dep/libc/eventfd_block_read_twice.rs:LL:CC + | +LL | let res: i64 = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 8).try_into().unwrap() }; + | ^ the evaluated program deadlocked + | + = note: BACKTRACE on thread `unnamed-ID`: + = note: inside closure at tests/fail-dep/libc/eventfd_block_read_twice.rs:LL:CC + +error: deadlock: the evaluated program deadlocked + | + = note: the evaluated program deadlocked + = note: (no span available) + = note: BACKTRACE on thread `unnamed-ID`: + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 4 previous errors + diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.rs b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.rs new file mode 100644 index 0000000000000..f9d34d2fb58a2 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.rs @@ -0,0 +1,71 @@ +//@only-target: linux +//~^ERROR: deadlocked +//~^^ERROR: deadlocked +//@compile-flags: -Zmiri-preemption-rate=0 +//@error-in-other-file: deadlock + +use std::thread; + +// Test the behaviour of a thread being blocked on an eventfd `write`, get unblocked, and then +// get blocked again. + +// The expected execution is +// 1. Thread 1 blocks. +// 2. Thread 2 blocks. +// 3. Thread 3 unblocks both thread 1 and thread 2. +// 4. Thread 1 writes u64::MAX. +// 5. Thread 2's `write` deadlocked. +fn main() { + // eventfd write will block when EFD_NONBLOCK flag is clear + // and the addition caused counter to exceed u64::MAX - 1. + let flags = libc::EFD_CLOEXEC; + let fd = unsafe { libc::eventfd(0, flags) }; + // Write u64 - 1, so the all subsequent write will block. + let sized_8_data: [u8; 8] = (u64::MAX - 1).to_ne_bytes(); + let res: i64 = unsafe { + libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() + }; + assert_eq!(res, 8); + + let thread1 = thread::spawn(move || { + thread::park(); + let sized_8_data = (u64::MAX - 1).to_ne_bytes(); + let res: i64 = unsafe { + libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() + }; + // Make sure that write is successful. + assert_eq!(res, 8); + }); + + let thread2 = thread::spawn(move || { + thread::park(); + let sized_8_data = (u64::MAX - 1).to_ne_bytes(); + // Write u64::MAX - 1, so the all subsequent write will block. + let res: i64 = unsafe { + // This `write` will initially blocked, then get unblocked by thread3, then get blocked again + // because the `write` in thread1 executes first. + libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() + //~^ERROR: deadlocked + }; + // Make sure that write is successful. + assert_eq!(res, 8); + }); + + let thread3 = thread::spawn(move || { + thread::park(); + let mut buf: [u8; 8] = [0; 8]; + // This will unblock both `write` in thread1 and thread2. + let res: i64 = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 8).try_into().unwrap() }; + assert_eq!(res, 8); + let counter = u64::from_ne_bytes(buf); + assert_eq!(counter, (u64::MAX - 1)); + }); + + thread1.thread().unpark(); + thread2.thread().unpark(); + thread3.thread().unpark(); + + thread1.join().unwrap(); + thread2.join().unwrap(); + thread3.join().unwrap(); +} diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr new file mode 100644 index 0000000000000..d9163a5748cc0 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr @@ -0,0 +1,41 @@ +error: deadlock: the evaluated program deadlocked + --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + | +LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; + | ^ the evaluated program deadlocked + | + = note: BACKTRACE: + = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC +note: inside `main` + --> tests/fail-dep/libc/eventfd_block_write_twice.rs:LL:CC + | +LL | thread2.join().unwrap(); + | ^^^^^^^^^^^^^^ + +error: deadlock: the evaluated program deadlocked + | + = note: the evaluated program deadlocked + = note: (no span available) + = note: BACKTRACE on thread `unnamed-ID`: + +error: deadlock: the evaluated program deadlocked + --> tests/fail-dep/libc/eventfd_block_write_twice.rs:LL:CC + | +LL | libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() + | ^ the evaluated program deadlocked + | + = note: BACKTRACE on thread `unnamed-ID`: + = note: inside closure at tests/fail-dep/libc/eventfd_block_write_twice.rs:LL:CC + +error: deadlock: the evaluated program deadlocked + | + = note: the evaluated program deadlocked + = note: (no span available) + = note: BACKTRACE on thread `unnamed-ID`: + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 4 previous errors + diff --git a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.rs b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.rs new file mode 100644 index 0000000000000..7f5ec477e192c --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.rs @@ -0,0 +1,96 @@ +//@compile-flags: -Zmiri-preemption-rate=0 +//~^ERROR: deadlocked +//~^^ERROR: deadlocked +//@only-target: linux +//@error-in-other-file: deadlock + +use std::convert::TryInto; +use std::thread; +use std::thread::spawn; + +// Using `as` cast since `EPOLLET` wraps around +const EPOLL_IN_OUT_ET: u32 = (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _; + +#[track_caller] +fn check_epoll_wait( + epfd: i32, + expected_notifications: &[(u32, u64)], + timeout: i32, +) { + let epoll_event = libc::epoll_event { events: 0, u64: 0 }; + let mut array: [libc::epoll_event; N] = [epoll_event; N]; + let maxsize = N; + let array_ptr = array.as_mut_ptr(); + let res = unsafe { libc::epoll_wait(epfd, array_ptr, maxsize.try_into().unwrap(), timeout) }; + if res < 0 { + panic!("epoll_wait failed: {}", std::io::Error::last_os_error()); + } + assert_eq!( + res, + expected_notifications.len().try_into().unwrap(), + "got wrong number of notifications" + ); + let slice = unsafe { std::slice::from_raw_parts(array_ptr, res.try_into().unwrap()) }; + for (return_event, expected_event) in slice.iter().zip(expected_notifications.iter()) { + let event = return_event.events; + let data = return_event.u64; + assert_eq!(event, expected_event.0, "got wrong events"); + assert_eq!(data, expected_event.1, "got wrong data"); + } +} + +// Test if only one thread is unblocked if multiple threads blocked on same epfd. +// Expected execution: +// 1. Thread 2 blocks. +// 2. Thread 3 blocks. +// 3. Thread 1 unblocks thread 3. +// 4. Thread 2 deadlocks. +fn main() { + // Create an epoll instance. + let epfd = unsafe { libc::epoll_create1(0) }; + assert_ne!(epfd, -1); + + // Create a socketpair instance. + let mut fds = [-1, -1]; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + assert_eq!(res, 0); + + // Register one side of the socketpair with epoll. + let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 }; + let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; + assert_eq!(res, 0); + + // epoll_wait to clear notification. + let expected_event = u32::try_from(libc::EPOLLOUT).unwrap(); + let expected_value = fds[0] as u64; + check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 0); + + let thread1 = spawn(move || { + thread::park(); + let data = "abcde".as_bytes().as_ptr(); + let res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5) }; + assert_eq!(res, 5); + }); + + let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); + let expected_value = fds[0] as u64; + let thread2 = spawn(move || { + thread::park(); + check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], -1); + //~^ERROR: deadlocked + }); + let thread3 = spawn(move || { + thread::park(); + check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], -1); + }); + + thread2.thread().unpark(); + thread::yield_now(); + thread3.thread().unpark(); + thread::yield_now(); + thread1.thread().unpark(); + + thread1.join().unwrap(); + thread2.join().unwrap(); + thread3.join().unwrap(); +} diff --git a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr new file mode 100644 index 0000000000000..010dabc136449 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr @@ -0,0 +1,41 @@ +error: deadlock: the evaluated program deadlocked + --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + | +LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; + | ^ the evaluated program deadlocked + | + = note: BACKTRACE: + = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC +note: inside `main` + --> tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC + | +LL | thread2.join().unwrap(); + | ^^^^^^^^^^^^^^ + +error: deadlock: the evaluated program deadlocked + | + = note: the evaluated program deadlocked + = note: (no span available) + = note: BACKTRACE on thread `unnamed-ID`: + +error: deadlock: the evaluated program deadlocked + --> tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC + | +LL | check_epoll_wait::(epfd, &[(expected_event, expected_value)], -1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program deadlocked + | + = note: BACKTRACE on thread `unnamed-ID`: + = note: inside closure at tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC + +error: deadlock: the evaluated program deadlocked + | + = note: the evaluated program deadlocked + = note: (no span available) + = note: BACKTRACE on thread `unnamed-ID`: + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 4 previous errors + diff --git a/src/tools/miri/tests/fail-dep/libc/libc_eventfd_read_block.rs b/src/tools/miri/tests/fail-dep/libc/libc_eventfd_read_block.rs deleted file mode 100644 index 0212a63bd0fa2..0000000000000 --- a/src/tools/miri/tests/fail-dep/libc/libc_eventfd_read_block.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@only-target: linux -fn main() { - // eventfd read will block when EFD_NONBLOCK flag is clear and counter = 0. - // This will pass when blocking is implemented. - let flags = libc::EFD_CLOEXEC; - let fd = unsafe { libc::eventfd(0, flags) }; - let mut buf: [u8; 8] = [0; 8]; - let _res: i32 = unsafe { - libc::read(fd, buf.as_mut_ptr().cast(), buf.len() as libc::size_t).try_into().unwrap() //~ERROR: blocking is unsupported - }; -} diff --git a/src/tools/miri/tests/fail-dep/libc/libc_eventfd_read_block.stderr b/src/tools/miri/tests/fail-dep/libc/libc_eventfd_read_block.stderr deleted file mode 100644 index aff30c81ebdb9..0000000000000 --- a/src/tools/miri/tests/fail-dep/libc/libc_eventfd_read_block.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: unsupported operation: eventfd: blocking is unsupported - --> tests/fail-dep/libc/libc_eventfd_read_block.rs:LL:CC - | -LL | libc::read(fd, buf.as_mut_ptr().cast(), buf.len() as libc::size_t).try_into().unwrap() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ eventfd: blocking is unsupported - | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/libc_eventfd_read_block.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/libc/libc_eventfd_write_block.rs b/src/tools/miri/tests/fail-dep/libc/libc_eventfd_write_block.rs deleted file mode 100644 index ed6ad466901bc..0000000000000 --- a/src/tools/miri/tests/fail-dep/libc/libc_eventfd_write_block.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@only-target: linux -fn main() { - // eventfd write will block when EFD_NONBLOCK flag is clear - // and the addition caused counter to exceed u64::MAX - 1. - // This will pass when blocking is implemented. - let flags = libc::EFD_CLOEXEC; - let fd = unsafe { libc::eventfd(0, flags) }; - // Write u64 - 1. - let mut sized_8_data: [u8; 8] = (u64::MAX - 1).to_ne_bytes(); - let res: i64 = unsafe { - libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() - }; - assert_eq!(res, 8); - - // Write 1. - sized_8_data = 1_u64.to_ne_bytes(); - // Write 1 to the counter. - let _res: i64 = unsafe { - libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() //~ERROR: blocking is unsupported - }; -} diff --git a/src/tools/miri/tests/fail-dep/libc/libc_eventfd_write_block.stderr b/src/tools/miri/tests/fail-dep/libc/libc_eventfd_write_block.stderr deleted file mode 100644 index 2b6066057941f..0000000000000 --- a/src/tools/miri/tests/fail-dep/libc/libc_eventfd_write_block.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: unsupported operation: eventfd: blocking is unsupported - --> tests/fail-dep/libc/libc_eventfd_write_block.rs:LL:CC - | -LL | libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ eventfd: blocking is unsupported - | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/libc_eventfd_write_block.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.rs b/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.rs index a47bb671e32b8..a2e8a533c43ad 100644 --- a/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.rs +++ b/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.rs @@ -8,8 +8,8 @@ struct Foo(u64); impl Foo { - #[rustfmt::skip] // rustfmt is wrong about which line contains an error - fn add(&mut self, n: u64) -> u64 { //~ ERROR: /reborrow through .* is forbidden/ + fn add(&mut self, n: u64) -> u64 { + //~^ ERROR: /reborrow through .* is forbidden/ self.0 + n } } diff --git a/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs b/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs index c92d9c3fe7095..dd9c0eb0b54d6 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs @@ -1,5 +1,5 @@ //@only-target: linux -// test_race depends on a deterministic schedule. +// test_race, test_blocking_read and test_blocking_write depend on a deterministic schedule. //@compile-flags: -Zmiri-preemption-rate=0 // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint @@ -11,6 +11,9 @@ fn main() { test_read_write(); test_race(); test_syscall(); + test_blocking_read(); + test_blocking_write(); + test_two_threads_blocked_on_eventfd(); } fn read_bytes(fd: i32, buf: &mut [u8; N]) -> i32 { @@ -118,3 +121,117 @@ fn test_syscall() { let fd = unsafe { libc::syscall(libc::SYS_eventfd2, initval, flags) }; assert_ne!(fd, -1); } + +// This test will block on eventfd read then get unblocked by `write`. +fn test_blocking_read() { + // eventfd read will block when EFD_NONBLOCK flag is clear and counter = 0. + let flags = libc::EFD_CLOEXEC; + let fd = unsafe { libc::eventfd(0, flags) }; + let thread1 = thread::spawn(move || { + let mut buf: [u8; 8] = [0; 8]; + // This will block. + let res = read_bytes(fd, &mut buf); + // read returns number of bytes has been read, which is always 8. + assert_eq!(res, 8); + let counter = u64::from_ne_bytes(buf); + assert_eq!(counter, 1); + }); + let sized_8_data: [u8; 8] = 1_u64.to_ne_bytes(); + // Pass control to thread1 so it can block on eventfd `read`. + thread::yield_now(); + // Write 1 to the counter to unblock thread1. + let res = write_bytes(fd, sized_8_data); + assert_eq!(res, 8); + thread1.join().unwrap(); +} + +/// This test will block on eventfd `write` then get unblocked by `read`. +fn test_blocking_write() { + // eventfd write will block when EFD_NONBLOCK flag is clear + // and the addition caused counter to exceed u64::MAX - 1. + let flags = libc::EFD_CLOEXEC; + let fd = unsafe { libc::eventfd(0, flags) }; + // Write u64 - 1, so the all subsequent write will block. + let sized_8_data: [u8; 8] = (u64::MAX - 1).to_ne_bytes(); + let res: i64 = unsafe { + libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() + }; + assert_eq!(res, 8); + + let thread1 = thread::spawn(move || { + let sized_8_data = 1_u64.to_ne_bytes(); + // Write 1 to the counter, this will block. + let res: i64 = unsafe { + libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() + }; + // Make sure that write is successful. + assert_eq!(res, 8); + }); + let mut buf: [u8; 8] = [0; 8]; + // Pass control to thread1 so it can block on eventfd `write`. + thread::yield_now(); + // This will unblock previously blocked eventfd read. + let res = read_bytes(fd, &mut buf); + // read returns number of bytes has been read, which is always 8. + assert_eq!(res, 8); + let counter = u64::from_ne_bytes(buf); + assert_eq!(counter, (u64::MAX - 1)); + thread1.join().unwrap(); +} + +// Test two threads blocked on eventfd. +// Expected behaviour: +// 1. thread1 and thread2 both blocked on `write`. +// 2. thread3 unblocks both thread1 and thread2 +// 3. The write in thread1 and thread2 return successfully. +fn test_two_threads_blocked_on_eventfd() { + // eventfd write will block when EFD_NONBLOCK flag is clear + // and the addition caused counter to exceed u64::MAX - 1. + let flags = libc::EFD_CLOEXEC; + let fd = unsafe { libc::eventfd(0, flags) }; + // Write u64 - 1, so the all subsequent write will block. + let sized_8_data: [u8; 8] = (u64::MAX - 1).to_ne_bytes(); + let res: i64 = unsafe { + libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() + }; + assert_eq!(res, 8); + + let thread1 = thread::spawn(move || { + thread::park(); + let sized_8_data = 1_u64.to_ne_bytes(); + let res: i64 = unsafe { + libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() + }; + // Make sure that write is successful. + assert_eq!(res, 8); + }); + + let thread2 = thread::spawn(move || { + thread::park(); + let sized_8_data = 1_u64.to_ne_bytes(); + let res: i64 = unsafe { + libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() + }; + // Make sure that write is successful. + assert_eq!(res, 8); + }); + + let thread3 = thread::spawn(move || { + thread::park(); + let mut buf: [u8; 8] = [0; 8]; + // This will unblock previously blocked eventfd read. + let res = read_bytes(fd, &mut buf); + // read returns number of bytes has been read, which is always 8. + assert_eq!(res, 8); + let counter = u64::from_ne_bytes(buf); + assert_eq!(counter, (u64::MAX - 1)); + }); + + thread1.thread().unpark(); + thread2.thread().unpark(); + thread3.thread().unpark(); + + thread1.join().unwrap(); + thread2.join().unwrap(); + thread3.join().unwrap(); +} diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index 66843ca584b8d..4de315e358975 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -959,10 +959,20 @@ pub fn libm() { unsafe { ldexp(a, b) } } - assert_approx_eq!(64f32.sqrt(), 8f32); - assert_approx_eq!(64f64.sqrt(), 8f64); + assert_eq!(64_f32.sqrt(), 8_f32); + assert_eq!(64_f64.sqrt(), 8_f64); + assert_eq!(f32::INFINITY.sqrt(), f32::INFINITY); + assert_eq!(f64::INFINITY.sqrt(), f64::INFINITY); + assert_eq!(0.0_f32.sqrt().total_cmp(&0.0), std::cmp::Ordering::Equal); + assert_eq!(0.0_f64.sqrt().total_cmp(&0.0), std::cmp::Ordering::Equal); + assert_eq!((-0.0_f32).sqrt().total_cmp(&-0.0), std::cmp::Ordering::Equal); + assert_eq!((-0.0_f64).sqrt().total_cmp(&-0.0), std::cmp::Ordering::Equal); assert!((-5.0_f32).sqrt().is_nan()); assert!((-5.0_f64).sqrt().is_nan()); + assert!(f32::NEG_INFINITY.sqrt().is_nan()); + assert!(f64::NEG_INFINITY.sqrt().is_nan()); + assert!(f32::NAN.sqrt().is_nan()); + assert!(f64::NAN.sqrt().is_nan()); assert_approx_eq!(25f32.powi(-2), 0.0016f32); assert_approx_eq!(23.2f64.powi(2), 538.24f64); diff --git a/src/tools/miri/tests/pass/stacked-borrows/2phase.rs b/src/tools/miri/tests/pass/stacked-borrows/2phase.rs index eb543d691e10b..fb4ba60583736 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/2phase.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/2phase.rs @@ -1,3 +1,6 @@ +// FIXME: this miscompiles with optimizations, see . +//@compile-flags: -Zmir-opt-level=0 + trait S: Sized { fn tpb(&mut self, _s: Self) {} } @@ -75,6 +78,25 @@ fn with_interior_mutability() { }); } +// This one really shouldn't be accepted, but since we treat 2phase as raw, we do accept it. +// Tree Borrows rejects it. +fn aliasing_violation() { + struct Foo(u64); + impl Foo { + fn add(&mut self, n: u64) -> u64 { + self.0 + n + } + } + + let mut f = Foo(0); + let alias = &mut f.0 as *mut u64; + let res = f.add(unsafe { + *alias = 42; + 0 + }); + assert_eq!(res, 42); +} + fn main() { two_phase1(); two_phase2(); @@ -84,4 +106,5 @@ fn main() { with_interior_mutability(); two_phase_overlapping1(); two_phase_overlapping2(); + aliasing_violation(); } diff --git a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs index c75824d7f9be0..4261f411eea47 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs @@ -8,6 +8,7 @@ fn main() { mut_raw_then_mut_shr(); mut_shr_then_mut_raw(); mut_raw_mut(); + mut_raw_mut2(); partially_invalidate_mut(); drop_after_sharing(); // direct_mut_to_const_raw(); @@ -96,6 +97,18 @@ fn mut_raw_mut() { assert_eq!(x, 4); } +// A variant of `mut_raw_mut` that does *not* get accepted by Tree Borrows. +// It's kind of an accident that we accept it in Stacked Borrows... +fn mut_raw_mut2() { + unsafe { + let mut root = 0; + let to = &mut root as *mut i32; + *to = 0; + let _val = root; + *to = 0; + } +} + fn partially_invalidate_mut() { let data = &mut (0u8, 0u8); let reborrow = &mut *data as *mut (u8, u8); diff --git a/src/tools/miri/tests/pass/tls/windows-tls.rs b/src/tools/miri/tests/pass/tls/windows-tls.rs new file mode 100644 index 0000000000000..58131be190378 --- /dev/null +++ b/src/tools/miri/tests/pass/tls/windows-tls.rs @@ -0,0 +1,18 @@ +//@only-target: windows # this directly tests windows-only functions + +use std::ffi::c_void; +use std::ptr; + +extern "system" { + fn TlsAlloc() -> u32; + fn TlsSetValue(key: u32, val: *mut c_void) -> bool; + fn TlsGetValue(key: u32) -> *mut c_void; + fn TlsFree(key: u32) -> bool; +} + +fn main() { + let key = unsafe { TlsAlloc() }; + assert!(unsafe { TlsSetValue(key, ptr::without_provenance_mut(1)) }); + assert_eq!(unsafe { TlsGetValue(key).addr() }, 1); + assert!(unsafe { TlsFree(key) }); +} diff --git a/src/tools/nix-dev-shell/envrc-flake b/src/tools/nix-dev-shell/envrc-flake index 218d88d8721fa..9def420f05cb4 100644 --- a/src/tools/nix-dev-shell/envrc-flake +++ b/src/tools/nix-dev-shell/envrc-flake @@ -1,7 +1,7 @@ # If you want to use this as an .envrc file to create a shell with necessery components # to develop rustc, use the following command in the root of the rusr checkout: # -# ln -s ./src/tools/nix-dev-shell/envrc-flake ./.envrc && echo .envrc >> .git/info/exclude +# ln -s ./src/tools/nix-dev-shell/envrc-flake ./.envrc && nix flake update --flake ./src/tools/nix-dev-shell && echo .envrc >> .git/info/exclude if nix flake show path:./src/tools/nix-dev-shell &> /dev/null; then use flake path:./src/tools/nix-dev-shell diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs index 494daeca96364..ffe10092cc28a 100644 --- a/src/tools/run-make-support/src/external_deps/rustc.rs +++ b/src/tools/run-make-support/src/external_deps/rustc.rs @@ -227,6 +227,12 @@ impl Rustc { self } + /// Normalize the line number in the stderr output + pub fn ui_testing(&mut self) -> &mut Self { + self.cmd.arg(format!("-Zui-testing")); + self + } + /// Specify the target triple, or a path to a custom target json spec file. pub fn target>(&mut self, target: S) -> &mut Self { let target = target.as_ref(); diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 019609e6a5beb..2bd4d17fe2226 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1492,9 +1492,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_abi" -version = "0.76.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709fde78db053c78c87776ec738677649f791645883f82ff145f68caf9f18e1a" +checksum = "613760a3071b25a67a8d7bc97b37c7fd4722562e9479137b83ae9cf8f8c1601a" dependencies = [ "bitflags 2.6.0", "ra-ap-rustc_index", @@ -1503,9 +1503,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_index" -version = "0.76.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da115d496e5abd65e2dceb6883d7597593badfe23fea3439202b8da5a11ea250" +checksum = "5b2bc6b4ecede8ff28295041e22c2e66853f8e0125990c05135bad3c30bad12c" dependencies = [ "arrayvec", "ra-ap-rustc_index_macros", @@ -1514,9 +1514,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_index_macros" -version = "0.76.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be86d06a75a8125c1ace197d5030e6e02721348d32e572baea35c891669ad1e2" +checksum = "2374a39fb2d92d0509178c2b442eadca3cc10e403ef9729a040c1855b08ff261" dependencies = [ "proc-macro2", "quote", @@ -1525,9 +1525,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_lexer" -version = "0.76.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b64b46ae0d8f59acc32e64e0085532b831f0d6182d870a7cd86c046c2c46e722" +checksum = "5a2cf8e48b69af3ecc29ed3449892e8a999111d2f75212a78aa242e117cf1711" dependencies = [ "unicode-properties", "unicode-xid", @@ -1535,9 +1535,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_parse_format" -version = "0.76.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbdaad19ddbd0ff46e947ca8dbb6ae678a112d3938669fb3ad6bfd244917e24b" +checksum = "8d6f59a22b559263c5c42747ae362cf5d4fb272293fa119a4623f8ec288f9656" dependencies = [ "ra-ap-rustc_index", "ra-ap-rustc_lexer", @@ -1545,9 +1545,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_pattern_analysis" -version = "0.76.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc5761e37c78d98ede9f20f6b66526093d0be66aa256d5cbdf214495843ba74d" +checksum = "a7d0575b54ffe09bc5d2f158454bc05f0c30c01d9992310965f854be50ae22b8" dependencies = [ "ra-ap-rustc_index", "rustc-hash 2.0.0", diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 94e7de553bf49..632b290ba9844 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -84,11 +84,11 @@ tt = { path = "./crates/tt", version = "0.0.0" } vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" } vfs = { path = "./crates/vfs", version = "0.0.0" } -ra-ap-rustc_lexer = { version = "0.76", default-features = false } -ra-ap-rustc_parse_format = { version = "0.76", default-features = false } -ra-ap-rustc_index = { version = "0.76", default-features = false } -ra-ap-rustc_abi = { version = "0.76", default-features = false } -ra-ap-rustc_pattern_analysis = { version = "0.76", default-features = false } +ra-ap-rustc_lexer = { version = "0.80", default-features = false } +ra-ap-rustc_parse_format = { version = "0.80", default-features = false } +ra-ap-rustc_index = { version = "0.80", default-features = false } +ra-ap-rustc_abi = { version = "0.80", default-features = false } +ra-ap-rustc_pattern_analysis = { version = "0.80", default-features = false } # local crates that aren't published to crates.io. These should not have versions. test-fixture = { path = "./crates/test-fixture" } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index e4881d7520138..54aa18ce20766 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -916,6 +916,32 @@ impl<'a> InferenceTable<'a> { /// Check if given type is `Sized` or not pub(crate) fn is_sized(&mut self, ty: &Ty) -> bool { + let mut ty = ty.clone(); + { + let mut structs = SmallVec::<[_; 8]>::new(); + // Must use a loop here and not recursion because otherwise users will conduct completely + // artificial examples of structs that have themselves as the tail field and complain r-a crashes. + while let Some((AdtId::StructId(id), subst)) = ty.as_adt() { + let struct_data = self.db.struct_data(id); + if let Some((last_field, _)) = struct_data.variant_data.fields().iter().next_back() + { + let last_field_ty = self.db.field_types(id.into())[last_field] + .clone() + .substitute(Interner, subst); + if structs.contains(&ty) { + // A struct recursively contains itself as a tail field somewhere. + return true; // Don't overload the users with too many errors. + } + structs.push(ty); + // Structs can have DST as its last field and such cases are not handled + // as unsized by the chalk, so we do this manually. + ty = last_field_ty; + } else { + break; + }; + } + } + // Early return for some obvious types if matches!( ty.kind(Interner), @@ -930,16 +956,6 @@ impl<'a> InferenceTable<'a> { return true; } - if let Some((AdtId::StructId(id), subst)) = ty.as_adt() { - let struct_data = self.db.struct_data(id); - if let Some((last_field, _)) = struct_data.variant_data.fields().iter().last() { - let last_field_ty = - self.db.field_types(id.into())[last_field].clone().substitute(Interner, subst); - // Structs can have DST as its last field and such cases are not handled - // as unsized by the chalk, so we do this manually - return self.is_sized(&last_field_ty); - } - } let Some(sized) = self .db .lang_item(self.trait_env.krate, LangItem::Sized) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index 9b982a124e7b2..624148cab20f2 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs @@ -4790,3 +4790,24 @@ fn allowed3(baz: impl Baz>) {} "#]], ) } + +#[test] +fn recursive_tail_sized() { + check_infer( + r#" +struct WeirdFoo(WeirdBar); +struct WeirdBar(WeirdFoo); + +fn bar(v: *const ()) { + let _ = v as *const WeirdFoo; +} + "#, + expect![[r#" + 62..63 'v': *const () + 76..113 '{ ...Foo; }': () + 86..87 '_': *const WeirdFoo + 90..91 'v': *const () + 90..110 'v as *...irdFoo': *const WeirdFoo + "#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs index 1d2d3350f7c76..0146369f298b5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs @@ -116,6 +116,9 @@ impl<'a> AssistContext<'a> { pub(crate) fn find_node_at_offset(&self) -> Option { find_node_at_offset(self.source_file.syntax(), self.offset()) } + pub(crate) fn find_node_at_trimmed_offset(&self) -> Option { + find_node_at_offset(self.source_file.syntax(), self.trimmed_range.start()) + } pub(crate) fn find_node_at_range(&self) -> Option { find_node_at_range(self.source_file.syntax(), self.trimmed_range) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs index 2f4a263ee0700..42f615e71daf6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs @@ -1,5 +1,5 @@ use syntax::{ - ast::{self, edit::AstNodeEdit, make}, + ast::{self, edit_in_place::Indent, syntax_factory::SyntaxFactory}, AstNode, }; @@ -39,12 +39,16 @@ pub(crate) fn add_braces(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( }, expr.syntax().text_range(), |builder| { - let block_expr = AstNodeEdit::indent( - &make::block_expr(None, Some(expr.clone())), - AstNodeEdit::indent_level(&expr), - ); + let make = SyntaxFactory::new(); + let mut editor = builder.make_editor(expr.syntax()); - builder.replace(expr.syntax().text_range(), block_expr.syntax().text()); + let block_expr = make.block_expr(None, Some(expr.clone())); + block_expr.indent(expr.indent_level()); + + editor.replace(expr.syntax(), block_expr.syntax()); + + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.file_id(), editor); }, ) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs index a211ca8f2d675..236d33878edc1 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -30,8 +30,8 @@ use crate::{utils, AssistContext, AssistId, AssistKind, Assists}; // // fn handle(action: Action) { // match action { -// $0Action::Move { distance } => todo!(), -// Action::Stop => todo!(), +// Action::Move { distance } => ${1:todo!()}, +// Action::Stop => ${2:todo!()},$0 // } // } // ``` @@ -234,10 +234,11 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) } } - let mut first_new_arm = None; + let mut added_arms = Vec::new(); + let mut todo_placeholders = Vec::new(); for arm in missing_arms { - first_new_arm.get_or_insert_with(|| arm.clone()); - new_match_arm_list.add_arm(arm); + todo_placeholders.push(arm.expr().unwrap()); + added_arms.push(arm); } if needs_catch_all_arm && !has_catch_all_arm { @@ -248,14 +249,28 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) make::ext::expr_todo(), ) .clone_for_update(); - first_new_arm.get_or_insert_with(|| arm.clone()); + todo_placeholders.push(arm.expr().unwrap()); + added_arms.push(arm); + } + + let first_new_arm = added_arms.first().cloned(); + let last_new_arm = added_arms.last().cloned(); + + for arm in added_arms { new_match_arm_list.add_arm(arm); } - if let (Some(first_new_arm), Some(cap)) = (first_new_arm, ctx.config.snippet_cap) { - match first_new_arm.syntax().descendants().find_map(ast::WildcardPat::cast) { - Some(it) => edit.add_placeholder_snippet(cap, it), - None => edit.add_tabstop_before(cap, first_new_arm), + if let Some(cap) = ctx.config.snippet_cap { + if let Some(it) = first_new_arm.and_then(|arm| arm.syntax().descendants().find_map(ast::WildcardPat::cast)) { + edit.add_placeholder_snippet(cap, it); + } + + for placeholder in todo_placeholders { + edit.add_placeholder_snippet(cap, placeholder); + } + + if let Some(arm) = last_new_arm { + edit.add_tabstop_after(cap, arm); } } @@ -581,8 +596,8 @@ fn foo(a: bool) { r#" fn foo(a: bool) { match a { - $0true => todo!(), - false => todo!(), + true => ${1:todo!()}, + false => ${2:todo!()},$0 } } "#, @@ -604,7 +619,7 @@ fn foo(a: bool) { fn foo(a: bool) { match a { true => {} - $0false => todo!(), + false => ${1:todo!()},$0 } } "#, @@ -654,10 +669,10 @@ fn foo(a: bool) { r#" fn foo(a: bool) { match (a, a) { - $0(true, true) => todo!(), - (true, false) => todo!(), - (false, true) => todo!(), - (false, false) => todo!(), + (true, true) => ${1:todo!()}, + (true, false) => ${2:todo!()}, + (false, true) => ${3:todo!()}, + (false, false) => ${4:todo!()},$0 } } "#, @@ -677,8 +692,8 @@ fn foo(a: bool) { r#" fn foo(a: bool) { match [a] { - $0[true] => todo!(), - [false] => todo!(), + [true] => ${1:todo!()}, + [false] => ${2:todo!()},$0 } } "#, @@ -695,8 +710,8 @@ fn foo(a: bool) { r#" fn foo(a: bool) { match [a,] { - $0[true] => todo!(), - [false] => todo!(), + [true] => ${1:todo!()}, + [false] => ${2:todo!()},$0 } } "#, @@ -715,9 +730,9 @@ fn foo(a: bool) { fn foo(a: bool) { match [a, a] { [true, true] => todo!(), - $0[true, false] => todo!(), - [false, true] => todo!(), - [false, false] => todo!(), + [true, false] => ${1:todo!()}, + [false, true] => ${2:todo!()}, + [false, false] => ${3:todo!()},$0 } } "#, @@ -734,10 +749,10 @@ fn foo(a: bool) { r#" fn foo(a: bool) { match [a, a] { - $0[true, true] => todo!(), - [true, false] => todo!(), - [false, true] => todo!(), - [false, false] => todo!(), + [true, true] => ${1:todo!()}, + [true, false] => ${2:todo!()}, + [false, true] => ${3:todo!()}, + [false, false] => ${4:todo!()},$0 } } "#, @@ -759,8 +774,8 @@ fn foo(a: bool) { fn foo(a: bool) { match (a, a) { (true | false, true) => {} - $0(true, false) => todo!(), - (false, false) => todo!(), + (true, false) => ${1:todo!()}, + (false, false) => ${2:todo!()},$0 } } "#, @@ -779,9 +794,9 @@ fn foo(a: bool) { fn foo(a: bool) { match (a, a) { (false, true) => {} - $0(true, true) => todo!(), - (true, false) => todo!(), - (false, false) => todo!(), + (true, true) => ${1:todo!()}, + (true, false) => ${2:todo!()}, + (false, false) => ${3:todo!()},$0 } } "#, @@ -815,7 +830,7 @@ fn main() { match A::As { A::Bs { x, y: Some(_) } => {} A::Cs(_, Some(_)) => {} - $0A::As => todo!(), + A::As => ${1:todo!()},$0 } } "#, @@ -838,7 +853,7 @@ fn main() { fn main() { match None { None => {} - Some(${0:_}) => todo!(), + Some(${1:_}) => ${2:todo!()},$0 } } "#, @@ -862,7 +877,7 @@ enum A { As, Bs, Cs(Option) } fn main() { match A::As { A::Cs(_) | A::Bs => {} - $0A::As => todo!(), + A::As => ${1:todo!()},$0 } } "#, @@ -892,8 +907,8 @@ fn main() { A::Bs if 0 < 1 => {} A::Ds(_value) => { let x = 1; } A::Es(B::Xs) => (), - $0A::As => todo!(), - A::Cs => todo!(), + A::As => ${1:todo!()}, + A::Cs => ${2:todo!()},$0 } } "#, @@ -919,7 +934,7 @@ fn main() { match A::As { A::As(_) => {} a @ A::Bs(_) => {} - A::Cs(${0:_}) => todo!(), + A::Cs(${1:_}) => ${2:todo!()},$0 } } "#, @@ -945,11 +960,11 @@ enum A { As, Bs, Cs(String), Ds(String, String), Es { x: usize, y: usize } } fn main() { let a = A::As; match a { - $0A::As => todo!(), - A::Bs => todo!(), - A::Cs(_) => todo!(), - A::Ds(_, _) => todo!(), - A::Es { x, y } => todo!(), + A::As => ${1:todo!()}, + A::Bs => ${2:todo!()}, + A::Cs(_) => ${3:todo!()}, + A::Ds(_, _) => ${4:todo!()}, + A::Es { x, y } => ${5:todo!()},$0 } } "#, @@ -982,9 +997,9 @@ fn main() { let b = B::One; match (a, b) { (A::Two, B::One) => {}, - $0(A::One, B::One) => todo!(), - (A::One, B::Two) => todo!(), - (A::Two, B::Two) => todo!(), + (A::One, B::One) => ${1:todo!()}, + (A::One, B::Two) => ${2:todo!()}, + (A::Two, B::Two) => ${3:todo!()},$0 } } "#, @@ -1013,10 +1028,10 @@ fn main() { let a = A::One; let b = B::One; match (a, b) { - $0(A::One, B::One) => todo!(), - (A::One, B::Two) => todo!(), - (A::Two, B::One) => todo!(), - (A::Two, B::Two) => todo!(), + (A::One, B::One) => ${1:todo!()}, + (A::One, B::Two) => ${2:todo!()}, + (A::Two, B::One) => ${3:todo!()}, + (A::Two, B::Two) => ${4:todo!()},$0 } } "#, @@ -1045,10 +1060,10 @@ fn main() { let a = A::One; let b = B::One; match (&a, &b) { - $0(A::One, B::One) => todo!(), - (A::One, B::Two) => todo!(), - (A::Two, B::One) => todo!(), - (A::Two, B::Two) => todo!(), + (A::One, B::One) => ${1:todo!()}, + (A::One, B::Two) => ${2:todo!()}, + (A::Two, B::One) => ${3:todo!()}, + (A::Two, B::Two) => ${4:todo!()},$0 } } "#, @@ -1080,9 +1095,9 @@ fn main() { let b = B::One; match (a, b) { (A::Two, B::One) => {} - $0(A::One, B::One) => todo!(), - (A::One, B::Two) => todo!(), - (A::Two, B::Two) => todo!(), + (A::One, B::One) => ${1:todo!()}, + (A::One, B::Two) => ${2:todo!()}, + (A::Two, B::Two) => ${3:todo!()},$0 } } "#, @@ -1107,9 +1122,9 @@ fn main() { match (A, B, C) { (A | B , A, A | B | C) => (), (A | B | C , B | C, A | B | C) => (), - $0(C, A, A) => todo!(), - (C, A, B) => todo!(), - (C, A, C) => todo!(), + (C, A, A) => ${1:todo!()}, + (C, A, B) => ${2:todo!()}, + (C, A, C) => ${3:todo!()},$0 } } "#, @@ -1138,7 +1153,7 @@ fn main() { match (a, b) { (Some(_), _) => {} (None, Some(_)) => {} - $0(None, None) => todo!(), + (None, None) => ${1:todo!()},$0 } } "#, @@ -1203,8 +1218,8 @@ enum A { One, Two } fn main() { let a = A::One; match (a, ) { - $0(A::One,) => todo!(), - (A::Two,) => todo!(), + (A::One,) => ${1:todo!()}, + (A::Two,) => ${2:todo!()},$0 } } "#, @@ -1228,7 +1243,7 @@ enum A { As } fn foo(a: &A) { match a { - $0A::As => todo!(), + A::As => ${1:todo!()},$0 } } "#, @@ -1253,7 +1268,7 @@ enum A { fn foo(a: &mut A) { match a { - $0A::Es { x, y } => todo!(), + A::Es { x, y } => ${1:todo!()},$0 } } "#, @@ -1313,8 +1328,8 @@ enum E { X, Y } fn main() { match E::X { - $0E::X => todo!(), - E::Y => todo!(), + E::X => ${1:todo!()}, + E::Y => ${2:todo!()},$0 } } "#, @@ -1360,8 +1375,8 @@ use foo::E::X; fn main() { match X { - $0X => todo!(), - foo::E::Y => todo!(), + X => ${1:todo!()}, + foo::E::Y => ${2:todo!()},$0 } } "#, @@ -1388,7 +1403,7 @@ fn foo(a: A) { match a { // foo bar baz A::One => {} - $0A::Two => todo!(), + A::Two => ${1:todo!()},$0 // This is where the rest should be } } @@ -1412,8 +1427,8 @@ fn foo(a: A) { enum A { One, Two } fn foo(a: A) { match a { - $0A::One => todo!(), - A::Two => todo!(), + A::One => ${1:todo!()}, + A::Two => ${2:todo!()},$0 // foo bar baz } } @@ -1437,8 +1452,8 @@ fn foo(a: A) { enum A { One, Two, } fn foo(a: A) { match a { - $0A::One => todo!(), - A::Two => todo!(), + A::One => ${1:todo!()}, + A::Two => ${2:todo!()},$0 } } "#, @@ -1460,8 +1475,8 @@ fn foo(opt: Option) { r#" fn foo(opt: Option) { match opt { - Some(${0:_}) => todo!(), - None => todo!(), + Some(${1:_}) => ${2:todo!()}, + None => ${3:todo!()},$0 } } "#, @@ -1493,9 +1508,9 @@ enum Test { fn foo(t: Test) { m!(match t { - $0Test::A => todo!(), - Test::B => todo!(), - Test::C => todo!(), + Test::A => ${1:todo!()}, + Test::B => ${2:todo!()}, + Test::C => ${3:todo!()},$0 }); }"#, ); @@ -1530,7 +1545,7 @@ fn foo(t: bool) { fn foo(t: bool) { match t { true => 1 + 2, - $0false => todo!(), + false => ${1:todo!()},$0 } }"#, ); @@ -1550,7 +1565,7 @@ fn foo(t: bool) { fn foo(t: bool) { match t { true => 1 + 2, - $0false => todo!(), + false => ${1:todo!()},$0 } }"#, ); @@ -1571,8 +1586,8 @@ fn foo(t: bool) { fn foo(t: bool) { match t { _ => 1 + 2, - $0true => todo!(), - false => todo!(), + true => ${1:todo!()}, + false => ${2:todo!()},$0 } }"#, ); @@ -1595,8 +1610,8 @@ pub enum E { A, #[doc(hidden)] B, } r#" fn foo(t: ::e::E) { match t { - $0e::E::A => todo!(), - _ => todo!(), + e::E::A => ${1:todo!()}, + _ => ${2:todo!()},$0 } } "#, @@ -1620,9 +1635,9 @@ pub enum E { A, #[doc(hidden)] B, } r#" fn foo(t: (bool, ::e::E)) { match t { - $0(true, e::E::A) => todo!(), - (false, e::E::A) => todo!(), - _ => todo!(), + (true, e::E::A) => ${1:todo!()}, + (false, e::E::A) => ${2:todo!()}, + _ => ${3:todo!()},$0 } } "#, @@ -1646,7 +1661,7 @@ pub enum E { #[doc(hidden)] A, } r#" fn foo(t: ::e::E) { match t { - ${0:_} => todo!(), + ${1:_} => ${2:todo!()},$0 } } "#, @@ -1707,7 +1722,7 @@ pub enum E { A, } fn foo(t: ::e::E) { match t { e::E::A => todo!(), - ${0:_} => todo!(), + ${1:_} => ${2:todo!()},$0 } } "#, @@ -1732,8 +1747,8 @@ pub enum E { A, } r#" fn foo(t: ::e::E) { match t { - $0e::E::A => todo!(), - _ => todo!(), + e::E::A => ${1:todo!()}, + _ => ${2:todo!()},$0 } } "#, @@ -1757,8 +1772,8 @@ pub enum E { A, #[doc(hidden)] B }"#, r#" fn foo(t: ::e::E) { match t { - $0e::E::A => todo!(), - _ => todo!(), + e::E::A => ${1:todo!()}, + _ => ${2:todo!()},$0 } } "#, @@ -1784,7 +1799,7 @@ pub enum E { A, #[doc(hidden)] B }"#, fn foo(t: ::e::E) { match t { e::E::A => todo!(), - ${0:_} => todo!(), + ${1:_} => ${2:todo!()},$0 } } "#, @@ -1809,7 +1824,7 @@ pub enum E { #[doc(hidden)] A, }"#, fn foo(t: ::e::E, b: bool) { match t { _ if b => todo!(), - ${0:_} => todo!(), + ${1:_} => ${2:todo!()},$0 } } "#, @@ -1850,8 +1865,8 @@ pub enum E { A, #[doc(hidden)] B, }"#, r#" fn foo(t: ::e::E) { match t { - $0e::E::A => todo!(), - _ => todo!(), + e::E::A => ${1:todo!()}, + _ => ${2:todo!()},$0 } } "#, @@ -1874,8 +1889,8 @@ enum E { A, #[doc(hidden)] B, } fn foo(t: E) { match t { - $0E::A => todo!(), - E::B => todo!(), + E::A => ${1:todo!()}, + E::B => ${2:todo!()},$0 } }"#, ); @@ -1899,8 +1914,8 @@ enum E { A, B, } fn foo(t: E) { match t { - $0E::A => todo!(), - E::B => todo!(), + E::A => ${1:todo!()}, + E::B => ${2:todo!()},$0 } }"#, ); @@ -1924,8 +1939,8 @@ enum E { A, #[doc(hidden)] B, } fn foo(t: E) { match t { - $0E::A => todo!(), - E::B => todo!(), + E::A => ${1:todo!()}, + E::B => ${2:todo!()},$0 } }"#, ); @@ -1975,8 +1990,8 @@ enum A { fn a() { let b = A::A; match b { - $0A::A => todo!(), - A::Missing { a, u32, c } => todo!(), + A::A => ${1:todo!()}, + A::Missing { a, u32, c } => ${2:todo!()},$0 } }"#, ) @@ -2013,8 +2028,8 @@ pub enum E { fn f() { let value = E::A; match value { - $0E::A => todo!(), - E::B(s) => todo!(), + E::A => ${1:todo!()}, + E::B(s) => ${2:todo!()},$0 } } "#, @@ -2051,8 +2066,8 @@ pub enum E { fn f() { let value = E::A; match value { - $0E::A => todo!(), - E::B(s1, s2) => todo!(), + E::A => ${1:todo!()}, + E::B(s1, s2) => ${2:todo!()},$0 } } "#, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs index 4608e9494bca1..f83de931eaba7 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs @@ -34,7 +34,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists, TextRange}; // } // ``` pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - let current_arm = ctx.find_node_at_offset::()?; + let current_arm = ctx.find_node_at_trimmed_offset::()?; // Don't try to handle arms with guards for now - can add support for this later if current_arm.guard().is_some() { return None; @@ -42,12 +42,21 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let current_expr = current_arm.expr()?; let current_text_range = current_arm.syntax().text_range(); let current_arm_types = get_arm_types(ctx, ¤t_arm); + let multi_arm_selection = !ctx.has_empty_selection() + && ctx.selection_trimmed().end() > current_arm.syntax().text_range().end(); // We check if the following match arms match this one. We could, but don't, // compare to the previous match arm as well. let arms_to_merge = successors(Some(current_arm), |it| neighbor(it, Direction::Next)) .take_while(|arm| match arm.expr() { Some(expr) if arm.guard().is_none() => { + // don't include match arms that start after our selection + if multi_arm_selection + && arm.syntax().text_range().start() >= ctx.selection_trimmed().end() + { + return false; + } + let same_text = expr.syntax().text() == current_expr.syntax().text(); if !same_text { return false; @@ -298,6 +307,96 @@ fn main() { ) } + #[test] + fn merge_match_arms_selection_has_leading_whitespace() { + check_assist( + merge_match_arms, + r#" +#[derive(Debug)] +enum X { A, B, C } + +fn main() { + match X::A { + $0 X::A => 0, + X::B => 0,$0 + X::C => 1, + } +} +"#, + r#" +#[derive(Debug)] +enum X { A, B, C } + +fn main() { + match X::A { + X::A | X::B => 0, + X::C => 1, + } +} +"#, + ); + } + + #[test] + fn merge_match_arms_stops_at_end_of_selection() { + check_assist( + merge_match_arms, + r#" +#[derive(Debug)] +enum X { A, B, C } + +fn main() { + match X::A { + $0 X::A => 0, + X::B => 0, + $0X::C => 0, + } +} +"#, + r#" +#[derive(Debug)] +enum X { A, B, C } + +fn main() { + match X::A { + X::A | X::B => 0, + X::C => 0, + } +} +"#, + ); + } + + #[test] + fn merge_match_arms_works_despite_accidental_selection() { + check_assist( + merge_match_arms, + r#" +#[derive(Debug)] +enum X { A, B, C } + +fn main() { + match X::A { + X::$0A$0 => 0, + X::B => 0, + X::C => 1, + } +} +"#, + r#" +#[derive(Debug)] +enum X { A, B, C } + +fn main() { + match X::A { + X::A | X::B => 0, + X::C => 1, + } +} +"#, + ); + } + #[test] fn merge_match_arms_rejects_guards() { check_assist_not_applicable( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_impl_items.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_impl_items.rs index ada89ce7c40ac..d7fa8826125b6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_impl_items.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_impl_items.rs @@ -3,7 +3,7 @@ use ide_db::{FxHashMap, RootDatabase}; use itertools::Itertools; use syntax::{ ast::{self, HasName}, - ted, AstNode, + AstNode, SyntaxElement, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -46,6 +46,11 @@ pub(crate) fn reorder_impl_items(acc: &mut Assists, ctx: &AssistContext<'_>) -> let impl_ast = ctx.find_node_at_offset::()?; let items = impl_ast.assoc_item_list()?; + let parent_node = match ctx.covering_element() { + SyntaxElement::Node(n) => n, + SyntaxElement::Token(t) => t.parent()?, + }; + // restrict the range // if cursor is in assoc_items, abort let assoc_range = items.syntax().text_range(); @@ -94,12 +99,14 @@ pub(crate) fn reorder_impl_items(acc: &mut Assists, ctx: &AssistContext<'_>) -> "Sort items by trait definition", target, |builder| { - let assoc_items = - assoc_items.into_iter().map(|item| builder.make_mut(item)).collect::>(); - assoc_items - .into_iter() - .zip(sorted) - .for_each(|(old, new)| ted::replace(old.syntax(), new.clone_for_update().syntax())); + let mut editor = builder.make_editor(&parent_node); + + assoc_items.into_iter().zip(sorted).for_each(|(old, new)| { + // FIXME: remove `clone_for_update` when `SyntaxEditor` handles it for us + editor.replace(old.syntax(), new.clone_for_update().syntax()) + }); + + builder.add_file_edits(ctx.file_id(), editor); }, ) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 64b7ab1a12301..eef4da55e94a5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -187,8 +187,8 @@ enum Action { Move { distance: u32 }, Stop } fn handle(action: Action) { match action { - $0Action::Move { distance } => todo!(), - Action::Stop => todo!(), + Action::Move { distance } => ${1:todo!()}, + Action::Stop => ${2:todo!()},$0 } } "#####, diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index 2dc6f0357e3d8..cb5738a3b4094 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -13,7 +13,7 @@ use serde_json::from_value; use span::Edition; use toolchain::Tool; -use crate::{utf8_stdout, ManifestPath, Sysroot}; +use crate::{utf8_stdout, ManifestPath, Sysroot, SysrootQueryMetadata}; use crate::{CfgOverrides, InvocationStrategy}; /// [`CargoWorkspace`] represents the logical structure of, well, a Cargo @@ -85,6 +85,8 @@ pub struct CargoConfig { pub target: Option, /// Sysroot loading behavior pub sysroot: Option, + /// How to query metadata for the sysroot crate. + pub sysroot_query_metadata: SysrootQueryMetadata, pub sysroot_src: Option, /// rustc private crate source pub rustc_source: Option, diff --git a/src/tools/rust-analyzer/crates/project-model/src/lib.rs b/src/tools/rust-analyzer/crates/project-model/src/lib.rs index 91bdef4889ca1..da8afc5d3a184 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/lib.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/lib.rs @@ -240,3 +240,10 @@ fn parse_cfg(s: &str) -> Result { }; Ok(res) } + +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] +pub enum SysrootQueryMetadata { + #[default] + CargoMetadata, + None, +} diff --git a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs index 19f4c35b5addd..8426e689a64d1 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs @@ -14,7 +14,7 @@ use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; use rustc_hash::FxHashMap; use toolchain::{probe_for_binary, Tool}; -use crate::{utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath}; +use crate::{utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath, SysrootQueryMetadata}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Sysroot { @@ -123,27 +123,43 @@ impl Sysroot { // FIXME: Expose a builder api as loading the sysroot got way too modular and complicated. impl Sysroot { /// Attempts to discover the toolchain's sysroot from the given `dir`. - pub fn discover(dir: &AbsPath, extra_env: &FxHashMap) -> Sysroot { + pub fn discover( + dir: &AbsPath, + extra_env: &FxHashMap, + sysroot_query_metadata: SysrootQueryMetadata, + ) -> Sysroot { let sysroot_dir = discover_sysroot_dir(dir, extra_env); let sysroot_src_dir = sysroot_dir.as_ref().ok().map(|sysroot_dir| { discover_sysroot_src_dir_or_add_component(sysroot_dir, dir, extra_env) }); - Sysroot::load_core_check(Some(sysroot_dir), sysroot_src_dir) + Sysroot::load_core_check(Some(sysroot_dir), sysroot_src_dir, sysroot_query_metadata) } pub fn discover_with_src_override( current_dir: &AbsPath, extra_env: &FxHashMap, sysroot_src_dir: AbsPathBuf, + sysroot_query_metadata: SysrootQueryMetadata, ) -> Sysroot { let sysroot_dir = discover_sysroot_dir(current_dir, extra_env); - Sysroot::load_core_check(Some(sysroot_dir), Some(Ok(sysroot_src_dir))) + Sysroot::load_core_check( + Some(sysroot_dir), + Some(Ok(sysroot_src_dir)), + sysroot_query_metadata, + ) } - pub fn discover_sysroot_src_dir(sysroot_dir: AbsPathBuf) -> Sysroot { + pub fn discover_sysroot_src_dir( + sysroot_dir: AbsPathBuf, + sysroot_query_metadata: SysrootQueryMetadata, + ) -> Sysroot { let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir) .ok_or_else(|| format_err!("can't find standard library sources in {sysroot_dir}")); - Sysroot::load_core_check(Some(Ok(sysroot_dir)), Some(sysroot_src_dir)) + Sysroot::load_core_check( + Some(Ok(sysroot_dir)), + Some(sysroot_src_dir), + sysroot_query_metadata, + ) } pub fn discover_rustc_src(&self) -> Option { @@ -186,15 +202,20 @@ impl Sysroot { }) } - pub fn load(sysroot_dir: Option, sysroot_src_dir: Option) -> Sysroot { - Self::load_core_check(sysroot_dir.map(Ok), sysroot_src_dir.map(Ok)) + pub fn load( + sysroot_dir: Option, + sysroot_src_dir: Option, + sysroot_query_metadata: SysrootQueryMetadata, + ) -> Sysroot { + Self::load_core_check(sysroot_dir.map(Ok), sysroot_src_dir.map(Ok), sysroot_query_metadata) } fn load_core_check( sysroot_dir: Option>, sysroot_src_dir: Option>, + sysroot_query_metadata: SysrootQueryMetadata, ) -> Sysroot { - let mut sysroot = Self::load_(sysroot_dir, sysroot_src_dir); + let mut sysroot = Self::load_(sysroot_dir, sysroot_src_dir, sysroot_query_metadata); if sysroot.error.is_none() { if let Some(src_root) = &sysroot.src_root { let has_core = match &sysroot.mode { @@ -220,6 +241,7 @@ impl Sysroot { fn load_( sysroot_dir: Option>, sysroot_src_dir: Option>, + sysroot_query_metadata: SysrootQueryMetadata, ) -> Sysroot { let sysroot_dir = match sysroot_dir { Some(Ok(sysroot_dir)) => Some(sysroot_dir), @@ -252,12 +274,15 @@ impl Sysroot { } } }; - let library_manifest = ManifestPath::try_from(sysroot_src_dir.join("Cargo.toml")).unwrap(); - if fs::metadata(&library_manifest).is_ok() { - if let Some(sysroot) = - Self::load_library_via_cargo(library_manifest, &sysroot_dir, &sysroot_src_dir) - { - return sysroot; + if sysroot_query_metadata == SysrootQueryMetadata::CargoMetadata { + let library_manifest = + ManifestPath::try_from(sysroot_src_dir.join("Cargo.toml")).unwrap(); + if fs::metadata(&library_manifest).is_ok() { + if let Some(sysroot) = + Self::load_library_via_cargo(library_manifest, &sysroot_dir, &sysroot_src_dir) + { + return sysroot; + } } } tracing::debug!("Stitching sysroot library: {sysroot_src_dir}"); @@ -444,13 +469,14 @@ fn discover_sysroot_src_dir_or_add_component( get_rust_src(sysroot_path) }) .ok_or_else(|| { - let error = "\ + tracing::error!(%sysroot_path, "can't load standard library, try installing `rust-src`"); + format_err!( + "\ can't load standard library from sysroot {sysroot_path} (discovered via `rustc --print sysroot`) -try installing the Rust source the same way you installed rustc"; - tracing::error!(error); - format_err!(error) +try installing `rust-src` the same way you installed `rustc`" + ) }) } diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs index ef115494a8886..f3cf2d83eaca6 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs @@ -13,7 +13,8 @@ use triomphe::Arc; use crate::{ sysroot::SysrootMode, workspace::ProjectWorkspaceKind, CargoWorkspace, CfgOverrides, - ManifestPath, ProjectJson, ProjectJsonData, ProjectWorkspace, Sysroot, WorkspaceBuildScripts, + ManifestPath, ProjectJson, ProjectJsonData, ProjectWorkspace, Sysroot, SysrootQueryMetadata, + WorkspaceBuildScripts, }; fn load_cargo(file: &str) -> (CrateGraph, ProcMacroPaths) { @@ -116,7 +117,7 @@ fn get_fake_sysroot() -> Sysroot { // fake sysroot, so we give them both the same path: let sysroot_dir = AbsPathBuf::assert(sysroot_path); let sysroot_src_dir = sysroot_dir.clone(); - Sysroot::load(Some(sysroot_dir), Some(sysroot_src_dir)) + Sysroot::load(Some(sysroot_dir), Some(sysroot_src_dir), SysrootQueryMetadata::CargoMetadata) } fn rooted_project_json(data: ProjectJsonData) -> ProjectJson { @@ -231,6 +232,7 @@ fn smoke_test_real_sysroot_cargo() { let sysroot = Sysroot::discover( AbsPath::assert(Utf8Path::new(env!("CARGO_MANIFEST_DIR"))), &Default::default(), + SysrootQueryMetadata::CargoMetadata, ); assert!(matches!(sysroot.mode(), SysrootMode::Workspace(_))); let project_workspace = ProjectWorkspace { diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index d53639e242320..f5ba71fcd05ff 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -211,34 +211,35 @@ impl ProjectWorkspace { let project_location = project_json.parent().to_path_buf(); let project_json: ProjectJson = ProjectJson::new(Some(project_json.clone()), &project_location, data); - ProjectWorkspace::load_inline( - project_json, - config.target.as_deref(), - &config.extra_env, - &config.cfg_overrides, - ) + ProjectWorkspace::load_inline(project_json, config) } ProjectManifest::CargoScript(rust_file) => { ProjectWorkspace::load_detached_file(rust_file, config)? } ProjectManifest::CargoToml(cargo_toml) => { let sysroot = match (&config.sysroot, &config.sysroot_src) { - (Some(RustLibSource::Discover), None) => { - Sysroot::discover(cargo_toml.parent(), &config.extra_env) - } + (Some(RustLibSource::Discover), None) => Sysroot::discover( + cargo_toml.parent(), + &config.extra_env, + config.sysroot_query_metadata, + ), (Some(RustLibSource::Discover), Some(sysroot_src)) => { Sysroot::discover_with_src_override( cargo_toml.parent(), &config.extra_env, sysroot_src.clone(), + config.sysroot_query_metadata, ) } - (Some(RustLibSource::Path(path)), None) => { - Sysroot::discover_sysroot_src_dir(path.clone()) - } - (Some(RustLibSource::Path(sysroot)), Some(sysroot_src)) => { - Sysroot::load(Some(sysroot.clone()), Some(sysroot_src.clone())) - } + (Some(RustLibSource::Path(path)), None) => Sysroot::discover_sysroot_src_dir( + path.clone(), + config.sysroot_query_metadata, + ), + (Some(RustLibSource::Path(sysroot)), Some(sysroot_src)) => Sysroot::load( + Some(sysroot.clone()), + Some(sysroot_src.clone()), + config.sysroot_query_metadata, + ), (None, _) => Sysroot::empty(), }; tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = ?sysroot.root(), "Using sysroot"); @@ -352,20 +353,19 @@ impl ProjectWorkspace { Ok(res) } - pub fn load_inline( - project_json: ProjectJson, - target: Option<&str>, - extra_env: &FxHashMap, - cfg_overrides: &CfgOverrides, - ) -> ProjectWorkspace { - let sysroot = Sysroot::load(project_json.sysroot.clone(), project_json.sysroot_src.clone()); + pub fn load_inline(project_json: ProjectJson, config: &CargoConfig) -> ProjectWorkspace { + let sysroot = Sysroot::load( + project_json.sysroot.clone(), + project_json.sysroot_src.clone(), + config.sysroot_query_metadata, + ); let cfg_config = RustcCfgConfig::Rustc(&sysroot); let data_layout_config = RustcDataLayoutConfig::Rustc(&sysroot); let toolchain = match get_toolchain_version( project_json.path(), &sysroot, Tool::Rustc, - extra_env, + &config.extra_env, "rustc ", ) { Ok(it) => it, @@ -375,15 +375,16 @@ impl ProjectWorkspace { } }; - let rustc_cfg = rustc_cfg::get(target, extra_env, cfg_config); - let data_layout = target_data_layout::get(data_layout_config, target, extra_env); + let target = config.target.as_deref(); + let rustc_cfg = rustc_cfg::get(target, &config.extra_env, cfg_config); + let data_layout = target_data_layout::get(data_layout_config, target, &config.extra_env); ProjectWorkspace { kind: ProjectWorkspaceKind::Json(project_json), sysroot, rustc_cfg, toolchain, target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())), - cfg_overrides: cfg_overrides.clone(), + cfg_overrides: config.cfg_overrides.clone(), } } @@ -393,8 +394,12 @@ impl ProjectWorkspace { ) -> anyhow::Result { let dir = detached_file.parent(); let sysroot = match &config.sysroot { - Some(RustLibSource::Path(path)) => Sysroot::discover_sysroot_src_dir(path.clone()), - Some(RustLibSource::Discover) => Sysroot::discover(dir, &config.extra_env), + Some(RustLibSource::Path(path)) => { + Sysroot::discover_sysroot_src_dir(path.clone(), config.sysroot_query_metadata) + } + Some(RustLibSource::Discover) => { + Sysroot::discover(dir, &config.extra_env, config.sysroot_query_metadata) + } None => Sysroot::empty(), }; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index 155fb6f7c88c0..802d0c69a47af 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -65,6 +65,10 @@ impl flags::AnalysisStats { true => None, false => Some(RustLibSource::Discover), }, + sysroot_query_metadata: match self.no_query_sysroot_metadata { + true => project_model::SysrootQueryMetadata::None, + false => project_model::SysrootQueryMetadata::CargoMetadata, + }, all_targets: true, set_test: !self.no_test, cfg_overrides: CfgOverrides { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs index ff24602144a9d..920a2a37efb69 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs @@ -71,6 +71,9 @@ xflags::xflags! { optional --with-deps /// Don't load sysroot crates (`std`, `core` & friends). optional --no-sysroot + /// Don't run cargo metadata on the sysroot to analyze its third-party dependencies. + /// Requires --no-sysroot to not be set. + optional --no-query-sysroot-metadata /// Don't set #[cfg(test)]. optional --no-test @@ -235,6 +238,7 @@ pub struct AnalysisStats { pub only: Option, pub with_deps: bool, pub no_sysroot: bool, + pub no_query_sysroot_metadata: bool, pub no_test: bool, pub disable_build_scripts: bool, pub disable_proc_macros: bool, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs index 30378db0b388b..6483afc85b21d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -13,7 +13,7 @@ use profile::StopWatch; use project_model::target_data_layout::RustcDataLayoutConfig; use project_model::{ target_data_layout, CargoConfig, ManifestPath, ProjectWorkspace, ProjectWorkspaceKind, - RustLibSource, Sysroot, + RustLibSource, Sysroot, SysrootQueryMetadata, }; use load_cargo::{load_workspace, LoadCargoConfig, ProcMacroServerChoice}; @@ -74,7 +74,11 @@ impl Tester { ..Default::default() }; - let sysroot = Sysroot::discover(tmp_file.parent().unwrap(), &cargo_config.extra_env); + let sysroot = Sysroot::discover( + tmp_file.parent().unwrap(), + &cargo_config.extra_env, + SysrootQueryMetadata::CargoMetadata, + ); let data_layout = target_data_layout::get( RustcDataLayoutConfig::Rustc(&sysroot), None, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index f5b0fcecf3901..37d45255e29d1 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -558,6 +558,9 @@ config_data! { /// /// This option does not take effect until rust-analyzer is restarted. cargo_sysroot: Option = Some("discover".to_owned()), + /// How to query metadata for the sysroot crate. Using cargo metadata allows rust-analyzer + /// to analyze third-party dependencies of the standard libraries. + cargo_sysrootQueryMetadata: SysrootQueryMetadata = SysrootQueryMetadata::CargoMetadata, /// Relative path to the sysroot library sources. If left unset, this will default to /// `{cargo.sysroot}/lib/rustlib/src/rust/library`. /// @@ -1868,6 +1871,12 @@ impl Config { }, target: self.cargo_target(source_root).clone(), sysroot, + sysroot_query_metadata: match self.cargo_sysrootQueryMetadata(None) { + SysrootQueryMetadata::CargoMetadata => { + project_model::SysrootQueryMetadata::CargoMetadata + } + SysrootQueryMetadata::None => project_model::SysrootQueryMetadata::None, + }, sysroot_src, rustc_source, cfg_overrides: project_model::CfgOverrides { @@ -2559,6 +2568,13 @@ pub enum NumThreads { Concrete(usize), } +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum SysrootQueryMetadata { + CargoMetadata, + None, +} + macro_rules! _default_val { (@verbatim: $s:literal, $ty:ty) => {{ let default_: $ty = serde_json::from_str(&$s).unwrap(); @@ -3410,6 +3426,14 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json } ] }, + "SysrootQueryMetadata" => set! { + "type": "string", + "enum": ["none", "cargo_metadata"], + "enumDescriptions": [ + "Do not query sysroot metadata, always use stitched sysroot.", + "Use `cargo metadata` to query sysroot metadata." + ], + }, _ => panic!("missing entry for {ty}: {default} (field {field})"), } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index 0b24833358ddd..bc85afa0e4941 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -316,9 +316,7 @@ impl GlobalState { LinkedProject::InlineJsonProject(it) => { let workspace = project_model::ProjectWorkspace::load_inline( it.clone(), - cargo_config.target.as_deref(), - &cargo_config.extra_env, - &cargo_config.cfg_overrides, + &cargo_config, ); Ok(workspace) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs index 97c76bf8d1738..c1ca59606379a 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs @@ -1085,6 +1085,7 @@ fn resolve_proc_macro() { let sysroot = project_model::Sysroot::discover( &AbsPathBuf::assert_utf8(std::env::current_dir().unwrap()), &Default::default(), + project_model::SysrootQueryMetadata::CargoMetadata, ); let proc_macro_server_path = sysroot.discover_proc_macro_srv().unwrap(); diff --git a/src/tools/rust-analyzer/docs/dev/architecture.md b/src/tools/rust-analyzer/docs/dev/architecture.md index 6aa57b2f9be95..9c9e05a429bf8 100644 --- a/src/tools/rust-analyzer/docs/dev/architecture.md +++ b/src/tools/rust-analyzer/docs/dev/architecture.md @@ -42,7 +42,7 @@ The underlying engine makes sure that model is computed lazily (on-demand) and c `crates/rust-analyzer/src/bin/main.rs` contains the main function which spawns LSP. This is *the* entry point, but it front-loads a lot of complexity, so it's fine to just skim through it. -`crates/rust-analyzer/src/handlers/requests.rs` implements all LSP requests and is a great place to start if you are already familiar with LSP. +`crates/rust-analyzer/src/handlers/request.rs` implements all LSP requests and is a great place to start if you are already familiar with LSP. `Analysis` and `AnalysisHost` types define the main API for consumers of IDE services. diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc index 463718835b91f..052d0a2a41d0c 100644 --- a/src/tools/rust-analyzer/docs/user/generated_config.adoc +++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc @@ -135,6 +135,12 @@ Unsetting this disables sysroot loading. This option does not take effect until rust-analyzer is restarted. -- +[[rust-analyzer.cargo.sysrootQueryMetadata]]rust-analyzer.cargo.sysrootQueryMetadata (default: `"cargo_metadata"`):: ++ +-- +How to query metadata for the sysroot crate. Using cargo metadata allows rust-analyzer +to analyze third-party dependencies of the standard libraries. +-- [[rust-analyzer.cargo.sysrootSrc]]rust-analyzer.cargo.sysrootSrc (default: `null`):: + -- diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index b868622b3a520..82c43b76fdd56 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -816,6 +816,24 @@ } } }, + { + "title": "cargo", + "properties": { + "rust-analyzer.cargo.sysrootQueryMetadata": { + "markdownDescription": "How to query metadata for the sysroot crate. Using cargo metadata allows rust-analyzer\nto analyze third-party dependencies of the standard libraries.", + "default": "cargo_metadata", + "type": "string", + "enum": [ + "none", + "cargo_metadata" + ], + "enumDescriptions": [ + "Do not query sysroot metadata, always use stitched sysroot.", + "Use `cargo metadata` to query sysroot metadata." + ] + } + } + }, { "title": "cargo", "properties": { diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index 00f4f743a7c45..8f41ed9e14f95 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -145f9cf95de1fbde3fa11e98461310e0373253e6 +f005c7437def424a1c43cbc380352a58d8ac920b diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index 9e549348da3d4..400eb7c5e0d7b 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -161,9 +161,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.1.34" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9" +checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" dependencies = [ "shlex", ] diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index 2c29a2848b7e5..854c454733759 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -12,7 +12,7 @@ env_logger = "0.11" mdbook-trpl-listing = { path = "../../doc/book/packages/mdbook-trpl-listing" } mdbook-trpl-note = { path = "../../doc/book/packages/mdbook-trpl-note" } mdbook-i18n-helpers = "0.3.3" -mdbook-spec = { path = "../../doc/reference/mdbook-spec"} +mdbook-spec = { path = "../../doc/reference/mdbook-spec" } [dependencies.mdbook] version = "0.4.37" diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs index f905b9277ff51..a1ef18610b000 100644 --- a/src/tools/rustbook/src/main.rs +++ b/src/tools/rustbook/src/main.rs @@ -31,6 +31,20 @@ fn main() { (Defaults to the current directory when omitted)") .value_parser(clap::value_parser!(PathBuf)); + // Note: we don't parse this into a `PathBuf` because it is comma separated + // strings *and* we will ultimately pass it into `MDBook::test()`, which + // accepts `Vec<&str>`. Although it is a bit annoying that `-l/--lang` and + // `-L/--library-path` are so close, this is the same set of arguments we + // would pass when invoking mdbook on the CLI, so making them match when + // invoking rustbook makes for good consistency. + let library_path_arg = arg!( + -L --"library-path" + "A comma-separated list of directories to add to the crate search\n\ + path when building tests" + ) + .required(false) + .value_parser(parse_library_paths); + let matches = Command::new("rustbook") .about("Build a book with mdBook") .author("Steve Klabnik ") @@ -48,11 +62,12 @@ fn main() { .subcommand( Command::new("test") .about("Tests that a book's Rust code samples compile") - .arg(dir_arg), + .arg(dir_arg) + .arg(library_path_arg), ) .get_matches(); - // Check which subcomamnd the user ran... + // Check which subcommand the user ran... match matches.subcommand() { Some(("build", sub_matches)) => { if let Err(e) = build(sub_matches) { @@ -113,8 +128,12 @@ pub fn build(args: &ArgMatches) -> Result3<()> { fn test(args: &ArgMatches) -> Result3<()> { let book_dir = get_book_dir(args); + let library_paths = args + .try_get_one::>("library-path")? + .map(|v| v.iter().map(|s| s.as_str()).collect::>()) + .unwrap_or_default(); let mut book = load_book(&book_dir)?; - book.test(vec![]) + book.test(library_paths) } fn get_book_dir(args: &ArgMatches) -> PathBuf { @@ -132,6 +151,10 @@ fn load_book(book_dir: &Path) -> Result3 { Ok(book) } +fn parse_library_paths(input: &str) -> Result, String> { + Ok(input.split(",").map(String::from).collect()) +} + fn handle_error(error: mdbook::errors::Error) -> ! { eprintln!("Error: {}", error); @@ -139,5 +162,5 @@ fn handle_error(error: mdbook::errors::Error) -> ! { eprintln!("\tCaused By: {}", cause); } - ::std::process::exit(101); + std::process::exit(101); } diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index 68c481bda6e18..18932587f1fb0 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -1916,15 +1916,15 @@ pub(crate) fn rewrite_struct_field_prefix( field: &ast::FieldDef, ) -> RewriteResult { let vis = format_visibility(context, &field.vis); + let safety = format_safety(field.safety); let type_annotation_spacing = type_annotation_spacing(context.config); Ok(match field.ident { Some(name) => format!( - "{}{}{}:", - vis, + "{vis}{safety}{}{}:", rewrite_ident(context, name), type_annotation_spacing.0 ), - None => vis.to_string(), + None => format!("{vis}{safety}"), }) } diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs index 4d684f3c6350d..db7c3486e7179 100644 --- a/src/tools/rustfmt/src/spanned.rs +++ b/src/tools/rustfmt/src/spanned.rs @@ -150,11 +150,7 @@ impl Spanned for ast::FieldDef { impl Spanned for ast::WherePredicate { fn span(&self) -> Span { - match *self { - ast::WherePredicate::BoundPredicate(ref p) => p.span, - ast::WherePredicate::RegionPredicate(ref p) => p.span, - ast::WherePredicate::EqPredicate(ref p) => p.span, - } + self.span } } diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index e237662f5aa22..dd4a788c002b9 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -463,8 +463,8 @@ impl Rewrite for ast::WherePredicate { fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { // FIXME: dead spans? - let result = match *self { - ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { + let result = match self.kind { + ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { ref bound_generic_params, ref bounded_ty, ref bounds, @@ -482,12 +482,11 @@ impl Rewrite for ast::WherePredicate { rewrite_assign_rhs(context, lhs, bounds, &RhsAssignKind::Bounds, shape)? } - ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate { + ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate { ref lifetime, ref bounds, - span, - }) => rewrite_bounded_lifetime(lifetime, bounds, span, context, shape)?, - ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { + }) => rewrite_bounded_lifetime(lifetime, bounds, self.span, context, shape)?, + ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate { ref lhs_ty, ref rhs_ty, .. diff --git a/src/tools/rustfmt/tests/source/unsafe-field.rs b/src/tools/rustfmt/tests/source/unsafe-field.rs new file mode 100644 index 0000000000000..35cf40a22d367 --- /dev/null +++ b/src/tools/rustfmt/tests/source/unsafe-field.rs @@ -0,0 +1,16 @@ +struct Foo { + unsafe + field: (), +} + +enum Bar { + Variant { + unsafe + field: (), + }, +} + +union Baz { + unsafe + field: (), +} diff --git a/src/tools/rustfmt/tests/target/unsafe-field.rs b/src/tools/rustfmt/tests/target/unsafe-field.rs new file mode 100644 index 0000000000000..fc7fd3750c60e --- /dev/null +++ b/src/tools/rustfmt/tests/target/unsafe-field.rs @@ -0,0 +1,11 @@ +struct Foo { + unsafe field: (), +} + +enum Bar { + Variant { unsafe field: () }, +} + +union Baz { + unsafe field: (), +} diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 932a58788e04e..ac82a17e1459f 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -2756,7 +2756,6 @@ ui/lint/issue-57410-1.rs ui/lint/issue-57410.rs ui/lint/issue-63364.rs ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs -ui/lint/issue-79546-fuel-ice.rs ui/lint/issue-79744.rs ui/lint/issue-81218.rs ui/lint/issue-83477.rs diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 6394a1463b0da..35cda17e16884 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -337,12 +337,16 @@ pub fn check(path: &Path, bad: &mut bool) { .case_insensitive(true) .build() .unwrap(); - let style_file = Path::new(file!()); + + // In some cases, a style check would be triggered by its own implementation + // or comments. A simple workaround is to just allowlist this file. + let this_file = Path::new(file!()); + walk(path, skip, &mut |entry, contents| { let file = entry.path(); let filename = file.file_name().unwrap().to_string_lossy(); - let is_style_file = filename.ends_with(".css"); + let is_css_file = filename.ends_with(".css"); let under_rustfmt = filename.ends_with(".rs") && // This list should ideally be sourced from rustfmt.toml but we don't want to add a toml // parser to tidy. @@ -405,13 +409,13 @@ pub fn check(path: &Path, bad: &mut bool) { let mut comment_block: Option<(usize, usize)> = None; let is_test = file.components().any(|c| c.as_os_str() == "tests") || file.file_stem().unwrap() == "tests"; - let is_style = file.ends_with(style_file) || style_file.ends_with(file); - let is_style_test = - is_test && file.parent().unwrap().ends_with(style_file.with_extension("")); + let is_this_file = file.ends_with(this_file) || this_file.ends_with(file); + let is_test_for_this_file = + is_test && file.parent().unwrap().ends_with(this_file.with_extension("")); // scanning the whole file for multiple needles at once is more efficient than // executing lines times needles separate searches. let any_problematic_line = - !is_style && !is_style_test && problematic_regex.is_match(contents); + !is_this_file && !is_test_for_this_file && problematic_regex.is_match(contents); for (i, line) in contents.split('\n').enumerate() { if line.is_empty() { if i == 0 { @@ -458,19 +462,19 @@ pub fn check(path: &Path, bad: &mut bool) { "line longer than {max_columns} chars" ); } - if !is_style_file && line.contains('\t') { + if !is_css_file && line.contains('\t') { suppressible_tidy_err!(err, skip_tab, "tab character"); } if line.ends_with(' ') || line.ends_with('\t') { suppressible_tidy_err!(err, skip_end_whitespace, "trailing whitespace"); } - if is_style_file && line.starts_with(' ') { + if is_css_file && line.starts_with(' ') { err("CSS files use tabs for indent"); } if line.contains('\r') { suppressible_tidy_err!(err, skip_cr, "CR character"); } - if !is_style { + if !is_this_file { // Allow using TODO in diagnostic suggestions by marking the // relevant line with `// ignore-tidy-todo`. if trimmed.contains("TODO") && !trimmed.contains("ignore-tidy-todo") { diff --git a/src/tools/unicode-table-generator/src/range_search.rs b/src/tools/unicode-table-generator/src/range_search.rs index 14da876eda77d..9a51979a2f0d9 100644 --- a/src/tools/unicode-table-generator/src/range_search.rs +++ b/src/tools/unicode-table-generator/src/range_search.rs @@ -1,5 +1,4 @@ #[inline(always)] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0"))] const fn bitset_search< const N: usize, const CHUNK_SIZE: usize, diff --git a/src/tools/unicode-table-generator/src/raw_emitter.rs b/src/tools/unicode-table-generator/src/raw_emitter.rs index dd064c5928398..46010692fe561 100644 --- a/src/tools/unicode-table-generator/src/raw_emitter.rs +++ b/src/tools/unicode-table-generator/src/raw_emitter.rs @@ -97,10 +97,6 @@ impl RawEmitter { self.blank_line(); - writeln!( - &mut self.file, - r#"#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0"))]"# - ).unwrap(); writeln!(&mut self.file, "pub const fn lookup(c: char) -> bool {{").unwrap(); if first_code_point > 0x7f { writeln!(&mut self.file, " (c as u32) >= {first_code_point:#04x} &&").unwrap(); diff --git a/src/version b/src/version index bd0f9e6c28f77..f288d11142d11 100644 --- a/src/version +++ b/src/version @@ -1 +1 @@ -1.84.0 +1.85.0 diff --git a/tests/assembly/asm/s390x-types.rs b/tests/assembly/asm/s390x-types.rs index b1522198a087a..3da22d6c77b62 100644 --- a/tests/assembly/asm/s390x-types.rs +++ b/tests/assembly/asm/s390x-types.rs @@ -1,10 +1,13 @@ -//@ revisions: s390x +//@ revisions: s390x s390x_vector //@ assembly-output: emit-asm //@[s390x] compile-flags: --target s390x-unknown-linux-gnu //@[s390x] needs-llvm-components: systemz +//@[s390x_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector +//@[s390x_vector] needs-llvm-components: systemz //@ compile-flags: -Zmerge-functions=disabled -#![feature(no_core, lang_items, rustc_attrs, repr_simd)] +#![feature(no_core, lang_items, rustc_attrs, repr_simd, f128)] +#![cfg_attr(s390x_vector, feature(asm_experimental_reg))] #![crate_type = "rlib"] #![no_core] #![allow(asm_sub_register, non_camel_case_types)] @@ -27,16 +30,39 @@ trait Sized {} #[lang = "copy"] trait Copy {} +impl Copy for [T; N] {} + type ptr = *const i32; +#[repr(simd)] +pub struct i8x16([i8; 16]); +#[repr(simd)] +pub struct i16x8([i16; 8]); +#[repr(simd)] +pub struct i32x4([i32; 4]); +#[repr(simd)] +pub struct i64x2([i64; 2]); +#[repr(simd)] +pub struct f32x4([f32; 4]); +#[repr(simd)] +pub struct f64x2([f64; 2]); + impl Copy for i8 {} impl Copy for u8 {} impl Copy for i16 {} impl Copy for i32 {} impl Copy for i64 {} +impl Copy for i128 {} impl Copy for f32 {} impl Copy for f64 {} +impl Copy for f128 {} impl Copy for ptr {} +impl Copy for i8x16 {} +impl Copy for i16x8 {} +impl Copy for i32x4 {} +impl Copy for i64x2 {} +impl Copy for f32x4 {} +impl Copy for f64x2 {} extern "C" { fn extern_func(); @@ -65,7 +91,6 @@ macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => { // CHECK: #APP // CHECK: brasl %r14, extern_func // CHECK: #NO_APP -#[cfg(s390x)] #[no_mangle] pub unsafe fn sym_fn_32() { asm!("brasl %r14, {}", sym extern_func); @@ -146,6 +171,90 @@ check!(reg_f64, f64, freg, "ldr"); // CHECK: #NO_APP check!(reg_ptr, ptr, reg, "lgr"); +// s390x_vector-LABEL: vreg_i8x16: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_i8x16, i8x16, vreg, "vlr"); + +// s390x_vector-LABEL: vreg_i16x8: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_i16x8, i16x8, vreg, "vlr"); + +// s390x_vector-LABEL: vreg_i32x4: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_i32x4, i32x4, vreg, "vlr"); + +// s390x_vector-LABEL: vreg_i64x2: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_i64x2, i64x2, vreg, "vlr"); + +// s390x_vector-LABEL: vreg_f32x4: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_f32x4, f32x4, vreg, "vlr"); + +// s390x_vector-LABEL: vreg_f64x2: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_f64x2, f64x2, vreg, "vlr"); + +// s390x_vector-LABEL: vreg_i32: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_i32, i32, vreg, "vlr"); + +// s390x_vector-LABEL: vreg_i64: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_i64, i64, vreg, "vlr"); + +// s390x_vector-LABEL: vreg_i128: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_i128, i128, vreg, "vlr"); + +// s390x_vector-LABEL: vreg_f32: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_f32, f32, vreg, "vlr"); + +// s390x_vector-LABEL: vreg_f64: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_f64, f64, vreg, "vlr"); + +// s390x_vector-LABEL: vreg_f128: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_f128, f128, vreg, "vlr"); + // CHECK-LABEL: r0_i8: // CHECK: #APP // CHECK: lr %r0, %r0 @@ -181,3 +290,87 @@ check_reg!(f0_f32, f32, "f0", "ler"); // CHECK: ldr %f0, %f0 // CHECK: #NO_APP check_reg!(f0_f64, f64, "f0", "ldr"); + +// s390x_vector-LABEL: v0_i8x16: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_i8x16, i8x16, "v0", "vlr"); + +// s390x_vector-LABEL: v0_i16x8: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_i16x8, i16x8, "v0", "vlr"); + +// s390x_vector-LABEL: v0_i32x4: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_i32x4, i32x4, "v0", "vlr"); + +// s390x_vector-LABEL: v0_i64x2: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_i64x2, i64x2, "v0", "vlr"); + +// s390x_vector-LABEL: v0_f32x4: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_f32x4, f32x4, "v0", "vlr"); + +// s390x_vector-LABEL: v0_f64x2: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_f64x2, f64x2, "v0", "vlr"); + +// s390x_vector-LABEL: v0_i32: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_i32, i32, "v0", "vlr"); + +// s390x_vector-LABEL: v0_i64: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_i64, i64, "v0", "vlr"); + +// s390x_vector-LABEL: v0_i128: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_i128, i128, "v0", "vlr"); + +// s390x_vector-LABEL: v0_f32: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_f32, f32, "v0", "vlr"); + +// s390x_vector-LABEL: v0_f64: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_f64, f64, "v0", "vlr"); + +// s390x_vector-LABEL: v0_f128: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_f128, f128, "v0", "vlr"); diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 1e9f2ee59b48f..c4317752920f0 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -45,6 +45,7 @@ impl_marker_trait!( impl<'a, T: ?Sized> Copy for &'a T {} impl Copy for *const T {} impl Copy for *mut T {} +impl Copy for [T; N] {} #[lang = "phantom_data"] pub struct PhantomData; diff --git a/tests/codegen-units/partitioning/auxiliary/cgu_generic_function.rs b/tests/codegen-units/partitioning/auxiliary/cgu_generic_function.rs index 3926f295742bc..8bb78eb788a22 100644 --- a/tests/codegen-units/partitioning/auxiliary/cgu_generic_function.rs +++ b/tests/codegen-units/partitioning/auxiliary/cgu_generic_function.rs @@ -11,10 +11,21 @@ pub fn foo(x: T) -> (T, u32, i8) { #[inline(never)] fn bar(x: T) -> (T, Struct) { let _ = not_exported_and_not_generic(0); + exported_and_generic::(0); (x, Struct(1)) } +pub static F: fn(u32) -> u32 = exported_and_generic::; + // These should not contribute to the codegen items of other crates. + +// This is generic, but it's only instantiated with a u32 argument and that instantiation is present +// in the local crate (see F above). +#[inline(never)] +pub fn exported_and_generic(x: T) -> T { + x +} + #[inline(never)] pub fn exported_but_not_generic(x: i32) -> i64 { x as i64 diff --git a/tests/codegen/aarch64-softfloat.rs b/tests/codegen/aarch64-softfloat.rs new file mode 100644 index 0000000000000..85380a6c4728d --- /dev/null +++ b/tests/codegen/aarch64-softfloat.rs @@ -0,0 +1,48 @@ +//@ compile-flags: --target aarch64-unknown-none-softfloat -Zmerge-functions=disabled +//@ needs-llvm-components: aarch64 +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} +impl Copy for f32 {} +impl Copy for f64 {} + +// CHECK: i64 @pass_f64_C(i64 {{[^,]*}}) +#[no_mangle] +extern "C" fn pass_f64_C(x: f64) -> f64 { + x +} + +// CHECK: i64 @pass_f32_pair_C(i64 {{[^,]*}}) +#[no_mangle] +extern "C" fn pass_f32_pair_C(x: (f32, f32)) -> (f32, f32) { + x +} + +// CHECK: [2 x i64] @pass_f64_pair_C([2 x i64] {{[^,]*}}) +#[no_mangle] +extern "C" fn pass_f64_pair_C(x: (f64, f64)) -> (f64, f64) { + x +} + +// CHECK: i64 @pass_f64_Rust(i64 {{[^,]*}}) +#[no_mangle] +fn pass_f64_Rust(x: f64) -> f64 { + x +} + +// CHECK: i64 @pass_f32_pair_Rust(i64 {{[^,]*}}) +#[no_mangle] +fn pass_f32_pair_Rust(x: (f32, f32)) -> (f32, f32) { + x +} + +// CHECK: void @pass_f64_pair_Rust(ptr {{.*}}%{{[^ ]+}}, ptr {{.*}}%{{[^ ]+}}) +#[no_mangle] +fn pass_f64_pair_Rust(x: (f64, f64)) -> (f64, f64) { + x +} diff --git a/tests/codegen/asm/aarch64-clobbers.rs b/tests/codegen/asm/aarch64-clobbers.rs new file mode 100644 index 0000000000000..900e6629fd2c2 --- /dev/null +++ b/tests/codegen/asm/aarch64-clobbers.rs @@ -0,0 +1,51 @@ +//@ revisions: aarch64 aarch64_fixed_x18 aarch64_no_x18 aarch64_reserve_x18 arm64ec +//@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu +//@[aarch64] needs-llvm-components: aarch64 +//@[aarch64_fixed_x18] compile-flags: --target aarch64-unknown-linux-gnu -Zfixed-x18 +//@[aarch64_fixed_x18] needs-llvm-components: aarch64 +//@[aarch64_no_x18] compile-flags: --target aarch64-pc-windows-msvc +//@[aarch64_no_x18] needs-llvm-components: aarch64 +// aarch64-unknown-trusty uses aarch64-unknown-unknown-musl which doesn't +// reserve x18 by default as llvm_target, and pass +reserve-x18 in target-spec. +//@[aarch64_reserve_x18] compile-flags: --target aarch64-unknown-trusty +//@[aarch64_reserve_x18] needs-llvm-components: aarch64 +//@[arm64ec] compile-flags: --target arm64ec-pc-windows-msvc +//@[arm64ec] needs-llvm-components: aarch64 +// ignore-tidy-linelength + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +// CHECK-LABEL: @cc_clobber +// CHECK: call void asm sideeffect "", "~{cc}"() +#[no_mangle] +pub unsafe fn cc_clobber() { + asm!("", options(nostack, nomem)); +} + +// CHECK-LABEL: @no_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn no_clobber() { + asm!("", options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @clobber_abi +// aarch64: asm sideeffect "", "={w0},={w1},={w2},={w3},={w4},={w5},={w6},={w7},={w8},={w9},={w10},={w11},={w12},={w13},={w14},={w15},={w16},={w17},={w18},={w30},={q0},={q1},={q2},={q3},={q4},={q5},={q6},={q7},={q8},={q9},={q10},={q11},={q12},={q13},={q14},={q15},={q16},={q17},={q18},={q19},={q20},={q21},={q22},={q23},={q24},={q25},={q26},={q27},={q28},={q29},={q30},={q31},~{p0},~{p1},~{p2},~{p3},~{p4},~{p5},~{p6},~{p7},~{p8},~{p9},~{p10},~{p11},~{p12},~{p13},~{p14},~{p15},~{ffr}"() +// aarch64_fixed_x18: asm sideeffect "", "={w0},={w1},={w2},={w3},={w4},={w5},={w6},={w7},={w8},={w9},={w10},={w11},={w12},={w13},={w14},={w15},={w16},={w17},={w30},={q0},={q1},={q2},={q3},={q4},={q5},={q6},={q7},={q8},={q9},={q10},={q11},={q12},={q13},={q14},={q15},={q16},={q17},={q18},={q19},={q20},={q21},={q22},={q23},={q24},={q25},={q26},={q27},={q28},={q29},={q30},={q31},~{p0},~{p1},~{p2},~{p3},~{p4},~{p5},~{p6},~{p7},~{p8},~{p9},~{p10},~{p11},~{p12},~{p13},~{p14},~{p15},~{ffr}"() +// aarch64_no_x18: asm sideeffect "", "={w0},={w1},={w2},={w3},={w4},={w5},={w6},={w7},={w8},={w9},={w10},={w11},={w12},={w13},={w14},={w15},={w16},={w17},={w30},={q0},={q1},={q2},={q3},={q4},={q5},={q6},={q7},={q8},={q9},={q10},={q11},={q12},={q13},={q14},={q15},={q16},={q17},={q18},={q19},={q20},={q21},={q22},={q23},={q24},={q25},={q26},={q27},={q28},={q29},={q30},={q31},~{p0},~{p1},~{p2},~{p3},~{p4},~{p5},~{p6},~{p7},~{p8},~{p9},~{p10},~{p11},~{p12},~{p13},~{p14},~{p15},~{ffr}"() +// aarch64_reserve_x18: asm sideeffect "", "={w0},={w1},={w2},={w3},={w4},={w5},={w6},={w7},={w8},={w9},={w10},={w11},={w12},={w13},={w14},={w15},={w16},={w17},={w30},={q0},={q1},={q2},={q3},={q4},={q5},={q6},={q7},={q8},={q9},={q10},={q11},={q12},={q13},={q14},={q15},={q16},={q17},={q18},={q19},={q20},={q21},={q22},={q23},={q24},={q25},={q26},={q27},={q28},={q29},={q30},={q31},~{p0},~{p1},~{p2},~{p3},~{p4},~{p5},~{p6},~{p7},~{p8},~{p9},~{p10},~{p11},~{p12},~{p13},~{p14},~{p15},~{ffr}"() +// arm64ec: asm sideeffect "", "={w0},={w1},={w2},={w3},={w4},={w5},={w6},={w7},={w8},={w9},={w10},={w11},={w12},={w15},={w16},={w17},={w30},={q0},={q1},={q2},={q3},={q4},={q5},={q6},={q7},={q8},={q9},={q10},={q11},={q12},={q13},={q14},={q15}"() +#[no_mangle] +pub unsafe fn clobber_abi() { + asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); +} diff --git a/tests/codegen/asm/arm64ec-clobbers.rs b/tests/codegen/asm/arm64ec-clobbers.rs deleted file mode 100644 index 80059331642d7..0000000000000 --- a/tests/codegen/asm/arm64ec-clobbers.rs +++ /dev/null @@ -1,36 +0,0 @@ -//@ assembly-output: emit-asm -//@ compile-flags: --target arm64ec-pc-windows-msvc -//@ needs-llvm-components: aarch64 - -#![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items)] -#![no_core] - -#[lang = "sized"] -trait Sized {} - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} - -// CHECK-LABEL: @cc_clobber -// CHECK: call void asm sideeffect "", "~{cc}"() -#[no_mangle] -pub unsafe fn cc_clobber() { - asm!("", options(nostack, nomem)); -} - -// CHECK-LABEL: @no_clobber -// CHECK: call void asm sideeffect "", ""() -#[no_mangle] -pub unsafe fn no_clobber() { - asm!("", options(nostack, nomem, preserves_flags)); -} - -// CHECK-LABEL: @clobber_abi -// CHECK: asm sideeffect "", "={w0},={w1},={w2},={w3},={w4},={w5},={w6},={w7},={w8},={w9},={w10},={w11},={w12},={w15},={w16},={w17},={w30},={q0},={q1},={q2},={q3},={q4},={q5},={q6},={q7},={q8},={q9},={q10},={q11},={q12},={q13},={q14},={q15}"() -#[no_mangle] -pub unsafe fn clobber_abi() { - asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); -} diff --git a/tests/codegen/asm/avr-clobbers.rs b/tests/codegen/asm/avr-clobbers.rs new file mode 100644 index 0000000000000..6e0c75368e23f --- /dev/null +++ b/tests/codegen/asm/avr-clobbers.rs @@ -0,0 +1,43 @@ +//@ assembly-output: emit-asm +//@ compile-flags: --target avr-unknown-gnu-atmega328 +//@ needs-llvm-components: avr + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +// CHECK-LABEL: @sreg_is_clobbered +// CHECK: void asm sideeffect "", "~{sreg}"() +#[no_mangle] +pub unsafe fn sreg_is_clobbered() { + asm!("", options(nostack, nomem)); +} + +// CHECK-LABEL: @sreg_is_not_clobbered_if_preserve_flags_is_used +// CHECK: void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn sreg_is_not_clobbered_if_preserve_flags_is_used() { + asm!("", options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @clobber_abi +// CHECK: asm sideeffect "", "={r18},={r19},={r20},={r21},={r22},={r23},={r24},={r25},={r26},={r27},={r30},={r31},~{sreg}"() +#[no_mangle] +pub unsafe fn clobber_abi() { + asm!("", clobber_abi("C"), options(nostack, nomem)); +} + +// CHECK-LABEL: @clobber_abi_with_preserved_flags +// CHECK: asm sideeffect "", "={r18},={r19},={r20},={r21},={r22},={r23},={r24},={r25},={r26},={r27},={r30},={r31}"() +#[no_mangle] +pub unsafe fn clobber_abi_with_preserved_flags() { + asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); +} diff --git a/tests/codegen/asm/goto.rs b/tests/codegen/asm/goto.rs index e522d0da5b405..c40a43fbe1bd3 100644 --- a/tests/codegen/asm/goto.rs +++ b/tests/codegen/asm/goto.rs @@ -2,21 +2,10 @@ //@ only-x86_64 #![crate_type = "rlib"] -#![feature(asm_goto)] +#![feature(asm_goto, asm_goto_with_outputs)] use std::arch::asm; -#[no_mangle] -pub extern "C" fn panicky() {} - -struct Foo; - -impl Drop for Foo { - fn drop(&mut self) { - println!(); - } -} - // CHECK-LABEL: @asm_goto #[no_mangle] pub unsafe fn asm_goto() { @@ -38,14 +27,37 @@ pub unsafe fn asm_goto_with_outputs() -> u64 { out } +// CHECK-LABEL: @asm_goto_with_outputs_use_in_label +#[no_mangle] +pub unsafe fn asm_goto_with_outputs_use_in_label() -> u64 { + let out: u64; + // CHECK: [[RES:%[0-9]+]] = callbr i64 asm sideeffect alignstack inteldialect " + // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]] + asm!("{} /* {} */", out(reg) out, label { return out; }); + // CHECK: [[JUMPBB]]: + // CHECK-NEXT: [[RET:%.+]] = phi i64 [ 1, %[[FALLTHROUGHBB]] ], [ [[RES]], %start ] + // CHECK-NEXT: ret i64 [[RET]] + 1 +} + // CHECK-LABEL: @asm_goto_noreturn #[no_mangle] pub unsafe fn asm_goto_noreturn() -> u64 { - let out: u64; // CHECK: callbr void asm sideeffect alignstack inteldialect " // CHECK-NEXT: to label %unreachable [label %[[JUMPBB:[a-b0-9]+]]] asm!("jmp {}", label { return 1; }, options(noreturn)); // CHECK: [[JUMPBB]]: // CHECK-NEXT: ret i64 1 +} + +// CHECK-LABEL: @asm_goto_noreturn_with_outputs +#[no_mangle] +pub unsafe fn asm_goto_noreturn_with_outputs() -> u64 { + let out: u64; + // CHECK: [[RES:%[0-9]+]] = callbr i64 asm sideeffect alignstack inteldialect " + // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]] + asm!("mov {}, 1", "jmp {}", out(reg) out, label { return out; }); + // CHECK: [[JUMPBB]]: + // CHECK-NEXT: ret i64 [[RES]] out } diff --git a/tests/codegen/asm/hexagon-clobbers.rs b/tests/codegen/asm/hexagon-clobbers.rs new file mode 100644 index 0000000000000..6bb662ead9940 --- /dev/null +++ b/tests/codegen/asm/hexagon-clobbers.rs @@ -0,0 +1,37 @@ +//@ revisions: hexagon +//@[hexagon] compile-flags: --target hexagon-unknown-linux-musl +//@[hexagon] needs-llvm-components: hexagon +//@ compile-flags: -Zmerge-functions=disabled + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +// CHECK-LABEL: @flags_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn flags_clobber() { + asm!("", options(nostack, nomem)); +} + +// CHECK-LABEL: @no_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn no_clobber() { + asm!("", options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @p0_clobber +// CHECK: call void asm sideeffect "", "~{p0}"() +#[no_mangle] +pub unsafe fn p0_clobber() { + asm!("", out("p0") _, options(nostack, nomem, preserves_flags)); +} diff --git a/tests/codegen/asm/riscv-clobbers.rs b/tests/codegen/asm/riscv-clobbers.rs new file mode 100644 index 0000000000000..59b2705a4496a --- /dev/null +++ b/tests/codegen/asm/riscv-clobbers.rs @@ -0,0 +1,44 @@ +//@ assembly-output: emit-asm +//@ revisions: rv32i rv64i rv32e +//@[rv32i] compile-flags: --target riscv32i-unknown-none-elf +//@[rv32i] needs-llvm-components: riscv +//@[rv64i] compile-flags: --target riscv64imac-unknown-none-elf +//@[rv64i] needs-llvm-components: riscv +//@[rv32e] compile-flags: --target riscv32e-unknown-none-elf +//@[rv32e] needs-llvm-components: riscv +// ignore-tidy-linelength + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +// CHECK-LABEL: @flags_clobber +// CHECK: call void asm sideeffect "", "~{vtype},~{vl},~{vxsat},~{vxrm}"() +#[no_mangle] +pub unsafe fn flags_clobber() { + asm!("", options(nostack, nomem)); +} + +// CHECK-LABEL: @no_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn no_clobber() { + asm!("", options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @clobber_abi +// rv32i: asm sideeffect "", "={x1},={x5},={x6},={x7},={x10},={x11},={x12},={x13},={x14},={x15},={x16},={x17},={x28},={x29},={x30},={x31},~{f0},~{f1},~{f2},~{f3},~{f4},~{f5},~{f6},~{f7},~{f10},~{f11},~{f12},~{f13},~{f14},~{f15},~{f16},~{f17},~{f28},~{f29},~{f30},~{f31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31}"() +// rv64i: asm sideeffect "", "={x1},={x5},={x6},={x7},={x10},={x11},={x12},={x13},={x14},={x15},={x16},={x17},={x28},={x29},={x30},={x31},~{f0},~{f1},~{f2},~{f3},~{f4},~{f5},~{f6},~{f7},~{f10},~{f11},~{f12},~{f13},~{f14},~{f15},~{f16},~{f17},~{f28},~{f29},~{f30},~{f31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31}"() +// rv32e: asm sideeffect "", "={x1},={x5},={x6},={x7},={x10},={x11},={x12},={x13},={x14},={x15},~{f0},~{f1},~{f2},~{f3},~{f4},~{f5},~{f6},~{f7},~{f10},~{f11},~{f12},~{f13},~{f14},~{f15},~{f16},~{f17},~{f28},~{f29},~{f30},~{f31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31}"() +#[no_mangle] +pub unsafe fn clobber_abi() { + asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); +} diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs index a2dcb1c092472..7a36490fe93b8 100644 --- a/tests/codegen/avr/avr-func-addrspace.rs +++ b/tests/codegen/avr/avr-func-addrspace.rs @@ -86,7 +86,7 @@ pub extern "C" fn test() { // A call through the Fn trait must use address space 1. // - // CHECK: call{{.+}}addrspace(1) void @call_through_fn_trait() + // CHECK: call{{.+}}addrspace(1) void @call_through_fn_trait({{.*}}) call_through_fn_trait(&mut update_bar_value); // A call through a global variable must use address space 1. diff --git a/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs b/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs index 159ecfd09743d..c0691b23275e3 100644 --- a/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs +++ b/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs b/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs index c3858044c0c9f..0f6e99f9b1ee5 100644 --- a/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs +++ b/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs @@ -3,7 +3,7 @@ // MSVC is different because of the individual allocas. //@ ignore-msvc -//@ aux-build:macro_def.rs +//@ proc-macro: macro_def.rs // Find the variable. // CHECK-DAG: ![[#var_dbg:]] = !DILocalVariable(name: "n",{{( arg: 1,)?}} scope: ![[#var_scope:]] diff --git a/tests/codegen/issues/issue-13018.rs b/tests/codegen/issues/issue-13018.rs index 66282dc427499..a29452436d2c1 100644 --- a/tests/codegen/issues/issue-13018.rs +++ b/tests/codegen/issues/issue-13018.rs @@ -2,7 +2,10 @@ // A drop([...].clone()) sequence on an Rc should be a no-op // In particular, no call to __rust_dealloc should be emitted -#![crate_type = "lib"] +// +// We use a cdylib since it's a leaf unit for Rust purposes, so doesn't codegen -Zshare-generics +// code. +#![crate_type = "cdylib"] use std::rc::Rc; pub fn foo(t: &Rc>) { diff --git a/tests/codegen/sanitizer/no-sanitize.rs b/tests/codegen/sanitizer/no-sanitize.rs index 47d3fd83f1127..2a309f6b9c696 100644 --- a/tests/codegen/sanitizer/no-sanitize.rs +++ b/tests/codegen/sanitizer/no-sanitize.rs @@ -7,6 +7,16 @@ #![crate_type = "lib"] #![feature(no_sanitize)] +// CHECK: @UNSANITIZED = constant{{.*}} no_sanitize_address +// CHECK-NOT: @__asan_global_UNSANITIZED +#[no_mangle] +#[no_sanitize(address)] +pub static UNSANITIZED: u32 = 0; + +// CHECK: @__asan_global_SANITIZED +#[no_mangle] +pub static SANITIZED: u32 = 0; + // CHECK-LABEL: ; no_sanitize::unsanitized // CHECK-NEXT: ; Function Attrs: // CHECK-NOT: sanitize_address diff --git a/tests/coverage/closure.cov-map b/tests/coverage/closure.cov-map index adf4aba0c23a2..fa20c8cf6d789 100644 --- a/tests/coverage/closure.cov-map +++ b/tests/coverage/closure.cov-map @@ -140,17 +140,19 @@ Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10) Highest counter ID seen: c1 -Function name: closure::main::{closure#18} (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 00, 19, 0d, 02, 1c, 00, 02, 1d, 02, 12, 00, 02, 11, 00, 12, 00, 01, 11, 01, 0e] +Function name: closure::main::{closure#18} +Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 19, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e] Number of files: 1 - file 0 => global file 1 -Number of expressions: 0 +Number of expressions: 1 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 -- Code(Zero) at (prev + 25, 13) to (start + 2, 28) -- Code(Zero) at (prev + 2, 29) to (start + 2, 18) -- Code(Zero) at (prev + 2, 17) to (start + 0, 18) -- Code(Zero) at (prev + 1, 17) to (start + 1, 14) -Highest counter ID seen: (none) +- Code(Counter(0)) at (prev + 25, 13) to (start + 2, 28) +- Code(Counter(1)) at (prev + 2, 29) to (start + 2, 18) +- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 18) + = (c0 - c1) +- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 14) +Highest counter ID seen: c1 Function name: closure::main::{closure#19} Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 43, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e] diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map index a8ad17574ba3d..64870c434b33d 100644 --- a/tests/coverage/issue-84561.cov-map +++ b/tests/coverage/issue-84561.cov-map @@ -59,59 +59,69 @@ Number of file 0 mappings: 1 Highest counter ID seen: c0 Function name: issue_84561::test3 -Raw bytes (375): 0x[01, 01, 31, 05, 09, 0d, 00, 15, 19, 12, 00, 15, 19, 21, 00, 1e, 00, 21, 00, 31, 00, 3d, 00, 2e, 45, 3d, 00, 42, 49, 45, 00, 3f, 51, 42, 49, 45, 00, 7a, 55, 51, 00, 7a, 55, 51, 00, 77, 5d, 7a, 55, 51, 00, 77, 61, 7a, 55, 51, 00, 72, 65, 77, 61, 7a, 55, 51, 00, 75, be, 01, c2, 01, 79, 69, 6d, 69, 6d, 69, 6d, c2, 01, 00, 69, 6d, c2, 01, 79, 69, 6d, bb, 01, 7d, 75, be, 01, c2, 01, 79, 69, 6d, b6, 01, 00, bb, 01, 7d, 75, be, 01, c2, 01, 79, 69, 6d, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 02, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 06, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 12, 02, 05, 00, 1f, 0e, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 1e, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 1a, 04, 09, 05, 06, 31, 06, 05, 03, 06, 22, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 2e, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 2a, 05, 09, 03, 0a, 3f, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 3a, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 77, 03, 05, 00, 0f, 77, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 56, 02, 0d, 00, 13, 72, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 6e, 02, 0d, 00, 13, bb, 01, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 75, 04, 0d, 00, 13, c2, 01, 02, 0d, 00, 17, c2, 01, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 92, 01, 02, 15, 00, 1b, be, 01, 04, 0d, 00, 13, 7d, 03, 09, 00, 19, b6, 01, 02, 05, 00, 0f, b2, 01, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] +Raw bytes (414): 0x[01, 01, 3b, 05, 09, 0d, 11, 15, 19, 1e, 1d, 15, 19, 1a, 21, 1e, 1d, 15, 19, 25, 2d, 21, 25, 29, 35, 32, 29, 21, 25, 31, 39, 3d, 41, 42, 45, 3d, 41, 66, 49, 45, 4d, 63, 51, 66, 49, 45, 4d, 5e, 55, 63, 51, 66, 49, 45, 4d, 9e, 01, 55, 51, 59, 9e, 01, 55, 51, 59, 9b, 01, 5d, 9e, 01, 55, 51, 59, 9b, 01, 61, 9e, 01, 55, 51, 59, 96, 01, 65, 9b, 01, 61, 9e, 01, 55, 51, 59, 75, e2, 01, e6, 01, 79, 69, 6d, 69, 6d, 69, 6d, e6, 01, 00, 69, 6d, e6, 01, 79, 69, 6d, df, 01, 7d, 75, e2, 01, e6, 01, 79, 69, 6d, da, 01, 81, 01, df, 01, 7d, 75, e2, 01, e6, 01, 79, 69, 6d, 81, 01, 85, 01, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 02, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 06, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 1e, 02, 05, 00, 1f, 1a, 01, 05, 00, 0f, 16, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 25, 03, 20, 00, 30, 2d, 00, 33, 00, 41, 22, 00, 4b, 00, 5a, 32, 01, 05, 00, 0f, 29, 05, 09, 03, 10, 35, 05, 0d, 00, 1b, 2a, 02, 0d, 00, 1c, 2e, 04, 09, 05, 06, 31, 06, 05, 03, 06, 36, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 42, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 3e, 05, 09, 03, 0a, 63, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 59, 03, 0d, 00, 1d, 5e, 03, 09, 00, 13, 5a, 03, 0d, 00, 1d, 9b, 01, 03, 05, 00, 0f, 9b, 01, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 7a, 02, 0d, 00, 13, 96, 01, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 92, 01, 02, 0d, 00, 13, df, 01, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 75, 04, 0d, 00, 13, e6, 01, 02, 0d, 00, 17, e6, 01, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, b6, 01, 02, 15, 00, 1b, e2, 01, 04, 0d, 00, 13, 7d, 03, 09, 00, 19, da, 01, 02, 05, 00, 0f, d6, 01, 03, 09, 00, 22, 81, 01, 02, 05, 00, 0f, ea, 01, 03, 09, 00, 2c, 85, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 49 +Number of expressions: 59 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) -- expression 1 operands: lhs = Counter(3), rhs = Zero +- expression 1 operands: lhs = Counter(3), rhs = Counter(4) - expression 2 operands: lhs = Counter(5), rhs = Counter(6) -- expression 3 operands: lhs = Expression(4, Sub), rhs = Zero +- expression 3 operands: lhs = Expression(7, Sub), rhs = Counter(7) - expression 4 operands: lhs = Counter(5), rhs = Counter(6) -- expression 5 operands: lhs = Counter(8), rhs = Zero -- expression 6 operands: lhs = Expression(7, Sub), rhs = Zero -- expression 7 operands: lhs = Counter(8), rhs = Zero -- expression 8 operands: lhs = Counter(12), rhs = Zero -- expression 9 operands: lhs = Counter(15), rhs = Zero -- expression 10 operands: lhs = Expression(11, Sub), rhs = Counter(17) -- expression 11 operands: lhs = Counter(15), rhs = Zero -- expression 12 operands: lhs = Expression(16, Sub), rhs = Counter(18) -- expression 13 operands: lhs = Counter(17), rhs = Zero -- expression 14 operands: lhs = Expression(15, Add), rhs = Counter(20) -- expression 15 operands: lhs = Expression(16, Sub), rhs = Counter(18) -- expression 16 operands: lhs = Counter(17), rhs = Zero -- expression 17 operands: lhs = Expression(30, Sub), rhs = Counter(21) -- expression 18 operands: lhs = Counter(20), rhs = Zero -- expression 19 operands: lhs = Expression(30, Sub), rhs = Counter(21) -- expression 20 operands: lhs = Counter(20), rhs = Zero -- expression 21 operands: lhs = Expression(29, Add), rhs = Counter(23) -- expression 22 operands: lhs = Expression(30, Sub), rhs = Counter(21) -- expression 23 operands: lhs = Counter(20), rhs = Zero -- expression 24 operands: lhs = Expression(29, Add), rhs = Counter(24) -- expression 25 operands: lhs = Expression(30, Sub), rhs = Counter(21) -- expression 26 operands: lhs = Counter(20), rhs = Zero -- expression 27 operands: lhs = Expression(28, Sub), rhs = Counter(25) -- expression 28 operands: lhs = Expression(29, Add), rhs = Counter(24) -- expression 29 operands: lhs = Expression(30, Sub), rhs = Counter(21) -- expression 30 operands: lhs = Counter(20), rhs = Zero -- expression 31 operands: lhs = Counter(29), rhs = Expression(47, Sub) -- expression 32 operands: lhs = Expression(48, Sub), rhs = Counter(30) -- expression 33 operands: lhs = Counter(26), rhs = Counter(27) -- expression 34 operands: lhs = Counter(26), rhs = Counter(27) -- expression 35 operands: lhs = Counter(26), rhs = Counter(27) -- expression 36 operands: lhs = Expression(48, Sub), rhs = Zero -- expression 37 operands: lhs = Counter(26), rhs = Counter(27) -- expression 38 operands: lhs = Expression(48, Sub), rhs = Counter(30) -- expression 39 operands: lhs = Counter(26), rhs = Counter(27) -- expression 40 operands: lhs = Expression(46, Add), rhs = Counter(31) -- expression 41 operands: lhs = Counter(29), rhs = Expression(47, Sub) -- expression 42 operands: lhs = Expression(48, Sub), rhs = Counter(30) +- expression 5 operands: lhs = Expression(6, Sub), rhs = Counter(8) +- expression 6 operands: lhs = Expression(7, Sub), rhs = Counter(7) +- expression 7 operands: lhs = Counter(5), rhs = Counter(6) +- expression 8 operands: lhs = Counter(9), rhs = Counter(11) +- expression 9 operands: lhs = Counter(8), rhs = Counter(9) +- expression 10 operands: lhs = Counter(10), rhs = Counter(13) +- expression 11 operands: lhs = Expression(12, Sub), rhs = Counter(10) +- expression 12 operands: lhs = Counter(8), rhs = Counter(9) +- expression 13 operands: lhs = Counter(12), rhs = Counter(14) +- expression 14 operands: lhs = Counter(15), rhs = Counter(16) +- expression 15 operands: lhs = Expression(16, Sub), rhs = Counter(17) +- expression 16 operands: lhs = Counter(15), rhs = Counter(16) +- expression 17 operands: lhs = Expression(25, Sub), rhs = Counter(18) +- expression 18 operands: lhs = Counter(17), rhs = Counter(19) +- expression 19 operands: lhs = Expression(24, Add), rhs = Counter(20) +- expression 20 operands: lhs = Expression(25, Sub), rhs = Counter(18) +- expression 21 operands: lhs = Counter(17), rhs = Counter(19) +- expression 22 operands: lhs = Expression(23, Sub), rhs = Counter(21) +- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(20) +- expression 24 operands: lhs = Expression(25, Sub), rhs = Counter(18) +- expression 25 operands: lhs = Counter(17), rhs = Counter(19) +- expression 26 operands: lhs = Expression(39, Sub), rhs = Counter(21) +- expression 27 operands: lhs = Counter(20), rhs = Counter(22) +- expression 28 operands: lhs = Expression(39, Sub), rhs = Counter(21) +- expression 29 operands: lhs = Counter(20), rhs = Counter(22) +- expression 30 operands: lhs = Expression(38, Add), rhs = Counter(23) +- expression 31 operands: lhs = Expression(39, Sub), rhs = Counter(21) +- expression 32 operands: lhs = Counter(20), rhs = Counter(22) +- expression 33 operands: lhs = Expression(38, Add), rhs = Counter(24) +- expression 34 operands: lhs = Expression(39, Sub), rhs = Counter(21) +- expression 35 operands: lhs = Counter(20), rhs = Counter(22) +- expression 36 operands: lhs = Expression(37, Sub), rhs = Counter(25) +- expression 37 operands: lhs = Expression(38, Add), rhs = Counter(24) +- expression 38 operands: lhs = Expression(39, Sub), rhs = Counter(21) +- expression 39 operands: lhs = Counter(20), rhs = Counter(22) +- expression 40 operands: lhs = Counter(29), rhs = Expression(56, Sub) +- expression 41 operands: lhs = Expression(57, Sub), rhs = Counter(30) +- expression 42 operands: lhs = Counter(26), rhs = Counter(27) - expression 43 operands: lhs = Counter(26), rhs = Counter(27) -- expression 44 operands: lhs = Expression(45, Sub), rhs = Zero -- expression 45 operands: lhs = Expression(46, Add), rhs = Counter(31) -- expression 46 operands: lhs = Counter(29), rhs = Expression(47, Sub) -- expression 47 operands: lhs = Expression(48, Sub), rhs = Counter(30) +- expression 44 operands: lhs = Counter(26), rhs = Counter(27) +- expression 45 operands: lhs = Expression(57, Sub), rhs = Zero +- expression 46 operands: lhs = Counter(26), rhs = Counter(27) +- expression 47 operands: lhs = Expression(57, Sub), rhs = Counter(30) - expression 48 operands: lhs = Counter(26), rhs = Counter(27) +- expression 49 operands: lhs = Expression(55, Add), rhs = Counter(31) +- expression 50 operands: lhs = Counter(29), rhs = Expression(56, Sub) +- expression 51 operands: lhs = Expression(57, Sub), rhs = Counter(30) +- expression 52 operands: lhs = Counter(26), rhs = Counter(27) +- expression 53 operands: lhs = Expression(54, Sub), rhs = Counter(32) +- expression 54 operands: lhs = Expression(55, Add), rhs = Counter(31) +- expression 55 operands: lhs = Counter(29), rhs = Expression(56, Sub) +- expression 56 operands: lhs = Expression(57, Sub), rhs = Counter(30) +- expression 57 operands: lhs = Counter(26), rhs = Counter(27) +- expression 58 operands: lhs = Counter(32), rhs = Counter(33) Number of file 0 mappings: 51 - Code(Counter(0)) at (prev + 8, 1) to (start + 3, 28) - Code(Counter(1)) at (prev + 4, 9) to (start + 1, 28) @@ -119,73 +129,78 @@ Number of file 0 mappings: 51 = (c1 - c2) - Code(Counter(3)) at (prev + 5, 5) to (start + 0, 31) - Code(Expression(1, Sub)) at (prev + 1, 5) to (start + 0, 31) - = (c3 - Zero) + = (c3 - c4) - Code(Counter(5)) at (prev + 1, 9) to (start + 1, 28) -- Code(Expression(4, Sub)) at (prev + 2, 5) to (start + 0, 31) +- Code(Expression(7, Sub)) at (prev + 2, 5) to (start + 0, 31) = (c5 - c6) -- Code(Expression(3, Sub)) at (prev + 1, 5) to (start + 0, 15) - = ((c5 - c6) - Zero) -- Code(Zero) at (prev + 0, 32) to (start + 0, 48) +- Code(Expression(6, Sub)) at (prev + 1, 5) to (start + 0, 15) + = ((c5 - c6) - c7) +- Code(Expression(5, Sub)) at (prev + 0, 32) to (start + 0, 48) + = (((c5 - c6) - c7) - c8) - Code(Counter(8)) at (prev + 1, 5) to (start + 3, 15) -- Code(Zero) at (prev + 3, 32) to (start + 0, 48) -- Code(Zero) at (prev + 0, 51) to (start + 0, 65) -- Code(Zero) at (prev + 0, 75) to (start + 0, 90) -- Code(Expression(7, Sub)) at (prev + 1, 5) to (start + 0, 15) - = (c8 - Zero) -- Code(Zero) at (prev + 5, 9) to (start + 3, 16) -- Code(Zero) at (prev + 5, 13) to (start + 0, 27) -- Code(Zero) at (prev + 2, 13) to (start + 0, 28) -- Code(Expression(6, Sub)) at (prev + 4, 9) to (start + 5, 6) - = ((c8 - Zero) - Zero) +- Code(Counter(9)) at (prev + 3, 32) to (start + 0, 48) +- Code(Counter(11)) at (prev + 0, 51) to (start + 0, 65) +- Code(Expression(8, Sub)) at (prev + 0, 75) to (start + 0, 90) + = (c9 - c11) +- Code(Expression(12, Sub)) at (prev + 1, 5) to (start + 0, 15) + = (c8 - c9) +- Code(Counter(10)) at (prev + 5, 9) to (start + 3, 16) +- Code(Counter(13)) at (prev + 5, 13) to (start + 0, 27) +- Code(Expression(10, Sub)) at (prev + 2, 13) to (start + 0, 28) + = (c10 - c13) +- Code(Expression(11, Sub)) at (prev + 4, 9) to (start + 5, 6) + = ((c8 - c9) - c10) - Code(Counter(12)) at (prev + 6, 5) to (start + 3, 6) -- Code(Expression(8, Sub)) at (prev + 4, 5) to (start + 3, 6) - = (c12 - Zero) +- Code(Expression(13, Sub)) at (prev + 4, 5) to (start + 3, 6) + = (c12 - c14) - Code(Counter(15)) at (prev + 4, 9) to (start + 4, 6) -- Code(Expression(11, Sub)) at (prev + 5, 8) to (start + 0, 15) - = (c15 - Zero) +- Code(Expression(16, Sub)) at (prev + 5, 8) to (start + 0, 15) + = (c15 - c16) - Code(Counter(17)) at (prev + 1, 9) to (start + 3, 10) -- Code(Expression(10, Sub)) at (prev + 5, 9) to (start + 3, 10) - = ((c15 - Zero) - c17) -- Code(Expression(15, Add)) at (prev + 5, 8) to (start + 0, 15) - = ((c17 - Zero) + c18) +- Code(Expression(15, Sub)) at (prev + 5, 9) to (start + 3, 10) + = ((c15 - c16) - c17) +- Code(Expression(24, Add)) at (prev + 5, 8) to (start + 0, 15) + = ((c17 - c19) + c18) - Code(Counter(20)) at (prev + 1, 9) to (start + 0, 19) -- Code(Zero) at (prev + 3, 13) to (start + 0, 29) -- Code(Expression(14, Sub)) at (prev + 3, 9) to (start + 0, 19) - = (((c17 - Zero) + c18) - c20) -- Code(Zero) at (prev + 3, 13) to (start + 0, 29) -- Code(Expression(29, Add)) at (prev + 3, 5) to (start + 0, 15) - = ((c20 - Zero) + c21) -- Code(Expression(29, Add)) at (prev + 1, 12) to (start + 0, 19) - = ((c20 - Zero) + c21) +- Code(Counter(22)) at (prev + 3, 13) to (start + 0, 29) +- Code(Expression(23, Sub)) at (prev + 3, 9) to (start + 0, 19) + = (((c17 - c19) + c18) - c20) +- Code(Expression(22, Sub)) at (prev + 3, 13) to (start + 0, 29) + = ((((c17 - c19) + c18) - c20) - c21) +- Code(Expression(38, Add)) at (prev + 3, 5) to (start + 0, 15) + = ((c20 - c22) + c21) +- Code(Expression(38, Add)) at (prev + 1, 12) to (start + 0, 19) + = ((c20 - c22) + c21) - Code(Counter(23)) at (prev + 1, 13) to (start + 0, 19) -- Code(Expression(21, Sub)) at (prev + 2, 13) to (start + 0, 19) - = (((c20 - Zero) + c21) - c23) -- Code(Expression(28, Sub)) at (prev + 4, 5) to (start + 2, 19) - = (((c20 - Zero) + c21) - c24) +- Code(Expression(30, Sub)) at (prev + 2, 13) to (start + 0, 19) + = (((c20 - c22) + c21) - c23) +- Code(Expression(37, Sub)) at (prev + 4, 5) to (start + 2, 19) + = (((c20 - c22) + c21) - c24) - Code(Counter(25)) at (prev + 3, 13) to (start + 0, 19) -- Code(Expression(27, Sub)) at (prev + 2, 13) to (start + 0, 19) - = ((((c20 - Zero) + c21) - c24) - c25) -- Code(Expression(46, Add)) at (prev + 3, 5) to (start + 0, 15) +- Code(Expression(36, Sub)) at (prev + 2, 13) to (start + 0, 19) + = ((((c20 - c22) + c21) - c24) - c25) +- Code(Expression(55, Add)) at (prev + 3, 5) to (start + 0, 15) = (c29 + ((c26 - c27) - c30)) - Code(Counter(26)) at (prev + 1, 12) to (start + 0, 19) - Code(Counter(27)) at (prev + 1, 13) to (start + 3, 14) - Code(Counter(29)) at (prev + 4, 13) to (start + 0, 19) -- Code(Expression(48, Sub)) at (prev + 2, 13) to (start + 0, 23) +- Code(Expression(57, Sub)) at (prev + 2, 13) to (start + 0, 23) = (c26 - c27) -- Code(Expression(48, Sub)) at (prev + 1, 20) to (start + 0, 27) +- Code(Expression(57, Sub)) at (prev + 1, 20) to (start + 0, 27) = (c26 - c27) - Code(Zero) at (prev + 1, 21) to (start + 0, 27) -- Code(Expression(36, Sub)) at (prev + 2, 21) to (start + 0, 27) +- Code(Expression(45, Sub)) at (prev + 2, 21) to (start + 0, 27) = ((c26 - c27) - Zero) -- Code(Expression(47, Sub)) at (prev + 4, 13) to (start + 0, 19) +- Code(Expression(56, Sub)) at (prev + 4, 13) to (start + 0, 19) = ((c26 - c27) - c30) - Code(Counter(31)) at (prev + 3, 9) to (start + 0, 25) -- Code(Expression(45, Sub)) at (prev + 2, 5) to (start + 0, 15) +- Code(Expression(54, Sub)) at (prev + 2, 5) to (start + 0, 15) = ((c29 + ((c26 - c27) - c30)) - c31) -- Code(Expression(44, Sub)) at (prev + 3, 9) to (start + 0, 34) - = (((c29 + ((c26 - c27) - c30)) - c31) - Zero) -- Code(Zero) at (prev + 2, 5) to (start + 0, 15) -- Code(Zero) at (prev + 3, 9) to (start + 0, 44) -- Code(Zero) at (prev + 2, 1) to (start + 0, 2) -Highest counter ID seen: c31 +- Code(Expression(53, Sub)) at (prev + 3, 9) to (start + 0, 34) + = (((c29 + ((c26 - c27) - c30)) - c31) - c32) +- Code(Counter(32)) at (prev + 2, 5) to (start + 0, 15) +- Code(Expression(58, Sub)) at (prev + 3, 9) to (start + 0, 44) + = (c32 - c33) +- Code(Counter(33)) at (prev + 2, 1) to (start + 0, 2) +Highest counter ID seen: c33 diff --git a/tests/coverage/no-core.cov-map b/tests/coverage/no-core.cov-map new file mode 100644 index 0000000000000..3a1ca4745c73f --- /dev/null +++ b/tests/coverage/no-core.cov-map @@ -0,0 +1,9 @@ +Function name: no_core::main +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 01, 00, 0d] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 13) +Highest counter ID seen: c0 + diff --git a/tests/coverage/no-core.coverage b/tests/coverage/no-core.coverage new file mode 100644 index 0000000000000..8b89060956879 --- /dev/null +++ b/tests/coverage/no-core.coverage @@ -0,0 +1,13 @@ + LL| |#![feature(no_core)] + LL| |#![no_core] + LL| |//@ edition: 2021 + LL| | + LL| |// Test that coverage instrumentation works for `#![no_core]` crates. + LL| | + LL| |// For this test, we pull in std anyway, to avoid having to set up our own + LL| |// no-core or no-std environment. What's important is that the compiler allows + LL| |// coverage for a crate with the `#![no_core]` annotation. + LL| |extern crate std; + LL| | + LL| 1|fn main() {} + diff --git a/tests/coverage/no-core.rs b/tests/coverage/no-core.rs new file mode 100644 index 0000000000000..206222902fc94 --- /dev/null +++ b/tests/coverage/no-core.rs @@ -0,0 +1,12 @@ +#![feature(no_core)] +#![no_core] +//@ edition: 2021 + +// Test that coverage instrumentation works for `#![no_core]` crates. + +// For this test, we pull in std anyway, to avoid having to set up our own +// no-core or no-std environment. What's important is that the compiler allows +// coverage for a crate with the `#![no_core]` annotation. +extern crate std; + +fn main() {} diff --git a/tests/crashes/124350.rs b/tests/crashes/124350.rs deleted file mode 100644 index d6038f280cf81..0000000000000 --- a/tests/crashes/124350.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #124350 - -struct Node {} - -impl Node -where - SmallVec<{ D * 2 }>:, -{ - fn new() -> Self { - let mut node = Node::new(); - (&a, 0)(); - - node - } -} - -struct SmallVec {} diff --git a/tests/crashes/124751.rs b/tests/crashes/124751.rs index f15e39965d3ed..1372b97233d37 100644 --- a/tests/crashes/124751.rs +++ b/tests/crashes/124751.rs @@ -1,5 +1,5 @@ //@ known-bug: rust-lang/rust#124751 -//@ compile-flags: -Zunstable-options --edition=2024 +//@ edition: 2024 #![feature(gen_blocks)] diff --git a/tests/crashes/125758.rs b/tests/crashes/125758.rs deleted file mode 100644 index 86c3b80abab9d..0000000000000 --- a/tests/crashes/125758.rs +++ /dev/null @@ -1,26 +0,0 @@ -//@ known-bug: rust-lang/rust#125758 -#![feature(impl_trait_in_assoc_type)] - -trait Trait: Sized { - type Assoc2; -} - -impl Trait for Bar { - type Assoc2 = impl std::fmt::Debug; -} - -struct Foo { - field: ::Assoc2, -} - -enum Bar { - C = 42, - D = 99, -} - -static BAR: u8 = 42; - -static FOO2: (&Foo, &::Assoc2) = - unsafe { (std::mem::transmute(&BAR), std::mem::transmute(&BAR)) }; - -fn main() {} diff --git a/tests/crashes/126359.rs b/tests/crashes/126359.rs deleted file mode 100644 index 4b28c466b55c3..0000000000000 --- a/tests/crashes/126359.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ known-bug: rust-lang/rust#126359 - -struct OppOrder { - arr: [T; N], -} - -fn main() { - let _ = OppOrder::<3, u32> { arr: [0, 0, 0] }; -} diff --git a/tests/crashes/126646.rs b/tests/crashes/126646.rs deleted file mode 100644 index 24e3530320a89..0000000000000 --- a/tests/crashes/126646.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ known-bug: rust-lang/rust#126646 -mod foo { - pub trait Callable { - type Output; - fn call() -> Self::Output; - } - - impl<'a, V: ?Sized> Callable for &'a () { - type Output = (); - } -} -use foo::*; - -fn test<'a>() -> impl Sized { - <&'a () as Callable>::call() -} - -fn main() {} diff --git a/tests/crashes/127351.rs b/tests/crashes/127351.rs deleted file mode 100644 index e3f415948852d..0000000000000 --- a/tests/crashes/127351.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #127351 -#![feature(lazy_type_alias)] -#![allow(incomplete_features)] - -struct Outer0<'a, T>(ExplicitTypeOutlives<'a, T>); -type ExplicitTypeOutlives<'a, T: 'a> = (&'a (), T); - -pub struct Warns { - _significant_drop: ExplicitTypeOutlives, - field: String, -} - -pub fn test(w: Warns) { - _ = || drop(w.field); -} - -fn main() {} diff --git a/tests/crashes/127353.rs b/tests/crashes/127353.rs deleted file mode 100644 index 9bcb90b5c57f8..0000000000000 --- a/tests/crashes/127353.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ known-bug: #127353 -#![feature(type_alias_impl_trait)] -trait Trait {} -type Alias<'a, U> = impl Trait; - -fn f<'a>() -> Alias<'a, ()> {} - -pub enum UninhabitedVariants { - Tuple(Alias), -} - -struct A; - -fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { - match x {} -} - -fn main() {} diff --git a/tests/crashes/127742.rs b/tests/crashes/127742.rs deleted file mode 100644 index 24add45413566..0000000000000 --- a/tests/crashes/127742.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #127742 -struct Vtable(dyn Cap); // missing lifetime - -trait Cap<'a> {} - -union Transmute { - t: u64, // ICEs with u64, u128, or usize. Correctly errors with u32. - u: &'static Vtable, -} - -const G: &'static Vtable = unsafe { Transmute { t: 1 }.u }; diff --git a/tests/crashes/129444.rs b/tests/crashes/129444.rs deleted file mode 100644 index b1b547b5191bd..0000000000000 --- a/tests/crashes/129444.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: rust-lang/rust#129444 - -//@ compile-flags: -Znext-solver=coherence - -trait Trait { - type Assoc; -} - -struct W(*mut T); -impl Trait for W>> {} - -trait NoOverlap {} -impl>> NoOverlap for T {} - -impl> NoOverlap for W {} diff --git a/tests/crashes/130521.rs b/tests/crashes/130521.rs index 7c078ab579094..ebcfacf96238c 100644 --- a/tests/crashes/130521.rs +++ b/tests/crashes/130521.rs @@ -1,12 +1,12 @@ //@ known-bug: #130521 #![feature(dyn_compatible_for_dispatch)] -struct Vtable(dyn Cap); +struct Vtable(dyn Cap<'static>); trait Cap<'a> {} union Transmute { - t: u64, + t: u128, u: &'static Vtable, } diff --git a/tests/crashes/131101.rs b/tests/crashes/131101.rs deleted file mode 100644 index 3ec441101b7d9..0000000000000 --- a/tests/crashes/131101.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: #131101 -trait Foo { - fn do_x(&self) -> [u8; N]; -} - -struct Bar; - -impl Foo for Bar { - fn do_x(&self) -> [u8; 3] { - [0u8; 3] - } -} diff --git a/tests/incremental/auxiliary/incremental_proc_macro_aux.rs b/tests/incremental/auxiliary/incremental_proc_macro_aux.rs index 505a9ee27a40f..d0730eb00ee81 100644 --- a/tests/incremental/auxiliary/incremental_proc_macro_aux.rs +++ b/tests/incremental/auxiliary/incremental_proc_macro_aux.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/incremental/auxiliary/issue-49482-macro-def.rs b/tests/incremental/auxiliary/issue-49482-macro-def.rs index 9218d6b62cbb5..6cd565c3a110e 100644 --- a/tests/incremental/auxiliary/issue-49482-macro-def.rs +++ b/tests/incremental/auxiliary/issue-49482-macro-def.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type="proc-macro"] #![allow(non_snake_case)] extern crate proc_macro; diff --git a/tests/incremental/auxiliary/issue-49482-reexport.rs b/tests/incremental/auxiliary/issue-49482-reexport.rs index 39f19e3f15f24..686766de54fee 100644 --- a/tests/incremental/auxiliary/issue-49482-reexport.rs +++ b/tests/incremental/auxiliary/issue-49482-reexport.rs @@ -1,3 +1,4 @@ +//@ proc-macro: issue-49482-macro-def.rs #[macro_use] extern crate issue_49482_macro_def; diff --git a/tests/incremental/auxiliary/issue-54059.rs b/tests/incremental/auxiliary/issue-54059.rs index 5f45403735cd0..6bbc94149e822 100644 --- a/tests/incremental/auxiliary/issue-54059.rs +++ b/tests/incremental/auxiliary/issue-54059.rs @@ -1,9 +1,5 @@ -//@ force-host -//@ no-prefer-dynamic - // check that having extern "C" functions in a proc macro doesn't crash. -#![crate_type="proc-macro"] #![allow(non_snake_case)] extern crate proc_macro; diff --git a/tests/incremental/incremental_proc_macro.rs b/tests/incremental/incremental_proc_macro.rs index 97faf8e698a23..3cf89cae6528e 100644 --- a/tests/incremental/incremental_proc_macro.rs +++ b/tests/incremental/incremental_proc_macro.rs @@ -1,4 +1,4 @@ -//@ aux-build:incremental_proc_macro_aux.rs +//@ proc-macro: incremental_proc_macro_aux.rs //@ revisions: cfail1 cfail2 //@ build-pass (FIXME(62277): could be check-pass?) diff --git a/tests/incremental/issue-110457-same-span-closures/auxiliary/egui_inspect_derive.rs b/tests/incremental/issue-110457-same-span-closures/auxiliary/egui_inspect_derive.rs index 3b4933811d3f5..877d74d731d52 100644 --- a/tests/incremental/issue-110457-same-span-closures/auxiliary/egui_inspect_derive.rs +++ b/tests/incremental/issue-110457-same-span-closures/auxiliary/egui_inspect_derive.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; diff --git a/tests/incremental/issue-110457-same-span-closures/main.rs b/tests/incremental/issue-110457-same-span-closures/main.rs index c36b7e3ca8049..6a5e4b315ce3e 100644 --- a/tests/incremental/issue-110457-same-span-closures/main.rs +++ b/tests/incremental/issue-110457-same-span-closures/main.rs @@ -1,4 +1,4 @@ -//@ aux-build: egui_inspect_derive.rs +//@ proc-macro: egui_inspect_derive.rs //@ revisions: cpass1 cpass2 extern crate egui_inspect_derive; diff --git a/tests/incremental/issue-49482.rs b/tests/incremental/issue-49482.rs index 2dddde6c17109..849f1c6660091 100644 --- a/tests/incremental/issue-49482.rs +++ b/tests/incremental/issue-49482.rs @@ -1,4 +1,3 @@ -//@ aux-build:issue-49482-macro-def.rs //@ aux-build:issue-49482-reexport.rs //@ revisions: rpass1 diff --git a/tests/incremental/issue-54059.rs b/tests/incremental/issue-54059.rs index bfce4d487db12..b6668b4be28a9 100644 --- a/tests/incremental/issue-54059.rs +++ b/tests/incremental/issue-54059.rs @@ -1,4 +1,4 @@ -//@ aux-build:issue-54059.rs +//@ proc-macro: issue-54059.rs //@ ignore-windows - dealing with weird symbols issues on dylibs isn't worth it //@ revisions: rpass1 diff --git a/tests/incremental/issue-85197-invalid-span/auxiliary/invalid-span-helper-lib.rs b/tests/incremental/issue-85197-invalid-span/auxiliary/invalid-span-helper-lib.rs index f84c4fe9895e7..704193cffd0b1 100644 --- a/tests/incremental/issue-85197-invalid-span/auxiliary/invalid-span-helper-lib.rs +++ b/tests/incremental/issue-85197-invalid-span/auxiliary/invalid-span-helper-lib.rs @@ -1,3 +1,4 @@ +//@ proc-macro: respan.rs //@ revisions: rpass1 rpass2 extern crate respan; diff --git a/tests/incremental/issue-85197-invalid-span/auxiliary/respan.rs b/tests/incremental/issue-85197-invalid-span/auxiliary/respan.rs index c56d9052e32cb..5bedca8a265bd 100644 --- a/tests/incremental/issue-85197-invalid-span/auxiliary/respan.rs +++ b/tests/incremental/issue-85197-invalid-span/auxiliary/respan.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/incremental/issue-85197-invalid-span/invalid_span_main.rs b/tests/incremental/issue-85197-invalid-span/invalid_span_main.rs index eaad44780c743..6db5107cbe431 100644 --- a/tests/incremental/issue-85197-invalid-span/invalid_span_main.rs +++ b/tests/incremental/issue-85197-invalid-span/invalid_span_main.rs @@ -1,5 +1,4 @@ //@ revisions: rpass1 rpass2 -//@ aux-build:respan.rs //@ aux-build:invalid-span-helper-lib.rs // This issue has several different parts. The high level idea is: diff --git a/tests/mir-opt/building/custom/debuginfo.constant.built.after.mir b/tests/mir-opt/building/custom/debuginfo.constant.built.after.mir new file mode 100644 index 0000000000000..00702b5b99c41 --- /dev/null +++ b/tests/mir-opt/building/custom/debuginfo.constant.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `constant` after built + +fn constant() -> () { + debug scalar => const 5_usize; + let mut _0: (); + + bb0: { + return; + } +} diff --git a/tests/mir-opt/building/custom/debuginfo.numbered.built.after.mir b/tests/mir-opt/building/custom/debuginfo.numbered.built.after.mir index d863925371812..fba611818ef6b 100644 --- a/tests/mir-opt/building/custom/debuginfo.numbered.built.after.mir +++ b/tests/mir-opt/building/custom/debuginfo.numbered.built.after.mir @@ -2,7 +2,7 @@ fn numbered(_1: (u32, i32)) -> () { debug first => (_1.0: u32); - debug second => (_1.0: u32); + debug second => (_1.1: i32); let mut _0: (); bb0: { diff --git a/tests/mir-opt/building/custom/debuginfo.rs b/tests/mir-opt/building/custom/debuginfo.rs index 5ab83fd4214ba..c4ea2162e0b08 100644 --- a/tests/mir-opt/building/custom/debuginfo.rs +++ b/tests/mir-opt/building/custom/debuginfo.rs @@ -1,4 +1,3 @@ -// skip-filecheck #![feature(custom_mir, core_intrinsics)] extern crate core; @@ -7,6 +6,8 @@ use core::intrinsics::mir::*; // EMIT_MIR debuginfo.pointee.built.after.mir #[custom_mir(dialect = "built")] fn pointee(opt: &mut Option) { + // CHECK-LABEL: fn pointee( + // CHECK: debug foo => (((*_1) as variant#1).0: i32); mir! { debug foo => Field::(Variant(*opt, 1), 0); { @@ -18,9 +19,12 @@ fn pointee(opt: &mut Option) { // EMIT_MIR debuginfo.numbered.built.after.mir #[custom_mir(dialect = "analysis", phase = "post-cleanup")] fn numbered(i: (u32, i32)) { + // CHECK-LABEL: fn numbered( + // CHECK: debug first => (_1.0: u32); + // CHECK: debug second => (_1.1: i32); mir! { debug first => i.0; - debug second => i.0; + debug second => i.1; { Return() } @@ -34,6 +38,8 @@ struct S { // EMIT_MIR debuginfo.structured.built.after.mir #[custom_mir(dialect = "analysis", phase = "post-cleanup")] fn structured(i: S) { + // CHECK-LABEL: fn structured( + // CHECK: debug x => (_1.0: f32); mir! { debug x => i.x; { @@ -45,6 +51,8 @@ fn structured(i: S) { // EMIT_MIR debuginfo.variant.built.after.mir #[custom_mir(dialect = "built")] fn variant(opt: Option) { + // CHECK-LABEL: fn variant( + // CHECK: debug inner => ((_1 as variant#1).0: i32); mir! { debug inner => Field::(Variant(opt, 1), 0); { @@ -56,6 +64,9 @@ fn variant(opt: Option) { // EMIT_MIR debuginfo.variant_deref.built.after.mir #[custom_mir(dialect = "built")] fn variant_deref(opt: Option<&i32>) { + // CHECK-LABEL: fn variant_deref( + // CHECK: debug pointer => ((_1 as variant#1).0: &i32); + // CHECK: debug deref => (*((_1 as variant#1).0: &i32)); mir! { debug pointer => Field::<&i32>(Variant(opt, 1), 0); debug deref => *Field::<&i32>(Variant(opt, 1), 0); @@ -65,10 +76,24 @@ fn variant_deref(opt: Option<&i32>) { } } +// EMIT_MIR debuginfo.constant.built.after.mir +#[custom_mir(dialect = "built")] +fn constant() { + // CHECK-LABEL: fn constant( + // CHECK: debug scalar => const 5_usize; + mir!( + debug scalar => 5_usize; + { + Return() + } + ) +} + fn main() { numbered((5, 6)); structured(S { x: 5. }); variant(Some(5)); variant_deref(Some(&5)); pointee(&mut Some(5)); + constant(); } diff --git a/tests/mir-opt/const_prop/read_immutable_static.main.GVN.diff b/tests/mir-opt/const_prop/read_immutable_static.main.GVN.diff index 8df262b351f12..23928337bf77f 100644 --- a/tests/mir-opt/const_prop/read_immutable_static.main.GVN.diff +++ b/tests/mir-opt/const_prop/read_immutable_static.main.GVN.diff @@ -14,23 +14,19 @@ bb0: { StorageLive(_1); -- StorageLive(_2); + StorageLive(_2); - StorageLive(_3); -+ nop; + nop; _3 = const {ALLOC0: &u8}; -- _2 = copy (*_3); -+ _2 = const 2_u8; + _2 = copy (*_3); StorageLive(_4); StorageLive(_5); _5 = const {ALLOC0: &u8}; - _4 = copy (*_5); -- _1 = Add(move _2, move _4); -+ _4 = const 2_u8; -+ _1 = const 4_u8; ++ _4 = copy (*_3); + _1 = Add(move _2, move _4); StorageDead(_4); -- StorageDead(_2); -+ nop; + StorageDead(_2); StorageDead(_5); - StorageDead(_3); + nop; diff --git a/tests/mir-opt/const_prop/read_immutable_static.rs b/tests/mir-opt/const_prop/read_immutable_static.rs index 05fec2f3303b0..98ba76fb7655a 100644 --- a/tests/mir-opt/const_prop/read_immutable_static.rs +++ b/tests/mir-opt/const_prop/read_immutable_static.rs @@ -6,6 +6,7 @@ static FOO: u8 = 2; fn main() { // CHECK-LABEL: fn main( // CHECK: debug x => [[x:_.*]]; - // CHECK: [[x]] = const 4_u8; + // Disabled due to + // COM: CHECK: [[x]] = const 4_u8; let x = FOO + FOO; } diff --git a/tests/mir-opt/const_prop/ref_deref.main.GVN.diff b/tests/mir-opt/const_prop/ref_deref.main.GVN.diff index b9e269266b0b1..4477b4b005baf 100644 --- a/tests/mir-opt/const_prop/ref_deref.main.GVN.diff +++ b/tests/mir-opt/const_prop/ref_deref.main.GVN.diff @@ -16,8 +16,7 @@ StorageLive(_2); _4 = const main::promoted[0]; _2 = &(*_4); -- _1 = copy (*_2); -+ _1 = const 4_i32; + _1 = copy (*_2); StorageDead(_2); _0 = const (); StorageDead(_1); diff --git a/tests/mir-opt/const_prop/ref_deref_project.main.GVN.diff b/tests/mir-opt/const_prop/ref_deref_project.main.GVN.diff index dcc13c9251c41..bbfd70bea1684 100644 --- a/tests/mir-opt/const_prop/ref_deref_project.main.GVN.diff +++ b/tests/mir-opt/const_prop/ref_deref_project.main.GVN.diff @@ -16,8 +16,7 @@ StorageLive(_2); _4 = const main::promoted[0]; _2 = &((*_4).1: i32); -- _1 = copy (*_2); -+ _1 = const 5_i32; + _1 = copy (*_2); StorageDead(_2); _0 = const (); StorageDead(_1); diff --git a/tests/mir-opt/const_prop/ref_deref_project.rs b/tests/mir-opt/const_prop/ref_deref_project.rs index 5a48a887f93d7..31108e1a57f51 100644 --- a/tests/mir-opt/const_prop/ref_deref_project.rs +++ b/tests/mir-opt/const_prop/ref_deref_project.rs @@ -5,6 +5,7 @@ fn main() { // CHECK-LABEL: fn main( // CHECK: debug a => [[a:_.*]]; - // CHECK: [[a]] = const 5_i32; + // Disabled due to + // COM: CHECK: [[a]] = const 5_i32; let a = *(&(4, 5).1); } diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff index 41ce94eda7517..8a8ea5b7e200b 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff @@ -30,17 +30,16 @@ StorageDead(_3); StorageLive(_6); _6 = const 1_usize; -- _7 = Len((*_2)); + _7 = Len((*_2)); - _8 = Lt(copy _6, copy _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; -+ _7 = const 3_usize; -+ _8 = const true; -+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; ++ _8 = Lt(const 1_usize, copy _7); ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable]; } bb1: { - _1 = copy (*_2)[_6]; -+ _1 = const 2_u32; ++ _1 = copy (*_2)[1 of 2]; StorageDead(_6); StorageDead(_4); StorageDead(_2); diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff index 8cced96cd4331..f0c844884f670 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff @@ -30,17 +30,16 @@ StorageDead(_3); StorageLive(_6); _6 = const 1_usize; -- _7 = Len((*_2)); + _7 = Len((*_2)); - _8 = Lt(copy _6, copy _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; -+ _7 = const 3_usize; -+ _8 = const true; -+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; ++ _8 = Lt(const 1_usize, copy _7); ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue]; } bb1: { - _1 = copy (*_2)[_6]; -+ _1 = const 2_u32; ++ _1 = copy (*_2)[1 of 2]; StorageDead(_6); StorageDead(_4); StorageDead(_2); diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff index 41ce94eda7517..8a8ea5b7e200b 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff @@ -30,17 +30,16 @@ StorageDead(_3); StorageLive(_6); _6 = const 1_usize; -- _7 = Len((*_2)); + _7 = Len((*_2)); - _8 = Lt(copy _6, copy _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; -+ _7 = const 3_usize; -+ _8 = const true; -+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; ++ _8 = Lt(const 1_usize, copy _7); ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable]; } bb1: { - _1 = copy (*_2)[_6]; -+ _1 = const 2_u32; ++ _1 = copy (*_2)[1 of 2]; StorageDead(_6); StorageDead(_4); StorageDead(_2); diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff index 8cced96cd4331..f0c844884f670 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff @@ -30,17 +30,16 @@ StorageDead(_3); StorageLive(_6); _6 = const 1_usize; -- _7 = Len((*_2)); + _7 = Len((*_2)); - _8 = Lt(copy _6, copy _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; -+ _7 = const 3_usize; -+ _8 = const true; -+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; ++ _8 = Lt(const 1_usize, copy _7); ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue]; } bb1: { - _1 = copy (*_2)[_6]; -+ _1 = const 2_u32; ++ _1 = copy (*_2)[1 of 2]; StorageDead(_6); StorageDead(_4); StorageDead(_2); diff --git a/tests/mir-opt/const_prop/slice_len.rs b/tests/mir-opt/const_prop/slice_len.rs index ebd3c9e792dca..498e09fbb65c3 100644 --- a/tests/mir-opt/const_prop/slice_len.rs +++ b/tests/mir-opt/const_prop/slice_len.rs @@ -8,7 +8,8 @@ fn main() { // CHECK-LABEL: fn main( // CHECK: debug a => [[a:_.*]]; // CHECK: [[slice:_.*]] = copy {{.*}} as &[u32] (PointerCoercion(Unsize, AsCast)); - // CHECK: assert(const true, - // CHECK: [[a]] = const 2_u32; + // Disabled due to + // COM: CHECK: assert(const true, + // COM: CHECK: [[a]] = const 2_u32; let a = (&[1u32, 2, 3] as &[u32])[1]; } diff --git a/tests/mir-opt/gvn.borrowed.GVN.panic-abort.diff b/tests/mir-opt/gvn.borrowed.GVN.panic-abort.diff index b0702696e1871..acbea13642c1f 100644 --- a/tests/mir-opt/gvn.borrowed.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.borrowed.GVN.panic-abort.diff @@ -18,8 +18,7 @@ } bb2: { -- _0 = opaque::(copy (*_3)) -> [return: bb3, unwind unreachable]; -+ _0 = opaque::(copy _1) -> [return: bb3, unwind unreachable]; + _0 = opaque::(copy (*_3)) -> [return: bb3, unwind unreachable]; } bb3: { diff --git a/tests/mir-opt/gvn.borrowed.GVN.panic-unwind.diff b/tests/mir-opt/gvn.borrowed.GVN.panic-unwind.diff index fe05d4deeede9..ba080bfdb07a9 100644 --- a/tests/mir-opt/gvn.borrowed.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.borrowed.GVN.panic-unwind.diff @@ -18,8 +18,7 @@ } bb2: { -- _0 = opaque::(copy (*_3)) -> [return: bb3, unwind continue]; -+ _0 = opaque::(copy _1) -> [return: bb3, unwind continue]; + _0 = opaque::(copy (*_3)) -> [return: bb3, unwind continue]; } bb3: { diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff index a763614dc644b..ecd7bdc433cd9 100644 --- a/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff @@ -107,23 +107,18 @@ StorageLive(_18); _18 = &(*_1); StorageLive(_19); -- StorageLive(_20); -+ nop; + StorageLive(_20); _20 = copy (*_18); -- _19 = opaque::(move _20) -> [return: bb7, unwind unreachable]; -+ _19 = opaque::(copy _20) -> [return: bb7, unwind unreachable]; + _19 = opaque::(move _20) -> [return: bb7, unwind unreachable]; } bb7: { -- StorageDead(_20); -+ nop; + StorageDead(_20); StorageDead(_19); StorageLive(_21); StorageLive(_22); -- _22 = copy (*_18); -- _21 = opaque::(move _22) -> [return: bb8, unwind unreachable]; -+ _22 = copy _20; -+ _21 = opaque::(copy _20) -> [return: bb8, unwind unreachable]; + _22 = copy (*_18); + _21 = opaque::(move _22) -> [return: bb8, unwind unreachable]; } bb8: { @@ -157,23 +152,18 @@ StorageDead(_28); StorageDead(_27); StorageLive(_29); -- StorageLive(_30); -+ nop; + StorageLive(_30); _30 = copy ((*_3).0: u32); -- _29 = opaque::(move _30) -> [return: bb12, unwind unreachable]; -+ _29 = opaque::(copy _30) -> [return: bb12, unwind unreachable]; + _29 = opaque::(move _30) -> [return: bb12, unwind unreachable]; } bb12: { -- StorageDead(_30); -+ nop; + StorageDead(_30); StorageDead(_29); StorageLive(_31); StorageLive(_32); -- _32 = copy ((*_3).0: u32); -- _31 = opaque::(move _32) -> [return: bb13, unwind unreachable]; -+ _32 = copy _30; -+ _31 = opaque::(copy _30) -> [return: bb13, unwind unreachable]; + _32 = copy ((*_3).0: u32); + _31 = opaque::(move _32) -> [return: bb13, unwind unreachable]; } bb13: { diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff index ca6fda483642c..bbca6bc3c754d 100644 --- a/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff @@ -107,23 +107,18 @@ StorageLive(_18); _18 = &(*_1); StorageLive(_19); -- StorageLive(_20); -+ nop; + StorageLive(_20); _20 = copy (*_18); -- _19 = opaque::(move _20) -> [return: bb7, unwind continue]; -+ _19 = opaque::(copy _20) -> [return: bb7, unwind continue]; + _19 = opaque::(move _20) -> [return: bb7, unwind continue]; } bb7: { -- StorageDead(_20); -+ nop; + StorageDead(_20); StorageDead(_19); StorageLive(_21); StorageLive(_22); -- _22 = copy (*_18); -- _21 = opaque::(move _22) -> [return: bb8, unwind continue]; -+ _22 = copy _20; -+ _21 = opaque::(copy _20) -> [return: bb8, unwind continue]; + _22 = copy (*_18); + _21 = opaque::(move _22) -> [return: bb8, unwind continue]; } bb8: { @@ -157,23 +152,18 @@ StorageDead(_28); StorageDead(_27); StorageLive(_29); -- StorageLive(_30); -+ nop; + StorageLive(_30); _30 = copy ((*_3).0: u32); -- _29 = opaque::(move _30) -> [return: bb12, unwind continue]; -+ _29 = opaque::(copy _30) -> [return: bb12, unwind continue]; + _29 = opaque::(move _30) -> [return: bb12, unwind continue]; } bb12: { -- StorageDead(_30); -+ nop; + StorageDead(_30); StorageDead(_29); StorageLive(_31); StorageLive(_32); -- _32 = copy ((*_3).0: u32); -- _31 = opaque::(move _32) -> [return: bb13, unwind continue]; -+ _32 = copy _30; -+ _31 = opaque::(copy _30) -> [return: bb13, unwind continue]; + _32 = copy ((*_3).0: u32); + _31 = opaque::(move _32) -> [return: bb13, unwind continue]; } bb13: { diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff index 130b011630cc2..7f99b83d937dd 100644 --- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff @@ -8,10 +8,10 @@ let mut _3: fn(u8) -> u8; let _5: (); let mut _6: fn(u8) -> u8; - let mut _9: {closure@$DIR/gvn.rs:614:19: 614:21}; + let mut _9: {closure@$DIR/gvn.rs:615:19: 615:21}; let _10: (); let mut _11: fn(); - let mut _13: {closure@$DIR/gvn.rs:614:19: 614:21}; + let mut _13: {closure@$DIR/gvn.rs:615:19: 615:21}; let _14: (); let mut _15: fn(); scope 1 { @@ -19,7 +19,7 @@ let _4: fn(u8) -> u8; scope 2 { debug g => _4; - let _7: {closure@$DIR/gvn.rs:614:19: 614:21}; + let _7: {closure@$DIR/gvn.rs:615:19: 615:21}; scope 3 { debug closure => _7; let _8: fn(); @@ -62,16 +62,16 @@ StorageDead(_6); StorageDead(_5); - StorageLive(_7); -- _7 = {closure@$DIR/gvn.rs:614:19: 614:21}; +- _7 = {closure@$DIR/gvn.rs:615:19: 615:21}; - StorageLive(_8); + nop; -+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; ++ _7 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21}; + nop; StorageLive(_9); - _9 = copy _7; - _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; -+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _9 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21}; ++ _8 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_9); StorageLive(_10); StorageLive(_11); @@ -88,8 +88,8 @@ StorageLive(_13); - _13 = copy _7; - _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; -+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _13 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21}; ++ _12 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_13); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff index 372a08d547306..06dd0502f30f2 100644 --- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff @@ -8,10 +8,10 @@ let mut _3: fn(u8) -> u8; let _5: (); let mut _6: fn(u8) -> u8; - let mut _9: {closure@$DIR/gvn.rs:614:19: 614:21}; + let mut _9: {closure@$DIR/gvn.rs:615:19: 615:21}; let _10: (); let mut _11: fn(); - let mut _13: {closure@$DIR/gvn.rs:614:19: 614:21}; + let mut _13: {closure@$DIR/gvn.rs:615:19: 615:21}; let _14: (); let mut _15: fn(); scope 1 { @@ -19,7 +19,7 @@ let _4: fn(u8) -> u8; scope 2 { debug g => _4; - let _7: {closure@$DIR/gvn.rs:614:19: 614:21}; + let _7: {closure@$DIR/gvn.rs:615:19: 615:21}; scope 3 { debug closure => _7; let _8: fn(); @@ -62,16 +62,16 @@ StorageDead(_6); StorageDead(_5); - StorageLive(_7); -- _7 = {closure@$DIR/gvn.rs:614:19: 614:21}; +- _7 = {closure@$DIR/gvn.rs:615:19: 615:21}; - StorageLive(_8); + nop; -+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; ++ _7 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21}; + nop; StorageLive(_9); - _9 = copy _7; - _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; -+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _9 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21}; ++ _8 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_9); StorageLive(_10); StorageLive(_11); @@ -88,8 +88,8 @@ StorageLive(_13); - _13 = copy _7; - _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; -+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _13 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21}; ++ _12 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_13); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index faa6faa70179c..97513248e23c6 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -99,17 +99,18 @@ fn subexpression_elimination(x: u64, y: u64, mut z: u64) { opaque((x * y) - y); opaque((x * y) - y); - // We can substitute through an immutable reference too. + // We cannot substitute through an immutable reference. + // (Disabled due to ) // CHECK: [[ref:_.*]] = &_3; // CHECK: [[deref:_.*]] = copy (*[[ref]]); - // CHECK: [[addref:_.*]] = Add(copy [[deref]], copy _1); - // CHECK: opaque::(copy [[addref]]) - // CHECK: opaque::(copy [[addref]]) + // COM: CHECK: [[addref:_.*]] = Add(copy [[deref]], copy _1); + // COM: CHECK: opaque::(copy [[addref]]) + // COM: CHECK: opaque::(copy [[addref]]) let a = &z; opaque(*a + x); opaque(*a + x); - // But not through a mutable reference or a pointer. + // And certainly not through a mutable reference or a pointer. // CHECK: [[mut:_.*]] = &mut _3; // CHECK: [[addmut:_.*]] = Add( // CHECK: opaque::(move [[addmut]]) @@ -137,13 +138,13 @@ fn subexpression_elimination(x: u64, y: u64, mut z: u64) { opaque(*d + x); } - // We can substitute again, but not with the earlier computations. + // We still cannot substitute again, and never with the earlier computations. // Important: `e` is not `a`! // CHECK: [[ref2:_.*]] = &_3; // CHECK: [[deref2:_.*]] = copy (*[[ref2]]); - // CHECK: [[addref2:_.*]] = Add(copy [[deref2]], copy _1); - // CHECK: opaque::(copy [[addref2]]) - // CHECK: opaque::(copy [[addref2]]) + // COM: CHECK: [[addref2:_.*]] = Add(copy [[deref2]], copy _1); + // COM: CHECK: opaque::(copy [[addref2]]) + // COM: CHECK: opaque::(copy [[addref2]]) let e = &z; opaque(*e + x); opaque(*e + x); @@ -495,15 +496,15 @@ fn dereferences(t: &mut u32, u: &impl Copy, s: &S) { unsafe { opaque(*z) }; unsafe { opaque(*z) }; - // We can reuse dereferences of `&Freeze`. + // Do not reuse dereferences of `&Freeze`. // CHECK: [[ref:_.*]] = &(*_1); // CHECK: [[st7:_.*]] = copy (*[[ref]]); - // CHECK: opaque::(copy [[st7]]) - // CHECK: opaque::(copy [[st7]]) + // COM: CHECK: opaque::(copy [[st7]]) + // COM: CHECK: opaque::(copy [[st7]]) let z = &*t; opaque(*z); opaque(*z); - // But not in reborrows. + // Not in reborrows either. // CHECK: [[reborrow:_.*]] = &(*[[ref]]); // CHECK: opaque::<&u32>(move [[reborrow]]) opaque(&*z); @@ -516,10 +517,10 @@ fn dereferences(t: &mut u32, u: &impl Copy, s: &S) { opaque(*u); opaque(*u); - // `*s` is not Copy, but `(*s).0` is, so we can reuse. + // `*s` is not Copy, but `(*s).0` is, but we still cannot reuse. // CHECK: [[st10:_.*]] = copy ((*_3).0: u32); - // CHECK: opaque::(copy [[st10]]) - // CHECK: opaque::(copy [[st10]]) + // COM: CHECK: opaque::(copy [[st10]]) + // COM: CHECK: opaque::(copy [[st10]]) opaque(s.0); opaque(s.0); } @@ -736,7 +737,7 @@ fn borrowed(x: T) { // CHECK: bb1: { // CHECK-NEXT: _0 = opaque::(copy _1) // CHECK: bb2: { - // CHECK-NEXT: _0 = opaque::(copy _1) + // COM: CHECK-NEXT: _0 = opaque::(copy _1) mir! { { let a = x; diff --git a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff index e8e99b44e721b..43efcbdfb1e4b 100644 --- a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff @@ -111,9 +111,8 @@ StorageLive(_7); StorageLive(_8); - StorageLive(_9); -- StorageLive(_10); -+ nop; + nop; + StorageLive(_10); StorageLive(_11); _11 = &(*_1); _10 = core::str::::as_ptr(move _11) -> [return: bb3, unwind unreachable]; @@ -123,9 +122,8 @@ StorageDead(_11); _9 = &_10; - StorageLive(_12); -- StorageLive(_13); -+ nop; + nop; + StorageLive(_13); StorageLive(_14); - _14 = &(*_4); + _14 = &(*_1); @@ -150,12 +148,11 @@ StorageLive(_17); StorageLive(_18); - _18 = copy (*_15); -+ _18 = copy _10; ++ _18 = copy (*_9); StorageLive(_19); - _19 = copy (*_16); -- _17 = Eq(move _18, move _19); -+ _19 = copy _13; -+ _17 = Eq(copy _10, copy _13); ++ _19 = copy (*_12); + _17 = Eq(move _18, move _19); switchInt(move _17) -> [0: bb6, otherwise: bb5]; } @@ -166,10 +163,8 @@ StorageDead(_17); StorageDead(_16); StorageDead(_15); -- StorageDead(_13); -- StorageDead(_10); -+ nop; -+ nop; + StorageDead(_13); + StorageDead(_10); StorageDead(_8); StorageDead(_7); - StorageLive(_29); @@ -218,9 +213,8 @@ StorageLive(_33); StorageLive(_34); - StorageLive(_35); -- StorageLive(_36); -+ nop; + nop; + StorageLive(_36); StorageLive(_37); _37 = &(*_1); _36 = core::str::::as_ptr(move _37) -> [return: bb8, unwind unreachable]; @@ -230,9 +224,8 @@ StorageDead(_37); _35 = &_36; - StorageLive(_38); -- StorageLive(_39); -+ nop; + nop; + StorageLive(_39); StorageLive(_40); _40 = &(*_29); _39 = core::slice::::as_ptr(move _40) -> [return: bb9, unwind unreachable]; @@ -256,12 +249,11 @@ StorageLive(_43); StorageLive(_44); - _44 = copy (*_41); -+ _44 = copy _36; ++ _44 = copy (*_35); StorageLive(_45); - _45 = copy (*_42); -- _43 = Eq(move _44, move _45); -+ _45 = copy _39; -+ _43 = Eq(copy _36, copy _39); ++ _45 = copy (*_38); + _43 = Eq(move _44, move _45); switchInt(move _43) -> [0: bb11, otherwise: bb10]; } @@ -272,10 +264,8 @@ StorageDead(_43); StorageDead(_42); StorageDead(_41); -- StorageDead(_39); -- StorageDead(_36); -+ nop; -+ nop; + StorageDead(_39); + StorageDead(_36); StorageDead(_34); StorageDead(_33); _0 = const (); diff --git a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff index 4296d4d4a5945..8572f538c0ff7 100644 --- a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff @@ -111,9 +111,8 @@ StorageLive(_7); StorageLive(_8); - StorageLive(_9); -- StorageLive(_10); -+ nop; + nop; + StorageLive(_10); StorageLive(_11); _11 = &(*_1); _10 = core::str::::as_ptr(move _11) -> [return: bb3, unwind continue]; @@ -123,9 +122,8 @@ StorageDead(_11); _9 = &_10; - StorageLive(_12); -- StorageLive(_13); -+ nop; + nop; + StorageLive(_13); StorageLive(_14); - _14 = &(*_4); + _14 = &(*_1); @@ -150,12 +148,11 @@ StorageLive(_17); StorageLive(_18); - _18 = copy (*_15); -+ _18 = copy _10; ++ _18 = copy (*_9); StorageLive(_19); - _19 = copy (*_16); -- _17 = Eq(move _18, move _19); -+ _19 = copy _13; -+ _17 = Eq(copy _10, copy _13); ++ _19 = copy (*_12); + _17 = Eq(move _18, move _19); switchInt(move _17) -> [0: bb6, otherwise: bb5]; } @@ -166,10 +163,8 @@ StorageDead(_17); StorageDead(_16); StorageDead(_15); -- StorageDead(_13); -- StorageDead(_10); -+ nop; -+ nop; + StorageDead(_13); + StorageDead(_10); StorageDead(_8); StorageDead(_7); - StorageLive(_29); @@ -218,9 +213,8 @@ StorageLive(_33); StorageLive(_34); - StorageLive(_35); -- StorageLive(_36); -+ nop; + nop; + StorageLive(_36); StorageLive(_37); _37 = &(*_1); _36 = core::str::::as_ptr(move _37) -> [return: bb8, unwind continue]; @@ -230,9 +224,8 @@ StorageDead(_37); _35 = &_36; - StorageLive(_38); -- StorageLive(_39); -+ nop; + nop; + StorageLive(_39); StorageLive(_40); _40 = &(*_29); _39 = core::slice::::as_ptr(move _40) -> [return: bb9, unwind continue]; @@ -256,12 +249,11 @@ StorageLive(_43); StorageLive(_44); - _44 = copy (*_41); -+ _44 = copy _36; ++ _44 = copy (*_35); StorageLive(_45); - _45 = copy (*_42); -- _43 = Eq(move _44, move _45); -+ _45 = copy _39; -+ _43 = Eq(copy _36, copy _39); ++ _45 = copy (*_38); + _43 = Eq(move _44, move _45); switchInt(move _43) -> [0: bb11, otherwise: bb10]; } @@ -272,10 +264,8 @@ StorageDead(_43); StorageDead(_42); StorageDead(_41); -- StorageDead(_39); -- StorageDead(_36); -+ nop; -+ nop; + StorageDead(_39); + StorageDead(_36); StorageDead(_34); StorageDead(_33); _0 = const (); diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff index 7a479bc55da75..e872e011542b3 100644 --- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff @@ -758,39 +758,32 @@ StorageLive(_126); _126 = &_3; StorageLive(_127); -- StorageLive(_128); -- StorageLive(_129); -+ nop; -+ nop; + StorageLive(_128); + StorageLive(_129); _129 = copy (*_126); StorageLive(_130); _130 = copy _1; - _128 = Add(move _129, move _130); -+ _128 = Add(copy _129, copy _1); ++ _128 = Add(move _129, copy _1); StorageDead(_130); -- StorageDead(_129); -- _127 = opaque::(move _128) -> [return: bb35, unwind unreachable]; -+ nop; -+ _127 = opaque::(copy _128) -> [return: bb35, unwind unreachable]; + StorageDead(_129); + _127 = opaque::(move _128) -> [return: bb35, unwind unreachable]; } bb35: { -- StorageDead(_128); -+ nop; + StorageDead(_128); StorageDead(_127); StorageLive(_131); StorageLive(_132); StorageLive(_133); -- _133 = copy (*_126); -+ _133 = copy _129; + _133 = copy (*_126); StorageLive(_134); _134 = copy _1; - _132 = Add(move _133, move _134); -+ _132 = copy _128; ++ _132 = Add(move _133, copy _1); StorageDead(_134); StorageDead(_133); -- _131 = opaque::(move _132) -> [return: bb36, unwind unreachable]; -+ _131 = opaque::(copy _128) -> [return: bb36, unwind unreachable]; + _131 = opaque::(move _132) -> [return: bb36, unwind unreachable]; } bb36: { @@ -906,39 +899,32 @@ StorageLive(_163); _163 = &_3; StorageLive(_164); -- StorageLive(_165); -- StorageLive(_166); -+ nop; -+ nop; + StorageLive(_165); + StorageLive(_166); _166 = copy (*_163); StorageLive(_167); _167 = copy _1; - _165 = Add(move _166, move _167); -+ _165 = Add(copy _166, copy _1); ++ _165 = Add(move _166, copy _1); StorageDead(_167); -- StorageDead(_166); -- _164 = opaque::(move _165) -> [return: bb43, unwind unreachable]; -+ nop; -+ _164 = opaque::(copy _165) -> [return: bb43, unwind unreachable]; + StorageDead(_166); + _164 = opaque::(move _165) -> [return: bb43, unwind unreachable]; } bb43: { -- StorageDead(_165); -+ nop; + StorageDead(_165); StorageDead(_164); StorageLive(_168); StorageLive(_169); StorageLive(_170); -- _170 = copy (*_163); -+ _170 = copy _166; + _170 = copy (*_163); StorageLive(_171); _171 = copy _1; - _169 = Add(move _170, move _171); -+ _169 = copy _165; ++ _169 = Add(move _170, copy _1); StorageDead(_171); StorageDead(_170); -- _168 = opaque::(move _169) -> [return: bb44, unwind unreachable]; -+ _168 = opaque::(copy _165) -> [return: bb44, unwind unreachable]; + _168 = opaque::(move _169) -> [return: bb44, unwind unreachable]; } bb44: { diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff index 3ca5238663c28..3996dab27a343 100644 --- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff @@ -758,39 +758,32 @@ StorageLive(_126); _126 = &_3; StorageLive(_127); -- StorageLive(_128); -- StorageLive(_129); -+ nop; -+ nop; + StorageLive(_128); + StorageLive(_129); _129 = copy (*_126); StorageLive(_130); _130 = copy _1; - _128 = Add(move _129, move _130); -+ _128 = Add(copy _129, copy _1); ++ _128 = Add(move _129, copy _1); StorageDead(_130); -- StorageDead(_129); -- _127 = opaque::(move _128) -> [return: bb35, unwind continue]; -+ nop; -+ _127 = opaque::(copy _128) -> [return: bb35, unwind continue]; + StorageDead(_129); + _127 = opaque::(move _128) -> [return: bb35, unwind continue]; } bb35: { -- StorageDead(_128); -+ nop; + StorageDead(_128); StorageDead(_127); StorageLive(_131); StorageLive(_132); StorageLive(_133); -- _133 = copy (*_126); -+ _133 = copy _129; + _133 = copy (*_126); StorageLive(_134); _134 = copy _1; - _132 = Add(move _133, move _134); -+ _132 = copy _128; ++ _132 = Add(move _133, copy _1); StorageDead(_134); StorageDead(_133); -- _131 = opaque::(move _132) -> [return: bb36, unwind continue]; -+ _131 = opaque::(copy _128) -> [return: bb36, unwind continue]; + _131 = opaque::(move _132) -> [return: bb36, unwind continue]; } bb36: { @@ -906,39 +899,32 @@ StorageLive(_163); _163 = &_3; StorageLive(_164); -- StorageLive(_165); -- StorageLive(_166); -+ nop; -+ nop; + StorageLive(_165); + StorageLive(_166); _166 = copy (*_163); StorageLive(_167); _167 = copy _1; - _165 = Add(move _166, move _167); -+ _165 = Add(copy _166, copy _1); ++ _165 = Add(move _166, copy _1); StorageDead(_167); -- StorageDead(_166); -- _164 = opaque::(move _165) -> [return: bb43, unwind continue]; -+ nop; -+ _164 = opaque::(copy _165) -> [return: bb43, unwind continue]; + StorageDead(_166); + _164 = opaque::(move _165) -> [return: bb43, unwind continue]; } bb43: { -- StorageDead(_165); -+ nop; + StorageDead(_165); StorageDead(_164); StorageLive(_168); StorageLive(_169); StorageLive(_170); -- _170 = copy (*_163); -+ _170 = copy _166; + _170 = copy (*_163); StorageLive(_171); _171 = copy _1; - _169 = Add(move _170, move _171); -+ _169 = copy _165; ++ _169 = Add(move _170, copy _1); StorageDead(_171); StorageDead(_170); -- _168 = opaque::(move _169) -> [return: bb44, unwind continue]; -+ _168 = opaque::(copy _165) -> [return: bb44, unwind continue]; + _168 = opaque::(move _169) -> [return: bb44, unwind continue]; } bb44: { diff --git a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff index 37b7b0d2c9db3..881b629803a34 100644 --- a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff @@ -17,16 +17,15 @@ StorageLive(_3); _5 = const f::promoted[0]; _3 = &(*_5); -- _2 = copy ((*_3).1: E); -+ _2 = copy ((*_5).1: E); - StorageLive(_1); -- _1 = copy ((_2 as A).1: u32); -+ _1 = const 0_u32; + _2 = copy ((*_3).1: E); +- StorageLive(_1); ++ nop; + _1 = copy ((_2 as A).1: u32); StorageDead(_3); StorageDead(_2); -- _0 = copy _1; -+ _0 = const 0_u32; - StorageDead(_1); + _0 = copy _1; +- StorageDead(_1); ++ nop; return; } } diff --git a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff index 37b7b0d2c9db3..881b629803a34 100644 --- a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff @@ -17,16 +17,15 @@ StorageLive(_3); _5 = const f::promoted[0]; _3 = &(*_5); -- _2 = copy ((*_3).1: E); -+ _2 = copy ((*_5).1: E); - StorageLive(_1); -- _1 = copy ((_2 as A).1: u32); -+ _1 = const 0_u32; + _2 = copy ((*_3).1: E); +- StorageLive(_1); ++ nop; + _1 = copy ((_2 as A).1: u32); StorageDead(_3); StorageDead(_2); -- _0 = copy _1; -+ _0 = const 0_u32; - StorageDead(_1); + _0 = copy _1; +- StorageDead(_1); ++ nop; return; } } diff --git a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff b/tests/mir-opt/inline/issue_78442.bar.PostAnalysisNormalize.panic-abort.diff similarity index 92% rename from tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff rename to tests/mir-opt/inline/issue_78442.bar.PostAnalysisNormalize.panic-abort.diff index b532b133a83a5..95c529254019e 100644 --- a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff +++ b/tests/mir-opt/inline/issue_78442.bar.PostAnalysisNormalize.panic-abort.diff @@ -1,5 +1,5 @@ -- // MIR for `bar` before RevealAll -+ // MIR for `bar` after RevealAll +- // MIR for `bar` before PostAnalysisNormalize ++ // MIR for `bar` after PostAnalysisNormalize fn bar(_1: P) -> () { debug _baz => _1; diff --git a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff b/tests/mir-opt/inline/issue_78442.bar.PostAnalysisNormalize.panic-unwind.diff similarity index 92% rename from tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff rename to tests/mir-opt/inline/issue_78442.bar.PostAnalysisNormalize.panic-unwind.diff index bcebcf297c2b1..1b710a78cb189 100644 --- a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff +++ b/tests/mir-opt/inline/issue_78442.bar.PostAnalysisNormalize.panic-unwind.diff @@ -1,5 +1,5 @@ -- // MIR for `bar` before RevealAll -+ // MIR for `bar` after RevealAll +- // MIR for `bar` before PostAnalysisNormalize ++ // MIR for `bar` after PostAnalysisNormalize fn bar(_1: P) -> () { debug _baz => _1; diff --git a/tests/mir-opt/inline/issue_78442.rs b/tests/mir-opt/inline/issue_78442.rs index 6dc875f9a407c..4eb5c142034c2 100644 --- a/tests/mir-opt/inline/issue_78442.rs +++ b/tests/mir-opt/inline/issue_78442.rs @@ -2,7 +2,7 @@ // EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] -// EMIT_MIR issue_78442.bar.RevealAll.diff +// EMIT_MIR issue_78442.bar.PostAnalysisNormalize.diff // EMIT_MIR issue_78442.bar.Inline.diff pub fn bar

( // Error won't happen if "bar" is not generic diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.rs b/tests/mir-opt/pre-codegen/deref_nested_borrows.rs new file mode 100644 index 0000000000000..4f70ec36bc925 --- /dev/null +++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.rs @@ -0,0 +1,25 @@ +//! Regression test for +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY + +fn src(x: &&u8) -> bool { + // CHECK-LABEL: fn src( + // CHECK-NOT: _0 = const true; + // CHECK: _0 = Eq({{.*}}, {{.*}}); + // CHECK-NOT: _0 = const true; + let y = **x; + unsafe { unknown() }; + **x == y +} + +#[inline(never)] +unsafe fn unknown() { + // CHECK-LABEL: fn unknown( +} + +fn main() { + // CHECK-LABEL: fn main( + src(&&0); +} + +// EMIT_MIR deref_nested_borrows.src.GVN.diff +// EMIT_MIR deref_nested_borrows.src.PreCodegen.after.mir diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff new file mode 100644 index 0000000000000..993857f225a81 --- /dev/null +++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff @@ -0,0 +1,42 @@ +- // MIR for `src` before GVN ++ // MIR for `src` after GVN + + fn src(_1: &&u8) -> bool { + debug x => _1; + let mut _0: bool; + let _2: u8; + let _3: (); + let mut _4: u8; + let mut _5: u8; + let mut _6: &u8; + let mut _7: &u8; + scope 1 { + debug y => _2; + } + + bb0: { +- StorageLive(_2); +- _6 = deref_copy (*_1); ++ nop; ++ _6 = copy (*_1); + _2 = copy (*_6); + _3 = unknown() -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageLive(_4); +- _7 = deref_copy (*_1); ++ _7 = copy (*_1); + _4 = copy (*_7); + StorageLive(_5); + _5 = copy _2; +- _0 = Eq(move _4, move _5); ++ _0 = Eq(move _4, copy _2); + StorageDead(_5); + StorageDead(_4); +- StorageDead(_2); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff new file mode 100644 index 0000000000000..d81bfa9310bc1 --- /dev/null +++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff @@ -0,0 +1,42 @@ +- // MIR for `src` before GVN ++ // MIR for `src` after GVN + + fn src(_1: &&u8) -> bool { + debug x => _1; + let mut _0: bool; + let _2: u8; + let _3: (); + let mut _4: u8; + let mut _5: u8; + let mut _6: &u8; + let mut _7: &u8; + scope 1 { + debug y => _2; + } + + bb0: { +- StorageLive(_2); +- _6 = deref_copy (*_1); ++ nop; ++ _6 = copy (*_1); + _2 = copy (*_6); + _3 = unknown() -> [return: bb1, unwind continue]; + } + + bb1: { + StorageLive(_4); +- _7 = deref_copy (*_1); ++ _7 = copy (*_1); + _4 = copy (*_7); + StorageLive(_5); + _5 = copy _2; +- _0 = Eq(move _4, move _5); ++ _0 = Eq(move _4, copy _2); + StorageDead(_5); + StorageDead(_4); +- StorageDead(_2); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..23b1c3f3f43ad --- /dev/null +++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-abort.mir @@ -0,0 +1,29 @@ +// MIR for `src` after PreCodegen + +fn src(_1: &&u8) -> bool { + debug x => _1; + let mut _0: bool; + let mut _2: &u8; + let _3: u8; + let _4: (); + let mut _5: &u8; + let mut _6: u8; + scope 1 { + debug y => _3; + } + + bb0: { + _2 = copy (*_1); + _3 = copy (*_2); + _4 = unknown() -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageLive(_6); + _5 = copy (*_1); + _6 = copy (*_5); + _0 = Eq(move _6, copy _3); + StorageDead(_6); + return; + } +} diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-unwind.mir new file mode 100644 index 0000000000000..4c01e9464bf49 --- /dev/null +++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-unwind.mir @@ -0,0 +1,29 @@ +// MIR for `src` after PreCodegen + +fn src(_1: &&u8) -> bool { + debug x => _1; + let mut _0: bool; + let mut _2: &u8; + let _3: u8; + let _4: (); + let mut _5: &u8; + let mut _6: u8; + scope 1 { + debug y => _3; + } + + bb0: { + _2 = copy (*_1); + _3 = copy (*_2); + _4 = unknown() -> [return: bb1, unwind continue]; + } + + bb1: { + StorageLive(_6); + _5 = copy (*_1); + _6 = copy (*_5); + _0 = Eq(move _6, copy _3); + StorageDead(_6); + return; + } +} diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir index cbdd194afd3ab..5a269717f8297 100644 --- a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir @@ -4,65 +4,70 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 let mut _0: bool; let mut _3: &(usize, usize, usize, usize); let _4: &usize; - let _5: &usize; + let mut _5: &(usize, usize, usize, usize); let _6: &usize; - let _7: &usize; - let mut _8: &&usize; - let _9: &usize; - let mut _10: &&usize; - let mut _13: bool; - let mut _14: &&usize; - let _15: &usize; - let mut _16: &&usize; - let mut _19: bool; - let mut _20: &&usize; - let _21: &usize; - let mut _22: &&usize; - let mut _23: bool; - let mut _24: &&usize; - let _25: &usize; - let mut _26: &&usize; + let mut _7: &(usize, usize, usize, usize); + let _8: &usize; + let mut _9: &(usize, usize, usize, usize); + let _10: &usize; + let mut _11: &&usize; + let _12: &usize; + let mut _13: &&usize; + let mut _16: bool; + let mut _17: &&usize; + let _18: &usize; + let mut _19: &&usize; + let mut _22: bool; + let mut _23: &&usize; + let _24: &usize; + let mut _25: &&usize; + let mut _28: bool; + let mut _29: &&usize; + let _30: &usize; + let mut _31: &&usize; scope 1 { debug a => _4; - debug b => _5; - debug c => _6; - debug d => _7; + debug b => _6; + debug c => _8; + debug d => _10; scope 2 (inlined std::cmp::impls::::le) { - debug self => _8; - debug other => _10; + debug self => _11; + debug other => _13; scope 3 (inlined std::cmp::impls::::le) { debug self => _4; - debug other => _6; - let mut _11: usize; - let mut _12: usize; + debug other => _8; + let mut _14: usize; + let mut _15: usize; } } scope 4 (inlined std::cmp::impls::::le) { - debug self => _14; - debug other => _16; + debug self => _17; + debug other => _19; scope 5 (inlined std::cmp::impls::::le) { - debug self => _7; - debug other => _5; - let mut _17: usize; - let mut _18: usize; + debug self => _10; + debug other => _6; + let mut _20: usize; + let mut _21: usize; } } scope 6 (inlined std::cmp::impls::::le) { - debug self => _20; - debug other => _22; + debug self => _23; + debug other => _25; scope 7 (inlined std::cmp::impls::::le) { - debug self => _6; + debug self => _8; debug other => _4; + let mut _26: usize; + let mut _27: usize; } } scope 8 (inlined std::cmp::impls::::le) { - debug self => _24; - debug other => _26; + debug self => _29; + debug other => _31; scope 9 (inlined std::cmp::impls::::le) { - debug self => _5; - debug other => _7; - let mut _27: usize; - let mut _28: usize; + debug self => _6; + debug other => _10; + let mut _32: usize; + let mut _33: usize; } } } @@ -70,116 +75,129 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 bb0: { _3 = copy (*_2); _4 = &((*_3).0: usize); - _5 = &((*_3).1: usize); - _6 = &((*_3).2: usize); - _7 = &((*_3).3: usize); + _5 = copy (*_2); + _6 = &((*_5).1: usize); + _7 = copy (*_2); + _8 = &((*_7).2: usize); + _9 = copy (*_2); + _10 = &((*_9).3: usize); + StorageLive(_16); + StorageLive(_11); + _11 = &_4; StorageLive(_13); - StorageLive(_8); - _8 = &_4; - StorageLive(_10); - StorageLive(_9); - _9 = copy _6; - _10 = &_9; - _11 = copy ((*_3).0: usize); - _12 = copy ((*_3).2: usize); - _13 = Le(copy _11, copy _12); - switchInt(move _13) -> [0: bb1, otherwise: bb2]; + StorageLive(_12); + _12 = copy _8; + _13 = &_12; + StorageLive(_14); + _14 = copy ((*_3).0: usize); + StorageLive(_15); + _15 = copy ((*_7).2: usize); + _16 = Le(move _14, move _15); + StorageDead(_15); + StorageDead(_14); + switchInt(move _16) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageDead(_9); - StorageDead(_10); - StorageDead(_8); + StorageDead(_12); + StorageDead(_13); + StorageDead(_11); goto -> bb4; } bb2: { - StorageDead(_9); - StorageDead(_10); - StorageDead(_8); - StorageLive(_19); - StorageLive(_14); - _14 = &_7; - StorageLive(_16); - StorageLive(_15); - _15 = copy _5; - _16 = &_15; + StorageDead(_12); + StorageDead(_13); + StorageDead(_11); + StorageLive(_22); StorageLive(_17); - _17 = copy ((*_3).3: usize); + _17 = &_10; + StorageLive(_19); StorageLive(_18); - _18 = copy ((*_3).1: usize); - _19 = Le(move _17, move _18); - StorageDead(_18); - StorageDead(_17); - switchInt(move _19) -> [0: bb3, otherwise: bb8]; + _18 = copy _6; + _19 = &_18; + StorageLive(_20); + _20 = copy ((*_9).3: usize); + StorageLive(_21); + _21 = copy ((*_5).1: usize); + _22 = Le(move _20, move _21); + StorageDead(_21); + StorageDead(_20); + switchInt(move _22) -> [0: bb3, otherwise: bb8]; } bb3: { - StorageDead(_15); - StorageDead(_16); - StorageDead(_14); + StorageDead(_18); + StorageDead(_19); + StorageDead(_17); goto -> bb4; } bb4: { + StorageLive(_28); StorageLive(_23); - StorageLive(_20); - _20 = &_6; - StorageLive(_22); - StorageLive(_21); - _21 = copy _4; - _22 = &_21; - _23 = Le(copy _12, copy _11); - switchInt(move _23) -> [0: bb5, otherwise: bb6]; + _23 = &_8; + StorageLive(_25); + StorageLive(_24); + _24 = copy _4; + _25 = &_24; + StorageLive(_26); + _26 = copy ((*_7).2: usize); + StorageLive(_27); + _27 = copy ((*_3).0: usize); + _28 = Le(move _26, move _27); + StorageDead(_27); + StorageDead(_26); + switchInt(move _28) -> [0: bb5, otherwise: bb6]; } bb5: { - StorageDead(_21); - StorageDead(_22); - StorageDead(_20); + StorageDead(_24); + StorageDead(_25); + StorageDead(_23); _0 = const false; goto -> bb7; } bb6: { - StorageDead(_21); - StorageDead(_22); - StorageDead(_20); - StorageLive(_24); - _24 = &_5; - StorageLive(_26); - StorageLive(_25); - _25 = copy _7; - _26 = &_25; - StorageLive(_27); - _27 = copy ((*_3).1: usize); - StorageLive(_28); - _28 = copy ((*_3).3: usize); - _0 = Le(move _27, move _28); - StorageDead(_28); - StorageDead(_27); - StorageDead(_25); - StorageDead(_26); StorageDead(_24); + StorageDead(_25); + StorageDead(_23); + StorageLive(_29); + _29 = &_6; + StorageLive(_31); + StorageLive(_30); + _30 = copy _10; + _31 = &_30; + StorageLive(_32); + _32 = copy ((*_5).1: usize); + StorageLive(_33); + _33 = copy ((*_9).3: usize); + _0 = Le(move _32, move _33); + StorageDead(_33); + StorageDead(_32); + StorageDead(_30); + StorageDead(_31); + StorageDead(_29); goto -> bb7; } bb7: { - StorageDead(_23); + StorageDead(_28); goto -> bb9; } bb8: { - StorageDead(_15); - StorageDead(_16); - StorageDead(_14); + StorageDead(_18); + StorageDead(_19); + StorageDead(_17); _0 = const true; goto -> bb9; } bb9: { - StorageDead(_19); - StorageDead(_13); + StorageDead(_22); + StorageDead(_16); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir index bc7a31d52199b..f93f7264dec20 100644 --- a/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir @@ -4,40 +4,46 @@ fn variant_b::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:11:25: 11:41}, let mut _0: bool; let mut _3: &(usize, usize, usize, usize); let _4: usize; - let _5: usize; + let mut _5: &(usize, usize, usize, usize); let _6: usize; - let _7: usize; - let mut _8: bool; - let mut _9: bool; - let mut _10: bool; + let mut _7: &(usize, usize, usize, usize); + let _8: usize; + let mut _9: &(usize, usize, usize, usize); + let _10: usize; + let mut _11: bool; + let mut _12: bool; + let mut _13: bool; scope 1 { debug a => _4; - debug b => _5; - debug c => _6; - debug d => _7; + debug b => _6; + debug c => _8; + debug d => _10; } bb0: { _3 = copy (*_2); _4 = copy ((*_3).0: usize); - _5 = copy ((*_3).1: usize); - _6 = copy ((*_3).2: usize); - _7 = copy ((*_3).3: usize); - StorageLive(_8); - _8 = Le(copy _4, copy _6); - switchInt(move _8) -> [0: bb2, otherwise: bb1]; + _5 = copy (*_2); + _6 = copy ((*_5).1: usize); + _7 = copy (*_2); + _8 = copy ((*_7).2: usize); + _9 = copy (*_2); + _10 = copy ((*_9).3: usize); + StorageLive(_11); + _11 = Le(copy _4, copy _8); + switchInt(move _11) -> [0: bb2, otherwise: bb1]; } bb1: { - StorageLive(_9); - _9 = Le(copy _7, copy _5); - switchInt(move _9) -> [0: bb2, otherwise: bb6]; + StorageLive(_12); + _12 = Le(copy _10, copy _6); + switchInt(move _12) -> [0: bb2, otherwise: bb6]; } bb2: { - StorageLive(_10); - _10 = Le(copy _6, copy _4); - switchInt(move _10) -> [0: bb3, otherwise: bb4]; + StorageLive(_13); + _13 = Le(copy _8, copy _4); + switchInt(move _13) -> [0: bb3, otherwise: bb4]; } bb3: { @@ -46,12 +52,12 @@ fn variant_b::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:11:25: 11:41}, } bb4: { - _0 = Le(copy _5, copy _7); + _0 = Le(copy _6, copy _10); goto -> bb5; } bb5: { - StorageDead(_10); + StorageDead(_13); goto -> bb7; } @@ -61,8 +67,8 @@ fn variant_b::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:11:25: 11:41}, } bb7: { - StorageDead(_9); - StorageDead(_8); + StorageDead(_12); + StorageDead(_11); return; } } diff --git a/tests/pretty/attr-derive.rs b/tests/pretty/attr-derive.rs index 79b6ea5144635..afb86b293156c 100644 --- a/tests/pretty/attr-derive.rs +++ b/tests/pretty/attr-derive.rs @@ -1,4 +1,4 @@ -//@ aux-build:derive-foo.rs +//@ proc-macro: derive-foo.rs //@ pp-exact // Testing that both the inner item and next outer item are // preserved, and that the first outer item parsed in main is not diff --git a/tests/pretty/auxiliary/derive-foo.rs b/tests/pretty/auxiliary/derive-foo.rs index dc682beafadef..1602750828116 100644 --- a/tests/pretty/auxiliary/derive-foo.rs +++ b/tests/pretty/auxiliary/derive-foo.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/run-make/avr-rjmp-offset/rmake.rs b/tests/run-make/avr-rjmp-offset/rmake.rs index 89cbca309be09..de64b724eed2d 100644 --- a/tests/run-make/avr-rjmp-offset/rmake.rs +++ b/tests/run-make/avr-rjmp-offset/rmake.rs @@ -10,6 +10,11 @@ //! wrong output is only produced with direct assembly generation, but not when //! "emit-asm" is used, as described in the issue description of #129301: //! https://github.com/rust-lang/rust/issues/129301#issue-2475070770 + +// FIXME(#133480): this has been randomly failing on `x86_64-mingw` due to linker hangs or +// crashes... so I'm going to disable this test for windows for now. +//@ ignore-windows-gnu + use run_make_support::{llvm_objdump, rustc}; fn main() { diff --git a/tests/run-make/crate-loading-crate-depends-on-itself/foo-current.rs b/tests/run-make/crate-loading-crate-depends-on-itself/foo-current.rs new file mode 100644 index 0000000000000..71b27cd85bfed --- /dev/null +++ b/tests/run-make/crate-loading-crate-depends-on-itself/foo-current.rs @@ -0,0 +1,14 @@ +#![crate_type = "lib"] +#![crate_name = "foo"] + +extern crate foo; + +pub struct Struct; +pub trait Trait {} +impl Trait for Struct {} + +fn check_trait() {} + +fn ice() { + check_trait::(); +} diff --git a/tests/run-make/crate-loading-crate-depends-on-itself/foo-prev.rs b/tests/run-make/crate-loading-crate-depends-on-itself/foo-prev.rs new file mode 100644 index 0000000000000..19d3f3c972b09 --- /dev/null +++ b/tests/run-make/crate-loading-crate-depends-on-itself/foo-prev.rs @@ -0,0 +1,6 @@ +#![crate_type = "lib"] +#![crate_name = "foo"] + +pub struct Struct; +pub trait Trait {} +impl Trait for Struct {} diff --git a/tests/run-make/crate-loading-crate-depends-on-itself/foo.stderr b/tests/run-make/crate-loading-crate-depends-on-itself/foo.stderr new file mode 100644 index 0000000000000..36379429530bc --- /dev/null +++ b/tests/run-make/crate-loading-crate-depends-on-itself/foo.stderr @@ -0,0 +1,34 @@ +error[E0277]: the trait bound `foo::Struct: Trait` is not satisfied + --> foo-current.rs:13:19 + | +13 | check_trait::(); + | ^^^^^^^^^^^ the trait `Trait` is not implemented for `foo::Struct` + | +note: there are multiple different versions of crate `foo` in the dependency graph + --> foo-current.rs:7:1 + | +4 | extern crate foo; + | ----------------- one version of crate `foo` is used here, as a direct dependency of the current crate +5 | +6 | pub struct Struct; + | ----------------- this type implements the required trait +7 | pub trait Trait {} + | ^^^^^^^^^^^^^^^ this is the required trait + | + ::: foo-prev.rs:X:Y + | +4 | pub struct Struct; + | ----------------- this type doesn't implement the required trait +5 | pub trait Trait {} + | --------------- this is the found trait + = note: two types coming from two different versions of the same crate are different types even if they look the same + = help: you can use `cargo tree` to explore your dependency tree +note: required by a bound in `check_trait` + --> foo-current.rs:10:19 + | +10 | fn check_trait() {} + | ^^^^^ required by this bound in `check_trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. \ No newline at end of file diff --git a/tests/run-make/crate-loading-crate-depends-on-itself/rmake.rs b/tests/run-make/crate-loading-crate-depends-on-itself/rmake.rs new file mode 100644 index 0000000000000..57e0cab92f1ef --- /dev/null +++ b/tests/run-make/crate-loading-crate-depends-on-itself/rmake.rs @@ -0,0 +1,31 @@ +//@ only-linux +//@ ignore-wasm32 +//@ ignore-wasm64 +// ignore-tidy-linelength + +// Verify that if the current crate depends on a different version of the same crate, *and* types +// and traits of the different versions are mixed, we produce diagnostic output and not an ICE. +// #133563 + +use run_make_support::{diff, rust_lib_name, rustc}; + +fn main() { + rustc().input("foo-prev.rs").run(); + + let out = rustc() + .extra_filename("current") + .metadata("current") + .input("foo-current.rs") + .extern_("foo", rust_lib_name("foo")) + .run_fail() + .stderr_utf8(); + + // We don't remap the path of the `foo-prev` crate, so we remap it here. + let mut lines: Vec<_> = out.lines().collect(); + for line in &mut lines { + if line.starts_with(" ::: ") { + *line = " ::: foo-prev.rs:X:Y"; + } + } + diff().expected_file("foo.stderr").actual_text("(rustc)", &lines.join("\n")).run(); +} diff --git a/tests/run-make/crate-loading/multiple-dep-versions.stderr b/tests/run-make/crate-loading/multiple-dep-versions.stderr new file mode 100644 index 0000000000000..5888aad8f37bc --- /dev/null +++ b/tests/run-make/crate-loading/multiple-dep-versions.stderr @@ -0,0 +1,127 @@ +error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied + --> replaced + | +LL | do_something(Type); + | ------------ ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type` + | | + | required by a bound introduced by this call + | +note: there are multiple different versions of crate `dependency` in the dependency graph + --> replaced + | +LL | pub struct Type(pub i32); + | --------------- this type implements the required trait +LL | pub trait Trait { + | ^^^^^^^^^^^^^^^ this is the required trait + | + ::: replaced + | +LL | extern crate dep_2_reexport; + | ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo` +LL | extern crate dependency; + | ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate + | + ::: replaced + | +LL | pub struct Type; + | --------------- this type doesn't implement the required trait +LL | pub trait Trait { + | --------------- this is the found trait + = note: two types coming from two different versions of the same crate are different types even if they look the same + = help: you can use `cargo tree` to explore your dependency tree +note: required by a bound in `do_something` + --> replaced + | +LL | pub fn do_something(_: X) {} + | ^^^^^ required by this bound in `do_something` + +error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope + --> replaced + | +LL | Type.foo(); + | ^^^ method not found in `Type` + | +note: there are multiple different versions of crate `dependency` in the dependency graph + --> replaced + | +LL | pub trait Trait { + | ^^^^^^^^^^^^^^^ this is the trait that is needed +LL | fn foo(&self); + | -------------- the method is available for `dep_2_reexport::Type` here + | + ::: replaced + | +LL | use dependency::{Trait, do_something}; + | ----- `Trait` imported here doesn't correspond to the right version of crate `dependency` + | + ::: replaced + | +LL | pub trait Trait { + | --------------- this is the trait that was imported + +error[E0599]: no function or associated item named `bar` found for struct `dep_2_reexport::Type` in the current scope + --> replaced + | +LL | Type::bar(); + | ^^^ function or associated item not found in `Type` + | +note: there are multiple different versions of crate `dependency` in the dependency graph + --> replaced + | +LL | pub trait Trait { + | ^^^^^^^^^^^^^^^ this is the trait that is needed +LL | fn foo(&self); +LL | fn bar(); + | --------- the associated function is available for `dep_2_reexport::Type` here + | + ::: replaced + | +LL | use dependency::{Trait, do_something}; + | ----- `Trait` imported here doesn't correspond to the right version of crate `dependency` + | + ::: replaced + | +LL | pub trait Trait { + | --------------- this is the trait that was imported + +error[E0277]: the trait bound `OtherType: Trait` is not satisfied + --> replaced + | +LL | do_something(OtherType); + | ------------ ^^^^^^^^^ the trait `Trait` is not implemented for `OtherType` + | | + | required by a bound introduced by this call + | +note: there are multiple different versions of crate `dependency` in the dependency graph + --> replaced + | +LL | pub trait Trait { + | ^^^^^^^^^^^^^^^ this is the required trait + | + ::: replaced + | +LL | extern crate dep_2_reexport; + | ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo` +LL | extern crate dependency; + | ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate + | + ::: replaced + | +LL | pub struct OtherType; + | -------------------- this type doesn't implement the required trait + | + ::: replaced + | +LL | pub trait Trait { + | --------------- this is the found trait + = help: you can use `cargo tree` to explore your dependency tree +note: required by a bound in `do_something` + --> replaced + | +LL | pub fn do_something(_: X) {} + | ^^^^^ required by this bound in `do_something` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0599. +For more information about an error, try `rustc --explain E0277`. \ No newline at end of file diff --git a/tests/run-make/crate-loading/rmake.rs b/tests/run-make/crate-loading/rmake.rs index 2d5913c4bcb09..6ad456e3e3e57 100644 --- a/tests/run-make/crate-loading/rmake.rs +++ b/tests/run-make/crate-loading/rmake.rs @@ -3,7 +3,7 @@ //@ ignore-wasm64 // ignore-tidy-linelength -use run_make_support::{rust_lib_name, rustc}; +use run_make_support::{diff, rust_lib_name, rustc}; fn main() { rustc().input("multiple-dep-versions-1.rs").run(); @@ -13,77 +13,26 @@ fn main() { .extern_("dependency", rust_lib_name("dependency2")) .run(); - rustc() + let out = rustc() .input("multiple-dep-versions.rs") .extern_("dependency", rust_lib_name("dependency")) .extern_("dep_2_reexport", rust_lib_name("foo")) + .ui_testing() .run_fail() - .assert_stderr_contains(r#"error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied because the trait comes from a different crate version - --> multiple-dep-versions.rs:7:18 - | -7 | do_something(Type); - | ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type` - | -note: there are multiple different versions of crate `dependency` in the dependency graph"#) - .assert_stderr_contains(r#" -3 | pub struct Type(pub i32); - | --------------- this type implements the required trait -4 | pub trait Trait { - | ^^^^^^^^^^^^^^^ this is the required trait -"#) - .assert_stderr_contains(r#" -1 | extern crate dep_2_reexport; - | ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo` -2 | extern crate dependency; - | ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate"#) - .assert_stderr_contains(r#" -3 | pub struct Type; - | --------------- this type doesn't implement the required trait -4 | pub trait Trait { - | --------------- this is the found trait - = note: two types coming from two different versions of the same crate are different types even if they look the same - = help: you can use `cargo tree` to explore your dependency tree"#) - .assert_stderr_contains(r#"error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope - --> multiple-dep-versions.rs:8:10 - | -8 | Type.foo(); - | ^^^ method not found in `Type` - | -note: there are multiple different versions of crate `dependency` in the dependency graph"#) - .assert_stderr_contains(r#" -4 | pub trait Trait { - | ^^^^^^^^^^^^^^^ this is the trait that is needed -5 | fn foo(&self); - | -------------- the method is available for `dep_2_reexport::Type` here - | - ::: multiple-dep-versions.rs:4:18 - | -4 | use dependency::{Trait, do_something}; - | ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#) - .assert_stderr_contains(r#" -4 | pub trait Trait { - | --------------- this is the trait that was imported"#) - .assert_stderr_contains(r#" -error[E0599]: no function or associated item named `bar` found for struct `dep_2_reexport::Type` in the current scope - --> multiple-dep-versions.rs:9:11 - | -9 | Type::bar(); - | ^^^ function or associated item not found in `Type` - | -note: there are multiple different versions of crate `dependency` in the dependency graph"#) - .assert_stderr_contains(r#" -4 | pub trait Trait { - | ^^^^^^^^^^^^^^^ this is the trait that is needed -5 | fn foo(&self); -6 | fn bar(); - | --------- the associated function is available for `dep_2_reexport::Type` here - | - ::: multiple-dep-versions.rs:4:18 - | -4 | use dependency::{Trait, do_something}; - | ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#) - .assert_stderr_contains( - r#" -6 | pub struct OtherType; - | -------------------- this type doesn't implement the required trait"#); + .stderr_utf8(); + + // We don't remap all the paths, so we remap it here. + let mut lines: Vec<_> = out.lines().collect(); + for line in &mut lines { + if line.starts_with(" --> ") { + *line = " --> replaced"; + } + if line.starts_with(" ::: ") { + *line = " ::: replaced"; + } + } + diff() + .expected_file("multiple-dep-versions.stderr") + .actual_text("(rustc)", &lines.join("\n")) + .run(); } diff --git a/tests/run-make/diagnostics-traits-from-duplicate-crates/minibevy.rs b/tests/run-make/diagnostics-traits-from-duplicate-crates/minibevy.rs new file mode 100644 index 0000000000000..1bc8473e08e32 --- /dev/null +++ b/tests/run-make/diagnostics-traits-from-duplicate-crates/minibevy.rs @@ -0,0 +1,2 @@ +pub trait Resource {} +pub struct Ray2d; diff --git a/tests/run-make/diagnostics-traits-from-duplicate-crates/minirapier.rs b/tests/run-make/diagnostics-traits-from-duplicate-crates/minirapier.rs new file mode 100644 index 0000000000000..2b84332aa517c --- /dev/null +++ b/tests/run-make/diagnostics-traits-from-duplicate-crates/minirapier.rs @@ -0,0 +1 @@ +pub type Ray = minibevy::Ray2d; diff --git a/tests/run-make/diagnostics-traits-from-duplicate-crates/repro.rs b/tests/run-make/diagnostics-traits-from-duplicate-crates/repro.rs new file mode 100644 index 0000000000000..90a6dfc2e15f8 --- /dev/null +++ b/tests/run-make/diagnostics-traits-from-duplicate-crates/repro.rs @@ -0,0 +1,14 @@ +extern crate minibevy; +extern crate minirapier; + +use minibevy::Resource; +use minirapier::Ray; + +fn insert_resource(_resource: R) {} + +struct Res; +impl Resource for Res {} + +fn main() { + insert_resource(Res.into()); +} diff --git a/tests/run-make/diagnostics-traits-from-duplicate-crates/rmake.rs b/tests/run-make/diagnostics-traits-from-duplicate-crates/rmake.rs new file mode 100644 index 0000000000000..32c4cf3389647 --- /dev/null +++ b/tests/run-make/diagnostics-traits-from-duplicate-crates/rmake.rs @@ -0,0 +1,45 @@ +// Non-regression test for issue #132920 where multiple versions of the same crate are present in +// the dependency graph, and an unexpected error in a dependent crate caused an ICE in the +// unsatisfied bounds diagnostics for traits present in multiple crate versions. +// +// Setup: +// - two versions of the same crate: minibevy_a and minibevy_b +// - minirapier: depends on minibevy_a +// - repro: depends on minirapier and minibevy_b + +use run_make_support::rustc; + +fn main() { + // Prepare dependencies, mimicking a check build with cargo. + rustc() + .input("minibevy.rs") + .crate_name("minibevy") + .crate_type("lib") + .emit("metadata") + .metadata("a") + .extra_filename("-a") + .run(); + rustc() + .input("minibevy.rs") + .crate_name("minibevy") + .crate_type("lib") + .emit("metadata") + .metadata("b") + .extra_filename("-b") + .run(); + rustc() + .input("minirapier.rs") + .crate_name("minirapier") + .crate_type("lib") + .emit("metadata") + .extern_("minibevy", "libminibevy-a.rmeta") + .run(); + + // Building the main crate used to ICE here when printing the `type annotations needed` error. + rustc() + .input("repro.rs") + .extern_("minibevy", "libminibevy-b.rmeta") + .extern_("minirapier", "libminirapier.rmeta") + .run_fail() + .assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug"); +} diff --git a/tests/run-make/libstd-no-protected/rmake.rs b/tests/run-make/libstd-no-protected/rmake.rs new file mode 100644 index 0000000000000..3bba59a8f4d55 --- /dev/null +++ b/tests/run-make/libstd-no-protected/rmake.rs @@ -0,0 +1,63 @@ +// If libstd was compiled to use protected symbols, then linking would fail if GNU ld < 2.40 were +// used. This might not be noticed, since usually we use LLD for linking, so we could end up +// distributing a version of libstd that would cause link errors for such users. + +//@ only-x86_64-unknown-linux-gnu + +use run_make_support::object::Endianness; +use run_make_support::object::read::archive::ArchiveFile; +use run_make_support::object::read::elf::{FileHeader as _, SectionHeader as _}; +use run_make_support::rfs::{read, read_dir}; +use run_make_support::{has_prefix, has_suffix, object, path, rustc, shallow_find_files, target}; + +type FileHeader = run_make_support::object::elf::FileHeader64; +type SymbolTable<'data> = run_make_support::object::read::elf::SymbolTable<'data, FileHeader>; + +fn main() { + // Find libstd-...rlib + let sysroot = rustc().print("sysroot").run().stdout_utf8(); + let sysroot = sysroot.trim(); + let target_sysroot = path(sysroot).join("lib/rustlib").join(target()).join("lib"); + let mut libs = shallow_find_files(&target_sysroot, |path| { + has_prefix(path, "libstd-") && has_suffix(path, ".rlib") + }); + assert_eq!(libs.len(), 1); + let libstd_path = libs.pop().unwrap(); + let archive_data = read(libstd_path); + + // Parse all the object files within the libstd archive, checking defined symbols. + let mut num_protected = 0; + let mut num_symbols = 0; + + let archive = ArchiveFile::parse(&*archive_data).unwrap(); + for member in archive.members() { + let member = member.unwrap(); + if member.name() == b"lib.rmeta" { + continue; + } + let data = member.data(&*archive_data).unwrap(); + + let header = FileHeader::parse(data).unwrap(); + let endian = header.endian().unwrap(); + let sections = header.sections(endian, data).unwrap(); + + for (section_index, section) in sections.enumerate() { + if section.sh_type(endian) == object::elf::SHT_SYMTAB { + let symbols = + SymbolTable::parse(endian, data, §ions, section_index, section).unwrap(); + for symbol in symbols.symbols() { + if symbol.st_visibility() == object::elf::STV_PROTECTED { + num_protected += 1; + } + num_symbols += 1; + } + } + } + } + + // If there were no symbols at all, then something is wrong with the test. + assert_ne!(num_symbols, 0); + + // The purpose of this test - check that no symbols have protected visibility. + assert_eq!(num_protected, 0); +} diff --git a/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs b/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs index 8dd19e613bff8..f98a2036544c3 100644 --- a/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs +++ b/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs @@ -1,4 +1,4 @@ -#![feature(naked_functions, asm_const, linkage)] +#![feature(naked_functions, linkage)] #![crate_type = "dylib"] use std::arch::naked_asm; @@ -38,7 +38,7 @@ pub extern "C" fn public_vanilla() -> u32 { #[naked] #[no_mangle] -pub extern "C" fn public_naked() -> u32 { +pub extern "C" fn public_naked_nongeneric() -> u32 { unsafe { naked_asm!("mov rax, 42", "ret") } } diff --git a/tests/run-make/naked-symbol-visibility/rmake.rs b/tests/run-make/naked-symbol-visibility/rmake.rs index d026196f43baa..c69a9ef9eeb01 100644 --- a/tests/run-make/naked-symbol-visibility/rmake.rs +++ b/tests/run-make/naked-symbol-visibility/rmake.rs @@ -17,10 +17,12 @@ fn main() { not_exported(&rdylib, "private_naked"); global_function(&rdylib, "public_vanilla"); - global_function(&rdylib, "public_naked"); + global_function(&rdylib, "public_naked_nongeneric"); not_exported(&rdylib, "public_vanilla_generic"); - not_exported(&rdylib, "public_naked_generic"); + // #[naked] functions are implicitly #[inline(never)], so they get shared regardless of + // -Zshare-generics. + global_function(&rdylib, "public_naked_generic"); global_function(&rdylib, "vanilla_external_linkage"); global_function(&rdylib, "naked_external_linkage"); diff --git a/tests/run-make/rustc-help/help-v.stdout b/tests/run-make/rustc-help/help-v.stdout index dbd67b57df2f0..8f6fde69c29b1 100644 --- a/tests/run-make/rustc-help/help-v.stdout +++ b/tests/run-make/rustc-help/help-v.stdout @@ -25,7 +25,7 @@ Options: --edition 2015|2018|2021|2024 Specify which edition of the compiler to use when compiling code. The default is 2015 and the latest - stable edition is 2021. + stable edition is 2024. --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir] Comma separated list of types of output for the compiler to emit diff --git a/tests/run-make/rustc-help/help.stdout b/tests/run-make/rustc-help/help.stdout index a7d07162799b0..131efa93282fd 100644 --- a/tests/run-make/rustc-help/help.stdout +++ b/tests/run-make/rustc-help/help.stdout @@ -25,7 +25,7 @@ Options: --edition 2015|2018|2021|2024 Specify which edition of the compiler to use when compiling code. The default is 2015 and the latest - stable edition is 2021. + stable edition is 2024. --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir] Comma separated list of types of output for the compiler to emit diff --git a/tests/rustdoc-gui/deref-block.goml b/tests/rustdoc-gui/deref-block.goml index 24f612f8a6fd1..97930b61ef4a5 100644 --- a/tests/rustdoc-gui/deref-block.goml +++ b/tests/rustdoc-gui/deref-block.goml @@ -20,8 +20,12 @@ assert-css: (".big-toggle summary::before", { "left": "-11px", "top": "9px", }) -// It should have the same X position as the other toggles. -compare-elements-position: (".big-toggle summary::before", ".method-toggle summary::before", ["x"]) +// It should have a slightly different X position as the other toggles. +store-position: (".big-toggle summary::before", {"x": big_toggle}) +store-position: (".method-toggle summary::before", {"x": small_toggle}) +assert: |big_toggle| < |small_toggle| +// Margin is 0.5em so around 8 px. +assert: |small_toggle| - |big_toggle| < 10 // But still shouldn't have the same Y position. compare-elements-position-false: ( ".big-toggle summary::before", diff --git a/tests/rustdoc-gui/docblock-table-overflow.goml b/tests/rustdoc-gui/docblock-table-overflow.goml index 1ca919d1eabc3..abfa820ef2708 100644 --- a/tests/rustdoc-gui/docblock-table-overflow.goml +++ b/tests/rustdoc-gui/docblock-table-overflow.goml @@ -16,6 +16,6 @@ compare-elements-property: ( "#implementations-list > details .docblock > p", ["scrollWidth"], ) -assert-property: ("#implementations-list > details .docblock", {"scrollWidth": "816"}) +assert-property: ("#implementations-list > details .docblock", {"scrollWidth": "835"}) // However, since there is overflow in the , its scroll width is bigger. assert-property: ("#implementations-list > details .docblock table", {"scrollWidth": "1572"}) diff --git a/tests/rustdoc-gui/item-info-alignment.goml b/tests/rustdoc-gui/item-info-alignment.goml index cd0624056b9a1..075722bb539c5 100644 --- a/tests/rustdoc-gui/item-info-alignment.goml +++ b/tests/rustdoc-gui/item-info-alignment.goml @@ -4,7 +4,9 @@ go-to: "file://" + |DOC_PATH| + "/lib2/struct.ItemInfoAlignmentTest.html" // First, we try it in "desktop" mode. set-window-size: (1200, 870) +wait-for-size: ("body", {"width": 1200}) compare-elements-position: (".impl-items > .item-info", "summary > .item-info", ["x"]) // Next, we try it in "mobile" mode (max-width: 700px). set-window-size: (650, 650) +wait-for-size: ("body", {"width": 650}) compare-elements-position: (".impl-items > .item-info", "summary > .item-info", ["x"]) diff --git a/tests/rustdoc-gui/item-info.goml b/tests/rustdoc-gui/item-info.goml index 1636e1496923f..b5b0052fe6139 100644 --- a/tests/rustdoc-gui/item-info.goml +++ b/tests/rustdoc-gui/item-info.goml @@ -19,7 +19,7 @@ store-position: ( "//*[@class='stab portability']//code[normalize-space()='Win32_System_Diagnostics']", {"x": second_line_x, "y": second_line_y}, ) -assert: |first_line_x| != |second_line_x| && |first_line_x| == 516 && |second_line_x| == 272 +assert: |first_line_x| != |second_line_x| && |first_line_x| == 521 && |second_line_x| == 277 assert: |first_line_y| != |second_line_y| && |first_line_y| == 718 && |second_line_y| == 741 // Now we ensure that they're not rendered on the same line. diff --git a/tests/rustdoc-gui/methods-left-margin.goml b/tests/rustdoc-gui/methods-left-margin.goml index 1003cec33f952..31b53faf75604 100644 --- a/tests/rustdoc-gui/methods-left-margin.goml +++ b/tests/rustdoc-gui/methods-left-margin.goml @@ -1,7 +1,6 @@ // This test is to ensure that methods are correctly aligned on the left side. go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" - // First we ensure that we have methods with and without documentation. assert: ".impl-items > details.method-toggle > summary > section.method" assert: ".impl-items > section.method" diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml index e02974e60829a..4624fb80b3779 100644 --- a/tests/rustdoc-gui/notable-trait.goml +++ b/tests/rustdoc-gui/notable-trait.goml @@ -62,9 +62,9 @@ define-function: ( // We start with a wide screen. set-window-size: (1100, 600) call-function: ("check-notable-tooltip-position-complete", { - "x": 677, - "i_x": 955, - "popover_x": 463, + "x": 682, + "i_x": 960, + "popover_x": 468, }) // Now only the `i` should be on the next line. @@ -78,16 +78,16 @@ compare-elements-position-false: ( // Now both the `i` and the struct name should be on the next line. set-window-size: (980, 600) call-function: ("check-notable-tooltip-position", { - "x": 245, - "i_x": 523, + "x": 250, + "i_x": 528, }) // Checking on mobile now. set-window-size: (650, 600) wait-for-size: ("body", {"width": 650}) call-function: ("check-notable-tooltip-position-complete", { - "x": 25, - "i_x": 303, + "x": 26, + "i_x": 305, "popover_x": 0, }) diff --git a/tests/rustdoc-gui/toggle-docs-mobile.goml b/tests/rustdoc-gui/toggle-docs-mobile.goml index b69aa6e30ca0b..be12e4c19b3bd 100644 --- a/tests/rustdoc-gui/toggle-docs-mobile.goml +++ b/tests/rustdoc-gui/toggle-docs-mobile.goml @@ -18,7 +18,7 @@ assert-position: ("#implementations-list > details > summary::before", {"x": 4}) // Assert the position of the toggle on a method. assert-position: ( "#trait-implementations-list .impl-items .method-toggle > summary::before", - {"x": 4}, + {"x": 6}, ) // Now we do the same but with a little bigger width diff --git a/tests/rustdoc-ui/2024-doctests-checks.rs b/tests/rustdoc-ui/2024-doctests-checks.rs index 464cf5b200df0..f3e4e10f57149 100644 --- a/tests/rustdoc-ui/2024-doctests-checks.rs +++ b/tests/rustdoc-ui/2024-doctests-checks.rs @@ -1,5 +1,6 @@ //@ check-pass -//@ compile-flags: --test --test-args=--test-threads=1 -Zunstable-options --edition 2024 +//@ edition: 2024 +//@ compile-flags: --test --test-args=--test-threads=1 //@ normalize-stdout-test: "tests/rustdoc-ui" -> "$$DIR" //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" diff --git a/tests/rustdoc-ui/2024-doctests-checks.stdout b/tests/rustdoc-ui/2024-doctests-checks.stdout index d1064084a8564..534fe466fe701 100644 --- a/tests/rustdoc-ui/2024-doctests-checks.stdout +++ b/tests/rustdoc-ui/2024-doctests-checks.stdout @@ -1,12 +1,12 @@ running 1 test -test $DIR/2024-doctests-checks.rs - Foo (line 7) ... ok +test $DIR/2024-doctests-checks.rs - Foo (line 8) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME running 1 test -test $DIR/2024-doctests-checks.rs - Foo (line 14) ... ok +test $DIR/2024-doctests-checks.rs - Foo (line 15) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/tests/rustdoc-ui/2024-doctests-crate-attribute.rs b/tests/rustdoc-ui/2024-doctests-crate-attribute.rs index 4984fdfe1949a..a353fc7cc445b 100644 --- a/tests/rustdoc-ui/2024-doctests-crate-attribute.rs +++ b/tests/rustdoc-ui/2024-doctests-crate-attribute.rs @@ -1,5 +1,6 @@ //@ check-pass -//@ compile-flags: --test --test-args=--test-threads=1 -Zunstable-options --edition 2024 +//@ edition: 2024 +//@ compile-flags: --test --test-args=--test-threads=1 //@ normalize-stdout-test: "tests/rustdoc-ui" -> "$$DIR" //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" diff --git a/tests/rustdoc-ui/2024-doctests-crate-attribute.stdout b/tests/rustdoc-ui/2024-doctests-crate-attribute.stdout index 29702ce8929bd..c084ac4522e8a 100644 --- a/tests/rustdoc-ui/2024-doctests-crate-attribute.stdout +++ b/tests/rustdoc-ui/2024-doctests-crate-attribute.stdout @@ -1,12 +1,12 @@ running 1 test -test $DIR/2024-doctests-crate-attribute.rs - Foo (line 19) ... ok +test $DIR/2024-doctests-crate-attribute.rs - Foo (line 20) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME running 1 test -test $DIR/2024-doctests-crate-attribute.rs - Foo (line 10) ... ok +test $DIR/2024-doctests-crate-attribute.rs - Foo (line 11) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/tests/rustdoc-ui/doctest/auxiliary/extern_macros_2024.rs b/tests/rustdoc-ui/doctest/auxiliary/extern_macros_2024.rs index 354427000bf71..388b8f310ae39 100644 --- a/tests/rustdoc-ui/doctest/auxiliary/extern_macros_2024.rs +++ b/tests/rustdoc-ui/doctest/auxiliary/extern_macros_2024.rs @@ -1,5 +1,4 @@ //@ edition:2024 -//@ compile-flags:-Z unstable-options #![crate_name="extern_macros"] #[macro_export] macro_rules! attrs_on_struct { diff --git a/tests/rustdoc-ui/doctest/dead-code-2024.rs b/tests/rustdoc-ui/doctest/dead-code-2024.rs index 4c77112e61a6b..41459c5e6512d 100644 --- a/tests/rustdoc-ui/doctest/dead-code-2024.rs +++ b/tests/rustdoc-ui/doctest/dead-code-2024.rs @@ -1,6 +1,7 @@ // This test ensures that the 2024 edition merged doctest will not use `#[allow(unused)]`. -//@ compile-flags:--test -Zunstable-options --edition 2024 +//@ edition: 2024 +//@ compile-flags:--test //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 diff --git a/tests/rustdoc-ui/doctest/dead-code-2024.stdout b/tests/rustdoc-ui/doctest/dead-code-2024.stdout index 69dd4e2ede1ac..a943a177e10b6 100644 --- a/tests/rustdoc-ui/doctest/dead-code-2024.stdout +++ b/tests/rustdoc-ui/doctest/dead-code-2024.stdout @@ -1,18 +1,18 @@ running 1 test -test $DIR/dead-code-2024.rs - f (line 12) - compile ... FAILED +test $DIR/dead-code-2024.rs - f (line 13) - compile ... FAILED failures: ----- $DIR/dead-code-2024.rs - f (line 12) stdout ---- +---- $DIR/dead-code-2024.rs - f (line 13) stdout ---- error: trait `T` is never used - --> $DIR/dead-code-2024.rs:13:7 + --> $DIR/dead-code-2024.rs:14:7 | LL | trait T { fn f(); } | ^ | note: the lint level is defined here - --> $DIR/dead-code-2024.rs:11:9 + --> $DIR/dead-code-2024.rs:12:9 | LL | #![deny(warnings)] | ^^^^^^^^ @@ -23,7 +23,7 @@ error: aborting due to 1 previous error Couldn't compile the test. failures: - $DIR/dead-code-2024.rs - f (line 12) + $DIR/dead-code-2024.rs - f (line 13) test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs b/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs index bae61992eb212..58612b682a000 100644 --- a/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs +++ b/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs @@ -1,5 +1,5 @@ //@ edition:2024 -//@ compile-flags:--test --test-args=--test-threads=1 -Z unstable-options +//@ compile-flags:--test --test-args=--test-threads=1 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 diff --git a/tests/rustdoc-ui/doctest/doctest-output.rs b/tests/rustdoc-ui/doctest/doctest-output.rs index 0e5ccf0b090bb..946bc550b12fb 100644 --- a/tests/rustdoc-ui/doctest/doctest-output.rs +++ b/tests/rustdoc-ui/doctest/doctest-output.rs @@ -4,7 +4,7 @@ //@[edition2015]compile-flags:--test --test-args=--test-threads=1 //@[edition2024]edition:2015 //@[edition2024]aux-build:extern_macros.rs -//@[edition2024]compile-flags:--test --test-args=--test-threads=1 -Z unstable-options +//@[edition2024]compile-flags:--test --test-args=--test-threads=1 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs index 4018e37105ff1..d057218688c48 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs @@ -1,7 +1,8 @@ // FIXME: if/when the output of the test harness can be tested on its own, this test should be // adapted to use that, and that normalize line can go away -//@ compile-flags:--test -Z unstable-options --edition 2024 +//@ edition: 2024 +//@ compile-flags:--test //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.stdout b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.stdout index cb3456e087ebe..90c0463d832e1 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.stdout +++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.stdout @@ -1,14 +1,14 @@ running 1 test -test $DIR/failed-doctest-should-panic.rs - Foo (line 9) - should panic ... FAILED +test $DIR/failed-doctest-should-panic.rs - Foo (line 10) - should panic ... FAILED failures: ----- $DIR/failed-doctest-should-panic.rs - Foo (line 9) stdout ---- +---- $DIR/failed-doctest-should-panic.rs - Foo (line 10) stdout ---- note: test did not panic as expected failures: - $DIR/failed-doctest-should-panic.rs - Foo (line 9) + $DIR/failed-doctest-should-panic.rs - Foo (line 10) test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs index 4c21d54295106..754791361e8bf 100644 --- a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs +++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs @@ -1,4 +1,5 @@ -//@ compile-flags:--test --test-args=--test-threads=1 -Zunstable-options --edition 2024 +//@ edition: 2024 +//@ compile-flags:--test --test-args=--test-threads=1 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout b/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout index f2cb1e7e72f70..a32da0aeb9649 100644 --- a/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout +++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout @@ -1,7 +1,7 @@ running 2 tests -test $DIR/merged-ignore-no_run.rs - ignored (line 6) ... ignored -test $DIR/merged-ignore-no_run.rs - no_run (line 11) - compile ... ok +test $DIR/merged-ignore-no_run.rs - ignored (line 7) ... ignored +test $DIR/merged-ignore-no_run.rs - no_run (line 12) - compile ... ok test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs index b393d126306aa..5a1d4d0a60dd0 100644 --- a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs +++ b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs @@ -6,7 +6,7 @@ //@[edition2015]compile-flags:--test --test-args=--test-threads=1 //@[edition2024]edition:2024 //@[edition2024]check-pass -//@[edition2024]compile-flags:--test --test-args=--test-threads=1 -Z unstable-options +//@[edition2024]compile-flags:--test --test-args=--test-threads=1 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" diff --git a/tests/rustdoc-ui/doctest/standalone-warning-2024.rs b/tests/rustdoc-ui/doctest/standalone-warning-2024.rs index aac4303154697..35d1c738bb16f 100644 --- a/tests/rustdoc-ui/doctest/standalone-warning-2024.rs +++ b/tests/rustdoc-ui/doctest/standalone-warning-2024.rs @@ -1,6 +1,7 @@ // This test checks that it will output warnings for usage of `standalone` or `standalone_crate`. -//@ compile-flags:--test -Zunstable-options --edition 2024 +//@ edition: 2024 +//@ compile-flags:--test //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" diff --git a/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr b/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr index d69d03d8657c1..bfc1e91940453 100644 --- a/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr +++ b/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr @@ -1,34 +1,34 @@ error: unknown attribute `standalone` - --> $DIR/standalone-warning-2024.rs:10:1 + --> $DIR/standalone-warning-2024.rs:11:1 | -10 | / //! ```standalone -11 | | //! bla -12 | | //! ``` -13 | | //! -14 | | //! ```standalone-crate -15 | | //! bla -16 | | //! ``` +11 | / //! ```standalone +12 | | //! bla +13 | | //! ``` +14 | | //! +15 | | //! ```standalone-crate +16 | | //! bla +17 | | //! ``` | |_______^ | = help: use `standalone_crate` to compile this code block separately = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` note: the lint level is defined here - --> $DIR/standalone-warning-2024.rs:8:9 + --> $DIR/standalone-warning-2024.rs:9:9 | -8 | #![deny(warnings)] +9 | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]` error: unknown attribute `standalone-crate` - --> $DIR/standalone-warning-2024.rs:10:1 + --> $DIR/standalone-warning-2024.rs:11:1 | -10 | / //! ```standalone -11 | | //! bla -12 | | //! ``` -13 | | //! -14 | | //! ```standalone-crate -15 | | //! bla -16 | | //! ``` +11 | / //! ```standalone +12 | | //! bla +13 | | //! ``` +14 | | //! +15 | | //! ```standalone-crate +16 | | //! bla +17 | | //! ``` | |_______^ | = help: use `standalone_crate` to compile this code block separately diff --git a/tests/rustdoc-ui/doctest/wrong-ast-2024.rs b/tests/rustdoc-ui/doctest/wrong-ast-2024.rs index 7b4fa8fd2c9b9..a1455c01bc69d 100644 --- a/tests/rustdoc-ui/doctest/wrong-ast-2024.rs +++ b/tests/rustdoc-ui/doctest/wrong-ast-2024.rs @@ -1,4 +1,5 @@ -//@ compile-flags:--test --test-args=--test-threads=1 -Zunstable-options --edition 2024 +//@ edition: 2024 +//@ compile-flags:--test --test-args=--test-threads=1 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" diff --git a/tests/rustdoc-ui/doctest/wrong-ast-2024.stdout b/tests/rustdoc-ui/doctest/wrong-ast-2024.stdout index 22c8ce468fd7c..62e1fb10b9f4a 100644 --- a/tests/rustdoc-ui/doctest/wrong-ast-2024.stdout +++ b/tests/rustdoc-ui/doctest/wrong-ast-2024.stdout @@ -1,17 +1,17 @@ running 1 test -test $DIR/wrong-ast-2024.rs - three (line 17) - should panic ... ok +test $DIR/wrong-ast-2024.rs - three (line 18) - should panic ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME running 2 tests -test $DIR/wrong-ast-2024.rs - one (line 7) ... FAILED -test $DIR/wrong-ast-2024.rs - two (line 12) ... FAILED +test $DIR/wrong-ast-2024.rs - one (line 8) ... FAILED +test $DIR/wrong-ast-2024.rs - two (line 13) ... FAILED failures: ----- $DIR/wrong-ast-2024.rs - one (line 7) stdout ---- +---- $DIR/wrong-ast-2024.rs - one (line 8) stdout ---- error[E0758]: unterminated block comment --> $DIR/wrong-ast-2024.rs:$LINE:$COL | @@ -22,7 +22,7 @@ error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0758`. Couldn't compile the test. ----- $DIR/wrong-ast-2024.rs - two (line 12) stdout ---- +---- $DIR/wrong-ast-2024.rs - two (line 13) stdout ---- error: unexpected closing delimiter: `}` --> $DIR/wrong-ast-2024.rs:$LINE:$COL | @@ -34,8 +34,8 @@ error: aborting due to 1 previous error Couldn't compile the test. failures: - $DIR/wrong-ast-2024.rs - one (line 7) - $DIR/wrong-ast-2024.rs - two (line 12) + $DIR/wrong-ast-2024.rs - one (line 8) + $DIR/wrong-ast-2024.rs - two (line 13) test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/in-proc-item-comment.rs b/tests/rustdoc-ui/intra-doc/auxiliary/in-proc-item-comment.rs new file mode 100644 index 0000000000000..5d3d3c196e1d6 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/auxiliary/in-proc-item-comment.rs @@ -0,0 +1,20 @@ +//@ force-host +//@ no-prefer-dynamic +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +mod view {} + +/// [`view`] +#[proc_macro] +pub fn f(_: TokenStream) -> TokenStream { + todo!() +} + +/// [`f()`] +#[proc_macro] +pub fn g(_: TokenStream) -> TokenStream { + todo!() +} diff --git a/tests/rustdoc-ui/intra-doc/pub-proc-item.rs b/tests/rustdoc-ui/intra-doc/pub-proc-item.rs new file mode 100644 index 0000000000000..413efb40b0da5 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/pub-proc-item.rs @@ -0,0 +1,8 @@ +//@ aux-build:in-proc-item-comment.rs +//@ check-pass + +// issue#132743 + +extern crate in_proc_item_comment; + +pub use in_proc_item_comment::{f, g}; diff --git a/tests/rustdoc-ui/unable-fulfill-trait.rs b/tests/rustdoc-ui/unable-fulfill-trait.rs index 4edc7ab76c198..49dce32072b61 100644 --- a/tests/rustdoc-ui/unable-fulfill-trait.rs +++ b/tests/rustdoc-ui/unable-fulfill-trait.rs @@ -3,7 +3,6 @@ pub struct Foo<'a, 'b, T> { field1: dyn Bar<'a, 'b>, //~^ ERROR - //~| ERROR } pub trait Bar<'x, 's, U> diff --git a/tests/rustdoc-ui/unable-fulfill-trait.stderr b/tests/rustdoc-ui/unable-fulfill-trait.stderr index 12e53546cdacc..2786a005cd183 100644 --- a/tests/rustdoc-ui/unable-fulfill-trait.stderr +++ b/tests/rustdoc-ui/unable-fulfill-trait.stderr @@ -5,7 +5,7 @@ LL | field1: dyn Bar<'a, 'b>, | ^^^ expected 1 generic argument | note: trait defined here, with 1 generic parameter: `U` - --> $DIR/unable-fulfill-trait.rs:9:11 + --> $DIR/unable-fulfill-trait.rs:8:11 | LL | pub trait Bar<'x, 's, U> | ^^^ - @@ -14,13 +14,6 @@ help: add missing generic argument LL | field1: dyn Bar<'a, 'b, U>, | +++ -error[E0227]: ambiguous lifetime bound, explicit lifetime bound required - --> $DIR/unable-fulfill-trait.rs:4:13 - | -LL | field1: dyn Bar<'a, 'b>, - | ^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0107, E0227. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/rustdoc-ui/unescaped_backticks.rs b/tests/rustdoc-ui/unescaped_backticks.rs index e813fba47179d..8d6239296bf78 100644 --- a/tests/rustdoc-ui/unescaped_backticks.rs +++ b/tests/rustdoc-ui/unescaped_backticks.rs @@ -218,7 +218,7 @@ pub mod rustc { pub fn with_options() {} /// Subtracts `set from `row`. `set` can be either `BitSet` or - /// `HybridBitSet`. Has no effect if `row` does not exist. + /// `ChunkedBitSet`. Has no effect if `row` does not exist. //~^ ERROR unescaped backtick /// /// Returns true if the row was changed. diff --git a/tests/rustdoc-ui/unescaped_backticks.stderr b/tests/rustdoc-ui/unescaped_backticks.stderr index 67b87f353a153..1e2b3528d4afd 100644 --- a/tests/rustdoc-ui/unescaped_backticks.stderr +++ b/tests/rustdoc-ui/unescaped_backticks.stderr @@ -124,10 +124,10 @@ LL | /// also avoids the need to import `OpenOptions\`. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:221:46 + --> $DIR/unescaped_backticks.rs:221:47 | -LL | /// `HybridBitSet`. Has no effect if `row` does not exist. - | ^ +LL | /// `ChunkedBitSet`. Has no effect if `row` does not exist. + | ^ | help: a previous inline code might be longer than expected | @@ -135,8 +135,8 @@ LL | /// Subtracts `set` from `row`. `set` can be either `BitSet` or | + help: if you meant to use a literal backtick, escape it | -LL | /// `HybridBitSet`. Has no effect if `row\` does not exist. - | + +LL | /// `ChunkedBitSet`. Has no effect if `row\` does not exist. + | + error: unescaped backtick --> $DIR/unescaped_backticks.rs:247:12 diff --git a/tests/rustdoc/jump-to-def-prelude-types.rs b/tests/rustdoc/jump-to-def-prelude-types.rs new file mode 100644 index 0000000000000..43617b1bc9df7 --- /dev/null +++ b/tests/rustdoc/jump-to-def-prelude-types.rs @@ -0,0 +1,23 @@ +// This test checks that prelude types like `Result` and `Option` still get a link generated. + +//@ compile-flags: -Zunstable-options --generate-link-to-definition + +#![crate_name = "foo"] + +//@ has 'src/foo/jump-to-def-prelude-types.rs.html' +// FIXME: would be nice to be able to check both the class and the href at the same time so +// we could check the text as well... +//@ has - '//a[@class="prelude-ty"]/@href' '{{channel}}/core/result/enum.Result.html' +//@ has - '//a[@class="prelude-ty"]/@href' '{{channel}}/core/option/enum.Option.html' +pub fn foo() -> Result, ()> { Err(()) } + +// This part is to ensure that they are not linking to the actual prelude ty. +pub mod bar { + struct Result; + struct Option; + + //@ has - '//a[@href="#16"]' 'Result' + pub fn bar() -> Result { Result } + //@ has - '//a[@href="#17"]' 'Option' + pub fn bar2() -> Option { Option } +} diff --git a/tests/ui-fulldeps/obtain-borrowck.rs b/tests/ui-fulldeps/obtain-borrowck.rs index e6c703addd924..af98f93297b6e 100644 --- a/tests/ui-fulldeps/obtain-borrowck.rs +++ b/tests/ui-fulldeps/obtain-borrowck.rs @@ -25,19 +25,20 @@ extern crate rustc_interface; extern crate rustc_middle; extern crate rustc_session; +use std::cell::RefCell; +use std::collections::HashMap; +use std::thread_local; + use rustc_borrowck::consumers::{self, BodyWithBorrowckFacts, ConsumerOptions}; use rustc_driver::Compilation; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; +use rustc_interface::Config; use rustc_interface::interface::Compiler; -use rustc_interface::{Config, Queries}; use rustc_middle::query::queries::mir_borrowck::ProvidedValue; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; -use std::cell::RefCell; -use std::collections::HashMap; -use std::thread_local; fn main() { let exit_code = rustc_driver::catch_with_exit_code(move || { @@ -63,55 +64,49 @@ impl rustc_driver::Callbacks for CompilerCalls { // In this callback we trigger borrow checking of all functions and obtain // the result. - fn after_analysis<'tcx>( - &mut self, - compiler: &Compiler, - queries: &'tcx Queries<'tcx>, - ) -> Compilation { - compiler.sess.dcx().abort_if_errors(); - queries.global_ctxt().unwrap().enter(|tcx| { - // Collect definition ids of MIR bodies. - let hir = tcx.hir(); - let mut bodies = Vec::new(); - - let crate_items = tcx.hir_crate_items(()); - for id in crate_items.free_items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Fn) { - bodies.push(id.owner_id); - } + fn after_analysis<'tcx>(&mut self, _compiler: &Compiler, tcx: TyCtxt<'tcx>) -> Compilation { + tcx.sess.dcx().abort_if_errors(); + // Collect definition ids of MIR bodies. + let hir = tcx.hir(); + let mut bodies = Vec::new(); + + let crate_items = tcx.hir_crate_items(()); + for id in crate_items.free_items() { + if matches!(tcx.def_kind(id.owner_id), DefKind::Fn) { + bodies.push(id.owner_id); } - - for id in crate_items.trait_items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::AssocFn) { - let trait_item = hir.trait_item(id); - if let rustc_hir::TraitItemKind::Fn(_, trait_fn) = &trait_item.kind { - if let rustc_hir::TraitFn::Provided(_) = trait_fn { - bodies.push(trait_item.owner_id); - } + } + + for id in crate_items.trait_items() { + if matches!(tcx.def_kind(id.owner_id), DefKind::AssocFn) { + let trait_item = hir.trait_item(id); + if let rustc_hir::TraitItemKind::Fn(_, trait_fn) = &trait_item.kind { + if let rustc_hir::TraitFn::Provided(_) = trait_fn { + bodies.push(trait_item.owner_id); } } } + } - for id in crate_items.impl_items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::AssocFn) { - bodies.push(id.owner_id); - } - } - - // Trigger borrow checking of all bodies. - for def_id in bodies { - let _ = tcx.optimized_mir(def_id); - } - - // See what bodies were borrow checked. - let mut bodies = get_bodies(tcx); - bodies.sort_by(|(def_id1, _), (def_id2, _)| def_id1.cmp(def_id2)); - println!("Bodies retrieved for:"); - for (def_id, body) in bodies { - println!("{}", def_id); - assert!(body.input_facts.unwrap().cfg_edge.len() > 0); + for id in crate_items.impl_items() { + if matches!(tcx.def_kind(id.owner_id), DefKind::AssocFn) { + bodies.push(id.owner_id); } - }); + } + + // Trigger borrow checking of all bodies. + for def_id in bodies { + let _ = tcx.optimized_mir(def_id); + } + + // See what bodies were borrow checked. + let mut bodies = get_bodies(tcx); + bodies.sort_by(|(def_id1, _), (def_id2, _)| def_id1.cmp(def_id2)); + println!("Bodies retrieved for:"); + for (def_id, body) in bodies { + println!("{}", def_id); + assert!(body.input_facts.unwrap().cfg_edge.len() > 0); + } Compilation::Continue } diff --git a/tests/ui-fulldeps/stable-mir/check_abi.rs b/tests/ui-fulldeps/stable-mir/check_abi.rs index 5b7da7bb12995..8caf3032afc44 100644 --- a/tests/ui-fulldeps/stable-mir/check_abi.rs +++ b/tests/ui-fulldeps/stable-mir/check_abi.rs @@ -11,6 +11,7 @@ #![feature(ascii_char, ascii_char_variants)] extern crate rustc_hir; +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/check_allocation.rs b/tests/ui-fulldeps/stable-mir/check_allocation.rs index 1e2f640f39f5f..072c8ba6a442c 100644 --- a/tests/ui-fulldeps/stable-mir/check_allocation.rs +++ b/tests/ui-fulldeps/stable-mir/check_allocation.rs @@ -13,6 +13,7 @@ #![feature(ascii_char, ascii_char_variants)] extern crate rustc_hir; +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/check_attribute.rs b/tests/ui-fulldeps/stable-mir/check_attribute.rs index 131fd99ebaa97..22481e275a99f 100644 --- a/tests/ui-fulldeps/stable-mir/check_attribute.rs +++ b/tests/ui-fulldeps/stable-mir/check_attribute.rs @@ -9,6 +9,7 @@ #![feature(rustc_private)] extern crate rustc_hir; +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/check_binop.rs b/tests/ui-fulldeps/stable-mir/check_binop.rs index 3b52d88de3cdf..8c44e28510843 100644 --- a/tests/ui-fulldeps/stable-mir/check_binop.rs +++ b/tests/ui-fulldeps/stable-mir/check_binop.rs @@ -9,6 +9,7 @@ #![feature(rustc_private)] extern crate rustc_hir; +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/check_crate_defs.rs b/tests/ui-fulldeps/stable-mir/check_crate_defs.rs index e039ca07dd4ad..ed093903381b2 100644 --- a/tests/ui-fulldeps/stable-mir/check_crate_defs.rs +++ b/tests/ui-fulldeps/stable-mir/check_crate_defs.rs @@ -10,6 +10,7 @@ #![feature(assert_matches)] extern crate rustc_hir; +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/check_def_ty.rs b/tests/ui-fulldeps/stable-mir/check_def_ty.rs index ec3cf1753e2cd..482dbd22d5fe2 100644 --- a/tests/ui-fulldeps/stable-mir/check_def_ty.rs +++ b/tests/ui-fulldeps/stable-mir/check_def_ty.rs @@ -11,6 +11,7 @@ #![feature(rustc_private)] #![feature(assert_matches)] +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/check_defs.rs b/tests/ui-fulldeps/stable-mir/check_defs.rs index 3402b345818c7..bf1f1a2ceab98 100644 --- a/tests/ui-fulldeps/stable-mir/check_defs.rs +++ b/tests/ui-fulldeps/stable-mir/check_defs.rs @@ -10,6 +10,7 @@ #![feature(rustc_private)] #![feature(assert_matches)] +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/check_instance.rs b/tests/ui-fulldeps/stable-mir/check_instance.rs index 7d63e202fa6ca..464350b104571 100644 --- a/tests/ui-fulldeps/stable-mir/check_instance.rs +++ b/tests/ui-fulldeps/stable-mir/check_instance.rs @@ -10,6 +10,7 @@ #![feature(rustc_private)] #![feature(assert_matches)] +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/check_intrinsics.rs b/tests/ui-fulldeps/stable-mir/check_intrinsics.rs index 3534228f73ed9..6edebaf756c56 100644 --- a/tests/ui-fulldeps/stable-mir/check_intrinsics.rs +++ b/tests/ui-fulldeps/stable-mir/check_intrinsics.rs @@ -13,6 +13,7 @@ #![feature(rustc_private)] #![feature(assert_matches)] +extern crate rustc_middle; extern crate rustc_hir; #[macro_use] extern crate rustc_smir; diff --git a/tests/ui-fulldeps/stable-mir/check_item_kind.rs b/tests/ui-fulldeps/stable-mir/check_item_kind.rs index 91baa074c1085..23b54e6c60b39 100644 --- a/tests/ui-fulldeps/stable-mir/check_item_kind.rs +++ b/tests/ui-fulldeps/stable-mir/check_item_kind.rs @@ -10,6 +10,7 @@ #![feature(rustc_private)] #![feature(assert_matches)] +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/check_normalization.rs b/tests/ui-fulldeps/stable-mir/check_normalization.rs index 72e410f80809b..928173b154b4f 100644 --- a/tests/ui-fulldeps/stable-mir/check_normalization.rs +++ b/tests/ui-fulldeps/stable-mir/check_normalization.rs @@ -9,6 +9,7 @@ #![feature(rustc_private)] +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/check_trait_queries.rs b/tests/ui-fulldeps/stable-mir/check_trait_queries.rs index 8721f243587b4..304a7ce925554 100644 --- a/tests/ui-fulldeps/stable-mir/check_trait_queries.rs +++ b/tests/ui-fulldeps/stable-mir/check_trait_queries.rs @@ -10,6 +10,7 @@ #![feature(rustc_private)] #![feature(assert_matches)] +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/check_transform.rs b/tests/ui-fulldeps/stable-mir/check_transform.rs index 40217b9aa95a6..bcf79c456b073 100644 --- a/tests/ui-fulldeps/stable-mir/check_transform.rs +++ b/tests/ui-fulldeps/stable-mir/check_transform.rs @@ -11,6 +11,7 @@ #![feature(ascii_char, ascii_char_variants)] extern crate rustc_hir; +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/check_ty_fold.rs b/tests/ui-fulldeps/stable-mir/check_ty_fold.rs index 0715e0cfc52d0..e21508c9b4612 100644 --- a/tests/ui-fulldeps/stable-mir/check_ty_fold.rs +++ b/tests/ui-fulldeps/stable-mir/check_ty_fold.rs @@ -11,6 +11,7 @@ #![feature(rustc_private)] #![feature(assert_matches)] +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/compilation-result.rs b/tests/ui-fulldeps/stable-mir/compilation-result.rs index 286bbd7c59477..d921de73f4364 100644 --- a/tests/ui-fulldeps/stable-mir/compilation-result.rs +++ b/tests/ui-fulldeps/stable-mir/compilation-result.rs @@ -10,6 +10,7 @@ #![feature(rustc_private)] #![feature(assert_matches)] +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index 6b458c5d923de..53be8eb10c1ed 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -11,6 +11,7 @@ #![feature(assert_matches)] extern crate rustc_hir; +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/projections.rs b/tests/ui-fulldeps/stable-mir/projections.rs index a8bf4c1d39974..fdb7eeed1b0e5 100644 --- a/tests/ui-fulldeps/stable-mir/projections.rs +++ b/tests/ui-fulldeps/stable-mir/projections.rs @@ -11,6 +11,7 @@ #![feature(assert_matches)] extern crate rustc_hir; +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui-fulldeps/stable-mir/smir_visitor.rs b/tests/ui-fulldeps/stable-mir/smir_visitor.rs index f1bc03781b94e..666000d3b070f 100644 --- a/tests/ui-fulldeps/stable-mir/smir_visitor.rs +++ b/tests/ui-fulldeps/stable-mir/smir_visitor.rs @@ -10,6 +10,7 @@ #![feature(rustc_private)] #![feature(assert_matches)] +extern crate rustc_middle; #[macro_use] extern crate rustc_smir; extern crate rustc_driver; diff --git a/tests/ui/abi/anon-extern-mod.rs b/tests/ui/abi/anon-extern-mod.rs index bb3739bc4afab..134542b9cff38 100644 --- a/tests/ui/abi/anon-extern-mod.rs +++ b/tests/ui/abi/anon-extern-mod.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #[link(name = "rust_test_helpers", kind = "static")] extern "C" { diff --git a/tests/ui/abi/c-stack-as-value.rs b/tests/ui/abi/c-stack-as-value.rs index 401bc132b6e77..10933bdb2781f 100644 --- a/tests/ui/abi/c-stack-as-value.rs +++ b/tests/ui/abi/c-stack-as-value.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 mod rustrt { #[link(name = "rust_test_helpers", kind = "static")] diff --git a/tests/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs b/tests/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs index 95bf4df68df26..b2d06444c1367 100644 --- a/tests/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs +++ b/tests/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs @@ -1,6 +1,5 @@ //@ run-pass //@ aux-build:anon-extern-mod-cross-crate-1.rs -//@ pretty-expanded FIXME #23616 extern crate anonexternmod; diff --git a/tests/ui/abi/cross-crate/duplicated-external-mods.rs b/tests/ui/abi/cross-crate/duplicated-external-mods.rs index 2a3875d27734c..19a9b07d65c9f 100644 --- a/tests/ui/abi/cross-crate/duplicated-external-mods.rs +++ b/tests/ui/abi/cross-crate/duplicated-external-mods.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:anon-extern-mod-cross-crate-1.rs //@ aux-build:anon-extern-mod-cross-crate-1.rs -//@ pretty-expanded FIXME #23616 extern crate anonexternmod; diff --git a/tests/ui/abi/extern/extern-pass-empty.rs b/tests/ui/abi/extern/extern-pass-empty.rs index f168f5faa1786..1ad52b128ad93 100644 --- a/tests/ui/abi/extern/extern-pass-empty.rs +++ b/tests/ui/abi/extern/extern-pass-empty.rs @@ -3,7 +3,6 @@ // Test a foreign function that accepts empty struct. -//@ pretty-expanded FIXME #23616 //@ ignore-msvc //@ ignore-emscripten emcc asserts on an empty struct as an argument diff --git a/tests/ui/abi/foreign/invoke-external-foreign.rs b/tests/ui/abi/foreign/invoke-external-foreign.rs index 78cc84804bfd0..a22b12af67202 100644 --- a/tests/ui/abi/foreign/invoke-external-foreign.rs +++ b/tests/ui/abi/foreign/invoke-external-foreign.rs @@ -5,7 +5,6 @@ // successfully (and safely) invoke external, cdecl // functions from outside the crate. -//@ pretty-expanded FIXME #23616 extern crate foreign_lib; diff --git a/tests/ui/alias-uninit-value.rs b/tests/ui/alias-uninit-value.rs index 3223bac18201d..0084a98e62735 100644 --- a/tests/ui/alias-uninit-value.rs +++ b/tests/ui/alias-uninit-value.rs @@ -7,7 +7,6 @@ // Regression test for issue #374 -//@ pretty-expanded FIXME #23616 enum sty { ty_nil, } diff --git a/tests/ui/annotate-snippet/auxiliary/multispan.rs b/tests/ui/annotate-snippet/auxiliary/multispan.rs index b5f1ed9b56a9e..1eb379d3877d2 100644 --- a/tests/ui/annotate-snippet/auxiliary/multispan.rs +++ b/tests/ui/annotate-snippet/auxiliary/multispan.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_diagnostic, proc_macro_span, proc_macro_def_site)] extern crate proc_macro; diff --git a/tests/ui/annotate-snippet/multispan.rs b/tests/ui/annotate-snippet/multispan.rs index c9ec4043e374f..b7cf22eebcbff 100644 --- a/tests/ui/annotate-snippet/multispan.rs +++ b/tests/ui/annotate-snippet/multispan.rs @@ -1,4 +1,4 @@ -//@ aux-build:multispan.rs +//@ proc-macro: multispan.rs //@ error-pattern:hello to you, too! //@ compile-flags: --error-format human-annotate-rs -Z unstable-options diff --git a/tests/ui/array-slice-vec/cast-in-array-size.rs b/tests/ui/array-slice-vec/cast-in-array-size.rs index cb5072564b2e1..5276288f8199c 100644 --- a/tests/ui/array-slice-vec/cast-in-array-size.rs +++ b/tests/ui/array-slice-vec/cast-in-array-size.rs @@ -2,7 +2,6 @@ // issues #10618 and #16382 -//@ pretty-expanded FIXME #23616 const SIZE: isize = 25; diff --git a/tests/ui/array-slice-vec/empty-mutable-vec.rs b/tests/ui/array-slice-vec/empty-mutable-vec.rs index 663071bf61335..1785b1aa39e81 100644 --- a/tests/ui/array-slice-vec/empty-mutable-vec.rs +++ b/tests/ui/array-slice-vec/empty-mutable-vec.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(unused_mut)] diff --git a/tests/ui/array-slice-vec/issue-15730.rs b/tests/ui/array-slice-vec/issue-15730.rs index fe9d908a1ff7c..2a69417819d95 100644 --- a/tests/ui/array-slice-vec/issue-15730.rs +++ b/tests/ui/array-slice-vec/issue-15730.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_mut)] #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 fn main() { let mut array = [1, 2, 3]; diff --git a/tests/ui/array-slice-vec/issue-18425.rs b/tests/ui/array-slice-vec/issue-18425.rs index 22345718ad8e4..e74a20de72662 100644 --- a/tests/ui/array-slice-vec/issue-18425.rs +++ b/tests/ui/array-slice-vec/issue-18425.rs @@ -2,7 +2,6 @@ // Check that codegen doesn't ICE when codegenning an array repeat // expression with a count of 1 and a non-Copy element type. -//@ pretty-expanded FIXME #23616 fn main() { let _ = [Box::new(1_usize); 1]; diff --git a/tests/ui/array-slice-vec/match_arr_unknown_len.stderr b/tests/ui/array-slice-vec/match_arr_unknown_len.stderr index 3ed0d6bdf3ac9..f617ff339383d 100644 --- a/tests/ui/array-slice-vec/match_arr_unknown_len.stderr +++ b/tests/ui/array-slice-vec/match_arr_unknown_len.stderr @@ -2,10 +2,7 @@ error[E0308]: mismatched types --> $DIR/match_arr_unknown_len.rs:3:9 | LL | [1, 2] => true, - | ^^^^^^ expected `2`, found `N` - | - = note: expected array `[u32; 2]` - found array `[u32; N]` + | ^^^^^^ expected an array with a size of 2, found one with a size of N error: aborting due to 1 previous error diff --git a/tests/ui/array-slice-vec/mut-vstore-expr.rs b/tests/ui/array-slice-vec/mut-vstore-expr.rs index 809c001b0797f..9553aed9a00ea 100644 --- a/tests/ui/array-slice-vec/mut-vstore-expr.rs +++ b/tests/ui/array-slice-vec/mut-vstore-expr.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { let _x: &mut [isize] = &mut [ 1, 2, 3 ]; diff --git a/tests/ui/array-slice-vec/vec-macro-with-brackets.rs b/tests/ui/array-slice-vec/vec-macro-with-brackets.rs index 65ca182b61567..b62e294f9d1d6 100644 --- a/tests/ui/array-slice-vec/vec-macro-with-brackets.rs +++ b/tests/ui/array-slice-vec/vec-macro-with-brackets.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 macro_rules! vec [ ($($e:expr),*) => ({ diff --git a/tests/ui/array-slice-vec/vec-repeat-with-cast.rs b/tests/ui/array-slice-vec/vec-repeat-with-cast.rs index 4af38d9cf3286..1f1fd4cd0d29c 100644 --- a/tests/ui/array-slice-vec/vec-repeat-with-cast.rs +++ b/tests/ui/array-slice-vec/vec-repeat-with-cast.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { let _a = [0; 1 as usize]; } diff --git a/tests/ui/array-slice-vec/vector-no-ann-2.rs b/tests/ui/array-slice-vec/vector-no-ann-2.rs index b130c6bc2ffb5..63828551af114 100644 --- a/tests/ui/array-slice-vec/vector-no-ann-2.rs +++ b/tests/ui/array-slice-vec/vector-no-ann-2.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { let _quux: Box> = Box::new(Vec::new()); diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr new file mode 100644 index 0000000000000..0e54411965012 --- /dev/null +++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr @@ -0,0 +1,38 @@ +error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:22:18 + | +LL | asm!("", out("$r0") _); + | ^^^^^^^^^^^^ + +error: invalid register `$tp`: reserved for TLS + --> $DIR/bad-reg.rs:24:18 + | +LL | asm!("", out("$tp") _); + | ^^^^^^^^^^^^ + +error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:26:18 + | +LL | asm!("", out("$sp") _); + | ^^^^^^^^^^^^ + +error: invalid register `$r21`: reserved by the ABI + --> $DIR/bad-reg.rs:28:18 + | +LL | asm!("", out("$r21") _); + | ^^^^^^^^^^^^^ + +error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:30:18 + | +LL | asm!("", out("$fp") _); + | ^^^^^^^^^^^^ + +error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:32:18 + | +LL | asm!("", out("$r31") _); + | ^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr new file mode 100644 index 0000000000000..6d0410dc6a13f --- /dev/null +++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr @@ -0,0 +1,62 @@ +error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:22:18 + | +LL | asm!("", out("$r0") _); + | ^^^^^^^^^^^^ + +error: invalid register `$tp`: reserved for TLS + --> $DIR/bad-reg.rs:24:18 + | +LL | asm!("", out("$tp") _); + | ^^^^^^^^^^^^ + +error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:26:18 + | +LL | asm!("", out("$sp") _); + | ^^^^^^^^^^^^ + +error: invalid register `$r21`: reserved by the ABI + --> $DIR/bad-reg.rs:28:18 + | +LL | asm!("", out("$r21") _); + | ^^^^^^^^^^^^^ + +error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:30:18 + | +LL | asm!("", out("$fp") _); + | ^^^^^^^^^^^^ + +error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:32:18 + | +LL | asm!("", out("$r31") _); + | ^^^^^^^^^^^^^ + +error: register class `freg` requires at least one of the following target features: d, f + --> $DIR/bad-reg.rs:36:26 + | +LL | asm!("/* {} */", in(freg) f); + | ^^^^^^^^^^ + +error: register class `freg` requires at least one of the following target features: d, f + --> $DIR/bad-reg.rs:38:26 + | +LL | asm!("/* {} */", out(freg) _); + | ^^^^^^^^^^^ + +error: register class `freg` requires at least one of the following target features: d, f + --> $DIR/bad-reg.rs:40:26 + | +LL | asm!("/* {} */", in(freg) d); + | ^^^^^^^^^^ + +error: register class `freg` requires at least one of the following target features: d, f + --> $DIR/bad-reg.rs:42:26 + | +LL | asm!("/* {} */", out(freg) d); + | ^^^^^^^^^^^ + +error: aborting due to 10 previous errors + diff --git a/tests/ui/asm/loongarch/bad-reg.rs b/tests/ui/asm/loongarch/bad-reg.rs new file mode 100644 index 0000000000000..c5288cc78b71f --- /dev/null +++ b/tests/ui/asm/loongarch/bad-reg.rs @@ -0,0 +1,45 @@ +//@ add-core-stubs +//@ needs-asm-support +//@ revisions: loongarch64_lp64d loongarch64_lp64s +//@[loongarch64_lp64d] compile-flags: --target loongarch64-unknown-linux-gnu +//@[loongarch64_lp64d] needs-llvm-components: loongarch +//@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat +//@[loongarch64_lp64s] needs-llvm-components: loongarch + +#![crate_type = "lib"] +#![feature(no_core, rustc_attrs)] +#![no_core] + +extern crate minicore; +use minicore::*; + +fn f() { + let mut x = 0; + let mut f = 0.0_f32; + let mut d = 0.0_f64; + unsafe { + // Unsupported registers + asm!("", out("$r0") _); + //~^ ERROR constant zero cannot be used as an operand for inline asm + asm!("", out("$tp") _); + //~^ ERROR invalid register `$tp`: reserved for TLS + asm!("", out("$sp") _); + //~^ ERROR invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm + asm!("", out("$r21") _); + //~^ ERROR invalid register `$r21`: reserved by the ABI + asm!("", out("$fp") _); + //~^ ERROR invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm + asm!("", out("$r31") _); + //~^ ERROR invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm + + asm!("", out("$f0") _); // ok + asm!("/* {} */", in(freg) f); + //[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f + asm!("/* {} */", out(freg) _); + //[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f + asm!("/* {} */", in(freg) d); + //[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f + asm!("/* {} */", out(freg) d); + //[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f + } +} diff --git a/tests/ui/asm/s390x/bad-reg.rs b/tests/ui/asm/s390x/bad-reg.rs index 6de43fdfe5eb0..144215b1a3d35 100644 --- a/tests/ui/asm/s390x/bad-reg.rs +++ b/tests/ui/asm/s390x/bad-reg.rs @@ -1,19 +1,31 @@ //@ add-core-stubs //@ needs-asm-support -//@ revisions: s390x +//@ revisions: s390x s390x_vector s390x_vector_stable //@[s390x] compile-flags: --target s390x-unknown-linux-gnu //@[s390x] needs-llvm-components: systemz +//@[s390x_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector +//@[s390x_vector] needs-llvm-components: systemz +//@[s390x_vector_stable] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector +//@[s390x_vector_stable] needs-llvm-components: systemz #![crate_type = "rlib"] -#![feature(no_core, rustc_attrs)] -#![feature(asm_experimental_arch)] +#![feature(no_core, rustc_attrs, repr_simd)] +#![cfg_attr(not(s390x_vector_stable), feature(asm_experimental_reg))] #![no_core] +#![allow(non_camel_case_types)] extern crate minicore; use minicore::*; +#[repr(simd)] +pub struct i64x2([i64; 2]); + +impl Copy for i64x2 {} + fn f() { let mut x = 0; + let mut b = 0u8; + let mut v = i64x2([0; 2]); unsafe { // Unsupported registers asm!("", out("r11") _); @@ -57,6 +69,51 @@ fn f() { asm!("", out("a1") _); //~^ ERROR invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm + // vreg + asm!("", out("v0") _); // always ok + asm!("", in("v0") v); // requires vector & asm_experimental_reg + //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature + //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] + //[s390x_vector_stable]~| ERROR type `i64x2` cannot be used with this register class in stable [E0658] + asm!("", out("v0") v); // requires vector & asm_experimental_reg + //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature + //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] + //[s390x_vector_stable]~| ERROR type `i64x2` cannot be used with this register class in stable [E0658] + asm!("", in("v0") x); // requires vector & asm_experimental_reg + //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature + //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] + //[s390x_vector_stable]~| ERROR type `i32` cannot be used with this register class in stable [E0658] + asm!("", out("v0") x); // requires vector & asm_experimental_reg + //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature + //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] + //[s390x_vector_stable]~| ERROR type `i32` cannot be used with this register class in stable [E0658] + asm!("", in("v0") b); + //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature + //[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class + //[s390x_vector_stable]~^^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] + //[s390x_vector_stable]~| ERROR type `u8` cannot be used with this register class + asm!("", out("v0") b); + //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature + //[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class + //[s390x_vector_stable]~^^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] + //[s390x_vector_stable]~| ERROR type `u8` cannot be used with this register class + asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg + //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature + //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] + //[s390x_vector_stable]~| ERROR type `i64x2` cannot be used with this register class in stable [E0658] + asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg + //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature + //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] + //[s390x_vector_stable]~| ERROR type `i32` cannot be used with this register class in stable [E0658] + asm!("/* {} */", in(vreg) b); + //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature + //[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class + //[s390x_vector_stable]~^^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] + //[s390x_vector_stable]~| ERROR type `u8` cannot be used with this register class + asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg + //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature + //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] + // Clobber-only registers // areg asm!("", out("a2") _); // ok @@ -72,21 +129,6 @@ fn f() { asm!("/* {} */", out(areg) _); //~^ ERROR can only be used as a clobber - // vreg - asm!("", out("v0") _); // ok - // FIXME: will be supported in https://github.com/rust-lang/rust/pull/131664 - asm!("", in("v0") x); - //~^ ERROR can only be used as a clobber - //~| ERROR type `i32` cannot be used with this register class - asm!("", out("v0") x); - //~^ ERROR can only be used as a clobber - //~| ERROR type `i32` cannot be used with this register class - asm!("/* {} */", in(vreg) x); - //~^ ERROR can only be used as a clobber - //~| ERROR type `i32` cannot be used with this register class - asm!("/* {} */", out(vreg) _); - //~^ ERROR can only be used as a clobber - // Overlapping registers // vreg/freg asm!("", out("v0") _, out("f0") _); diff --git a/tests/ui/asm/s390x/bad-reg.s390x.stderr b/tests/ui/asm/s390x/bad-reg.s390x.stderr index 460d7c15de114..238419b376b7f 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x.stderr @@ -1,173 +1,149 @@ error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:19:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:21:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:23:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:25:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:27:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:29:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:31:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:51:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:53:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:45:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:47:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:51:18 + --> $DIR/bad-reg.rs:63:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:65:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:67:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:69:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:120:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:66:18 + --> $DIR/bad-reg.rs:123:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:69:26 + --> $DIR/bad-reg.rs:126:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:72:26 + --> $DIR/bad-reg.rs:129:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:78:18 - | -LL | asm!("", in("v0") x); - | ^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:81:18 - | -LL | asm!("", out("v0") x); - | ^^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:84:26 - | -LL | asm!("/* {} */", in(vreg) x); - | ^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:87:26 - | -LL | asm!("/* {} */", out(vreg) _); - | ^^^^^^^^^^^ - error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:92:31 + --> $DIR/bad-reg.rs:134:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -175,7 +151,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:94:31 + --> $DIR/bad-reg.rs:136:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -183,7 +159,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:96:31 + --> $DIR/bad-reg.rs:138:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -191,7 +167,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:98:31 + --> $DIR/bad-reg.rs:140:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -199,7 +175,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:100:31 + --> $DIR/bad-reg.rs:142:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -207,7 +183,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:102:31 + --> $DIR/bad-reg.rs:144:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -215,7 +191,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:104:31 + --> $DIR/bad-reg.rs:146:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -223,7 +199,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:106:31 + --> $DIR/bad-reg.rs:148:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -231,7 +207,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:108:31 + --> $DIR/bad-reg.rs:150:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -239,7 +215,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:110:31 + --> $DIR/bad-reg.rs:152:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -247,7 +223,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:112:32 + --> $DIR/bad-reg.rs:154:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -255,7 +231,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:114:32 + --> $DIR/bad-reg.rs:156:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -263,7 +239,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:116:32 + --> $DIR/bad-reg.rs:158:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -271,7 +247,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:118:32 + --> $DIR/bad-reg.rs:160:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -279,7 +255,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:120:32 + --> $DIR/bad-reg.rs:162:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -287,7 +263,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:122:32 + --> $DIR/bad-reg.rs:164:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -295,58 +271,94 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:125:32 + --> $DIR/bad-reg.rs:167:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:63:27 +error: register class `vreg` requires the `vector` target feature + --> $DIR/bad-reg.rs:74:18 | -LL | asm!("", in("a2") x); - | ^ +LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg + | ^^^^^^^^^^ + +error: register class `vreg` requires the `vector` target feature + --> $DIR/bad-reg.rs:78:18 | - = note: register class `areg` supports these types: +LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg + | ^^^^^^^^^^^ -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:66:28 +error: register class `vreg` requires the `vector` target feature + --> $DIR/bad-reg.rs:82:18 | -LL | asm!("", out("a2") x); - | ^ +LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg + | ^^^^^^^^^^ + +error: register class `vreg` requires the `vector` target feature + --> $DIR/bad-reg.rs:86:18 | - = note: register class `areg` supports these types: +LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg + | ^^^^^^^^^^^ -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:69:35 +error: register class `vreg` requires the `vector` target feature + --> $DIR/bad-reg.rs:90:18 | -LL | asm!("/* {} */", in(areg) x); - | ^ +LL | asm!("", in("v0") b); + | ^^^^^^^^^^ + +error: register class `vreg` requires the `vector` target feature + --> $DIR/bad-reg.rs:95:18 | - = note: register class `areg` supports these types: +LL | asm!("", out("v0") b); + | ^^^^^^^^^^^ + +error: register class `vreg` requires the `vector` target feature + --> $DIR/bad-reg.rs:100:26 + | +LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg + | ^^^^^^^^^^ + +error: register class `vreg` requires the `vector` target feature + --> $DIR/bad-reg.rs:104:26 + | +LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg + | ^^^^^^^^^^ + +error: register class `vreg` requires the `vector` target feature + --> $DIR/bad-reg.rs:108:26 + | +LL | asm!("/* {} */", in(vreg) b); + | ^^^^^^^^^^ + +error: register class `vreg` requires the `vector` target feature + --> $DIR/bad-reg.rs:113:26 + | +LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg + | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:78:27 + --> $DIR/bad-reg.rs:120:27 | -LL | asm!("", in("v0") x); +LL | asm!("", in("a2") x); | ^ | - = note: register class `vreg` supports these types: + = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:81:28 + --> $DIR/bad-reg.rs:123:28 | -LL | asm!("", out("v0") x); +LL | asm!("", out("a2") x); | ^ | - = note: register class `vreg` supports these types: + = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:84:35 + --> $DIR/bad-reg.rs:126:35 | -LL | asm!("/* {} */", in(vreg) x); +LL | asm!("/* {} */", in(areg) x); | ^ | - = note: register class `vreg` supports these types: + = note: register class `areg` supports these types: -error: aborting due to 51 previous errors +error: aborting due to 54 previous errors diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr new file mode 100644 index 0000000000000..897f872ae72af --- /dev/null +++ b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr @@ -0,0 +1,328 @@ +error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:31:18 + | +LL | asm!("", out("r11") _); + | ^^^^^^^^^^^^ + +error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:33:18 + | +LL | asm!("", out("r15") _); + | ^^^^^^^^^^^^ + +error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:35:18 + | +LL | asm!("", out("c0") _); + | ^^^^^^^^^^^ + +error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:37:18 + | +LL | asm!("", out("c1") _); + | ^^^^^^^^^^^ + +error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:39:18 + | +LL | asm!("", out("c2") _); + | ^^^^^^^^^^^ + +error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:41:18 + | +LL | asm!("", out("c3") _); + | ^^^^^^^^^^^ + +error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:43:18 + | +LL | asm!("", out("c4") _); + | ^^^^^^^^^^^ + +error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:45:18 + | +LL | asm!("", out("c5") _); + | ^^^^^^^^^^^ + +error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:47:18 + | +LL | asm!("", out("c6") _); + | ^^^^^^^^^^^ + +error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:49:18 + | +LL | asm!("", out("c7") _); + | ^^^^^^^^^^^ + +error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:51:18 + | +LL | asm!("", out("c8") _); + | ^^^^^^^^^^^ + +error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:53:18 + | +LL | asm!("", out("c9") _); + | ^^^^^^^^^^^ + +error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:55:18 + | +LL | asm!("", out("c10") _); + | ^^^^^^^^^^^^ + +error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:57:18 + | +LL | asm!("", out("c11") _); + | ^^^^^^^^^^^^ + +error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:59:18 + | +LL | asm!("", out("c12") _); + | ^^^^^^^^^^^^ + +error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:61:18 + | +LL | asm!("", out("c13") _); + | ^^^^^^^^^^^^ + +error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:63:18 + | +LL | asm!("", out("c14") _); + | ^^^^^^^^^^^^ + +error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:65:18 + | +LL | asm!("", out("c15") _); + | ^^^^^^^^^^^^ + +error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:67:18 + | +LL | asm!("", out("a0") _); + | ^^^^^^^^^^^ + +error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:69:18 + | +LL | asm!("", out("a1") _); + | ^^^^^^^^^^^ + +error: register class `areg` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:120:18 + | +LL | asm!("", in("a2") x); + | ^^^^^^^^^^ + +error: register class `areg` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:123:18 + | +LL | asm!("", out("a2") x); + | ^^^^^^^^^^^ + +error: register class `areg` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:126:26 + | +LL | asm!("/* {} */", in(areg) x); + | ^^^^^^^^^^ + +error: register class `areg` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:129:26 + | +LL | asm!("/* {} */", out(areg) _); + | ^^^^^^^^^^^ + +error: register `f0` conflicts with register `v0` + --> $DIR/bad-reg.rs:134:31 + | +LL | asm!("", out("v0") _, out("f0") _); + | ----------- ^^^^^^^^^^^ register `f0` + | | + | register `v0` + +error: register `f1` conflicts with register `v1` + --> $DIR/bad-reg.rs:136:31 + | +LL | asm!("", out("v1") _, out("f1") _); + | ----------- ^^^^^^^^^^^ register `f1` + | | + | register `v1` + +error: register `f2` conflicts with register `v2` + --> $DIR/bad-reg.rs:138:31 + | +LL | asm!("", out("v2") _, out("f2") _); + | ----------- ^^^^^^^^^^^ register `f2` + | | + | register `v2` + +error: register `f3` conflicts with register `v3` + --> $DIR/bad-reg.rs:140:31 + | +LL | asm!("", out("v3") _, out("f3") _); + | ----------- ^^^^^^^^^^^ register `f3` + | | + | register `v3` + +error: register `f4` conflicts with register `v4` + --> $DIR/bad-reg.rs:142:31 + | +LL | asm!("", out("v4") _, out("f4") _); + | ----------- ^^^^^^^^^^^ register `f4` + | | + | register `v4` + +error: register `f5` conflicts with register `v5` + --> $DIR/bad-reg.rs:144:31 + | +LL | asm!("", out("v5") _, out("f5") _); + | ----------- ^^^^^^^^^^^ register `f5` + | | + | register `v5` + +error: register `f6` conflicts with register `v6` + --> $DIR/bad-reg.rs:146:31 + | +LL | asm!("", out("v6") _, out("f6") _); + | ----------- ^^^^^^^^^^^ register `f6` + | | + | register `v6` + +error: register `f7` conflicts with register `v7` + --> $DIR/bad-reg.rs:148:31 + | +LL | asm!("", out("v7") _, out("f7") _); + | ----------- ^^^^^^^^^^^ register `f7` + | | + | register `v7` + +error: register `f8` conflicts with register `v8` + --> $DIR/bad-reg.rs:150:31 + | +LL | asm!("", out("v8") _, out("f8") _); + | ----------- ^^^^^^^^^^^ register `f8` + | | + | register `v8` + +error: register `f9` conflicts with register `v9` + --> $DIR/bad-reg.rs:152:31 + | +LL | asm!("", out("v9") _, out("f9") _); + | ----------- ^^^^^^^^^^^ register `f9` + | | + | register `v9` + +error: register `f10` conflicts with register `v10` + --> $DIR/bad-reg.rs:154:32 + | +LL | asm!("", out("v10") _, out("f10") _); + | ------------ ^^^^^^^^^^^^ register `f10` + | | + | register `v10` + +error: register `f11` conflicts with register `v11` + --> $DIR/bad-reg.rs:156:32 + | +LL | asm!("", out("v11") _, out("f11") _); + | ------------ ^^^^^^^^^^^^ register `f11` + | | + | register `v11` + +error: register `f12` conflicts with register `v12` + --> $DIR/bad-reg.rs:158:32 + | +LL | asm!("", out("v12") _, out("f12") _); + | ------------ ^^^^^^^^^^^^ register `f12` + | | + | register `v12` + +error: register `f13` conflicts with register `v13` + --> $DIR/bad-reg.rs:160:32 + | +LL | asm!("", out("v13") _, out("f13") _); + | ------------ ^^^^^^^^^^^^ register `f13` + | | + | register `v13` + +error: register `f14` conflicts with register `v14` + --> $DIR/bad-reg.rs:162:32 + | +LL | asm!("", out("v14") _, out("f14") _); + | ------------ ^^^^^^^^^^^^ register `f14` + | | + | register `v14` + +error: register `f15` conflicts with register `v15` + --> $DIR/bad-reg.rs:164:32 + | +LL | asm!("", out("v15") _, out("f15") _); + | ------------ ^^^^^^^^^^^^ register `f15` + | | + | register `v15` + +error: invalid register `f16`: unknown register + --> $DIR/bad-reg.rs:167:32 + | +LL | asm!("", out("v16") _, out("f16") _); + | ^^^^^^^^^^^^ + +error: type `u8` cannot be used with this register class + --> $DIR/bad-reg.rs:90:27 + | +LL | asm!("", in("v0") b); + | ^ + | + = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + +error: type `u8` cannot be used with this register class + --> $DIR/bad-reg.rs:95:28 + | +LL | asm!("", out("v0") b); + | ^ + | + = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + +error: type `u8` cannot be used with this register class + --> $DIR/bad-reg.rs:108:35 + | +LL | asm!("/* {} */", in(vreg) b); + | ^ + | + = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:120:27 + | +LL | asm!("", in("a2") x); + | ^ + | + = note: register class `areg` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:123:28 + | +LL | asm!("", out("a2") x); + | ^ + | + = note: register class `areg` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:126:35 + | +LL | asm!("/* {} */", in(areg) x); + | ^ + | + = note: register class `areg` supports these types: + +error: aborting due to 47 previous errors + diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr new file mode 100644 index 0000000000000..e2b3eeef4e925 --- /dev/null +++ b/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr @@ -0,0 +1,489 @@ +error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:31:18 + | +LL | asm!("", out("r11") _); + | ^^^^^^^^^^^^ + +error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:33:18 + | +LL | asm!("", out("r15") _); + | ^^^^^^^^^^^^ + +error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:35:18 + | +LL | asm!("", out("c0") _); + | ^^^^^^^^^^^ + +error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:37:18 + | +LL | asm!("", out("c1") _); + | ^^^^^^^^^^^ + +error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:39:18 + | +LL | asm!("", out("c2") _); + | ^^^^^^^^^^^ + +error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:41:18 + | +LL | asm!("", out("c3") _); + | ^^^^^^^^^^^ + +error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:43:18 + | +LL | asm!("", out("c4") _); + | ^^^^^^^^^^^ + +error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:45:18 + | +LL | asm!("", out("c5") _); + | ^^^^^^^^^^^ + +error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:47:18 + | +LL | asm!("", out("c6") _); + | ^^^^^^^^^^^ + +error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:49:18 + | +LL | asm!("", out("c7") _); + | ^^^^^^^^^^^ + +error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:51:18 + | +LL | asm!("", out("c8") _); + | ^^^^^^^^^^^ + +error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:53:18 + | +LL | asm!("", out("c9") _); + | ^^^^^^^^^^^ + +error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:55:18 + | +LL | asm!("", out("c10") _); + | ^^^^^^^^^^^^ + +error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:57:18 + | +LL | asm!("", out("c11") _); + | ^^^^^^^^^^^^ + +error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:59:18 + | +LL | asm!("", out("c12") _); + | ^^^^^^^^^^^^ + +error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:61:18 + | +LL | asm!("", out("c13") _); + | ^^^^^^^^^^^^ + +error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:63:18 + | +LL | asm!("", out("c14") _); + | ^^^^^^^^^^^^ + +error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:65:18 + | +LL | asm!("", out("c15") _); + | ^^^^^^^^^^^^ + +error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:67:18 + | +LL | asm!("", out("a0") _); + | ^^^^^^^^^^^ + +error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm + --> $DIR/bad-reg.rs:69:18 + | +LL | asm!("", out("a1") _); + | ^^^^^^^^^^^ + +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:74:18 + | +LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:78:18 + | +LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg + | ^^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:82:18 + | +LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:86:18 + | +LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg + | ^^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:90:18 + | +LL | asm!("", in("v0") b); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:95:18 + | +LL | asm!("", out("v0") b); + | ^^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:100:26 + | +LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:104:26 + | +LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:108:26 + | +LL | asm!("/* {} */", in(vreg) b); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:113:26 + | +LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg + | ^^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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: register class `areg` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:120:18 + | +LL | asm!("", in("a2") x); + | ^^^^^^^^^^ + +error: register class `areg` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:123:18 + | +LL | asm!("", out("a2") x); + | ^^^^^^^^^^^ + +error: register class `areg` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:126:26 + | +LL | asm!("/* {} */", in(areg) x); + | ^^^^^^^^^^ + +error: register class `areg` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:129:26 + | +LL | asm!("/* {} */", out(areg) _); + | ^^^^^^^^^^^ + +error: register `f0` conflicts with register `v0` + --> $DIR/bad-reg.rs:134:31 + | +LL | asm!("", out("v0") _, out("f0") _); + | ----------- ^^^^^^^^^^^ register `f0` + | | + | register `v0` + +error: register `f1` conflicts with register `v1` + --> $DIR/bad-reg.rs:136:31 + | +LL | asm!("", out("v1") _, out("f1") _); + | ----------- ^^^^^^^^^^^ register `f1` + | | + | register `v1` + +error: register `f2` conflicts with register `v2` + --> $DIR/bad-reg.rs:138:31 + | +LL | asm!("", out("v2") _, out("f2") _); + | ----------- ^^^^^^^^^^^ register `f2` + | | + | register `v2` + +error: register `f3` conflicts with register `v3` + --> $DIR/bad-reg.rs:140:31 + | +LL | asm!("", out("v3") _, out("f3") _); + | ----------- ^^^^^^^^^^^ register `f3` + | | + | register `v3` + +error: register `f4` conflicts with register `v4` + --> $DIR/bad-reg.rs:142:31 + | +LL | asm!("", out("v4") _, out("f4") _); + | ----------- ^^^^^^^^^^^ register `f4` + | | + | register `v4` + +error: register `f5` conflicts with register `v5` + --> $DIR/bad-reg.rs:144:31 + | +LL | asm!("", out("v5") _, out("f5") _); + | ----------- ^^^^^^^^^^^ register `f5` + | | + | register `v5` + +error: register `f6` conflicts with register `v6` + --> $DIR/bad-reg.rs:146:31 + | +LL | asm!("", out("v6") _, out("f6") _); + | ----------- ^^^^^^^^^^^ register `f6` + | | + | register `v6` + +error: register `f7` conflicts with register `v7` + --> $DIR/bad-reg.rs:148:31 + | +LL | asm!("", out("v7") _, out("f7") _); + | ----------- ^^^^^^^^^^^ register `f7` + | | + | register `v7` + +error: register `f8` conflicts with register `v8` + --> $DIR/bad-reg.rs:150:31 + | +LL | asm!("", out("v8") _, out("f8") _); + | ----------- ^^^^^^^^^^^ register `f8` + | | + | register `v8` + +error: register `f9` conflicts with register `v9` + --> $DIR/bad-reg.rs:152:31 + | +LL | asm!("", out("v9") _, out("f9") _); + | ----------- ^^^^^^^^^^^ register `f9` + | | + | register `v9` + +error: register `f10` conflicts with register `v10` + --> $DIR/bad-reg.rs:154:32 + | +LL | asm!("", out("v10") _, out("f10") _); + | ------------ ^^^^^^^^^^^^ register `f10` + | | + | register `v10` + +error: register `f11` conflicts with register `v11` + --> $DIR/bad-reg.rs:156:32 + | +LL | asm!("", out("v11") _, out("f11") _); + | ------------ ^^^^^^^^^^^^ register `f11` + | | + | register `v11` + +error: register `f12` conflicts with register `v12` + --> $DIR/bad-reg.rs:158:32 + | +LL | asm!("", out("v12") _, out("f12") _); + | ------------ ^^^^^^^^^^^^ register `f12` + | | + | register `v12` + +error: register `f13` conflicts with register `v13` + --> $DIR/bad-reg.rs:160:32 + | +LL | asm!("", out("v13") _, out("f13") _); + | ------------ ^^^^^^^^^^^^ register `f13` + | | + | register `v13` + +error: register `f14` conflicts with register `v14` + --> $DIR/bad-reg.rs:162:32 + | +LL | asm!("", out("v14") _, out("f14") _); + | ------------ ^^^^^^^^^^^^ register `f14` + | | + | register `v14` + +error: register `f15` conflicts with register `v15` + --> $DIR/bad-reg.rs:164:32 + | +LL | asm!("", out("v15") _, out("f15") _); + | ------------ ^^^^^^^^^^^^ register `f15` + | | + | register `v15` + +error: invalid register `f16`: unknown register + --> $DIR/bad-reg.rs:167:32 + | +LL | asm!("", out("v16") _, out("f16") _); + | ^^^^^^^^^^^^ + +error[E0658]: type `i64x2` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:74:27 + | +LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: type `i64x2` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:78:28 + | +LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: type `i32` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:82:27 + | +LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: type `i32` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:86:28 + | +LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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: type `u8` cannot be used with this register class + --> $DIR/bad-reg.rs:90:27 + | +LL | asm!("", in("v0") b); + | ^ + | + = note: register class `vreg` supports these types: + +error: type `u8` cannot be used with this register class + --> $DIR/bad-reg.rs:95:28 + | +LL | asm!("", out("v0") b); + | ^ + | + = note: register class `vreg` supports these types: + +error[E0658]: type `i64x2` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:100:35 + | +LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: type `i32` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:104:35 + | +LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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: type `u8` cannot be used with this register class + --> $DIR/bad-reg.rs:108:35 + | +LL | asm!("/* {} */", in(vreg) b); + | ^ + | + = note: register class `vreg` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:120:27 + | +LL | asm!("", in("a2") x); + | ^ + | + = note: register class `areg` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:123:28 + | +LL | asm!("", out("a2") x); + | ^ + | + = note: register class `areg` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:126:35 + | +LL | asm!("/* {} */", in(areg) x); + | ^ + | + = note: register class `areg` supports these types: + +error: aborting due to 63 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/asm/x86_64/goto.rs b/tests/ui/asm/x86_64/goto.rs index 6c14bb57ac6e2..50e7441509ac2 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)] +#![feature(asm_goto, asm_goto_with_outputs)] use std::arch::asm; @@ -31,10 +31,6 @@ fn goto_jump() { } } -// asm goto with outputs cause miscompilation in LLVM. UB can be triggered -// when outputs are used inside the label block when optimisation is enabled. -// See: https://github.com/llvm/llvm-project/issues/74483 -/* fn goto_out_fallthrough() { unsafe { let mut out: usize; @@ -68,7 +64,57 @@ fn goto_out_jump() { assert!(value); } } -*/ + +fn goto_out_jump_noreturn() { + unsafe { + let mut value = false; + let mut out: usize; + asm!( + "lea {}, [{} + 1]", + "jmp {}", + out(reg) out, + in(reg) 0x12345678usize, + label { + value = true; + assert_eq!(out, 0x12345679); + }, + options(noreturn) + ); + assert!(value); + } +} + +// asm goto with outputs cause miscompilation in LLVM when multiple outputs are present. +// The code sample below is adapted from https://github.com/llvm/llvm-project/issues/74483 +// and does not work with `-C opt-level=0` +#[expect(unused)] +fn goto_multi_out() { + #[inline(never)] + #[allow(unused)] + fn goto_multi_out(a: usize, b: usize) -> usize { + let mut x: usize; + let mut y: usize; + let mut z: usize; + unsafe { + core::arch::asm!( + "mov {x}, {a}", + "test {a}, {a}", + "jnz {label1}", + "/* {y} {z} {b} {label2} */", + x = out(reg) x, + y = out(reg) y, + z = out(reg) z, + a = in(reg) a, + b = in(reg) b, + label1 = label { return x }, + label2 = label { return 1 }, + ); + 0 + } + } + + assert_eq!(goto_multi_out(11, 22), 11); +} fn goto_noreturn() { unsafe { @@ -102,8 +148,10 @@ fn goto_noreturn_diverge() { fn main() { goto_fallthough(); goto_jump(); - // goto_out_fallthrough(); - // goto_out_jump(); + goto_out_fallthrough(); + goto_out_jump(); + goto_out_jump_noreturn(); + // goto_multi_out(); goto_noreturn(); goto_noreturn_diverge(); } diff --git a/tests/ui/asm/x86_64/goto.stderr b/tests/ui/asm/x86_64/goto.stderr index 27e227d71a5f5..8f89e2b129081 100644 --- a/tests/ui/asm/x86_64/goto.stderr +++ b/tests/ui/asm/x86_64/goto.stderr @@ -1,5 +1,5 @@ warning: unreachable statement - --> $DIR/goto.rs:97:9 + --> $DIR/goto.rs:143:9 | LL | / asm!( LL | | "jmp {}", @@ -13,7 +13,7 @@ LL | unreachable!(); | ^^^^^^^^^^^^^^ unreachable statement | note: the lint level is defined here - --> $DIR/goto.rs:87:8 + --> $DIR/goto.rs:133:8 | LL | #[warn(unreachable_code)] | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.rs b/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.rs index 8fe79b97d9ba2..977ef604b341b 100644 --- a/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.rs +++ b/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.rs @@ -15,6 +15,7 @@ impl Foo for Def { pub fn test() { let _array = [4; ::Y]; //~^ ERROR constant expression depends on a generic parameter + //~| ERROR constant expression depends on a generic parameter } fn main() { diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr b/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr index cd83039428567..8202342c65daf 100644 --- a/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr +++ b/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr @@ -6,5 +6,13 @@ LL | let _array = [4; ::Y]; | = note: this may fail depending on what value the parameter takes -error: aborting due to 1 previous error +error: constant expression depends on a generic parameter + --> $DIR/associated-const-type-parameter-arrays-2.rs:16:18 + | +LL | let _array = [4; ::Y]; + | ^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 2 previous errors diff --git a/tests/ui/associated-types/associated-types-binding-in-where-clause.rs b/tests/ui/associated-types/associated-types-binding-in-where-clause.rs index ed2cebb5f7e87..b82656945a256 100644 --- a/tests/ui/associated-types/associated-types-binding-in-where-clause.rs +++ b/tests/ui/associated-types/associated-types-binding-in-where-clause.rs @@ -1,7 +1,6 @@ //@ run-pass // Test equality constraints on associated types in a where clause. -//@ pretty-expanded FIXME #23616 pub trait Foo { type A; diff --git a/tests/ui/associated-types/associated-types-conditional-dispatch.rs b/tests/ui/associated-types/associated-types-conditional-dispatch.rs index d30ea66e9b97f..3ec835ccbc3ac 100644 --- a/tests/ui/associated-types/associated-types-conditional-dispatch.rs +++ b/tests/ui/associated-types/associated-types-conditional-dispatch.rs @@ -5,7 +5,6 @@ // `Target=[A]`, then the impl marked with `(*)` is seen to conflict // with all the others. -//@ pretty-expanded FIXME #23616 use std::marker::PhantomData; use std::ops::Deref; diff --git a/tests/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs b/tests/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs index e2c13716a6948..9bf7570534c50 100644 --- a/tests/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs +++ b/tests/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs @@ -4,7 +4,6 @@ // (modulo bound lifetime names) appears in the environment // twice. Issue #21965. -//@ pretty-expanded FIXME #23616 fn foo(t: T) -> i32 where T : for<'a> Fn(&'a u8) -> i32, diff --git a/tests/ui/associated-types/associated-types-duplicate-binding-in-env.rs b/tests/ui/associated-types/associated-types-duplicate-binding-in-env.rs index d1ff4b222b789..44c5634f4ef8a 100644 --- a/tests/ui/associated-types/associated-types-duplicate-binding-in-env.rs +++ b/tests/ui/associated-types/associated-types-duplicate-binding-in-env.rs @@ -3,7 +3,6 @@ // Check that we do not report ambiguities when the same predicate // appears in the environment twice. Issue #21965. -//@ pretty-expanded FIXME #23616 trait Foo { type B; diff --git a/tests/ui/associated-types/associated-types-eq-obj.rs b/tests/ui/associated-types/associated-types-eq-obj.rs index 1236d770b95c7..c1ca8bbd7393c 100644 --- a/tests/ui/associated-types/associated-types-eq-obj.rs +++ b/tests/ui/associated-types/associated-types-eq-obj.rs @@ -1,7 +1,6 @@ //@ run-pass // Test equality constraints on associated types inside of an object type -//@ pretty-expanded FIXME #23616 pub trait Foo { type A; diff --git a/tests/ui/associated-types/associated-types-issue-20371.rs b/tests/ui/associated-types/associated-types-issue-20371.rs index 32fe1ca1c00af..d2e056a57b218 100644 --- a/tests/ui/associated-types/associated-types-issue-20371.rs +++ b/tests/ui/associated-types/associated-types-issue-20371.rs @@ -2,7 +2,6 @@ // Test that we are able to have an impl that defines an associated type // before the actual trait. -//@ pretty-expanded FIXME #23616 impl X for f64 { type Y = isize; } trait X { type Y; } diff --git a/tests/ui/associated-types/associated-types-nested-projections.rs b/tests/ui/associated-types/associated-types-nested-projections.rs index 90ff170a6a711..659016b4644b7 100644 --- a/tests/ui/associated-types/associated-types-nested-projections.rs +++ b/tests/ui/associated-types/associated-types-nested-projections.rs @@ -2,7 +2,6 @@ #![allow(unused_variables)] // Test that we can resolve nested projection types. Issue #20666. -//@ pretty-expanded FIXME #23616 use std::slice; diff --git a/tests/ui/associated-types/associated-types-nested-projections.stderr b/tests/ui/associated-types/associated-types-nested-projections.stderr index 97d5a7585736c..1b69fcfacf52e 100644 --- a/tests/ui/associated-types/associated-types-nested-projections.stderr +++ b/tests/ui/associated-types/associated-types-nested-projections.stderr @@ -1,5 +1,5 @@ warning: method `into_iter` is never used - --> $DIR/associated-types-nested-projections.rs:16:8 + --> $DIR/associated-types-nested-projections.rs:15:8 | LL | trait IntoIterator { | ------------ method in this trait diff --git a/tests/ui/associated-types/associated-types-normalize-in-bounds-binding.rs b/tests/ui/associated-types/associated-types-normalize-in-bounds-binding.rs index bd9b91b002eec..a6e426df1c920 100644 --- a/tests/ui/associated-types/associated-types-normalize-in-bounds-binding.rs +++ b/tests/ui/associated-types/associated-types-normalize-in-bounds-binding.rs @@ -3,7 +3,6 @@ // Test that we normalize associated types that appear in a bound that // contains a binding. Issue #21664. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs b/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs index 884b1a17a2cbc..f15de0d9a2898 100644 --- a/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs +++ b/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs @@ -3,7 +3,6 @@ // Test that we normalize associated types that appear in bounds; if // we didn't, the call to `self.split2()` fails to type check. -//@ pretty-expanded FIXME #23616 use std::marker::PhantomData; diff --git a/tests/ui/associated-types/associated-types-normalize-in-bounds.rs b/tests/ui/associated-types/associated-types-normalize-in-bounds.rs index 8da60e1d9cba0..7e94d3a011f55 100644 --- a/tests/ui/associated-types/associated-types-normalize-in-bounds.rs +++ b/tests/ui/associated-types/associated-types-normalize-in-bounds.rs @@ -3,7 +3,6 @@ // Test that we normalize associated types that appear in bounds; if // we didn't, the call to `self.split2()` fails to type check. -//@ pretty-expanded FIXME #23616 use std::marker::PhantomData; diff --git a/tests/ui/associated-types/associated-types-projection-in-object-type.rs b/tests/ui/associated-types/associated-types-projection-in-object-type.rs index 4cf1c256f3d3f..d5d7a294dfd79 100644 --- a/tests/ui/associated-types/associated-types-projection-in-object-type.rs +++ b/tests/ui/associated-types/associated-types-projection-in-object-type.rs @@ -6,7 +6,6 @@ // appear in associated type bindings in object types, which were not // being properly flagged. -//@ pretty-expanded FIXME #23616 use std::ops::{Shl, Shr}; use std::cell::RefCell; diff --git a/tests/ui/associated-types/associated-types-projection-in-where-clause.rs b/tests/ui/associated-types/associated-types-projection-in-where-clause.rs index ed8259396d11b..6f4ee8bf17772 100644 --- a/tests/ui/associated-types/associated-types-projection-in-where-clause.rs +++ b/tests/ui/associated-types/associated-types-projection-in-where-clause.rs @@ -3,7 +3,6 @@ #![allow(unused_variables)] // Test a where clause that uses a non-normalized projection type. -//@ pretty-expanded FIXME #23616 trait Int { diff --git a/tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs b/tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs index f0a3432519646..c2550c930d3b1 100644 --- a/tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs +++ b/tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait Foo { type Bar; diff --git a/tests/ui/associated-types/associated-types-ref-from-struct.rs b/tests/ui/associated-types/associated-types-ref-from-struct.rs index c16bb8651c3c7..bdff76e86a3e2 100644 --- a/tests/ui/associated-types/associated-types-ref-from-struct.rs +++ b/tests/ui/associated-types/associated-types-ref-from-struct.rs @@ -1,7 +1,6 @@ //@ run-pass // Test associated type references in structure fields. -//@ pretty-expanded FIXME #23616 trait Test { type V; diff --git a/tests/ui/associated-types/associated-types-region-erasure-issue-20582.rs b/tests/ui/associated-types/associated-types-region-erasure-issue-20582.rs index dec3a3c924563..7c556005f2d5c 100644 --- a/tests/ui/associated-types/associated-types-region-erasure-issue-20582.rs +++ b/tests/ui/associated-types/associated-types-region-erasure-issue-20582.rs @@ -3,7 +3,6 @@ // Regression test for #20582. This test caused an ICE related to // inconsistent region erasure in codegen. -//@ pretty-expanded FIXME #23616 struct Foo<'a> { buf: &'a[u8] diff --git a/tests/ui/associated-types/associated-types-resolve-lifetime.rs b/tests/ui/associated-types/associated-types-resolve-lifetime.rs index 6be2fa6f2ab49..a75488cf8436c 100644 --- a/tests/ui/associated-types/associated-types-resolve-lifetime.rs +++ b/tests/ui/associated-types/associated-types-resolve-lifetime.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait Get { fn get(&self) -> T; diff --git a/tests/ui/associated-types/issue-19129-1.rs b/tests/ui/associated-types/issue-19129-1.rs index 65340b413e9c5..e4d8082c05a70 100644 --- a/tests/ui/associated-types/issue-19129-1.rs +++ b/tests/ui/associated-types/issue-19129-1.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait Trait { type Output; diff --git a/tests/ui/associated-types/issue-19129-2.rs b/tests/ui/associated-types/issue-19129-2.rs index 6562c54b0b7c2..15e73bfc53236 100644 --- a/tests/ui/associated-types/issue-19129-2.rs +++ b/tests/ui/associated-types/issue-19129-2.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 trait Trait { type Output; diff --git a/tests/ui/associated-types/issue-20763-1.rs b/tests/ui/associated-types/issue-20763-1.rs index ea2e696767da7..0abd2317fa9d9 100644 --- a/tests/ui/associated-types/issue-20763-1.rs +++ b/tests/ui/associated-types/issue-20763-1.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 trait T0 { type O; diff --git a/tests/ui/associated-types/issue-20763-2.rs b/tests/ui/associated-types/issue-20763-2.rs index 149bfcb8c99a9..9e7f3e15fe08b 100644 --- a/tests/ui/associated-types/issue-20763-2.rs +++ b/tests/ui/associated-types/issue-20763-2.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 trait T0 { type O; diff --git a/tests/ui/associated-types/issue-21363.rs b/tests/ui/associated-types/issue-21363.rs index 0dcebafd95b05..96d4c20234911 100644 --- a/tests/ui/associated-types/issue-21363.rs +++ b/tests/ui/associated-types/issue-21363.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 #![no_implicit_prelude] diff --git a/tests/ui/associated-types/issue-21726.rs b/tests/ui/associated-types/issue-21726.rs index f014c64478630..9611423b9f036 100644 --- a/tests/ui/associated-types/issue-21726.rs +++ b/tests/ui/associated-types/issue-21726.rs @@ -4,7 +4,6 @@ // subtyping of projection types that resulted in an unconstrained // region, yielding region inference failures. -//@ pretty-expanded FIXME #23616 fn main() { } diff --git a/tests/ui/associated-types/issue-22560.rs b/tests/ui/associated-types/issue-22560.rs index 44be8817b08c7..465aea515eef5 100644 --- a/tests/ui/associated-types/issue-22560.rs +++ b/tests/ui/associated-types/issue-22560.rs @@ -7,9 +7,6 @@ trait Sub { } type Test = dyn Add + Sub; -//~^ ERROR E0393 -//~| ERROR E0191 -//~| ERROR E0393 -//~| ERROR E0225 +//~^ ERROR E0225 fn main() { } diff --git a/tests/ui/associated-types/issue-22560.stderr b/tests/ui/associated-types/issue-22560.stderr index 834040490f940..d0b6adc520c7e 100644 --- a/tests/ui/associated-types/issue-22560.stderr +++ b/tests/ui/associated-types/issue-22560.stderr @@ -9,56 +9,6 @@ LL | type Test = dyn Add + Sub; = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add + Sub {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit -error[E0191]: the value of the associated types `Output` in `Add`, `Output` in `Sub` must be specified - --> $DIR/issue-22560.rs:9:17 - | -LL | type Output; - | ----------- `Output` defined here -... -LL | type Output; - | ----------- `Output` defined here -... -LL | type Test = dyn Add + Sub; - | ^^^ ^^^ associated type `Output` must be specified - | | - | associated type `Output` must be specified - | -help: specify the associated types - | -LL | type Test = dyn Add + Sub; - | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ - -error[E0393]: the type parameter `Rhs` must be explicitly specified - --> $DIR/issue-22560.rs:9:17 - | -LL | trait Add { - | ------------------- type parameter `Rhs` must be specified for this -... -LL | type Test = dyn Add + Sub; - | ^^^ - | - = note: because of the default `Self` reference, type parameters must be specified on object types -help: set the type parameter to the desired type - | -LL | type Test = dyn Add + Sub; - | +++++ - -error[E0393]: the type parameter `Rhs` must be explicitly specified - --> $DIR/issue-22560.rs:9:23 - | -LL | trait Sub { - | ------------------- type parameter `Rhs` must be specified for this -... -LL | type Test = dyn Add + Sub; - | ^^^ - | - = note: because of the default `Self` reference, type parameters must be specified on object types -help: set the type parameter to the desired type - | -LL | type Test = dyn Add + Sub; - | +++++ - -error: aborting due to 4 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0191, E0225, E0393. -For more information about an error, try `rustc --explain E0191`. +For more information about this error, try `rustc --explain E0225`. diff --git a/tests/ui/associated-types/issue-22828.rs b/tests/ui/associated-types/issue-22828.rs index 2f65f1c230386..5624b9c693b54 100644 --- a/tests/ui/associated-types/issue-22828.rs +++ b/tests/ui/associated-types/issue-22828.rs @@ -3,7 +3,6 @@ // Test transitive analysis for associated types. Collected types // should be normalized and new obligations generated. -//@ pretty-expanded FIXME #23616 trait Foo { type A; diff --git a/tests/ui/associated-types/missing-associated-types.rs b/tests/ui/associated-types/missing-associated-types.rs index 3c8410e39bd09..4e532715f1e27 100644 --- a/tests/ui/associated-types/missing-associated-types.rs +++ b/tests/ui/associated-types/missing-associated-types.rs @@ -11,16 +11,12 @@ trait Fine: Div {} type Foo = dyn Add + Sub + X + Y; //~^ ERROR only auto traits can be used as additional traits in a trait object -//~| ERROR the value of the associated types type Bar = dyn Add + Sub + X + Z; //~^ ERROR only auto traits can be used as additional traits in a trait object -//~| ERROR the value of the associated types type Baz = dyn Add + Sub + Y; //~^ ERROR only auto traits can be used as additional traits in a trait object -//~| ERROR the value of the associated types type Bat = dyn Add + Sub + Fine; //~^ ERROR only auto traits can be used as additional traits in a trait object -//~| ERROR the value of the associated types type Bal = dyn X; //~^ ERROR the value of the associated types diff --git a/tests/ui/associated-types/missing-associated-types.stderr b/tests/ui/associated-types/missing-associated-types.stderr index 0636667ea1fd5..ce4b57e8af813 100644 --- a/tests/ui/associated-types/missing-associated-types.stderr +++ b/tests/ui/associated-types/missing-associated-types.stderr @@ -9,26 +9,8 @@ LL | type Foo = dyn Add + Sub + X + Y; = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add + Sub + X + Y {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit -error[E0191]: the value of the associated types `A` in `Y`, `Output` in `Add`, `Output` in `Mul`, `Output` in `Sub` must be specified - --> $DIR/missing-associated-types.rs:12:21 - | -LL | type A; - | ------ `A` defined here -... -LL | type Foo = dyn Add + Sub + X + Y; - | ^^^^^^^^ ^^^^^^^^ ^^^^^^ ^^^^^^ associated type `A` must be specified - | | | | - | | | associated type `Output` must be specified - | | associated type `Output` must be specified - | associated type `Output` must be specified - | -help: specify the associated types - | -LL | type Foo = dyn Add + Sub + X + Y; - | ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ - error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/missing-associated-types.rs:15:32 + --> $DIR/missing-associated-types.rs:14:32 | LL | type Bar = dyn Add + Sub + X + Z; | -------- ^^^^^^^^ additional non-auto trait @@ -38,33 +20,8 @@ LL | type Bar = dyn Add + Sub + X + Z; = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add + Sub + X + Z {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit -error[E0191]: the value of the associated types `A` and `B` in `Z`, `Output` and `Output` in `Div`, `Output` in `Add`, `Output` in `Mul`, `Output` in `Sub` must be specified - --> $DIR/missing-associated-types.rs:15:21 - | -LL | type A; - | ------ `A` defined here -LL | type B; - | ------ `B` defined here -... -LL | type Bar = dyn Add + Sub + X + Z; - | ^^^^^^^^ ^^^^^^^^ ^^^^^^ ^^^^^^ associated types `A`, `B`, `Output` must be specified - | | | | - | | | associated types `Output` (from trait `Div`), `Output` (from trait `Mul`) must be specified - | | associated type `Output` must be specified - | associated type `Output` must be specified - | -help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated types - --> $DIR/missing-associated-types.rs:15:43 - | -LL | type Bar = dyn Add + Sub + X + Z; - | ^^^^^^ -help: specify the associated types - | -LL | type Bar = dyn Add + Sub + X + Z; - | ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/missing-associated-types.rs:18:32 + --> $DIR/missing-associated-types.rs:16:32 | LL | type Baz = dyn Add + Sub + Y; | -------- ^^^^^^^^ additional non-auto trait @@ -74,25 +31,8 @@ LL | type Baz = dyn Add + Sub + Y; = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add + Sub + Y {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit -error[E0191]: the value of the associated types `A` in `Y`, `Output` in `Add`, `Output` in `Sub` must be specified - --> $DIR/missing-associated-types.rs:18:21 - | -LL | type A; - | ------ `A` defined here -... -LL | type Baz = dyn Add + Sub + Y; - | ^^^^^^^^ ^^^^^^^^ ^^^^^^ associated type `A` must be specified - | | | - | | associated type `Output` must be specified - | associated type `Output` must be specified - | -help: specify the associated types - | -LL | type Baz = dyn Add + Sub + Y; - | ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ - error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/missing-associated-types.rs:21:32 + --> $DIR/missing-associated-types.rs:18:32 | LL | type Bat = dyn Add + Sub + Fine; | -------- ^^^^^^^^ additional non-auto trait @@ -102,28 +42,15 @@ LL | type Bat = dyn Add + Sub + Fine; = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add + Sub + Fine {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit -error[E0191]: the value of the associated types `Output` in `Add`, `Output` in `Sub` must be specified - --> $DIR/missing-associated-types.rs:21:21 - | -LL | type Bat = dyn Add + Sub + Fine; - | ^^^^^^^^ ^^^^^^^^ associated type `Output` must be specified - | | - | associated type `Output` must be specified - | -help: specify the associated types - | -LL | type Bat = dyn Add + Sub + Fine; - | ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ - error[E0191]: the value of the associated types `Output` in `Div`, `Output` in `Mul` must be specified - --> $DIR/missing-associated-types.rs:24:21 + --> $DIR/missing-associated-types.rs:20:21 | LL | type Bal = dyn X; | ^^^^^^ associated types `Output` (from trait `Div`), `Output` (from trait `Mul`) must be specified | = help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated types -error: aborting due to 9 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0191, E0225. For more information about an error, try `rustc --explain E0191`. diff --git a/tests/ui/async-await/async-closures/fn-exception-target-features.stderr b/tests/ui/async-await/async-closures/fn-exception-target-features.stderr index 396167f407055..e965c40fb5b86 100644 --- a/tests/ui/async-await/async-closures/fn-exception-target-features.stderr +++ b/tests/ui/async-await/async-closures/fn-exception-target-features.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `fn() -> Pin + 'static)>> {target_feature}: AsyncFn<()>` is not satisfied +error[E0277]: the trait bound `fn() -> Pin + 'static)>> {target_feature}: AsyncFn()` is not satisfied --> $DIR/fn-exception-target-features.rs:16:10 | LL | test(target_feature); - | ---- ^^^^^^^^^^^^^^ the trait `AsyncFn<()>` is not implemented for fn item `fn() -> Pin + 'static)>> {target_feature}` + | ---- ^^^^^^^^^^^^^^ the trait `AsyncFn()` is not implemented for fn item `fn() -> Pin + 'static)>> {target_feature}` | | | required by a bound introduced by this call | diff --git a/tests/ui/async-await/async-closures/fn-exception.stderr b/tests/ui/async-await/async-closures/fn-exception.stderr index bacd079af0f2d..20132e428332a 100644 --- a/tests/ui/async-await/async-closures/fn-exception.stderr +++ b/tests/ui/async-await/async-closures/fn-exception.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `unsafe fn() -> Pin + 'static)>> {unsafety}: AsyncFn<()>` is not satisfied +error[E0277]: the trait bound `unsafe fn() -> Pin + 'static)>> {unsafety}: AsyncFn()` is not satisfied --> $DIR/fn-exception.rs:19:10 | LL | test(unsafety); - | ---- ^^^^^^^^ the trait `AsyncFn<()>` is not implemented for fn item `unsafe fn() -> Pin + 'static)>> {unsafety}` + | ---- ^^^^^^^^ the trait `AsyncFn()` is not implemented for fn item `unsafe fn() -> Pin + 'static)>> {unsafety}` | | | required by a bound introduced by this call | @@ -12,11 +12,11 @@ note: required by a bound in `test` LL | fn test(f: impl async Fn()) {} | ^^^^^^^^^^ required by this bound in `test` -error[E0277]: the trait bound `extern "C" fn() -> Pin + 'static)>> {abi}: AsyncFn<()>` is not satisfied +error[E0277]: the trait bound `extern "C" fn() -> Pin + 'static)>> {abi}: AsyncFn()` is not satisfied --> $DIR/fn-exception.rs:20:10 | LL | test(abi); - | ---- ^^^ the trait `AsyncFn<()>` is not implemented for fn item `extern "C" fn() -> Pin + 'static)>> {abi}` + | ---- ^^^ the trait `AsyncFn()` is not implemented for fn item `extern "C" fn() -> Pin + 'static)>> {abi}` | | | required by a bound introduced by this call | diff --git a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs new file mode 100644 index 0000000000000..2e7cf1b09fd00 --- /dev/null +++ b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs @@ -0,0 +1,14 @@ +//@ edition: 2021 + +#![feature(async_closure)] + +use std::ops::AsyncFnMut; + +fn produce() -> impl AsyncFnMut() -> &'static str { + async || "" +} + +fn main() { + let x: i32 = produce(); + //~^ ERROR mismatched types +} diff --git a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr new file mode 100644 index 0000000000000..863e61eb35ad4 --- /dev/null +++ b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/pretty-async-fn-opaque.rs:12:18 + | +LL | fn produce() -> impl AsyncFnMut() -> &'static str { + | --------------------------------- the found opaque type +... +LL | let x: i32 = produce(); + | --- ^^^^^^^^^ expected `i32`, found opaque type + | | + | expected due to this + | + = note: expected type `i32` + found opaque type `impl AsyncFnMut() -> &'static str` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/async-await/async-fn/edition-2015.stderr b/tests/ui/async-await/async-fn/edition-2015.stderr index 25101cb65df51..9fbceafd75d7a 100644 --- a/tests/ui/async-await/async-fn/edition-2015.stderr +++ b/tests/ui/async-await/async-fn/edition-2015.stderr @@ -4,7 +4,7 @@ error: `async` trait bounds are only allowed in Rust 2018 or later LL | fn foo(x: impl async Fn()) -> impl async Fn() { x } | ^^^^^ | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error: `async` trait bounds are only allowed in Rust 2018 or later @@ -13,7 +13,7 @@ error: `async` trait bounds are only allowed in Rust 2018 or later LL | fn foo(x: impl async Fn()) -> impl async Fn() { x } | ^^^^^ | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0658]: async closures are unstable diff --git a/tests/ui/async-await/coroutine-desc.stderr b/tests/ui/async-await/coroutine-desc.stderr index e1d7898478e0a..5434ff3d958f8 100644 --- a/tests/ui/async-await/coroutine-desc.stderr +++ b/tests/ui/async-await/coroutine-desc.stderr @@ -19,7 +19,7 @@ LL | fn fun>(f1: F, f2: F) {} | ^^^ - ----- ----- this parameter needs to match the `async` block type of `f1` | | | | | `f2` needs to match the `async` block type of this parameter - | `f1` and `f2` all reference this parameter F + | `f1` and `f2` both reference this parameter `F` error[E0308]: mismatched types --> $DIR/coroutine-desc.rs:12:16 @@ -39,7 +39,7 @@ LL | fn fun>(f1: F, f2: F) {} | ^^^ - ----- ----- this parameter needs to match the future type of `f1` | | | | | `f2` needs to match the future type of this parameter - | `f1` and `f2` all reference this parameter F + | `f1` and `f2` both reference this parameter `F` error[E0308]: mismatched types --> $DIR/coroutine-desc.rs:14:26 @@ -62,7 +62,7 @@ LL | fn fun>(f1: F, f2: F) {} | ^^^ - ----- ----- this parameter needs to match the `async` closure body type of `f1` | | | | | `f2` needs to match the `async` closure body type of this parameter - | `f1` and `f2` all reference this parameter F + | `f1` and `f2` both reference this parameter `F` error: aborting due to 3 previous errors diff --git a/tests/ui/async-await/edition-deny-async-fns-2015.stderr b/tests/ui/async-await/edition-deny-async-fns-2015.stderr index c40cdc5acec12..f39ec033e7068 100644 --- a/tests/ui/async-await/edition-deny-async-fns-2015.stderr +++ b/tests/ui/async-await/edition-deny-async-fns-2015.stderr @@ -4,7 +4,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015 LL | async fn foo() {} | ^^^^^ to use `async fn`, switch to Rust 2018 or later | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0670]: `async fn` is not permitted in Rust 2015 @@ -13,7 +13,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015 LL | fn baz() { async fn foo() {} } | ^^^^^ to use `async fn`, switch to Rust 2018 or later | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0670]: `async fn` is not permitted in Rust 2015 @@ -22,7 +22,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015 LL | async fn async_baz() { | ^^^^^ to use `async fn`, switch to Rust 2018 or later | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0670]: `async fn` is not permitted in Rust 2015 @@ -31,7 +31,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015 LL | async fn bar() {} | ^^^^^ to use `async fn`, switch to Rust 2018 or later | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0670]: `async fn` is not permitted in Rust 2015 @@ -40,7 +40,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015 LL | async fn foo() {} | ^^^^^ to use `async fn`, switch to Rust 2018 or later | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0670]: `async fn` is not permitted in Rust 2015 @@ -49,7 +49,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015 LL | async fn foo() {} | ^^^^^ to use `async fn`, switch to Rust 2018 or later | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0670]: `async fn` is not permitted in Rust 2015 @@ -58,7 +58,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015 LL | async fn bar() {} | ^^^^^ to use `async fn`, switch to Rust 2018 or later | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0670]: `async fn` is not permitted in Rust 2015 @@ -67,7 +67,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015 LL | async fn foo() {} | ^^^^^ to use `async fn`, switch to Rust 2018 or later | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0670]: `async fn` is not permitted in Rust 2015 @@ -76,7 +76,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015 LL | async fn bar() {} | ^^^^^ to use `async fn`, switch to Rust 2018 or later | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error: aborting due to 9 previous errors diff --git a/tests/ui/async-await/for-await-passthrough.rs b/tests/ui/async-await/for-await-passthrough.rs index b4fba6b2f7653..1918e2f61aa81 100644 --- a/tests/ui/async-await/for-await-passthrough.rs +++ b/tests/ui/async-await/for-await-passthrough.rs @@ -1,6 +1,5 @@ //@ run-pass //@ edition: 2024 -//@ compile-flags: -Zunstable-options #![feature(async_iterator, async_iter_from_iter, async_for_loop, noop_waker, gen_blocks)] diff --git a/tests/ui/async-await/issues/auxiliary/issue-60674.rs b/tests/ui/async-await/issues/auxiliary/issue-60674.rs index da11142a3a4ac..a22f90e951684 100644 --- a/tests/ui/async-await/issues/auxiliary/issue-60674.rs +++ b/tests/ui/async-await/issues/auxiliary/issue-60674.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/async-await/issues/issue-60674.rs b/tests/ui/async-await/issues/issue-60674.rs index 9def3552e6773..d04fa23840e61 100644 --- a/tests/ui/async-await/issues/issue-60674.rs +++ b/tests/ui/async-await/issues/issue-60674.rs @@ -1,4 +1,4 @@ -//@ aux-build:issue-60674.rs +//@ proc-macro: issue-60674.rs //@ build-pass (FIXME(62277): could be check-pass?) //@ edition:2018 diff --git a/tests/ui/async-await/pin-ergonomics/coerce-non-pointer-pin.rs b/tests/ui/async-await/pin-ergonomics/coerce-non-pointer-pin.rs new file mode 100644 index 0000000000000..a95665f126d1e --- /dev/null +++ b/tests/ui/async-await/pin-ergonomics/coerce-non-pointer-pin.rs @@ -0,0 +1,10 @@ +//@ check-pass + +#![feature(pin_ergonomics)] +//~^ WARN the feature `pin_ergonomics` is incomplete + +use std::pin::Pin; + +fn main() { + let _: Pin> = Box::pin(()); +} diff --git a/tests/ui/async-await/pin-ergonomics/coerce-non-pointer-pin.stderr b/tests/ui/async-await/pin-ergonomics/coerce-non-pointer-pin.stderr new file mode 100644 index 0000000000000..2deb5b09884c3 --- /dev/null +++ b/tests/ui/async-await/pin-ergonomics/coerce-non-pointer-pin.stderr @@ -0,0 +1,11 @@ +warning: the feature `pin_ergonomics` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/coerce-non-pointer-pin.rs:3:12 + | +LL | #![feature(pin_ergonomics)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #130494 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/async-await/pin-reborrow-arg.rs b/tests/ui/async-await/pin-ergonomics/reborrow-arg.rs similarity index 100% rename from tests/ui/async-await/pin-reborrow-arg.rs rename to tests/ui/async-await/pin-ergonomics/reborrow-arg.rs diff --git a/tests/ui/async-await/pin-reborrow-const-as-mut.rs b/tests/ui/async-await/pin-ergonomics/reborrow-const-as-mut.rs similarity index 100% rename from tests/ui/async-await/pin-reborrow-const-as-mut.rs rename to tests/ui/async-await/pin-ergonomics/reborrow-const-as-mut.rs diff --git a/tests/ui/async-await/pin-reborrow-const-as-mut.stderr b/tests/ui/async-await/pin-ergonomics/reborrow-const-as-mut.stderr similarity index 83% rename from tests/ui/async-await/pin-reborrow-const-as-mut.stderr rename to tests/ui/async-await/pin-ergonomics/reborrow-const-as-mut.stderr index 2c2d9ec271742..36bbf1c493ab7 100644 --- a/tests/ui/async-await/pin-reborrow-const-as-mut.stderr +++ b/tests/ui/async-await/pin-ergonomics/reborrow-const-as-mut.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pin-reborrow-const-as-mut.rs:14:9 + --> $DIR/reborrow-const-as-mut.rs:14:9 | LL | foo(x); | --- ^ types differ in mutability @@ -9,7 +9,7 @@ LL | foo(x); = note: expected struct `Pin<&mut Foo>` found struct `Pin<&Foo>` note: function defined here - --> $DIR/pin-reborrow-const-as-mut.rs:10:4 + --> $DIR/reborrow-const-as-mut.rs:10:4 | LL | fn foo(_: Pin<&mut Foo>) { | ^^^ ---------------- diff --git a/tests/ui/async-await/pin-reborrow-once.rs b/tests/ui/async-await/pin-ergonomics/reborrow-once.rs similarity index 100% rename from tests/ui/async-await/pin-reborrow-once.rs rename to tests/ui/async-await/pin-ergonomics/reborrow-once.rs diff --git a/tests/ui/async-await/pin-reborrow-once.stderr b/tests/ui/async-await/pin-ergonomics/reborrow-once.stderr similarity index 90% rename from tests/ui/async-await/pin-reborrow-once.stderr rename to tests/ui/async-await/pin-ergonomics/reborrow-once.stderr index b8fde8ffee898..a1ea2b4a57a70 100644 --- a/tests/ui/async-await/pin-reborrow-once.stderr +++ b/tests/ui/async-await/pin-ergonomics/reborrow-once.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `*x.__pointer` as mutable more than once at a time - --> $DIR/pin-reborrow-once.rs:12:14 + --> $DIR/reborrow-once.rs:12:14 | LL | twice(x, x); | ----- - ^ second mutable borrow occurs here diff --git a/tests/ui/async-await/pin-reborrow-self.rs b/tests/ui/async-await/pin-ergonomics/reborrow-self.rs similarity index 100% rename from tests/ui/async-await/pin-reborrow-self.rs rename to tests/ui/async-await/pin-ergonomics/reborrow-self.rs diff --git a/tests/ui/async-await/pin-reborrow-shorter.rs b/tests/ui/async-await/pin-ergonomics/reborrow-shorter.rs similarity index 100% rename from tests/ui/async-await/pin-reborrow-shorter.rs rename to tests/ui/async-await/pin-ergonomics/reborrow-shorter.rs diff --git a/tests/ui/async-await/pin-sugar-ambiguity.rs b/tests/ui/async-await/pin-ergonomics/sugar-ambiguity.rs similarity index 100% rename from tests/ui/async-await/pin-sugar-ambiguity.rs rename to tests/ui/async-await/pin-ergonomics/sugar-ambiguity.rs diff --git a/tests/ui/async-await/pin-sugar-no-const.rs b/tests/ui/async-await/pin-ergonomics/sugar-no-const.rs similarity index 100% rename from tests/ui/async-await/pin-sugar-no-const.rs rename to tests/ui/async-await/pin-ergonomics/sugar-no-const.rs diff --git a/tests/ui/async-await/pin-sugar-no-const.stderr b/tests/ui/async-await/pin-ergonomics/sugar-no-const.stderr similarity index 91% rename from tests/ui/async-await/pin-sugar-no-const.stderr rename to tests/ui/async-await/pin-ergonomics/sugar-no-const.stderr index 5f01156c1f0a4..822cfffcb8c62 100644 --- a/tests/ui/async-await/pin-sugar-no-const.stderr +++ b/tests/ui/async-await/pin-ergonomics/sugar-no-const.stderr @@ -1,5 +1,5 @@ error: expected one of `!`, `(`, `::`, `;`, `<`, or `=`, found `i32` - --> $DIR/pin-sugar-no-const.rs:7:18 + --> $DIR/sugar-no-const.rs:7:18 | LL | let _x: &pin i32 = todo!(); | - ^^^ expected one of `!`, `(`, `::`, `;`, `<`, or `=` diff --git a/tests/ui/async-await/pin-sugar.rs b/tests/ui/async-await/pin-ergonomics/sugar.rs similarity index 100% rename from tests/ui/async-await/pin-sugar.rs rename to tests/ui/async-await/pin-ergonomics/sugar.rs diff --git a/tests/ui/async-await/suggest-switching-edition-on-await-cargo.rs b/tests/ui/async-await/suggest-switching-edition-on-await-cargo.rs index e1fae0f0e9343..bcb5cb94b77c8 100644 --- a/tests/ui/async-await/suggest-switching-edition-on-await-cargo.rs +++ b/tests/ui/async-await/suggest-switching-edition-on-await-cargo.rs @@ -12,7 +12,7 @@ fn await_on_struct_missing() { //~^ ERROR no field `await` on type //~| NOTE unknown field //~| NOTE to `.await` a `Future`, switch to Rust 2018 - //~| HELP set `edition = "2021"` in `Cargo.toml` + //~| HELP set `edition = "2024"` in `Cargo.toml` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide } @@ -26,7 +26,7 @@ fn await_on_struct_similar() { //~| NOTE unknown field //~| HELP a field with a similar name exists //~| NOTE to `.await` a `Future`, switch to Rust 2018 - //~| HELP set `edition = "2021"` in `Cargo.toml` + //~| HELP set `edition = "2024"` in `Cargo.toml` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide } @@ -35,7 +35,7 @@ fn await_on_63533(x: Pin<&mut dyn Future>) { //~^ ERROR no field `await` on type //~| NOTE unknown field //~| NOTE to `.await` a `Future`, switch to Rust 2018 - //~| HELP set `edition = "2021"` in `Cargo.toml` + //~| HELP set `edition = "2024"` in `Cargo.toml` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide } @@ -44,6 +44,6 @@ fn await_on_apit(x: impl Future) { //~^ ERROR no field `await` on type //~| NOTE unknown field //~| NOTE to `.await` a `Future`, switch to Rust 2018 - //~| HELP set `edition = "2021"` in `Cargo.toml` + //~| HELP set `edition = "2024"` in `Cargo.toml` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide } diff --git a/tests/ui/async-await/suggest-switching-edition-on-await-cargo.stderr b/tests/ui/async-await/suggest-switching-edition-on-await-cargo.stderr index dd863ca541c9e..c8bbb3a243cf4 100644 --- a/tests/ui/async-await/suggest-switching-edition-on-await-cargo.stderr +++ b/tests/ui/async-await/suggest-switching-edition-on-await-cargo.stderr @@ -5,7 +5,7 @@ LL | x.await; | ^^^^^ unknown field | = note: to `.await` a `Future`, switch to Rust 2018 or later - = help: set `edition = "2021"` in `Cargo.toml` + = help: set `edition = "2024"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0609]: no field `await` on type `await_on_struct_similar::S` @@ -15,7 +15,7 @@ LL | x.await; | ^^^^^ unknown field | = note: to `.await` a `Future`, switch to Rust 2018 or later - = help: set `edition = "2021"` in `Cargo.toml` + = help: set `edition = "2024"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide help: a field with a similar name exists | @@ -29,7 +29,7 @@ LL | x.await; | ^^^^^ unknown field | = note: to `.await` a `Future`, switch to Rust 2018 or later - = help: set `edition = "2021"` in `Cargo.toml` + = help: set `edition = "2024"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0609]: no field `await` on type `impl Future` @@ -39,7 +39,7 @@ LL | x.await; | ^^^^^ unknown field | = note: to `.await` a `Future`, switch to Rust 2018 or later - = help: set `edition = "2021"` in `Cargo.toml` + = help: set `edition = "2024"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error: aborting due to 4 previous errors diff --git a/tests/ui/async-await/suggest-switching-edition-on-await.rs b/tests/ui/async-await/suggest-switching-edition-on-await.rs index 10e245796ee3c..0907a87e02cf3 100644 --- a/tests/ui/async-await/suggest-switching-edition-on-await.rs +++ b/tests/ui/async-await/suggest-switching-edition-on-await.rs @@ -10,7 +10,7 @@ fn await_on_struct_missing() { //~^ ERROR no field `await` on type //~| NOTE unknown field //~| NOTE to `.await` a `Future`, switch to Rust 2018 - //~| HELP pass `--edition 2021` to `rustc` + //~| HELP pass `--edition 2024` to `rustc` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide } @@ -24,7 +24,7 @@ fn await_on_struct_similar() { //~| NOTE unknown field //~| HELP a field with a similar name exists //~| NOTE to `.await` a `Future`, switch to Rust 2018 - //~| HELP pass `--edition 2021` to `rustc` + //~| HELP pass `--edition 2024` to `rustc` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide } @@ -33,7 +33,7 @@ fn await_on_63533(x: Pin<&mut dyn Future>) { //~^ ERROR no field `await` on type //~| NOTE unknown field //~| NOTE to `.await` a `Future`, switch to Rust 2018 - //~| HELP pass `--edition 2021` to `rustc` + //~| HELP pass `--edition 2024` to `rustc` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide } @@ -42,6 +42,6 @@ fn await_on_apit(x: impl Future) { //~^ ERROR no field `await` on type //~| NOTE unknown field //~| NOTE to `.await` a `Future`, switch to Rust 2018 - //~| HELP pass `--edition 2021` to `rustc` + //~| HELP pass `--edition 2024` to `rustc` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide } diff --git a/tests/ui/async-await/suggest-switching-edition-on-await.stderr b/tests/ui/async-await/suggest-switching-edition-on-await.stderr index 0ed256b059ffe..ef5a5f8126988 100644 --- a/tests/ui/async-await/suggest-switching-edition-on-await.stderr +++ b/tests/ui/async-await/suggest-switching-edition-on-await.stderr @@ -5,7 +5,7 @@ LL | x.await; | ^^^^^ unknown field | = note: to `.await` a `Future`, switch to Rust 2018 or later - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0609]: no field `await` on type `await_on_struct_similar::S` @@ -15,7 +15,7 @@ LL | x.await; | ^^^^^ unknown field | = note: to `.await` a `Future`, switch to Rust 2018 or later - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide help: a field with a similar name exists | @@ -29,7 +29,7 @@ LL | x.await; | ^^^^^ unknown field | = note: to `.await` a `Future`, switch to Rust 2018 or later - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0609]: no field `await` on type `impl Future` @@ -39,7 +39,7 @@ LL | x.await; | ^^^^^ unknown field | = note: to `.await` a `Future`, switch to Rust 2018 or later - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error: aborting due to 4 previous errors diff --git a/tests/ui/attr-start.rs b/tests/ui/attr-start.rs index 27cf35601fdf7..232f50955b2ee 100644 --- a/tests/ui/attr-start.rs +++ b/tests/ui/attr-start.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![feature(start)] diff --git a/tests/ui/attributes/attr-before-view-item.rs b/tests/ui/attributes/attr-before-view-item.rs index e0e086ea476ac..19874052e3368 100644 --- a/tests/ui/attributes/attr-before-view-item.rs +++ b/tests/ui/attributes/attr-before-view-item.rs @@ -1,5 +1,4 @@ //@ build-pass (FIXME(62277): could be check-pass?) -//@ pretty-expanded FIXME #23616 #![feature(rustc_attrs)] #![feature(test)] diff --git a/tests/ui/attributes/attr-before-view-item2.rs b/tests/ui/attributes/attr-before-view-item2.rs index 8d74d73fe2ec8..e58063a13ab0a 100644 --- a/tests/ui/attributes/attr-before-view-item2.rs +++ b/tests/ui/attributes/attr-before-view-item2.rs @@ -1,5 +1,4 @@ //@ build-pass (FIXME(62277): could be check-pass?) -//@ pretty-expanded FIXME #23616 #![feature(rustc_attrs)] #![feature(test)] diff --git a/tests/ui/attributes/attr-mix-new.rs b/tests/ui/attributes/attr-mix-new.rs index bb2bab8f26781..bd249a0c198ab 100644 --- a/tests/ui/attributes/attr-mix-new.rs +++ b/tests/ui/attributes/attr-mix-new.rs @@ -1,5 +1,4 @@ //@ build-pass (FIXME(62277): could be check-pass?) -//@ pretty-expanded FIXME #23616 #![feature(rustc_attrs)] diff --git a/tests/ui/attributes/auxiliary/key-value-expansion.rs b/tests/ui/attributes/auxiliary/key-value-expansion.rs index 9db82cec6356f..5ecc62ed3fa3a 100644 --- a/tests/ui/attributes/auxiliary/key-value-expansion.rs +++ b/tests/ui/attributes/auxiliary/key-value-expansion.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/attributes/key-value-expansion.rs b/tests/ui/attributes/key-value-expansion.rs index dd408ebb77e4c..e5700a7593562 100644 --- a/tests/ui/attributes/key-value-expansion.rs +++ b/tests/ui/attributes/key-value-expansion.rs @@ -1,7 +1,7 @@ // Regression tests for issue #55414, expansion happens in the value of a key-value attribute, // and the expanded expression is more complex than simply a macro call. -//@ aux-build:key-value-expansion.rs +//@ proc-macro: key-value-expansion.rs #![feature(rustc_attrs)] diff --git a/tests/ui/attributes/main-removed-2/auxiliary/tokyo.rs b/tests/ui/attributes/main-removed-2/auxiliary/tokyo.rs index 25879d17027bc..038183a80b8b8 100644 --- a/tests/ui/attributes/main-removed-2/auxiliary/tokyo.rs +++ b/tests/ui/attributes/main-removed-2/auxiliary/tokyo.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/attributes/main-removed-2/main.rs b/tests/ui/attributes/main-removed-2/main.rs index e4a3de79ec99d..53696d68ced07 100644 --- a/tests/ui/attributes/main-removed-2/main.rs +++ b/tests/ui/attributes/main-removed-2/main.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:tokyo.rs +//@ proc-macro: tokyo.rs //@ compile-flags:--extern tokyo //@ edition:2021 diff --git a/tests/ui/attributes/method-attributes.rs b/tests/ui/attributes/method-attributes.rs index 4a7f042c20a62..ded72d2457b1c 100644 --- a/tests/ui/attributes/method-attributes.rs +++ b/tests/ui/attributes/method-attributes.rs @@ -1,6 +1,5 @@ //@ build-pass (FIXME(62277): could be check-pass?) //@ pp-exact - Make sure we print all the attributes -//@ pretty-expanded FIXME #23616 #![feature(rustc_attrs)] diff --git a/tests/ui/attributes/no-sanitize.rs b/tests/ui/attributes/no-sanitize.rs index 82b7a22d5701e..8c79866d5aa31 100644 --- a/tests/ui/attributes/no-sanitize.rs +++ b/tests/ui/attributes/no-sanitize.rs @@ -4,31 +4,37 @@ #![allow(dead_code)] fn invalid() { - #[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition + #[no_sanitize(memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function { 1 }; } -#[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition +#[no_sanitize(memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function type InvalidTy = (); -#[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition +#[no_sanitize(memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function mod invalid_module {} fn main() { - let _ = #[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition + let _ = #[no_sanitize(memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function (|| 1); } -#[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition +#[no_sanitize(memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function struct F; -#[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition +#[no_sanitize(memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function impl F { #[no_sanitize(memory)] fn valid(&self) {} } +#[no_sanitize(address, memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function +static INVALID : i32 = 0; + #[no_sanitize(memory)] fn valid() {} + +#[no_sanitize(address)] +static VALID : i32 = 0; diff --git a/tests/ui/attributes/no-sanitize.stderr b/tests/ui/attributes/no-sanitize.stderr index f742ba0beed18..9b0b76e3f4eba 100644 --- a/tests/ui/attributes/no-sanitize.stderr +++ b/tests/ui/attributes/no-sanitize.stderr @@ -1,55 +1,63 @@ -error: attribute should be applied to a function definition - --> $DIR/no-sanitize.rs:7:5 +error: `#[no_sanitize(memory)]` should be applied to a function + --> $DIR/no-sanitize.rs:7:19 | LL | #[no_sanitize(memory)] - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ LL | / { LL | | 1 LL | | }; - | |_____- not a function definition + | |_____- not a function -error: attribute should be applied to a function definition - --> $DIR/no-sanitize.rs:13:1 +error: `#[no_sanitize(memory)]` should be applied to a function + --> $DIR/no-sanitize.rs:13:15 | LL | #[no_sanitize(memory)] - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ LL | type InvalidTy = (); - | -------------------- not a function definition + | -------------------- not a function -error: attribute should be applied to a function definition - --> $DIR/no-sanitize.rs:16:1 +error: `#[no_sanitize(memory)]` should be applied to a function + --> $DIR/no-sanitize.rs:16:15 | LL | #[no_sanitize(memory)] - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ LL | mod invalid_module {} - | --------------------- not a function definition + | --------------------- not a function -error: attribute should be applied to a function definition - --> $DIR/no-sanitize.rs:20:13 +error: `#[no_sanitize(memory)]` should be applied to a function + --> $DIR/no-sanitize.rs:20:27 | LL | let _ = #[no_sanitize(memory)] - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ LL | (|| 1); - | ------ not a function definition + | ------ not a function -error: attribute should be applied to a function definition - --> $DIR/no-sanitize.rs:24:1 +error: `#[no_sanitize(memory)]` should be applied to a function + --> $DIR/no-sanitize.rs:24:15 | LL | #[no_sanitize(memory)] - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ LL | struct F; - | --------- not a function definition + | --------- not a function -error: attribute should be applied to a function definition - --> $DIR/no-sanitize.rs:27:1 +error: `#[no_sanitize(memory)]` should be applied to a function + --> $DIR/no-sanitize.rs:27:15 | LL | #[no_sanitize(memory)] - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ LL | / impl F { LL | | #[no_sanitize(memory)] LL | | fn valid(&self) {} LL | | } - | |_- not a function definition + | |_- not a function -error: aborting due to 6 previous errors +error: `#[no_sanitize(memory)]` should be applied to a function + --> $DIR/no-sanitize.rs:33:24 + | +LL | #[no_sanitize(address, memory)] + | ^^^^^^ +LL | static INVALID : i32 = 0; + | ------------------------- not a function + +error: aborting due to 7 previous errors diff --git a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs index 273b127bf9cb4..19046c08ca8bd 100644 --- a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options #[unsafe(cfg(any()))] //~ ERROR: is not an unsafe attribute fn a() {} diff --git a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr index 445d239d86729..b549a638d5eae 100644 --- a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr @@ -1,5 +1,5 @@ error: `cfg` is not an unsafe attribute - --> $DIR/extraneous-unsafe-attributes.rs:4:3 + --> $DIR/extraneous-unsafe-attributes.rs:3:3 | LL | #[unsafe(cfg(any()))] | ^^^^^^ this is not an unsafe attribute @@ -7,7 +7,7 @@ LL | #[unsafe(cfg(any()))] = note: extraneous unsafe is not allowed in attributes error: `cfg_attr` is not an unsafe attribute - --> $DIR/extraneous-unsafe-attributes.rs:7:3 + --> $DIR/extraneous-unsafe-attributes.rs:6:3 | LL | #[unsafe(cfg_attr(any(), allow(dead_code)))] | ^^^^^^ this is not an unsafe attribute @@ -15,7 +15,7 @@ LL | #[unsafe(cfg_attr(any(), allow(dead_code)))] = note: extraneous unsafe is not allowed in attributes error: `test` is not an unsafe attribute - --> $DIR/extraneous-unsafe-attributes.rs:10:3 + --> $DIR/extraneous-unsafe-attributes.rs:9:3 | LL | #[unsafe(test)] | ^^^^^^ this is not an unsafe attribute @@ -23,7 +23,7 @@ LL | #[unsafe(test)] = note: extraneous unsafe is not allowed in attributes error: expected identifier, found keyword `unsafe` - --> $DIR/extraneous-unsafe-attributes.rs:31:19 + --> $DIR/extraneous-unsafe-attributes.rs:30:19 | LL | let _a = cfg!(unsafe(foo)); | ^^^^^^ expected identifier, found keyword @@ -34,13 +34,13 @@ LL | let _a = cfg!(r#unsafe(foo)); | ++ error[E0537]: invalid predicate `r#unsafe` - --> $DIR/extraneous-unsafe-attributes.rs:31:19 + --> $DIR/extraneous-unsafe-attributes.rs:30:19 | LL | let _a = cfg!(unsafe(foo)); | ^^^^^^^^^^^ error: `ignore` is not an unsafe attribute - --> $DIR/extraneous-unsafe-attributes.rs:13:3 + --> $DIR/extraneous-unsafe-attributes.rs:12:3 | LL | #[unsafe(ignore = "test")] | ^^^^^^ this is not an unsafe attribute @@ -48,7 +48,7 @@ LL | #[unsafe(ignore = "test")] = note: extraneous unsafe is not allowed in attributes error: `should_panic` is not an unsafe attribute - --> $DIR/extraneous-unsafe-attributes.rs:16:3 + --> $DIR/extraneous-unsafe-attributes.rs:15:3 | LL | #[unsafe(should_panic(expected = "test"))] | ^^^^^^ this is not an unsafe attribute @@ -56,7 +56,7 @@ LL | #[unsafe(should_panic(expected = "test"))] = note: extraneous unsafe is not allowed in attributes error: `macro_use` is not an unsafe attribute - --> $DIR/extraneous-unsafe-attributes.rs:19:3 + --> $DIR/extraneous-unsafe-attributes.rs:18:3 | LL | #[unsafe(macro_use)] | ^^^^^^ this is not an unsafe attribute @@ -64,7 +64,7 @@ LL | #[unsafe(macro_use)] = note: extraneous unsafe is not allowed in attributes error: `macro_export` is not an unsafe attribute - --> $DIR/extraneous-unsafe-attributes.rs:21:7 + --> $DIR/extraneous-unsafe-attributes.rs:20:7 | LL | #[unsafe(macro_export)] | ^^^^^^ this is not an unsafe attribute @@ -72,7 +72,7 @@ LL | #[unsafe(macro_export)] = note: extraneous unsafe is not allowed in attributes error: `used` is not an unsafe attribute - --> $DIR/extraneous-unsafe-attributes.rs:27:3 + --> $DIR/extraneous-unsafe-attributes.rs:26:3 | LL | #[unsafe(used)] | ^^^^^^ this is not an unsafe attribute diff --git a/tests/ui/attributes/variant-attributes.rs b/tests/ui/attributes/variant-attributes.rs index 57423ad61b219..a08856aa278d3 100644 --- a/tests/ui/attributes/variant-attributes.rs +++ b/tests/ui/attributes/variant-attributes.rs @@ -1,6 +1,5 @@ //@ build-pass (FIXME(62277): could be check-pass?) //@ pp-exact - Make sure we actually print the attributes -//@ pretty-expanded FIXME #23616 #![allow(non_camel_case_types)] #![feature(rustc_attrs)] diff --git a/tests/ui/autodiff/auxiliary/my_macro.rs b/tests/ui/autodiff/auxiliary/my_macro.rs index 417199611cca6..217631a33c9bc 100644 --- a/tests/ui/autodiff/auxiliary/my_macro.rs +++ b/tests/ui/autodiff/auxiliary/my_macro.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/autodiff/visibility.rs b/tests/ui/autodiff/visibility.rs index 6a4851de2dc02..dfaec03aef01f 100644 --- a/tests/ui/autodiff/visibility.rs +++ b/tests/ui/autodiff/visibility.rs @@ -1,7 +1,7 @@ //@ ignore-enzyme //@ revisions: std_autodiff no_std_autodiff //@[no_std_autodiff] check-pass -//@ aux-build: my_macro.rs +//@ proc-macro: my_macro.rs #![crate_type = "lib"] #![feature(autodiff)] diff --git a/tests/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs b/tests/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs index b44e2a8cd37cb..d75a2ab8bdba4 100644 --- a/tests/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs +++ b/tests/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct Foo { x: isize, diff --git a/tests/ui/auxiliary/unsafe-fields-crate-dep.rs b/tests/ui/auxiliary/unsafe-fields-crate-dep.rs new file mode 100644 index 0000000000000..95b928402a9f8 --- /dev/null +++ b/tests/ui/auxiliary/unsafe-fields-crate-dep.rs @@ -0,0 +1,7 @@ +#![allow(incomplete_features)] +#![feature(unsafe_fields)] + +pub struct WithUnsafeField { + pub unsafe unsafe_field: u32, + pub safe_field: u32, +} diff --git a/tests/ui/bench/issue-32062.rs b/tests/ui/bench/issue-32062.rs index 84de427a20063..a7d1f8073d46b 100644 --- a/tests/ui/bench/issue-32062.rs +++ b/tests/ui/bench/issue-32062.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn main() { let _ = test(Some(0).into_iter()); diff --git a/tests/ui/binding/inconsistent-lifetime-mismatch.rs b/tests/ui/binding/inconsistent-lifetime-mismatch.rs index b45c72cd9bdc8..539f8f58a1d5e 100644 --- a/tests/ui/binding/inconsistent-lifetime-mismatch.rs +++ b/tests/ui/binding/inconsistent-lifetime-mismatch.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn foo(_: &[&str]) {} diff --git a/tests/ui/binding/match-naked-record-expr.rs b/tests/ui/binding/match-naked-record-expr.rs index c6557cc10d669..57697a73ca4b2 100644 --- a/tests/ui/binding/match-naked-record-expr.rs +++ b/tests/ui/binding/match-naked-record-expr.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 struct X { x: isize } diff --git a/tests/ui/binding/match-naked-record.rs b/tests/ui/binding/match-naked-record.rs index 24d7aec00e7b8..ce9489a00f2c6 100644 --- a/tests/ui/binding/match-naked-record.rs +++ b/tests/ui/binding/match-naked-record.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct X { x: isize } diff --git a/tests/ui/binding/match-path.rs b/tests/ui/binding/match-path.rs index 9bcef9914d152..1305ac7668ea6 100644 --- a/tests/ui/binding/match-path.rs +++ b/tests/ui/binding/match-path.rs @@ -3,7 +3,6 @@ #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 mod m1 { pub enum foo { foo1, foo2, } diff --git a/tests/ui/binding/match-pattern-simple.rs b/tests/ui/binding/match-pattern-simple.rs index 2e43b702fae94..da22acd7f37f3 100644 --- a/tests/ui/binding/match-pattern-simple.rs +++ b/tests/ui/binding/match-pattern-simple.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn altsimple(f: isize) { match f { _x => () } } diff --git a/tests/ui/binding/match-phi.rs b/tests/ui/binding/match-phi.rs index cfef03adaa47a..128d4d618a096 100644 --- a/tests/ui/binding/match-phi.rs +++ b/tests/ui/binding/match-phi.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(unused_assignments)] -//@ pretty-expanded FIXME #23616 #![allow(non_camel_case_types)] #![allow(unused_variables)] diff --git a/tests/ui/binding/match-range-static.rs b/tests/ui/binding/match-range-static.rs index 478dfb3cf4149..cf4d030b66fbe 100644 --- a/tests/ui/binding/match-range-static.rs +++ b/tests/ui/binding/match-range-static.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(non_upper_case_globals)] const s: isize = 1; diff --git a/tests/ui/binding/match-value-binding-in-guard-3291.rs b/tests/ui/binding/match-value-binding-in-guard-3291.rs index a1f939cadca4e..ca8c34628b71e 100644 --- a/tests/ui/binding/match-value-binding-in-guard-3291.rs +++ b/tests/ui/binding/match-value-binding-in-guard-3291.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn foo(x: Option>, b: bool) -> isize { match x { diff --git a/tests/ui/binding/nil-pattern.rs b/tests/ui/binding/nil-pattern.rs index 757d701c15a7f..68dbfe3b45316 100644 --- a/tests/ui/binding/nil-pattern.rs +++ b/tests/ui/binding/nil-pattern.rs @@ -1,4 +1,3 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { let x = (); match x { () => { } } } diff --git a/tests/ui/binding/simple-generic-match.rs b/tests/ui/binding/simple-generic-match.rs index 910bab03e1f53..001b469d35e3f 100644 --- a/tests/ui/binding/simple-generic-match.rs +++ b/tests/ui/binding/simple-generic-match.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 enum clam { a(#[allow(dead_code)] T), } diff --git a/tests/ui/borrowck/borrowck-assign-to-subfield.rs b/tests/ui/borrowck/borrowck-assign-to-subfield.rs index 807941d9c8547..27d9046e7b7cb 100644 --- a/tests/ui/borrowck/borrowck-assign-to-subfield.rs +++ b/tests/ui/borrowck/borrowck-assign-to-subfield.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { struct A { diff --git a/tests/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs b/tests/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs index a815253d7147d..ef5baae450077 100644 --- a/tests/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs +++ b/tests/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs @@ -7,7 +7,6 @@ // // Example from compiler/rustc_borrowck/borrowck/README.md -//@ pretty-expanded FIXME #23616 fn foo<'a>(mut t0: &'a mut isize, mut t1: &'a mut isize) { diff --git a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs index d78d8a9d96666..d200ef6d6f872 100644 --- a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs +++ b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs @@ -2,7 +2,6 @@ #![allow(unused_mut)] #![allow(unused_variables)] #![allow(dropping_copy_types)] -//@ pretty-expanded FIXME #23616 struct A { a: isize, b: Box } struct B { a: Box, b: Box } diff --git a/tests/ui/borrowck/borrowck-lend-args.rs b/tests/ui/borrowck/borrowck-lend-args.rs index 08a7aea162793..9d45730f196de 100644 --- a/tests/ui/borrowck/borrowck-lend-args.rs +++ b/tests/ui/borrowck/borrowck-lend-args.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn borrow(_v: &isize) {} diff --git a/tests/ui/borrowck/borrowck-static-item-in-fn.rs b/tests/ui/borrowck/borrowck-static-item-in-fn.rs index 9cdd4c891320c..3c2e7b92c9ec3 100644 --- a/tests/ui/borrowck/borrowck-static-item-in-fn.rs +++ b/tests/ui/borrowck/borrowck-static-item-in-fn.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] // Regression test for issue #7740 -//@ pretty-expanded FIXME #23616 pub fn main() { static A: &'static char = &'A'; diff --git a/tests/ui/borrowck/borrowck-trait-lifetime.rs b/tests/ui/borrowck/borrowck-trait-lifetime.rs index e43201fb10b3e..26d4cfb888754 100644 --- a/tests/ui/borrowck/borrowck-trait-lifetime.rs +++ b/tests/ui/borrowck/borrowck-trait-lifetime.rs @@ -3,7 +3,6 @@ // This test verifies that casting from the same lifetime on a value // to the same lifetime on a trait succeeds. See issue #10766. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/borrowck/borrowck-uniq-via-ref.rs b/tests/ui/borrowck/borrowck-uniq-via-ref.rs index d3190d66bd31b..67f908a0c076f 100644 --- a/tests/ui/borrowck/borrowck-uniq-via-ref.rs +++ b/tests/ui/borrowck/borrowck-uniq-via-ref.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct Rec { f: Box, diff --git a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs index 9649f48447138..5bbac021504fa 100644 --- a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs +++ b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(dropping_copy_types)] diff --git a/tests/ui/box/new-box-syntax.rs b/tests/ui/box/new-box-syntax.rs index f2899ff3dde06..a0d8cb755849f 100644 --- a/tests/ui/box/new-box-syntax.rs +++ b/tests/ui/box/new-box-syntax.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ diff --git a/tests/ui/box/new.rs b/tests/ui/box/new.rs index 682a998ae1993..2e7525e208f2b 100644 --- a/tests/ui/box/new.rs +++ b/tests/ui/box/new.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn main() { let _a = Box::new(1); diff --git a/tests/ui/box/unit/unique-containing-tag.rs b/tests/ui/box/unit/unique-containing-tag.rs index cd88cfab4254f..a9752a64f4df0 100644 --- a/tests/ui/box/unit/unique-containing-tag.rs +++ b/tests/ui/box/unit/unique-containing-tag.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 pub fn main() { enum t { t1(isize), t2(isize), } diff --git a/tests/ui/box/unit/unique-create.rs b/tests/ui/box/unit/unique-create.rs index bf3826156b1d4..b3b72971e53c0 100644 --- a/tests/ui/box/unit/unique-create.rs +++ b/tests/ui/box/unit/unique-create.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub fn main() { let _: Box<_> = Box::new(100); diff --git a/tests/ui/box/unit/unique-drop-complex.rs b/tests/ui/box/unit/unique-drop-complex.rs index f23635e59cd50..6e5fb524f41e5 100644 --- a/tests/ui/box/unit/unique-drop-complex.rs +++ b/tests/ui/box/unit/unique-drop-complex.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { let _x: Box<_> = Box::new(vec![0,0,0,0,0]); diff --git a/tests/ui/box/unit/unique-generic-assign.rs b/tests/ui/box/unit/unique-generic-assign.rs index ef9c34c41a393..2c5cb0c1112a3 100644 --- a/tests/ui/box/unit/unique-generic-assign.rs +++ b/tests/ui/box/unit/unique-generic-assign.rs @@ -3,7 +3,6 @@ // Issue #976 -//@ pretty-expanded FIXME #23616 fn f(x: Box) { let _x2 = x; diff --git a/tests/ui/box/unit/unique-init.rs b/tests/ui/box/unit/unique-init.rs index ad2390c2ca01b..0950c794c4804 100644 --- a/tests/ui/box/unit/unique-init.rs +++ b/tests/ui/box/unit/unique-init.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { let _i: Box<_> = Box::new(100); diff --git a/tests/ui/box/unit/unique-match-discrim.rs b/tests/ui/box/unit/unique-match-discrim.rs index 97b502004f514..c1b7b15c7c41d 100644 --- a/tests/ui/box/unit/unique-match-discrim.rs +++ b/tests/ui/box/unit/unique-match-discrim.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] // Issue #961 -//@ pretty-expanded FIXME #23616 fn altsimple() { match Box::new(true) { diff --git a/tests/ui/box/unit/unique-object-move.rs b/tests/ui/box/unit/unique-object-move.rs index f30fc5c8e64f3..6ed2b1dc401ce 100644 --- a/tests/ui/box/unit/unique-object-move.rs +++ b/tests/ui/box/unit/unique-object-move.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] // Issue #5192 -//@ pretty-expanded FIXME #23616 pub trait EventLoop { fn foo(&self) {} } diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-phantom-typaram.rs b/tests/ui/builtin-superkinds/builtin-superkinds-phantom-typaram.rs index 8a2fa4685771f..ea5d3bdcfdbe6 100644 --- a/tests/ui/builtin-superkinds/builtin-superkinds-phantom-typaram.rs +++ b/tests/ui/builtin-superkinds/builtin-superkinds-phantom-typaram.rs @@ -5,7 +5,6 @@ // super-builtin-kind of a trait, if the type parameter is never used, // the type can implement the trait anyway. -//@ pretty-expanded FIXME #23616 use std::marker; diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs b/tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs index 1354b4ac18811..510ef4c158e45 100644 --- a/tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs +++ b/tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs @@ -1,7 +1,6 @@ //@ check-pass // Simple test case of implementing a trait with super-builtin-kinds. -//@ pretty-expanded FIXME #23616 trait Foo : Send { } diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs b/tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs index 15b867dd5e005..de2afc4a1713d 100644 --- a/tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs +++ b/tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs @@ -2,7 +2,6 @@ // Tests correct implementation of traits with super-builtin-kinds // using a bounded type parameter. -//@ pretty-expanded FIXME #23616 trait Foo : Send { } diff --git a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs b/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs deleted file mode 100644 index d47a8e085fd3a..0000000000000 --- a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs +++ /dev/null @@ -1,19 +0,0 @@ -//@ only-x86_64 - -fn efiapi(f: extern "efiapi" fn(usize, ...)) { - //~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl` - //~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable - f(22, 44); -} -fn sysv(f: extern "sysv64" fn(usize, ...)) { - //~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl` - //~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable - f(22, 44); -} -fn win(f: extern "win64" fn(usize, ...)) { - //~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl` - //~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable - f(22, 44); -} - -fn main() {} diff --git a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr b/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr deleted file mode 100644 index 41be378424543..0000000000000 --- a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr +++ /dev/null @@ -1,52 +0,0 @@ -error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable - --> $DIR/feature-gate-extended_varargs_abi_support.rs:3:14 - | -LL | fn efiapi(f: extern "efiapi" fn(usize, ...)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #100189 for more information - = help: add `#![feature(extended_varargs_abi_support)]` 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[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl` - --> $DIR/feature-gate-extended_varargs_abi_support.rs:3:14 - | -LL | fn efiapi(f: extern "efiapi" fn(usize, ...)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention - -error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable - --> $DIR/feature-gate-extended_varargs_abi_support.rs:8:12 - | -LL | fn sysv(f: extern "sysv64" fn(usize, ...)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #100189 for more information - = help: add `#![feature(extended_varargs_abi_support)]` 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[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl` - --> $DIR/feature-gate-extended_varargs_abi_support.rs:8:12 - | -LL | fn sysv(f: extern "sysv64" fn(usize, ...)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention - -error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable - --> $DIR/feature-gate-extended_varargs_abi_support.rs:13:11 - | -LL | fn win(f: extern "win64" fn(usize, ...)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #100189 for more information - = help: add `#![feature(extended_varargs_abi_support)]` 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[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl` - --> $DIR/feature-gate-extended_varargs_abi_support.rs:13:11 - | -LL | fn win(f: extern "win64" fn(usize, ...)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention - -error: aborting due to 6 previous errors - -Some errors have detailed explanations: E0045, E0658. -For more information about an error, try `rustc --explain E0045`. diff --git a/tests/ui/c-variadic/fn-item-diagnostic-issue-69232.rs b/tests/ui/c-variadic/fn-item-diagnostic-issue-69232.rs new file mode 100644 index 0000000000000..d0ef91b22b234 --- /dev/null +++ b/tests/ui/c-variadic/fn-item-diagnostic-issue-69232.rs @@ -0,0 +1,13 @@ +// https://github.com/rust-lang/rust/issues/69232 + +extern "C" { + fn foo(x: usize, ...); +} + +fn test() -> u8 { + 127 +} + +fn main() { + unsafe { foo(1, test) }; //~ ERROR can't pass a function item to a variadic function +} diff --git a/tests/ui/c-variadic/fn-item-diagnostic-issue-69232.stderr b/tests/ui/c-variadic/fn-item-diagnostic-issue-69232.stderr new file mode 100644 index 0000000000000..6aa1c8a109159 --- /dev/null +++ b/tests/ui/c-variadic/fn-item-diagnostic-issue-69232.stderr @@ -0,0 +1,16 @@ +error[E0617]: can't pass a function item to a variadic function + --> $DIR/fn-item-diagnostic-issue-69232.rs:12:21 + | +LL | unsafe { foo(1, test) }; + | ^^^^ + | + = help: a function item is zero-sized and needs to be cast into a function pointer to be used in FFI + = note: for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html +help: use a function pointer instead + | +LL | unsafe { foo(1, test as fn() -> u8) }; + | +++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0617`. diff --git a/tests/ui/c-variadic/issue-32201.rs b/tests/ui/c-variadic/issue-32201.rs index f27bb1c2eb5b6..434711b75236e 100644 --- a/tests/ui/c-variadic/issue-32201.rs +++ b/tests/ui/c-variadic/issue-32201.rs @@ -7,7 +7,8 @@ fn bar(_: *const u8) {} fn main() { unsafe { foo(0, bar); - //~^ ERROR can't pass `fn(*const u8) {bar}` to variadic function - //~| HELP cast the value to `fn(*const u8)` + //~^ ERROR can't pass a function item to a variadic function + //~| HELP a function item is zero-sized and needs to be cast into a function pointer to be used in FFI + ////~| HELP use a function pointer instead } } diff --git a/tests/ui/c-variadic/issue-32201.stderr b/tests/ui/c-variadic/issue-32201.stderr index 352db9f62f6d8..1cd85d7f07af3 100644 --- a/tests/ui/c-variadic/issue-32201.stderr +++ b/tests/ui/c-variadic/issue-32201.stderr @@ -1,8 +1,15 @@ -error[E0617]: can't pass `fn(*const u8) {bar}` to variadic function +error[E0617]: can't pass a function item to a variadic function --> $DIR/issue-32201.rs:9:16 | LL | foo(0, bar); - | ^^^ help: cast the value to `fn(*const u8)`: `bar as fn(*const u8)` + | ^^^ + | + = help: a function item is zero-sized and needs to be cast into a function pointer to be used in FFI + = note: for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html +help: use a function pointer instead + | +LL | foo(0, bar as fn(*const u8)); + | ++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/c-variadic/variadic-ffi-1.stderr b/tests/ui/c-variadic/variadic-ffi-1.stderr index 72d60a1439afc..7a54d043356a3 100644 --- a/tests/ui/c-variadic/variadic-ffi-1.stderr +++ b/tests/ui/c-variadic/variadic-ffi-1.stderr @@ -1,4 +1,4 @@ -error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl` +error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi` --> $DIR/variadic-ffi-1.rs:9:5 | LL | fn printf(_: *const u8, ...); @@ -62,37 +62,67 @@ error[E0617]: can't pass `f32` to variadic function --> $DIR/variadic-ffi-1.rs:28:19 | LL | foo(1, 2, 3f32); - | ^^^^ help: cast the value to `c_double`: `3f32 as c_double` + | ^^^^ + | +help: cast the value to `c_double` + | +LL | foo(1, 2, 3f32 as c_double); + | +++++++++++ error[E0617]: can't pass `bool` to variadic function --> $DIR/variadic-ffi-1.rs:29:19 | LL | foo(1, 2, true); - | ^^^^ help: cast the value to `c_int`: `true as c_int` + | ^^^^ + | +help: cast the value to `c_int` + | +LL | foo(1, 2, true as c_int); + | ++++++++ error[E0617]: can't pass `i8` to variadic function --> $DIR/variadic-ffi-1.rs:30:19 | LL | foo(1, 2, 1i8); - | ^^^ help: cast the value to `c_int`: `1i8 as c_int` + | ^^^ + | +help: cast the value to `c_int` + | +LL | foo(1, 2, 1i8 as c_int); + | ++++++++ error[E0617]: can't pass `u8` to variadic function --> $DIR/variadic-ffi-1.rs:31:19 | LL | foo(1, 2, 1u8); - | ^^^ help: cast the value to `c_uint`: `1u8 as c_uint` + | ^^^ + | +help: cast the value to `c_uint` + | +LL | foo(1, 2, 1u8 as c_uint); + | +++++++++ error[E0617]: can't pass `i16` to variadic function --> $DIR/variadic-ffi-1.rs:32:19 | LL | foo(1, 2, 1i16); - | ^^^^ help: cast the value to `c_int`: `1i16 as c_int` + | ^^^^ + | +help: cast the value to `c_int` + | +LL | foo(1, 2, 1i16 as c_int); + | ++++++++ error[E0617]: can't pass `u16` to variadic function --> $DIR/variadic-ffi-1.rs:33:19 | LL | foo(1, 2, 1u16); - | ^^^^ help: cast the value to `c_uint`: `1u16 as c_uint` + | ^^^^ + | +help: cast the value to `c_uint` + | +LL | foo(1, 2, 1u16 as c_uint); + | +++++++++ error: aborting due to 11 previous errors diff --git a/tests/ui/c-variadic/variadic-ffi-2-arm.rs b/tests/ui/c-variadic/variadic-ffi-2-arm.rs index 3b0a71007a0e6..82f9df5053c19 100644 --- a/tests/ui/c-variadic/variadic-ffi-2-arm.rs +++ b/tests/ui/c-variadic/variadic-ffi-2-arm.rs @@ -1,6 +1,5 @@ //@ only-arm //@ build-pass -#![feature(extended_varargs_abi_support)] fn aapcs(f: extern "aapcs" fn(usize, ...)) { f(22, 44); diff --git a/tests/ui/c-variadic/variadic-ffi-2.rs b/tests/ui/c-variadic/variadic-ffi-2.rs index bafb7e2b20cc7..17a1065279f4e 100644 --- a/tests/ui/c-variadic/variadic-ffi-2.rs +++ b/tests/ui/c-variadic/variadic-ffi-2.rs @@ -1,5 +1,4 @@ //@ ignore-arm stdcall isn't supported -#![feature(extended_varargs_abi_support)] #[allow(unsupported_fn_ptr_calling_conventions)] fn baz(f: extern "stdcall" fn(usize, ...)) { diff --git a/tests/ui/c-variadic/variadic-ffi-2.stderr b/tests/ui/c-variadic/variadic-ffi-2.stderr index e52de93a92646..fbf273b1f1dbf 100644 --- a/tests/ui/c-variadic/variadic-ffi-2.stderr +++ b/tests/ui/c-variadic/variadic-ffi-2.stderr @@ -1,5 +1,5 @@ error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi` - --> $DIR/variadic-ffi-2.rs:5:11 + --> $DIR/variadic-ffi-2.rs:4:11 | LL | fn baz(f: extern "stdcall" fn(usize, ...)) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention diff --git a/tests/ui/can-copy-pod.rs b/tests/ui/can-copy-pod.rs index dd4cf54040aaf..ffb8a08fa9804 100644 --- a/tests/ui/can-copy-pod.rs +++ b/tests/ui/can-copy-pod.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ diff --git a/tests/ui/cancel-clean-via-immediate-rvalue-ref.rs b/tests/ui/cancel-clean-via-immediate-rvalue-ref.rs index 0575c29bffdb3..12d143bd98953 100644 --- a/tests/ui/cancel-clean-via-immediate-rvalue-ref.rs +++ b/tests/ui/cancel-clean-via-immediate-rvalue-ref.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn foo(x: &mut Box) { *x = Box::new(5); diff --git a/tests/ui/cfg/assume-incomplete-release/assume-incomplete.rs b/tests/ui/cfg/assume-incomplete-release/assume-incomplete.rs index b04b1e0c32624..cafb7389e29fa 100644 --- a/tests/ui/cfg/assume-incomplete-release/assume-incomplete.rs +++ b/tests/ui/cfg/assume-incomplete-release/assume-incomplete.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:ver-cfg-rel.rs +//@ proc-macro: ver-cfg-rel.rs //@ revisions: assume no_assume //@ [assume]compile-flags: -Z assume-incomplete-release diff --git a/tests/ui/cfg/assume-incomplete-release/auxiliary/ver-cfg-rel.rs b/tests/ui/cfg/assume-incomplete-release/auxiliary/ver-cfg-rel.rs index e06ee94a1e96f..5d3e9c7a32fe6 100644 --- a/tests/ui/cfg/assume-incomplete-release/auxiliary/ver-cfg-rel.rs +++ b/tests/ui/cfg/assume-incomplete-release/auxiliary/ver-cfg-rel.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{TokenStream, TokenTree as Tt}; use std::str::FromStr; diff --git a/tests/ui/cfg/cfg-attr-cfg.rs b/tests/ui/cfg/cfg-attr-cfg.rs index 67d97e760d778..08b9374cfd7b9 100644 --- a/tests/ui/cfg/cfg-attr-cfg.rs +++ b/tests/ui/cfg/cfg-attr-cfg.rs @@ -2,7 +2,6 @@ // main is conditionally compiled, but the conditional compilation // is conditional too! -//@ pretty-expanded FIXME #23616 #[cfg_attr(FALSE, cfg(bar))] fn main() { } diff --git a/tests/ui/cfg/cfg-attr-crate.rs b/tests/ui/cfg/cfg-attr-crate.rs index 444704d132aa4..44242a6a57d2a 100644 --- a/tests/ui/cfg/cfg-attr-crate.rs +++ b/tests/ui/cfg/cfg-attr-crate.rs @@ -1,7 +1,6 @@ //@ run-pass // https://github.com/rust-lang/rust/issues/21833#issuecomment-72353044 -//@ pretty-expanded FIXME #23616 #![cfg_attr(FALSE, no_core)] diff --git a/tests/ui/cfg/cfg-family.rs b/tests/ui/cfg/cfg-family.rs index caf59327f108d..a13ae7f9616bf 100644 --- a/tests/ui/cfg/cfg-family.rs +++ b/tests/ui/cfg/cfg-family.rs @@ -1,5 +1,4 @@ //@ build-pass -//@ pretty-expanded FIXME #23616 //@ ignore-wasm32 no bare family //@ ignore-sgx diff --git a/tests/ui/cfg/cfg-match-arm.rs b/tests/ui/cfg/cfg-match-arm.rs index e646a63b8fbf8..f6cd52c475cfc 100644 --- a/tests/ui/cfg/cfg-match-arm.rs +++ b/tests/ui/cfg/cfg-match-arm.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 enum Foo { Bar, diff --git a/tests/ui/cfg/cfg-target-family.rs b/tests/ui/cfg/cfg-target-family.rs index ab3be302e6400..0b1c323307a9b 100644 --- a/tests/ui/cfg/cfg-target-family.rs +++ b/tests/ui/cfg/cfg-target-family.rs @@ -1,7 +1,6 @@ //@ build-pass //@ ignore-sgx -//@ pretty-expanded FIXME #23616 #[cfg(target_family = "windows")] pub fn main() {} diff --git a/tests/ui/cfg/cfg_inner_static.rs b/tests/ui/cfg/cfg_inner_static.rs index f4e2dc092f878..8d188b0aed73c 100644 --- a/tests/ui/cfg/cfg_inner_static.rs +++ b/tests/ui/cfg/cfg_inner_static.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:cfg_inner_static.rs -//@ pretty-expanded FIXME #23616 extern crate cfg_inner_static; diff --git a/tests/ui/cfg/conditional-compile-arch.rs b/tests/ui/cfg/conditional-compile-arch.rs index 678b32c6a4e82..594d9344561c2 100644 --- a/tests/ui/cfg/conditional-compile-arch.rs +++ b/tests/ui/cfg/conditional-compile-arch.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #[cfg(target_arch = "x86")] pub fn main() { } diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr index 0a993214f5a1e..32eb01c7018b0 100644 --- a/tests/ui/check-cfg/mix.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -251,7 +251,7 @@ warning: unexpected `cfg` condition value: `zebra` LL | cfg!(target_feature = "zebra"); | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, and `avx512vpopcntdq` and 251 more + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, and `avx512vpopcntdq` and 252 more = note: see for more information about checking conditional configuration warning: 27 warnings emitted diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index ca6a173d6387a..4d375d80e7718 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -174,7 +174,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_feature = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, `avxvnniint8`, `backchain`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `cssc`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `ecv`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `faminmax`, `fcma`, `fdivdu`, `fhm`, `flagm`, `flagm2`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fp8`, `fp8dot2`, `fp8dot4`, `fp8fma`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `hbc`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `leoncasa`, `lor`, `lse`, `lse128`, `lse2`, `lsx`, `lut`, `lvz`, `lzcnt`, `m`, `mclass`, `mops`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `partword-atomics`, `pauth-lr`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `quadword-atomics`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rcpc3`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sha512`, `sign-ext`, `simd128`, `sm3`, `sm4`, `sme`, `sme-b16b16`, `sme-f16f16`, `sme-f64f64`, `sme-f8f16`, `sme-f8f32`, `sme-fa64`, `sme-i16i64`, `sme-lutv2`, `sme2`, `sme2p1`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `ssve-fp8dot2`, `ssve-fp8dot4`, `ssve-fp8fma`, `sve`, `sve-b16b16`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `sve2p1`, `tail-call`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `v8.8a`, `v8.9a`, `v8plus`, `v9`, `v9.1a`, `v9.2a`, `v9.3a`, `v9.4a`, `v9.5a`, `v9a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vector`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `wfxt`, `wide-arithmetic`, `xop`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zaamo`, `zabha`, `zalrsc`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, `avxvnniint8`, `backchain`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `cssc`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `ecv`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `faminmax`, `fcma`, `fdivdu`, `fhm`, `flagm`, `flagm2`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fp8`, `fp8dot2`, `fp8dot4`, `fp8fma`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `hbc`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `leoncasa`, `lor`, `lse`, `lse128`, `lse2`, `lsx`, `lut`, `lvz`, `lzcnt`, `m`, `mclass`, `mops`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `partword-atomics`, `pauth-lr`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `quadword-atomics`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rcpc3`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `reserve-x18`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sha512`, `sign-ext`, `simd128`, `sm3`, `sm4`, `sme`, `sme-b16b16`, `sme-f16f16`, `sme-f64f64`, `sme-f8f16`, `sme-f8f32`, `sme-fa64`, `sme-i16i64`, `sme-lutv2`, `sme2`, `sme2p1`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `ssve-fp8dot2`, `ssve-fp8dot4`, `ssve-fp8fma`, `sve`, `sve-b16b16`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `sve2p1`, `tail-call`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `v8.8a`, `v8.9a`, `v8plus`, `v9`, `v9.1a`, `v9.2a`, `v9.3a`, `v9.4a`, `v9.5a`, `v9a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vector`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `wfxt`, `wide-arithmetic`, `xop`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zaamo`, `zabha`, `zalrsc`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` diff --git a/tests/ui/cleanup-shortcircuit.rs b/tests/ui/cleanup-shortcircuit.rs index 312491fee241e..40a5dfa94e373 100644 --- a/tests/ui/cleanup-shortcircuit.rs +++ b/tests/ui/cleanup-shortcircuit.rs @@ -1,7 +1,6 @@ //@ run-pass // Test that cleanups for the RHS of shortcircuiting operators work. -//@ pretty-expanded FIXME #23616 #![allow(deref_nullptr)] diff --git a/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr b/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr index 5f980c46a1f54..b5ad8eb790f2b 100644 --- a/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr +++ b/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr @@ -5,7 +5,7 @@ LL | let 0 = v1; | ^ pattern `1_u32..=u32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `u32` help: you might want to use `if let` to ignore the variant that isn't matched | @@ -23,7 +23,7 @@ LL | let (0 | 1) = v1; | ^^^^^ pattern `2_u32..=u32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `u32` help: you might want to use `if let` to ignore the variant that isn't matched | @@ -37,7 +37,7 @@ LL | let 1.. = v1; | ^^^ pattern `0_u32` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `u32` help: you might want to use `if let` to ignore the variant that isn't matched | @@ -51,7 +51,7 @@ LL | let [0, 0, 0, 0] = v2; | ^^^^^^^^^^^^ pattern `[1_u32..=u32::MAX, _, _, _]` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `[u32; 4]` help: you might want to use `if let` to ignore the variant that isn't matched | @@ -65,7 +65,7 @@ LL | let [0] = v4; | ^^^ patterns `&[]` and `&[_, _, ..]` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `&[u32]` help: you might want to use `if let` to ignore the variants that aren't matched | @@ -79,7 +79,7 @@ LL | let Refutable::A = v3; | ^^^^^^^^^^^^ pattern `Refutable::B` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `Refutable` defined here --> $DIR/bad-pattern.rs:4:6 | @@ -104,7 +104,7 @@ LL | let PAT = v1; | ^^^ pattern `1_u32..=u32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `u32` help: introduce a variable instead | diff --git a/tests/ui/closures/issue-10682.rs b/tests/ui/closures/issue-10682.rs index 25636b9063b98..265e72aaa690f 100644 --- a/tests/ui/closures/issue-10682.rs +++ b/tests/ui/closures/issue-10682.rs @@ -2,7 +2,6 @@ // Regression test for issue #10682 // Nested `proc` usage can't use outer owned data -//@ pretty-expanded FIXME #23616 fn work(_: Box) {} fn foo(_: F) {} diff --git a/tests/ui/closures/issue-1460.rs b/tests/ui/closures/issue-1460.rs index c201f026bca36..ceb030b92c8ff 100644 --- a/tests/ui/closures/issue-1460.rs +++ b/tests/ui/closures/issue-1460.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { {|i: u32| if 1 == i { }}; //~ WARN unused closure that must be used diff --git a/tests/ui/closures/issue-1460.stderr b/tests/ui/closures/issue-1460.stderr index d4a8c8955e233..15eaf7a9a11ab 100644 --- a/tests/ui/closures/issue-1460.stderr +++ b/tests/ui/closures/issue-1460.stderr @@ -1,5 +1,5 @@ warning: unused closure that must be used - --> $DIR/issue-1460.rs:6:6 + --> $DIR/issue-1460.rs:5:6 | LL | {|i: u32| if 1 == i { }}; | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/closures/issue-868.rs b/tests/ui/closures/issue-868.rs index 170597b4bd5ed..70debbc6c87c6 100644 --- a/tests/ui/closures/issue-868.rs +++ b/tests/ui/closures/issue-868.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_parens)] #![allow(unit_bindings)] -//@ pretty-expanded FIXME #23616 fn f(g: F) -> T where F: FnOnce() -> T { g() } diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs index 9e0ffa75c2296..da1327dace5d4 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs @@ -39,4 +39,4 @@ type WithTransparentTraitObject = //~^ ERROR return value of `"C-cmse-nonsecure-call"` function too large to pass via registers [E0798] type WithVarArgs = extern "C-cmse-nonsecure-call" fn(u32, ...); -//~^ ERROR C-variadic function must have a compatible calling convention, like `C` or `cdecl` [E0045] +//~^ ERROR C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi` [E0045] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr index 7cb8e135ea31b..f20e67e3d9438 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr @@ -68,7 +68,7 @@ LL | extern "C-cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTranspa = note: functions with the `"C-cmse-nonsecure-call"` ABI must pass their result via the available return registers = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size -error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl` +error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi` --> $DIR/generics.rs:41:20 | LL | type WithVarArgs = extern "C-cmse-nonsecure-call" fn(u32, ...); diff --git a/tests/ui/codegen/init-large-type.rs b/tests/ui/codegen/init-large-type.rs index b9fc6612e1687..08697198f2484 100644 --- a/tests/ui/codegen/init-large-type.rs +++ b/tests/ui/codegen/init-large-type.rs @@ -6,7 +6,6 @@ // Doing it incorrectly causes massive slowdown in LLVM during // optimisation. -//@ pretty-expanded FIXME #23616 //@ needs-threads #![feature(intrinsics)] diff --git a/tests/ui/codegen/mismatched-data-layout.json b/tests/ui/codegen/mismatched-data-layout.json index 4cb0602dc75b5..7adc883252474 100644 --- a/tests/ui/codegen/mismatched-data-layout.json +++ b/tests/ui/codegen/mismatched-data-layout.json @@ -5,7 +5,7 @@ "target-endian": "little", "target-pointer-width": "64", "target-c-int-width": "32", - "os": "unknown", + "os": "none", "linker-flavor": "ld.lld", "linker": "rust-lld", "executables": true diff --git a/tests/ui/codegen/mismatched-data-layouts.stderr b/tests/ui/codegen/mismatched-data-layouts.stderr index 1fe242266dff7..b7d5d82bee08c 100644 --- a/tests/ui/codegen/mismatched-data-layouts.stderr +++ b/tests/ui/codegen/mismatched-data-layouts.stderr @@ -1,4 +1,4 @@ -error: data-layout for target `mismatched-data-layout-7814813422914914169`, `normalized data layout`, differs from LLVM target's `x86_64-unknown-none-gnu` default layout, `normalized data layout` +error: data-layout for target `mismatched-data-layout-7193370089426056427`, `normalized data layout`, differs from LLVM target's `x86_64-unknown-none-gnu` default layout, `normalized data layout` error: aborting due to 1 previous error diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.rs b/tests/ui/codemap_tests/huge_multispan_highlight.rs index 7d7b757082350..6f6834b01bd61 100644 --- a/tests/ui/codemap_tests/huge_multispan_highlight.rs +++ b/tests/ui/codemap_tests/huge_multispan_highlight.rs @@ -1,7 +1,7 @@ //@ revisions: ascii unicode //@ compile-flags: --color=always //@[ascii] compile-flags: --error-format=human -//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode //@ ignore-windows fn main() { let _ = match true { diff --git a/tests/ui/coercion/coerce-overloaded-autoderef.rs b/tests/ui/coercion/coerce-overloaded-autoderef.rs index 0605f20e9a328..03d0b0df5435d 100644 --- a/tests/ui/coercion/coerce-overloaded-autoderef.rs +++ b/tests/ui/coercion/coerce-overloaded-autoderef.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_braces)] #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 use std::rc::Rc; diff --git a/tests/ui/coercion/coerce-reborrow-imm-ptr-arg.rs b/tests/ui/coercion/coerce-reborrow-imm-ptr-arg.rs index 139c1d18d2b18..f43b6dad71d32 100644 --- a/tests/ui/coercion/coerce-reborrow-imm-ptr-arg.rs +++ b/tests/ui/coercion/coerce-reborrow-imm-ptr-arg.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn negate(x: &isize) -> isize { -*x diff --git a/tests/ui/coercion/coerce-reborrow-imm-vec-arg.rs b/tests/ui/coercion/coerce-reborrow-imm-vec-arg.rs index d8edd8648c485..afcec17d55ba6 100644 --- a/tests/ui/coercion/coerce-reborrow-imm-vec-arg.rs +++ b/tests/ui/coercion/coerce-reborrow-imm-vec-arg.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn sum(x: &[isize]) -> isize { let mut sum = 0; diff --git a/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr b/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr index 46723c5a297f7..5dea3f70fdb5f 100644 --- a/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr +++ b/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr @@ -16,7 +16,7 @@ LL | fn test(_a: T, _b: T) {} | ^^^^ - ----- ----- this parameter needs to match the `&mut {integer}` type of `_a` | | | | | `_b` needs to match the `&mut {integer}` type of this parameter - | `_a` and `_b` all reference this parameter T + | `_a` and `_b` both reference this parameter `T` error: aborting due to 1 previous error diff --git a/tests/ui/coercion/coerce-reborrow-mut-ptr-arg.rs b/tests/ui/coercion/coerce-reborrow-mut-ptr-arg.rs index 7a08e9fdbe5aa..0367e384829dc 100644 --- a/tests/ui/coercion/coerce-reborrow-mut-ptr-arg.rs +++ b/tests/ui/coercion/coerce-reborrow-mut-ptr-arg.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 struct SpeechMaker { speeches: usize diff --git a/tests/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs b/tests/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs index fc41beb45ccdc..b9479f6bdf835 100644 --- a/tests/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs +++ b/tests/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 struct SpeechMaker { speeches: usize diff --git a/tests/ui/coercion/coerce-unify-return.rs b/tests/ui/coercion/coerce-unify-return.rs index def42d9dc148c..54998a35382c4 100644 --- a/tests/ui/coercion/coerce-unify-return.rs +++ b/tests/ui/coercion/coerce-unify-return.rs @@ -2,7 +2,6 @@ // Check that coercions unify the expected return type of a polymorphic // function call, instead of leaving the type variables as they were. -//@ pretty-expanded FIXME #23616 struct Foo; impl Foo { diff --git a/tests/ui/coercion/coerce-unsize-subtype.rs b/tests/ui/coercion/coerce-unsize-subtype.rs index 5ef9a10889217..a3e762e4c5fa1 100644 --- a/tests/ui/coercion/coerce-unsize-subtype.rs +++ b/tests/ui/coercion/coerce-unsize-subtype.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 use std::rc::Rc; diff --git a/tests/ui/coercion/issue-14589.rs b/tests/ui/coercion/issue-14589.rs index b25ba3758e1f2..1e99cc4f6a836 100644 --- a/tests/ui/coercion/issue-14589.rs +++ b/tests/ui/coercion/issue-14589.rs @@ -2,7 +2,6 @@ // All 3 expressions should work in that the argument gets // coerced to a trait object -//@ pretty-expanded FIXME #23616 fn main() { send::>(Box::new(Output(0))); diff --git a/tests/ui/coercion/issue-14589.stderr b/tests/ui/coercion/issue-14589.stderr index 37b7fce7462b3..5d7b840a8d7db 100644 --- a/tests/ui/coercion/issue-14589.stderr +++ b/tests/ui/coercion/issue-14589.stderr @@ -1,5 +1,5 @@ warning: method `dummy` is never used - --> $DIR/issue-14589.rs:22:16 + --> $DIR/issue-14589.rs:21:16 | LL | trait Foo { fn dummy(&self) { }} | --- ^^^^^ diff --git a/tests/ui/coherence/coherence-bigint-int.rs b/tests/ui/coherence/coherence-bigint-int.rs index 0a9ddf5e2d156..739c035cc9007 100644 --- a/tests/ui/coherence/coherence-bigint-int.rs +++ b/tests/ui/coherence/coherence-bigint-int.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:coherence_lib.rs -//@ pretty-expanded FIXME #23616 extern crate coherence_lib as lib; use lib::Remote1; diff --git a/tests/ui/coherence/coherence-bigint-vecint.rs b/tests/ui/coherence/coherence-bigint-vecint.rs index 6822c6c44b78f..c26defead3ff3 100644 --- a/tests/ui/coherence/coherence-bigint-vecint.rs +++ b/tests/ui/coherence/coherence-bigint-vecint.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:coherence_lib.rs -//@ pretty-expanded FIXME #23616 extern crate coherence_lib as lib; use lib::Remote1; diff --git a/tests/ui/coherence/coherence-blanket.rs b/tests/ui/coherence/coherence-blanket.rs index db10b8e654f5b..cc95e15a4122f 100644 --- a/tests/ui/coherence/coherence-blanket.rs +++ b/tests/ui/coherence/coherence-blanket.rs @@ -2,7 +2,6 @@ #![allow(unused_imports)] //@ aux-build:coherence_lib.rs -//@ pretty-expanded FIXME #23616 extern crate coherence_lib as lib; use lib::Remote1; diff --git a/tests/ui/coherence/coherence-covered-type-parameter.rs b/tests/ui/coherence/coherence-covered-type-parameter.rs index b6332a0442483..3f34934338228 100644 --- a/tests/ui/coherence/coherence-covered-type-parameter.rs +++ b/tests/ui/coherence/coherence-covered-type-parameter.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] //@ aux-build:coherence_lib.rs -//@ pretty-expanded FIXME #23616 extern crate coherence_lib as lib; use lib::Remote; diff --git a/tests/ui/coherence/coherence-iterator-vec-any-elem.rs b/tests/ui/coherence/coherence-iterator-vec-any-elem.rs index a406e4408a439..1e43595d1eb18 100644 --- a/tests/ui/coherence/coherence-iterator-vec-any-elem.rs +++ b/tests/ui/coherence/coherence-iterator-vec-any-elem.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] //@ aux-build:coherence_lib.rs -//@ pretty-expanded FIXME #23616 extern crate coherence_lib as lib; use lib::Remote1; diff --git a/tests/ui/coherence/coherence-iterator-vec.rs b/tests/ui/coherence/coherence-iterator-vec.rs index 2955348493175..02c3a9d2cee29 100644 --- a/tests/ui/coherence/coherence-iterator-vec.rs +++ b/tests/ui/coherence/coherence-iterator-vec.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] //@ aux-build:coherence_lib.rs -//@ pretty-expanded FIXME #23616 extern crate coherence_lib as lib; use lib::Remote1; diff --git a/tests/ui/coherence/coherence-multidispatch-tuple.rs b/tests/ui/coherence/coherence-multidispatch-tuple.rs index ac7b2578d774b..6a2de80c0ea64 100644 --- a/tests/ui/coherence/coherence-multidispatch-tuple.rs +++ b/tests/ui/coherence/coherence-multidispatch-tuple.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(unused_imports)] -//@ pretty-expanded FIXME #23616 use std::fmt::Debug; use std::default::Default; diff --git a/tests/ui/coherence/coherence-negative-impls-safe-rpass.rs b/tests/ui/coherence/coherence-negative-impls-safe-rpass.rs index d69872ba8cffa..5935e972e49e8 100644 --- a/tests/ui/coherence/coherence-negative-impls-safe-rpass.rs +++ b/tests/ui/coherence/coherence-negative-impls-safe-rpass.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #![feature(negative_impls)] diff --git a/tests/ui/coherence/fuzzing/best-obligation-ICE.rs b/tests/ui/coherence/fuzzing/best-obligation-ICE.rs new file mode 100644 index 0000000000000..49f40b579d400 --- /dev/null +++ b/tests/ui/coherence/fuzzing/best-obligation-ICE.rs @@ -0,0 +1,20 @@ +// A regression test for #129444. This previously ICE'd as +// computing the best obligation for one ambiguous obligation +// added spurious inference constraints which caused another +// candidate to pass. +trait Trait { + type Assoc; +} + +struct W(*mut T); +impl Trait for W>> {} +//~^ ERROR the trait bound `W>: Trait` is not satisfied +//~| ERROR the trait bound `W: Trait` is not satisfied +//~| ERROR the trait bound `T: Trait` is not satisfied +//~| ERROR not all trait items implemented, missing: `Assoc` + +trait NoOverlap {} +impl NoOverlap for T {} +impl> NoOverlap for W {} +//~^ ERROR conflicting implementations of trait `NoOverlap` for type `W>>>` +fn main() {} diff --git a/tests/ui/coherence/fuzzing/best-obligation-ICE.stderr b/tests/ui/coherence/fuzzing/best-obligation-ICE.stderr new file mode 100644 index 0000000000000..88de8023f6d79 --- /dev/null +++ b/tests/ui/coherence/fuzzing/best-obligation-ICE.stderr @@ -0,0 +1,69 @@ +error[E0277]: the trait bound `W>: Trait` is not satisfied + --> $DIR/best-obligation-ICE.rs:10:19 + | +LL | impl Trait for W>> {} + | ^^^^^^^^^^ the trait `Trait` is not implemented for `W>` + | +note: required by a bound in `W` + --> $DIR/best-obligation-ICE.rs:9:13 + | +LL | struct W(*mut T); + | ^^^^^ required by this bound in `W` +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | impl Trait for W>> where W>: Trait {} + | ++++++++++++++++++++ + +error[E0277]: the trait bound `W: Trait` is not satisfied + --> $DIR/best-obligation-ICE.rs:10:19 + | +LL | impl Trait for W>> {} + | ^^^^^^^^^^ the trait `Trait` is not implemented for `W` + | +note: required by a bound in `W` + --> $DIR/best-obligation-ICE.rs:9:13 + | +LL | struct W(*mut T); + | ^^^^^ required by this bound in `W` +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | impl Trait for W>> where W: Trait {} + | +++++++++++++++++ + +error[E0277]: the trait bound `T: Trait` is not satisfied + --> $DIR/best-obligation-ICE.rs:10:19 + | +LL | impl Trait for W>> {} + | ^^^^^^^^^^ the trait `Trait` is not implemented for `T` + | +note: required by a bound in `W` + --> $DIR/best-obligation-ICE.rs:9:13 + | +LL | struct W(*mut T); + | ^^^^^ required by this bound in `W` +help: consider restricting type parameter `T` + | +LL | impl Trait for W>> {} + | +++++++ + +error[E0046]: not all trait items implemented, missing: `Assoc` + --> $DIR/best-obligation-ICE.rs:10:1 + | +LL | type Assoc; + | ---------- `Assoc` from trait +... +LL | impl Trait for W>> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Assoc` in implementation + +error[E0119]: conflicting implementations of trait `NoOverlap` for type `W>>>` + --> $DIR/best-obligation-ICE.rs:18:1 + | +LL | impl NoOverlap for T {} + | ------------------------------ first implementation here +LL | impl> NoOverlap for W {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W>>>` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0046, E0119, E0277. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr index ce7fce2599360..06a6a5f59d6da 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr +++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr @@ -53,7 +53,7 @@ LL | let _: [u8; baz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:26:23 + --> $DIR/const-arg-in-const-arg.rs:27:23 | LL | let _ = [0; bar::()]; | ^ cannot perform const operation using `N` @@ -62,7 +62,7 @@ LL | let _ = [0; bar::()]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:28:23 + --> $DIR/const-arg-in-const-arg.rs:29:23 | LL | let _ = [0; faz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -71,7 +71,7 @@ LL | let _ = [0; faz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:30:23 + --> $DIR/const-arg-in-const-arg.rs:31:23 | LL | let _ = [0; baz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -80,7 +80,7 @@ LL | let _ = [0; baz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:31:23 + --> $DIR/const-arg-in-const-arg.rs:32:23 | LL | let _ = [0; faz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -89,7 +89,7 @@ LL | let _ = [0; faz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:33:23 + --> $DIR/const-arg-in-const-arg.rs:34:23 | LL | let _ = [0; baz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -98,7 +98,7 @@ LL | let _ = [0; baz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:34:24 + --> $DIR/const-arg-in-const-arg.rs:35:24 | LL | let _: Foo<{ foo::() }>; | ^ cannot perform const operation using `T` @@ -107,7 +107,7 @@ LL | let _: Foo<{ foo::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:35:24 + --> $DIR/const-arg-in-const-arg.rs:36:24 | LL | let _: Foo<{ bar::() }>; | ^ cannot perform const operation using `N` @@ -116,7 +116,7 @@ LL | let _: Foo<{ bar::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:37:24 + --> $DIR/const-arg-in-const-arg.rs:38:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -125,7 +125,7 @@ LL | let _: Foo<{ faz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:39:24 + --> $DIR/const-arg-in-const-arg.rs:40:24 | LL | let _: Foo<{ baz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -134,7 +134,7 @@ LL | let _: Foo<{ baz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:40:24 + --> $DIR/const-arg-in-const-arg.rs:41:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -143,7 +143,7 @@ LL | let _: Foo<{ faz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:42:24 + --> $DIR/const-arg-in-const-arg.rs:43:24 | LL | let _: Foo<{ baz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -152,7 +152,7 @@ LL | let _: Foo<{ baz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:43:27 + --> $DIR/const-arg-in-const-arg.rs:44:27 | LL | let _ = Foo::<{ foo::() }>; | ^ cannot perform const operation using `T` @@ -161,7 +161,7 @@ LL | let _ = Foo::<{ foo::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:44:27 + --> $DIR/const-arg-in-const-arg.rs:45:27 | LL | let _ = Foo::<{ bar::() }>; | ^ cannot perform const operation using `N` @@ -170,7 +170,7 @@ LL | let _ = Foo::<{ bar::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:46:27 + --> $DIR/const-arg-in-const-arg.rs:47:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -179,7 +179,7 @@ LL | let _ = Foo::<{ faz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:48:27 + --> $DIR/const-arg-in-const-arg.rs:49:27 | LL | let _ = Foo::<{ baz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -188,7 +188,7 @@ LL | let _ = Foo::<{ baz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:49:27 + --> $DIR/const-arg-in-const-arg.rs:50:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -197,7 +197,7 @@ LL | let _ = Foo::<{ faz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:51:27 + --> $DIR/const-arg-in-const-arg.rs:52:27 | LL | let _ = Foo::<{ baz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -241,7 +241,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:35:24 + --> $DIR/const-arg-in-const-arg.rs:36:24 | LL | let _: Foo<{ bar::() }>; | ^ @@ -252,7 +252,7 @@ LL | let _: Foo<{ bar::<{ N }>() }>; | + + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:37:24 + --> $DIR/const-arg-in-const-arg.rs:38:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ @@ -264,7 +264,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:40:24 + --> $DIR/const-arg-in-const-arg.rs:41:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ @@ -283,8 +283,16 @@ LL | let _ = [0; foo::()]; | = note: this may fail depending on what value the parameter takes +error: constant expression depends on a generic parameter + --> $DIR/const-arg-in-const-arg.rs:25:13 + | +LL | let _ = [0; foo::()]; + | ^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:26:23 + --> $DIR/const-arg-in-const-arg.rs:27:23 | LL | let _ = [0; bar::()]; | ^ @@ -295,7 +303,7 @@ LL | let _ = [0; bar::<{ N }>()]; | + + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:28:23 + --> $DIR/const-arg-in-const-arg.rs:29:23 | LL | let _ = [0; faz::<'a>(&())]; | ^^ @@ -307,7 +315,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:31:23 + --> $DIR/const-arg-in-const-arg.rs:32:23 | LL | let _ = [0; faz::<'b>(&())]; | ^^ @@ -319,7 +327,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:44:27 + --> $DIR/const-arg-in-const-arg.rs:45:27 | LL | let _ = Foo::<{ bar::() }>; | ^ @@ -330,7 +338,7 @@ LL | let _ = Foo::<{ bar::<{ N }>() }>; | + + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:46:27 + --> $DIR/const-arg-in-const-arg.rs:47:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ @@ -342,7 +350,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:49:27 + --> $DIR/const-arg-in-const-arg.rs:50:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ @@ -353,7 +361,7 @@ note: the late bound lifetime parameter is introduced here LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ -error: aborting due to 36 previous errors +error: aborting due to 37 previous errors Some errors have detailed explanations: E0747, E0794. For more information about an error, try `rustc --explain E0747`. diff --git a/tests/ui/const-generics/const-arg-in-const-arg.rs b/tests/ui/const-generics/const-arg-in-const-arg.rs index 27b74489fe8e0..0e1c6552edf1e 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.rs +++ b/tests/ui/const-generics/const-arg-in-const-arg.rs @@ -23,6 +23,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _: [u8; baz::<'b>(&())]; //[min]~ ERROR generic parameters may not let _ = [0; foo::()]; //[min]~ ERROR constant expression depends on a generic parameter + //[min]~^ ERROR constant expression depends on a generic parameter let _ = [0; bar::()]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected let _ = [0; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not diff --git a/tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr b/tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr index d5eefd3575365..f58821283e19f 100644 --- a/tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr +++ b/tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/const-argument-cross-crate-mismatch.rs:6:67 | LL | let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8])); - | ------------------------- ^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements + | ------------------------- ^^^^^^^^^^ expected an array with a size of 3, found one with a size of 2 | | | arguments to this struct are incorrect | @@ -16,7 +16,7 @@ error[E0308]: mismatched types --> $DIR/const-argument-cross-crate-mismatch.rs:8:65 | LL | let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]); - | ------------------------- ^^^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements + | ------------------------- ^^^^^^^^^^^^^^^ expected an array with a size of 2, found one with a size of 3 | | | arguments to this struct are incorrect | diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-1.rs similarity index 56% rename from tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs rename to tests/ui/const-generics/early/const_arg_trivial_macro_expansion-1.rs index 2fdd703ab6f32..5ea445520f1a5 100644 --- a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs +++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-1.rs @@ -85,6 +85,14 @@ macro_rules! braced_braced_expr { () => {{ braced_expr!() }}; } +macro_rules! closure { + () => { |()| () }; +} + +macro_rules! empty { + () => {}; +} + #[rustfmt::skip] mod array_paren_call { // Arrays where the expanded result is a `Res::Err` @@ -128,6 +136,14 @@ mod array_paren_call { fn array_33() -> [(); braced_expr!()] { loop {} } fn array_34() -> [(); { unbraced_expr!() }] { loop {} } fn array_35() -> [(); { braced_expr!() }] { loop {} } + + // Arrays whose expanded form contains a nested definition + fn array_36() -> [(); closure!()] { loop {} } + fn array_37() -> [(); { closure!() }] { loop {} } + + // Arrays whose macro expansion is empty + fn array_38() -> [(); empty!()] { loop {} } + fn array_39() -> [(); { empty!() }] { loop {} } } #[rustfmt::skip] @@ -173,6 +189,14 @@ mod array_brace_call { fn array_33() -> [(); braced_expr!{}] { loop {} } fn array_34() -> [(); { unbraced_expr!{} }] { loop {} } fn array_35() -> [(); { braced_expr!{} }] { loop {} } + + // Arrays whose expanded form contains a nested definition + fn array_36() -> [(); closure!{}] { loop {} } + fn array_37() -> [(); { closure!{} }] { loop {} } + + // Arrays whose macro expansion is empty + fn array_38() -> [(); empty!{}] { loop {} } + fn array_39() -> [(); { empty!{} }] { loop {} } } #[rustfmt::skip] @@ -218,6 +242,14 @@ mod array_square_call { fn array_33() -> [(); braced_expr![]] { loop {} } fn array_34() -> [(); { unbraced_expr![] }] { loop {} } fn array_35() -> [(); { braced_expr![] }] { loop {} } + + // Arrays whose expanded form contains a nested definition + fn array_36() -> [(); closure![]] { loop {} } + fn array_37() -> [(); { closure![] }] { loop {} } + + // Arrays whose macro expansion is empty + fn array_38() -> [(); empty![]] { loop {} } + fn array_39() -> [(); { empty![] }] { loop {} } } struct Foo; @@ -255,18 +287,26 @@ mod adt_paren_call { fn adt_23() -> Foo<{ braced_ident!() }> { loop {} } // An ADT where the expanded result is a complex expr - fn array_24() -> Foo { loop {} } - fn array_25() -> Foo { loop {} } - fn array_26() -> Foo { loop {} } - fn array_27() -> Foo { loop {} } - fn array_28() -> Foo<{ unbraced_unbraced_expr!() }> { loop {} } - fn array_29() -> Foo<{ braced_unbraced_expr!() }> { loop {} } - fn array_30() -> Foo<{ unbraced_braced_expr!() }> { loop {} } - fn array_31() -> Foo<{ braced_braced_expr!() }> { loop {} } - fn array_32() -> Foo { loop {} } - fn array_33() -> Foo { loop {} } - fn array_34() -> Foo<{ unbraced_expr!() }> { loop {} } - fn array_35() -> Foo<{ braced_expr!() }> { loop {} } + fn adt_24() -> Foo { loop {} } + fn adt_25() -> Foo { loop {} } + fn adt_26() -> Foo { loop {} } + fn adt_27() -> Foo { loop {} } + fn adt_28() -> Foo<{ unbraced_unbraced_expr!() }> { loop {} } + fn adt_29() -> Foo<{ braced_unbraced_expr!() }> { loop {} } + fn adt_30() -> Foo<{ unbraced_braced_expr!() }> { loop {} } + fn adt_31() -> Foo<{ braced_braced_expr!() }> { loop {} } + fn adt_32() -> Foo { loop {} } + fn adt_33() -> Foo { loop {} } + fn adt_34() -> Foo<{ unbraced_expr!() }> { loop {} } + fn adt_35() -> Foo<{ braced_expr!() }> { loop {} } + + // An ADT whose expanded form contains a nested definition + fn adt_36() -> Foo { loop {} } + fn adt_37() -> Foo<{ closure!() }> { loop {} } + + // An ADT whose macro expansion is empty + fn adt_38() -> Foo { loop {} } + fn adt_39() -> Foo<{ empty!() }> { loop {} } } #[rustfmt::skip] @@ -302,18 +342,26 @@ mod adt_brace_call { fn adt_23() -> Foo<{ braced_ident!{} }> { loop {} } // An ADT where the expanded result is a complex expr - fn array_24() -> Foo { loop {} } - fn array_25() -> Foo { loop {} } - fn array_26() -> Foo { loop {} } - fn array_27() -> Foo { loop {} } - fn array_28() -> Foo<{ unbraced_unbraced_expr!{} }> { loop {} } - fn array_29() -> Foo<{ braced_unbraced_expr!{} }> { loop {} } - fn array_30() -> Foo<{ unbraced_braced_expr!{} }> { loop {} } - fn array_31() -> Foo<{ braced_braced_expr!{} }> { loop {} } - fn array_32() -> Foo { loop {} } - fn array_33() -> Foo { loop {} } - fn array_34() -> Foo<{ unbraced_expr!{} }> { loop {} } - fn array_35() -> Foo<{ braced_expr!{} }> { loop {} } + fn adt_24() -> Foo { loop {} } + fn adt_25() -> Foo { loop {} } + fn adt_26() -> Foo { loop {} } + fn adt_27() -> Foo { loop {} } + fn adt_28() -> Foo<{ unbraced_unbraced_expr!{} }> { loop {} } + fn adt_29() -> Foo<{ braced_unbraced_expr!{} }> { loop {} } + fn adt_30() -> Foo<{ unbraced_braced_expr!{} }> { loop {} } + fn adt_31() -> Foo<{ braced_braced_expr!{} }> { loop {} } + fn adt_32() -> Foo { loop {} } + fn adt_33() -> Foo { loop {} } + fn adt_34() -> Foo<{ unbraced_expr!{} }> { loop {} } + fn adt_35() -> Foo<{ braced_expr!{} }> { loop {} } + + // An ADT whose expanded form contains a nested definition + fn adt_36() -> Foo { loop {} } + fn adt_37() -> Foo<{ closure!{} }> { loop {} } + + // An ADT whose macro expansion is empty + fn adt_38() -> Foo { loop {} } + fn adt_39() -> Foo<{ empty!{} }> { loop {} } } #[rustfmt::skip] @@ -349,18 +397,185 @@ mod adt_square_call { fn adt_23() -> Foo<{ braced_ident![] }> { loop {} } // An ADT where the expanded result is a complex expr - fn array_24() -> Foo { loop {} } - fn array_25() -> Foo { loop {} } - fn array_26() -> Foo { loop {} } - fn array_27() -> Foo { loop {} } - fn array_28() -> Foo<{ unbraced_unbraced_expr![] }> { loop {} } - fn array_29() -> Foo<{ braced_unbraced_expr![] }> { loop {} } - fn array_30() -> Foo<{ unbraced_braced_expr![] }> { loop {} } - fn array_31() -> Foo<{ braced_braced_expr![] }> { loop {} } - fn array_32() -> Foo { loop {} } - fn array_33() -> Foo { loop {} } - fn array_34() -> Foo<{ unbraced_expr![] }> { loop {} } - fn array_35() -> Foo<{ braced_expr![] }> { loop {} } + fn adt_24() -> Foo { loop {} } + fn adt_25() -> Foo { loop {} } + fn adt_26() -> Foo { loop {} } + fn adt_27() -> Foo { loop {} } + fn adt_28() -> Foo<{ unbraced_unbraced_expr![] }> { loop {} } + fn adt_29() -> Foo<{ braced_unbraced_expr![] }> { loop {} } + fn adt_30() -> Foo<{ unbraced_braced_expr![] }> { loop {} } + fn adt_31() -> Foo<{ braced_braced_expr![] }> { loop {} } + fn adt_32() -> Foo { loop {} } + fn adt_33() -> Foo { loop {} } + fn adt_34() -> Foo<{ unbraced_expr![] }> { loop {} } + fn adt_35() -> Foo<{ braced_expr![] }> { loop {} } + + // An ADT whose expanded form contains a nested definition + fn adt_36() -> Foo { loop {} } + fn adt_37() -> Foo<{ closure![] }> { loop {} } + + // An ADT whose macro expansion is empty + fn adt_38() -> Foo { loop {} } + fn adt_39() -> Foo<{ empty![] }> { loop {} } +} + +#[rustfmt::skip] +mod repeat_paren_call { + // A repeat expr where the expanded result is a `Res::Err` + fn repeat_0() { [(); unbraced_unbraced_ident!()]; } + fn repeat_1() { [(); braced_unbraced_ident!()]; } + fn repeat_2() { [(); unbraced_braced_ident!()]; } + fn repeat_3() { [(); braced_braced_ident!()]; } + fn repeat_4() { [(); { unbraced_unbraced_ident!() }]; } + fn repeat_5() { [(); { braced_unbraced_ident!() }]; } + fn repeat_6() { [(); { unbraced_braced_ident!() }]; } + fn repeat_7() { [(); { braced_braced_ident!() }]; } + fn repeat_8() { [(); unbraced_ident!()]; } + fn repeat_9() { [(); braced_ident!()]; } + fn repeat_10() { [(); { unbraced_ident!() }]; } + fn repeat_11() { [(); { braced_ident!() }]; } + + // A repeat expr where the expanded result is a `Res::ConstParam` + fn repeat_12() { [(); unbraced_unbraced_ident!()]; } + fn repeat_13() { [(); braced_unbraced_ident!()]; } + fn repeat_14() { [(); unbraced_braced_ident!()]; } + fn repeat_15() { [(); braced_braced_ident!()]; } + fn repeat_16() { [(); { unbraced_unbraced_ident!() }]; } + fn repeat_17() { [(); { braced_unbraced_ident!() }]; } + fn repeat_18() { [(); { unbraced_braced_ident!() }]; } + fn repeat_19() { [(); { braced_braced_ident!() }]; } + fn repeat_20() { [(); unbraced_ident!()]; } + fn repeat_21() { [(); braced_ident!()]; } + fn repeat_22() { [(); { unbraced_ident!() }]; } + fn repeat_23() { [(); { braced_ident!() }]; } + + // A repeat expr where the expanded result is a complex expr + fn repeat_24() { [(); unbraced_unbraced_expr!()]; } + fn repeat_25() { [(); braced_unbraced_expr!()]; } + fn repeat_26() { [(); unbraced_braced_expr!()]; } + fn repeat_27() { [(); braced_braced_expr!()]; } + fn repeat_28() { [(); { unbraced_unbraced_expr!() }]; } + fn repeat_29() { [(); { braced_unbraced_expr!() }]; } + fn repeat_30() { [(); { unbraced_braced_expr!() }]; } + fn repeat_31() { [(); { braced_braced_expr!() }]; } + fn repeat_32() { [(); unbraced_expr!()]; } + fn repeat_33() { [(); braced_expr!()]; } + fn repeat_34() { [(); { unbraced_expr!() }]; } + fn repeat_35() { [(); { braced_expr!() }]; } + + // A repeat expr whose expanded form contains a nested definition + fn repeat_36() { [(); closure!()] } + fn repeat_37() { [(); { closure!() }] } + + // A repeat expr whose macro expansion is empty + fn repeat_38() { [(); empty!()] } + fn repeat_39() { [(); { empty!() }] } +} + +#[rustfmt::skip] +mod repeat_brace_call { + // A repeat expr where the expanded result is a `Res::Err` + fn repeat_0() { [(); unbraced_unbraced_ident!{}]; } + fn repeat_1() { [(); braced_unbraced_ident!{}]; } + fn repeat_2() { [(); unbraced_braced_ident!{}]; } + fn repeat_3() { [(); braced_braced_ident!{}]; } + fn repeat_4() { [(); { unbraced_unbraced_ident!{} }]; } + fn repeat_5() { [(); { braced_unbraced_ident!{} }]; } + fn repeat_6() { [(); { unbraced_braced_ident!{} }]; } + fn repeat_7() { [(); { braced_braced_ident!{} }]; } + fn repeat_8() { [(); unbraced_ident!{}]; } + fn repeat_9() { [(); braced_ident!{}]; } + fn repeat_10() { [(); { unbraced_ident!{} }]; } + fn repeat_11() { [(); { braced_ident!{} }]; } + + // A repeat expr where the expanded result is a `Res::ConstParam` + fn repeat_12() { [(); unbraced_unbraced_ident!{}]; } + fn repeat_13() { [(); braced_unbraced_ident!{}]; } + fn repeat_14() { [(); unbraced_braced_ident!{}]; } + fn repeat_15() { [(); braced_braced_ident!{}]; } + fn repeat_16() { [(); { unbraced_unbraced_ident!{} }]; } + fn repeat_17() { [(); { braced_unbraced_ident!{} }]; } + fn repeat_18() { [(); { unbraced_braced_ident!{} }]; } + fn repeat_19() { [(); { braced_braced_ident!{} }]; } + fn repeat_20() { [(); unbraced_ident!{}]; } + fn repeat_21() { [(); braced_ident!{}]; } + fn repeat_22() { [(); { unbraced_ident!{} }]; } + fn repeat_23() { [(); { braced_ident!{} }]; } + + // A repeat expr where the expanded result is a complex expr + fn repeat_24() { [(); unbraced_unbraced_expr!{}]; } + fn repeat_25() { [(); braced_unbraced_expr!{}]; } + fn repeat_26() { [(); unbraced_braced_expr!{}]; } + fn repeat_27() { [(); braced_braced_expr!{}]; } + fn repeat_28() { [(); { unbraced_unbraced_expr!{} }]; } + fn repeat_29() { [(); { braced_unbraced_expr!{} }]; } + fn repeat_30() { [(); { unbraced_braced_expr!{} }]; } + fn repeat_31() { [(); { braced_braced_expr!{} }]; } + fn repeat_32() { [(); unbraced_expr!{}]; } + fn repeat_33() { [(); braced_expr!{}]; } + fn repeat_34() { [(); { unbraced_expr!{} }]; } + fn repeat_35() { [(); { braced_expr!{} }]; } + + // A repeat expr whose expanded form contains a nested definition + fn repeat_36() { [(); closure!{}] } + fn repeat_37() { [(); { closure!{} }] } + + // A repeat expr whose macro expansion is empty + fn repeat_38() { [(); empty!{}] } + fn repeat_39() { [(); { empty!{} }] } +} + +#[rustfmt::skip] +mod repeat_square_call { + // A repeat expr where the expanded result is a `Res::Err` + fn repeat_0() { [(); unbraced_unbraced_ident![]]; } + fn repeat_1() { [(); braced_unbraced_ident![]]; } + fn repeat_2() { [(); unbraced_braced_ident![]]; } + fn repeat_3() { [(); braced_braced_ident![]]; } + fn repeat_4() { [(); { unbraced_unbraced_ident![] }]; } + fn repeat_5() { [(); { braced_unbraced_ident![] }]; } + fn repeat_6() { [(); { unbraced_braced_ident![] }]; } + fn repeat_7() { [(); { braced_braced_ident![] }]; } + fn repeat_8() { [(); unbraced_ident![]]; } + fn repeat_9() { [(); braced_ident![]]; } + fn repeat_10() { [(); { unbraced_ident![] }]; } + fn repeat_11() { [(); { braced_ident![] }]; } + + // A repeat expr where the expanded result is a `Res::ConstParam` + fn repeat_12() { [(); unbraced_unbraced_ident![]]; } + fn repeat_13() { [(); braced_unbraced_ident![]]; } + fn repeat_14() { [(); unbraced_braced_ident![]]; } + fn repeat_15() { [(); braced_braced_ident![]]; } + fn repeat_16() { [(); { unbraced_unbraced_ident![] }]; } + fn repeat_17() { [(); { braced_unbraced_ident![] }]; } + fn repeat_18() { [(); { unbraced_braced_ident![] }]; } + fn repeat_19() { [(); { braced_braced_ident![] }]; } + fn repeat_20() { [(); unbraced_ident![]]; } + fn repeat_21() { [(); braced_ident![]]; } + fn repeat_22() { [(); { unbraced_ident![] }]; } + fn repeat_23() { [(); { braced_ident![] }]; } + + // A repeat expr where the expanded result is a complex expr + fn repeat_24() { [(); unbraced_unbraced_expr![]]; } + fn repeat_25() { [(); braced_unbraced_expr![]]; } + fn repeat_26() { [(); unbraced_braced_expr![]]; } + fn repeat_27() { [(); braced_braced_expr![]]; } + fn repeat_28() { [(); { unbraced_unbraced_expr![] }]; } + fn repeat_29() { [(); { braced_unbraced_expr![] }]; } + fn repeat_30() { [(); { unbraced_braced_expr![] }]; } + fn repeat_31() { [(); { braced_braced_expr![] }]; } + fn repeat_32() { [(); unbraced_expr![]]; } + fn repeat_33() { [(); braced_expr![]]; } + fn repeat_34() { [(); { unbraced_expr![] }]; } + fn repeat_35() { [(); { braced_expr![] }]; } + + // A repeat expr whose expanded form contains a nested definition + fn repeat_36() { [(); closure![]] } + fn repeat_37() { [(); { closure![] }] } + + // A repeat expr whose macro expansion is empty + fn repeat_38() { [(); empty![]] } + fn repeat_39() { [(); { empty![] }] } } fn main() {} diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-3-pass.rs b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-3-pass.rs new file mode 100644 index 0000000000000..fb6190324c6cf --- /dev/null +++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-3-pass.rs @@ -0,0 +1,46 @@ +// Additional checks for macro expansion in const args + +//@ check-pass + +macro_rules! closure { + () => { |()| () }; +} + +macro_rules! indir_semi { + ($nested:ident) => { $nested!(); }; +} + +macro_rules! indir { + ($nested:ident) => { $nested!() }; +} + +macro_rules! empty { + () => {}; +} + +macro_rules! arg { + () => { N }; +} + +struct Adt; + +fn array1() -> [(); { closure!(); 0 }] { loop {} } +fn array2() -> [(); { indir!(closure); 0}] { loop {} } +fn array3() -> [(); { indir_semi!{ closure } 0 }] { loop {} } +fn array4() -> [(); { indir!{ empty } arg!{} }] { loop {} } +fn array5() -> [(); { empty!{} arg!() }] { loop {} } +fn array6() -> [(); { empty!{} N }] { loop {} } +fn array7() -> [(); { arg!{} empty!{} }] { loop {} } +fn array8() -> [(); { empty!{} arg!{} empty!{} }] { loop {} } + +fn adt1() -> Adt<{ closure!(); 0 }> { loop {} } +fn adt2() -> Adt<{ indir!(closure); 0}> { loop {} } +fn adt3() -> Adt<{ indir_semi!{ closure } 0 }> { loop {} } +fn adt4() -> Adt<{ indir!{ empty } arg!{} }> { loop {} } +fn adt5() -> Adt<{ empty!{} arg!() }> { loop {} } +fn adt6() -> Adt<{ empty!{} N }> { loop {} } +fn adt7() -> Adt<{ arg!{} empty!{} }> { loop {} } +fn adt8() -> Adt<{ empty!{} arg!{} empty!{} }> { loop {} } + + +fn main() {} diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.rs b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.rs new file mode 100644 index 0000000000000..3353d6cf2da3d --- /dev/null +++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.rs @@ -0,0 +1,18 @@ +macro_rules! empty { + () => {}; +} + +macro_rules! arg { + () => { + N + //~^ ERROR generic parameters may not be used in const operations + //~| ERROR generic parameters may not be used in const operations + }; +} + +struct Foo; +fn foo() -> Foo<{ arg!{} arg!{} }> { loop {} } +fn bar() -> [(); { empty!{}; N }] { loop {} } +//~^ ERROR generic parameters may not be used in const operations + +fn main() {} diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.stderr b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.stderr new file mode 100644 index 0000000000000..4722968b20346 --- /dev/null +++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.stderr @@ -0,0 +1,37 @@ +error: generic parameters may not be used in const operations + --> $DIR/const_arg_trivial_macro_expansion-4.rs:7:9 + | +LL | N + | ^ cannot perform const operation using `N` +... +LL | fn foo() -> Foo<{ arg!{} arg!{} }> { loop {} } + | ------ in this macro invocation + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = note: this error originates in the macro `arg` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: generic parameters may not be used in const operations + --> $DIR/const_arg_trivial_macro_expansion-4.rs:7:9 + | +LL | N + | ^ cannot perform const operation using `N` +... +LL | fn foo() -> Foo<{ arg!{} arg!{} }> { loop {} } + | ------ in this macro invocation + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = note: this error originates in the macro `arg` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: generic parameters may not be used in const operations + --> $DIR/const_arg_trivial_macro_expansion-4.rs:15:46 + | +LL | fn bar() -> [(); { empty!{}; N }] { loop {} } + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: aborting due to 3 previous errors + diff --git a/tests/ui/const-generics/generic-param-mismatch.stderr b/tests/ui/const-generics/generic-param-mismatch.stderr index be6b3b90ec72a..099ce03317d33 100644 --- a/tests/ui/const-generics/generic-param-mismatch.stderr +++ b/tests/ui/const-generics/generic-param-mismatch.stderr @@ -4,10 +4,7 @@ error[E0308]: mismatched types LL | fn test() -> [u8; M] { | ------- expected `[u8; M]` because of return type LL | [0; N] - | ^^^^^^ expected `M`, found `N` - | - = note: expected array `[u8; M]` - found array `[u8; N]` + | ^^^^^^ expected an array with a size of M, found one with a size of N error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic_const_exprs/bad-multiply.rs b/tests/ui/const-generics/generic_const_exprs/bad-multiply.rs new file mode 100644 index 0000000000000..1af6d5742b1f6 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/bad-multiply.rs @@ -0,0 +1,18 @@ +// regression test for #124350 + +struct Node {} + +impl Node +where + SmallVec<{ D * 2 }>:, + //~^ ERROR generic parameters may not be used in const operations + //~| ERROR constant provided when a type was expected +{ + fn new() -> Self { + Node::new() + } +} + +struct SmallVec(T1); + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr b/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr new file mode 100644 index 0000000000000..a8d6cebabe718 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr @@ -0,0 +1,18 @@ +error: generic parameters may not be used in const operations + --> $DIR/bad-multiply.rs:7:16 + | +LL | SmallVec<{ D * 2 }>:, + | ^ cannot perform const operation using `D` + | + = help: const parameters may only be used as standalone arguments, i.e. `D` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error[E0747]: constant provided when a type was expected + --> $DIR/bad-multiply.rs:7:14 + | +LL | SmallVec<{ D * 2 }>:, + | ^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0747`. diff --git a/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr index 632ece0ddcb30..7e318f8786f39 100644 --- a/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr +++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr @@ -1,11 +1,3 @@ -error: overly complex generic constant - --> $DIR/dependence_lint.rs:17:9 - | -LL | [0; if false { size_of::() } else { 3 }]; // lint on stable, error with gce - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants - | - = help: consider moving this anonymous constant into a `const` function - error: overly complex generic constant --> $DIR/dependence_lint.rs:21:17 | @@ -36,5 +28,13 @@ help: try adding a `where` bound LL | fn foo() where [(); size_of::<*mut T>()]: { | ++++++++++++++++++++++++++++++++ +error: overly complex generic constant + --> $DIR/dependence_lint.rs:17:9 + | +LL | [0; if false { size_of::() } else { 3 }]; // lint on stable, error with gce + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants + | + = help: consider moving this anonymous constant into a `const` function + error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr index 14c67e2528a73..8efd433fd1fe9 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr @@ -10,12 +10,10 @@ error[E0308]: mismatched types --> $DIR/issue-62504.rs:18:21 | LL | ArrayHolder([0; Self::SIZE]) - | ----------- ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE` + | ----------- ^^^^^^^^^^^^^^^ expected an array with a size of X, found one with a size of Self::SIZE | | | arguments to this struct are incorrect | - = note: expected array `[u32; X]` - found array `[u32; Self::SIZE]` note: tuple struct defined here --> $DIR/issue-62504.rs:14:8 | diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs new file mode 100644 index 0000000000000..e5af632da7577 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs @@ -0,0 +1,18 @@ +// Regression test for #133271. +#![feature(generic_const_exprs)] +//~^ WARN the feature `generic_const_exprs` is incomplete + +struct Foo; +impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo +//~^ ERROR the const parameter `NUM` is not constrained by the impl trait, self type, or predicates +where + [(); 1 + 0]: Sized, +{ + fn unimplemented(self, _: &Foo) -> Self::Output { + //~^ ERROR method `unimplemented` is not a member of trait `std::ops::Add` + //~| ERROR type annotations needed + loop {} + } +} + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr new file mode 100644 index 0000000000000..ade18eb88b901 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr @@ -0,0 +1,46 @@ +error[E0407]: method `unimplemented` is not a member of trait `std::ops::Add` + --> $DIR/post-analysis-user-facing-param-env.rs:11:5 + | +LL | / fn unimplemented(self, _: &Foo) -> Self::Output { +LL | | +LL | | +LL | | loop {} +LL | | } + | |_____^ not a member of trait `std::ops::Add` + +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/post-analysis-user-facing-param-env.rs:2:12 + | +LL | #![feature(generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #76560 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0207]: the const parameter `NUM` is not constrained by the impl trait, self type, or predicates + --> $DIR/post-analysis-user-facing-param-env.rs:6:10 + | +LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo + | ^^^^^^^^^^^^^^^^ unconstrained const parameter + | + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported + +error[E0284]: type annotations needed + --> $DIR/post-analysis-user-facing-param-env.rs:11:40 + | +LL | fn unimplemented(self, _: &Foo) -> Self::Output { + | ^^^^^^^^^^^^ cannot infer the value of const parameter `NUM` + | +note: required for `Foo` to implement `Add<&'a Foo>` + --> $DIR/post-analysis-user-facing-param-env.rs:6:28 + | +LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo + | ---------------- ^^^^^^^^^^^^^^^^^^^^^^ ^^^ + | | + | unsatisfied trait bound introduced here + +error: aborting due to 3 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0207, E0284, E0407. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/const-generics/kind_mismatch.rs b/tests/ui/const-generics/kind_mismatch.rs index bab58d5952a5f..ecdc01a5ef901 100644 --- a/tests/ui/const-generics/kind_mismatch.rs +++ b/tests/ui/const-generics/kind_mismatch.rs @@ -20,5 +20,4 @@ pub fn remove_key>() -> S { fn main() { let map: KeyHolder<0> = remove_key::<_, _>(); - //~^ ERROR: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied } diff --git a/tests/ui/const-generics/kind_mismatch.stderr b/tests/ui/const-generics/kind_mismatch.stderr index e13bc6ee058d0..1487b18961986 100644 --- a/tests/ui/const-generics/kind_mismatch.stderr +++ b/tests/ui/const-generics/kind_mismatch.stderr @@ -14,26 +14,6 @@ LL | impl ContainsKey for KeyHolder {} | | | help: consider changing this type parameter to a const parameter: `const K: u8` -error[E0277]: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied - --> $DIR/kind_mismatch.rs:22:45 - | -LL | let map: KeyHolder<0> = remove_key::<_, _>(); - | ^ the trait `ContainsKey<0>` is not implemented for `KeyHolder<0>` - | -note: required for `KeyHolder<0>` to implement `SubsetExcept<_>` - --> $DIR/kind_mismatch.rs:15:28 - | -LL | impl> SubsetExcept

for T {} - | -------------- ^^^^^^^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here -note: required by a bound in `remove_key` - --> $DIR/kind_mismatch.rs:17:25 - | -LL | pub fn remove_key>() -> S { - | ^^^^^^^^^^^^^^^ required by this bound in `remove_key` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0277, E0747. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0747`. diff --git a/tests/ui/const-generics/not_wf_param_in_rpitit.rs b/tests/ui/const-generics/not_wf_param_in_rpitit.rs index b454562ad497a..cb1e90923e75d 100644 --- a/tests/ui/const-generics/not_wf_param_in_rpitit.rs +++ b/tests/ui/const-generics/not_wf_param_in_rpitit.rs @@ -3,9 +3,6 @@ trait Trait { //~^ ERROR: cannot find value `bar` in this scope //~| ERROR: cycle detected when computing type of `Trait::N` - //~| ERROR: the trait `Trait` cannot be made into an object - //~| ERROR: the trait `Trait` cannot be made into an object - //~| ERROR: the trait `Trait` cannot be made into an object async fn a() {} } diff --git a/tests/ui/const-generics/not_wf_param_in_rpitit.stderr b/tests/ui/const-generics/not_wf_param_in_rpitit.stderr index 2500409e82858..42ae012fa5570 100644 --- a/tests/ui/const-generics/not_wf_param_in_rpitit.stderr +++ b/tests/ui/const-generics/not_wf_param_in_rpitit.stderr @@ -18,77 +18,7 @@ LL | trait Trait { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/not_wf_param_in_rpitit.rs:3:22 - | -LL | trait Trait { - | ^^^^^^^^^ `Trait` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/not_wf_param_in_rpitit.rs:9:14 - | -LL | trait Trait { - | ----- this trait cannot be made into an object... -... -LL | async fn a() {} - | ^ ...because associated function `a` has no `self` parameter -help: consider turning `a` into a method by giving it a `&self` argument - | -LL | async fn a(&self) {} - | +++++ -help: alternatively, consider constraining `a` so it does not apply to trait objects - | -LL | async fn a() where Self: Sized {} - | +++++++++++++++++ - -error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/not_wf_param_in_rpitit.rs:3:13 - | -LL | trait Trait { - | ^^^^^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/not_wf_param_in_rpitit.rs:9:14 - | -LL | trait Trait { - | ----- this trait cannot be made into an object... -... -LL | async fn a() {} - | ^ ...because associated function `a` has no `self` parameter -help: consider turning `a` into a method by giving it a `&self` argument - | -LL | async fn a(&self) {} - | +++++ -help: alternatively, consider constraining `a` so it does not apply to trait objects - | -LL | async fn a() where Self: Sized {} - | +++++++++++++++++ - -error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/not_wf_param_in_rpitit.rs:3:13 - | -LL | trait Trait { - | ^^^^^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/not_wf_param_in_rpitit.rs:9:14 - | -LL | trait Trait { - | ----- this trait cannot be made into an object... -... -LL | async fn a() {} - | ^ ...because associated function `a` has no `self` parameter - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider turning `a` into a method by giving it a `&self` argument - | -LL | async fn a(&self) {} - | +++++ -help: alternatively, consider constraining `a` so it does not apply to trait objects - | -LL | async fn a() where Self: Sized {} - | +++++++++++++++++ - -error: aborting due to 5 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0038, E0391, E0425. -For more information about an error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0391, E0425. +For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/consts/array-literal-len-mismatch.stderr b/tests/ui/consts/array-literal-len-mismatch.stderr index a11506ecb6d6a..39b8a647324b3 100644 --- a/tests/ui/consts/array-literal-len-mismatch.stderr +++ b/tests/ui/consts/array-literal-len-mismatch.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/array-literal-len-mismatch.rs:1:26 | LL | const NUMBERS: [u8; 3] = [10, 20]; - | - ^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements + | - ^^^^^^^^ expected an array with a size of 3, found one with a size of 2 | | | help: consider specifying the actual array length: `2` diff --git a/tests/ui/consts/bad-array-size-in-type-err.rs b/tests/ui/consts/bad-array-size-in-type-err.rs new file mode 100644 index 0000000000000..cb02ad3205db6 --- /dev/null +++ b/tests/ui/consts/bad-array-size-in-type-err.rs @@ -0,0 +1,10 @@ +struct BadArraySize { + arr: [i32; N], + //~^ ERROR the constant `N` is not of type `usize` +} + +fn main() { + let _ = BadArraySize::<2> { arr: [0, 0, 0] }; + //~^ ERROR mismatched types + //~| ERROR the constant `2` is not of type `usize` +} diff --git a/tests/ui/consts/bad-array-size-in-type-err.stderr b/tests/ui/consts/bad-array-size-in-type-err.stderr new file mode 100644 index 0000000000000..25d14d80c3ec4 --- /dev/null +++ b/tests/ui/consts/bad-array-size-in-type-err.stderr @@ -0,0 +1,21 @@ +error: the constant `N` is not of type `usize` + --> $DIR/bad-array-size-in-type-err.rs:2:10 + | +LL | arr: [i32; N], + | ^^^^^^^^ expected `usize`, found `u8` + +error[E0308]: mismatched types + --> $DIR/bad-array-size-in-type-err.rs:7:38 + | +LL | let _ = BadArraySize::<2> { arr: [0, 0, 0] }; + | ^^^^^^^^^ expected an array with a size of 2, found one with a size of 3 + +error: the constant `2` is not of type `usize` + --> $DIR/bad-array-size-in-type-err.rs:7:38 + | +LL | let _ = BadArraySize::<2> { arr: [0, 0, 0] }; + | ^^^^^^^^^ expected `usize`, found `u8` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const-array-oob-arith.rs b/tests/ui/consts/const-array-oob-arith.rs index 9332cbbd4d7c9..0f6e76768cd15 100644 --- a/tests/ui/consts/const-array-oob-arith.rs +++ b/tests/ui/consts/const-array-oob-arith.rs @@ -4,10 +4,10 @@ const VAL: i32 = ARR[IDX]; const BONG: [i32; (ARR[0] - 41) as usize] = [5]; const BLUB: [i32; (ARR[0] - 40) as usize] = [5]; //~^ ERROR: mismatched types -//~| expected an array with a fixed size of 2 elements, found one with 1 element +//~| expected an array const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99]; //~^ ERROR: mismatched types -//~| expected an array with a fixed size of 1 element, found one with 2 elements +//~| expected an array fn main() { let _ = VAL; diff --git a/tests/ui/consts/const-array-oob-arith.stderr b/tests/ui/consts/const-array-oob-arith.stderr index 029d94273fae1..d3299082aa14c 100644 --- a/tests/ui/consts/const-array-oob-arith.stderr +++ b/tests/ui/consts/const-array-oob-arith.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/const-array-oob-arith.rs:5:45 | LL | const BLUB: [i32; (ARR[0] - 40) as usize] = [5]; - | ---------------------- ^^^ expected an array with a fixed size of 2 elements, found one with 1 element + | ---------------------- ^^^ expected an array with a size of 2, found one with a size of 1 | | | help: consider specifying the actual array length: `1` @@ -10,7 +10,7 @@ error[E0308]: mismatched types --> $DIR/const-array-oob-arith.rs:8:44 | LL | const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99]; - | ---------------------- ^^^^^^^ expected an array with a fixed size of 1 element, found one with 2 elements + | ---------------------- ^^^^^^^ expected an array with a size of 1, found one with a size of 2 | | | help: consider specifying the actual array length: `2` diff --git a/tests/ui/consts/const-block-const-bound.rs b/tests/ui/consts/const-block-const-bound.rs index 933eb6cfc0afb..596aac09b3114 100644 --- a/tests/ui/consts/const-block-const-bound.rs +++ b/tests/ui/consts/const-block-const-bound.rs @@ -1,7 +1,7 @@ //@ known-bug: #103507 #![allow(unused)] -#![feature(const_trait_impl, negative_impls)] +#![feature(const_trait_impl, negative_impls, const_destruct)] use std::marker::Destruct; diff --git a/tests/ui/consts/const-block-const-bound.stderr b/tests/ui/consts/const-block-const-bound.stderr index 5e24959146b83..b2b2f62c58f27 100644 --- a/tests/ui/consts/const-block-const-bound.stderr +++ b/tests/ui/consts/const-block-const-bound.stderr @@ -1,25 +1,9 @@ -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-block-const-bound.rs:8:15 +error[E0277]: the trait bound `UnconstDrop: const Destruct` is not satisfied + --> $DIR/const-block-const-bound.rs:18:9 | -LL | const fn f(x: T) {} - | ^^^^^^ +LL | f(UnconstDrop); + | ^^^^^^^^^^^^^^ -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-block-const-bound.rs:8:15 - | -LL | const fn f(x: T) {} - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `T` cannot be evaluated at compile-time - --> $DIR/const-block-const-bound.rs:8:32 - | -LL | const fn f(x: T) {} - | ^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constant functions - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0493`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/const-bound.rs b/tests/ui/consts/const-bound.rs index 682a2dcbbc63e..00a833ba3f79e 100644 --- a/tests/ui/consts/const-bound.rs +++ b/tests/ui/consts/const-bound.rs @@ -3,7 +3,6 @@ // Make sure const bounds work on things, and test that a few types // are const. -//@ pretty-expanded FIXME #23616 fn foo(x: T) -> T { x } diff --git a/tests/ui/consts/const-eval/float_methods.rs b/tests/ui/consts/const-eval/float_methods.rs index 49c31f68c5fa2..853f75825ac24 100644 --- a/tests/ui/consts/const-eval/float_methods.rs +++ b/tests/ui/consts/const-eval/float_methods.rs @@ -1,7 +1,6 @@ //@ run-pass //! Tests the float intrinsics: min, max, abs, copysign -#![feature(const_float_methods)] #![feature(f16, f128)] const F16_MIN: f16 = 1.0_f16.min(0.5_f16); diff --git a/tests/ui/consts/const-expr-in-fixed-length-vec.rs b/tests/ui/consts/const-expr-in-fixed-length-vec.rs index 60b4895f5f97b..f4d651af11540 100644 --- a/tests/ui/consts/const-expr-in-fixed-length-vec.rs +++ b/tests/ui/consts/const-expr-in-fixed-length-vec.rs @@ -2,7 +2,6 @@ // Check that constant expressions can be used for declaring the // type of a fixed length vector. -//@ pretty-expanded FIXME #23616 pub fn main() { diff --git a/tests/ui/consts/const-expr-in-vec-repeat.rs b/tests/ui/consts/const-expr-in-vec-repeat.rs index 5345a1c4c42ee..e270d4c1eb3c1 100644 --- a/tests/ui/consts/const-expr-in-vec-repeat.rs +++ b/tests/ui/consts/const-expr-in-vec-repeat.rs @@ -1,7 +1,6 @@ //@ run-pass // Check that constant expressions can be used in vec repeat syntax. -//@ pretty-expanded FIXME #23616 pub fn main() { diff --git a/tests/ui/consts/const-match-check.eval1.stderr b/tests/ui/consts/const-match-check.eval1.stderr index 84890214861b8..b1827009d2adc 100644 --- a/tests/ui/consts/const-match-check.eval1.stderr +++ b/tests/ui/consts/const-match-check.eval1.stderr @@ -5,7 +5,7 @@ LL | A = { let 0 = 0; 0 }, | ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` help: you might want to use `if let` to ignore the variants that aren't matched | diff --git a/tests/ui/consts/const-match-check.eval2.stderr b/tests/ui/consts/const-match-check.eval2.stderr index 0aa12eb86dddc..04ac58bfe402f 100644 --- a/tests/ui/consts/const-match-check.eval2.stderr +++ b/tests/ui/consts/const-match-check.eval2.stderr @@ -5,7 +5,7 @@ LL | let x: [i32; { let 0 = 0; 0 }] = []; | ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` help: you might want to use `if let` to ignore the variants that aren't matched | diff --git a/tests/ui/consts/const-match-check.matchck.stderr b/tests/ui/consts/const-match-check.matchck.stderr index bcca4c2a64783..05ddc4c821955 100644 --- a/tests/ui/consts/const-match-check.matchck.stderr +++ b/tests/ui/consts/const-match-check.matchck.stderr @@ -5,7 +5,7 @@ LL | const X: i32 = { let 0 = 0; 0 }; | ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` help: you might want to use `if let` to ignore the variants that aren't matched | @@ -23,7 +23,7 @@ LL | static Y: i32 = { let 0 = 0; 0 }; | ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` help: you might want to use `if let` to ignore the variants that aren't matched | @@ -41,7 +41,7 @@ LL | const X: i32 = { let 0 = 0; 0 }; | ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` help: you might want to use `if let` to ignore the variants that aren't matched | @@ -59,7 +59,7 @@ LL | const X: i32 = { let 0 = 0; 0 }; | ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` help: you might want to use `if let` to ignore the variants that aren't matched | diff --git a/tests/ui/consts/const-pattern-irrefutable.stderr b/tests/ui/consts/const-pattern-irrefutable.stderr index afb67a3a118a4..646426c942689 100644 --- a/tests/ui/consts/const-pattern-irrefutable.stderr +++ b/tests/ui/consts/const-pattern-irrefutable.stderr @@ -8,7 +8,7 @@ LL | let a = 4; | ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `u8` help: introduce a variable instead | @@ -25,7 +25,7 @@ LL | let c = 4; | ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `u8` help: introduce a variable instead | @@ -42,7 +42,7 @@ LL | let d = (4, 4); | ^ patterns `(0_u8..=1_u8, _)` and `(3_u8..=u8::MAX, _)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `(u8, u8)` help: introduce a variable instead | @@ -59,7 +59,7 @@ LL | let e = S { | ^ pattern `S { foo: 1_u8..=u8::MAX }` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `S` defined here --> $DIR/const-pattern-irrefutable.rs:15:8 | diff --git a/tests/ui/consts/const-struct-offsets.rs b/tests/ui/consts/const-struct-offsets.rs index ee97fe3cab941..491b7095b70d9 100644 --- a/tests/ui/consts/const-struct-offsets.rs +++ b/tests/ui/consts/const-struct-offsets.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #![allow(non_upper_case_globals)] enum Foo { diff --git a/tests/ui/consts/const-unit-struct.rs b/tests/ui/consts/const-unit-struct.rs index 096cd1e83847a..2dadb000f4cae 100644 --- a/tests/ui/consts/const-unit-struct.rs +++ b/tests/ui/consts/const-unit-struct.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 struct Foo; diff --git a/tests/ui/consts/const-vec-of-fns.rs b/tests/ui/consts/const-vec-of-fns.rs index a14cb06db6153..fa7eda789efa1 100644 --- a/tests/ui/consts/const-vec-of-fns.rs +++ b/tests/ui/consts/const-vec-of-fns.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(non_upper_case_globals)] /*! diff --git a/tests/ui/consts/const-vec-syntax.rs b/tests/ui/consts/const-vec-syntax.rs index 5537a8cec9006..d305d45a8cdaa 100644 --- a/tests/ui/consts/const-vec-syntax.rs +++ b/tests/ui/consts/const-vec-syntax.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn f(_: &[isize]) {} diff --git a/tests/ui/consts/control-flow/drop-fail.precise.stderr b/tests/ui/consts/control-flow/drop-fail.precise.stderr index 93b5f257efb77..32afc51c3ee34 100644 --- a/tests/ui/consts/control-flow/drop-fail.precise.stderr +++ b/tests/ui/consts/control-flow/drop-fail.precise.stderr @@ -1,14 +1,20 @@ error[E0493]: destructor of `Option>` cannot be evaluated at compile-time - --> $DIR/drop-fail.rs:8:9 + --> $DIR/drop-fail.rs:9:9 | LL | let x = Some(Vec::new()); | ^ the destructor for this type cannot be evaluated in constants +... +LL | }; + | - value is dropped here error[E0493]: destructor of `Option>` cannot be evaluated at compile-time - --> $DIR/drop-fail.rs:39:9 + --> $DIR/drop-fail.rs:40:9 | LL | let mut tmp = None; | ^^^^^^^ the destructor for this type cannot be evaluated in constants +... +LL | }; + | - value is dropped here error: aborting due to 2 previous errors diff --git a/tests/ui/consts/control-flow/drop-fail.rs b/tests/ui/consts/control-flow/drop-fail.rs index 25afe5d08d970..2b73e37b23d03 100644 --- a/tests/ui/consts/control-flow/drop-fail.rs +++ b/tests/ui/consts/control-flow/drop-fail.rs @@ -1,5 +1,6 @@ //@ revisions: stock precise +#![feature(const_destruct)] #![cfg_attr(precise, feature(const_precise_live_drops))] // `x` is *not* always moved into the final value and may be dropped inside the initializer. diff --git a/tests/ui/consts/control-flow/drop-fail.stock.stderr b/tests/ui/consts/control-flow/drop-fail.stock.stderr index 2cc8568026eb5..8fe60fd736765 100644 --- a/tests/ui/consts/control-flow/drop-fail.stock.stderr +++ b/tests/ui/consts/control-flow/drop-fail.stock.stderr @@ -1,5 +1,5 @@ error[E0493]: destructor of `Option>` cannot be evaluated at compile-time - --> $DIR/drop-fail.rs:8:9 + --> $DIR/drop-fail.rs:9:9 | LL | let x = Some(Vec::new()); | ^ the destructor for this type cannot be evaluated in constants @@ -8,7 +8,7 @@ LL | }; | - value is dropped here error[E0493]: destructor of `(Vec,)` cannot be evaluated at compile-time - --> $DIR/drop-fail.rs:21:9 + --> $DIR/drop-fail.rs:22:9 | LL | let vec_tuple = (Vec::new(),); | ^^^^^^^^^ the destructor for this type cannot be evaluated in constants @@ -17,7 +17,7 @@ LL | }; | - value is dropped here error[E0493]: destructor of `Result, Vec>` cannot be evaluated at compile-time - --> $DIR/drop-fail.rs:29:9 + --> $DIR/drop-fail.rs:30:9 | LL | let x: Result<_, Vec> = Ok(Vec::new()); | ^ the destructor for this type cannot be evaluated in constants @@ -26,7 +26,7 @@ LL | }; | - value is dropped here error[E0493]: destructor of `Option>` cannot be evaluated at compile-time - --> $DIR/drop-fail.rs:39:9 + --> $DIR/drop-fail.rs:40:9 | LL | let mut tmp = None; | ^^^^^^^ the destructor for this type cannot be evaluated in constants diff --git a/tests/ui/consts/drop_zst.stderr b/tests/ui/consts/drop_zst.stderr index e3c6785290d76..4d1af7ef93540 100644 --- a/tests/ui/consts/drop_zst.stderr +++ b/tests/ui/consts/drop_zst.stderr @@ -3,6 +3,8 @@ error[E0493]: destructor of `S` cannot be evaluated at compile-time | LL | let s = S; | ^ the destructor for this type cannot be evaluated in constant functions +LL | } + | - value is dropped here error: aborting due to 1 previous error diff --git a/tests/ui/consts/fn_trait_refs.rs b/tests/ui/consts/fn_trait_refs.rs index 4defe4dedc784..af233efd738a2 100644 --- a/tests/ui/consts/fn_trait_refs.rs +++ b/tests/ui/consts/fn_trait_refs.rs @@ -5,6 +5,7 @@ #![feature(unboxed_closures)] #![feature(const_trait_impl)] #![feature(const_cmp)] +#![feature(const_destruct)] use std::marker::Destruct; diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr index a686bc23c0f41..108500217139e 100644 --- a/tests/ui/consts/fn_trait_refs.stderr +++ b/tests/ui/consts/fn_trait_refs.stderr @@ -11,19 +11,13 @@ LL | #![feature(const_cmp)] | ^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:13:8 + --> $DIR/fn_trait_refs.rs:14:8 | LL | T: ~const Fn<()> + ~const Destruct, | ^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:13:24 - | -LL | T: ~const Fn<()> + ~const Destruct, - | ^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:13:8 + --> $DIR/fn_trait_refs.rs:14:8 | LL | T: ~const Fn<()> + ~const Destruct, | ^^^^^^ @@ -31,7 +25,7 @@ LL | T: ~const Fn<()> + ~const Destruct, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:13:8 + --> $DIR/fn_trait_refs.rs:14:8 | LL | T: ~const Fn<()> + ~const Destruct, | ^^^^^^ @@ -39,27 +33,13 @@ LL | T: ~const Fn<()> + ~const Destruct, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:13:24 - | -LL | T: ~const Fn<()> + ~const Destruct, - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:20:8 + --> $DIR/fn_trait_refs.rs:21:8 | LL | T: ~const FnMut<()> + ~const Destruct, | ^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:20:27 - | -LL | T: ~const FnMut<()> + ~const Destruct, - | ^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:20:8 + --> $DIR/fn_trait_refs.rs:21:8 | LL | T: ~const FnMut<()> + ~const Destruct, | ^^^^^^ @@ -67,7 +47,7 @@ LL | T: ~const FnMut<()> + ~const Destruct, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:20:8 + --> $DIR/fn_trait_refs.rs:21:8 | LL | T: ~const FnMut<()> + ~const Destruct, | ^^^^^^ @@ -75,21 +55,13 @@ LL | T: ~const FnMut<()> + ~const Destruct, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:20:27 - | -LL | T: ~const FnMut<()> + ~const Destruct, - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:27:8 + --> $DIR/fn_trait_refs.rs:28:8 | LL | T: ~const FnOnce<()>, | ^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:27:8 + --> $DIR/fn_trait_refs.rs:28:8 | LL | T: ~const FnOnce<()>, | ^^^^^^ @@ -97,7 +69,7 @@ LL | T: ~const FnOnce<()>, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:27:8 + --> $DIR/fn_trait_refs.rs:28:8 | LL | T: ~const FnOnce<()>, | ^^^^^^ @@ -105,19 +77,13 @@ LL | T: ~const FnOnce<()>, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:34:8 + --> $DIR/fn_trait_refs.rs:35:8 | LL | T: ~const Fn<()> + ~const Destruct, | ^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:34:24 - | -LL | T: ~const Fn<()> + ~const Destruct, - | ^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:34:8 + --> $DIR/fn_trait_refs.rs:35:8 | LL | T: ~const Fn<()> + ~const Destruct, | ^^^^^^ @@ -125,7 +91,7 @@ LL | T: ~const Fn<()> + ~const Destruct, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:34:8 + --> $DIR/fn_trait_refs.rs:35:8 | LL | T: ~const Fn<()> + ~const Destruct, | ^^^^^^ @@ -133,27 +99,13 @@ LL | T: ~const Fn<()> + ~const Destruct, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:34:24 - | -LL | T: ~const Fn<()> + ~const Destruct, - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:48:8 + --> $DIR/fn_trait_refs.rs:49:8 | LL | T: ~const FnMut<()> + ~const Destruct, | ^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:48:27 - | -LL | T: ~const FnMut<()> + ~const Destruct, - | ^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:48:8 + --> $DIR/fn_trait_refs.rs:49:8 | LL | T: ~const FnMut<()> + ~const Destruct, | ^^^^^^ @@ -161,39 +113,45 @@ LL | T: ~const FnMut<()> + ~const Destruct, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:48:8 + --> $DIR/fn_trait_refs.rs:49:8 | LL | T: ~const FnMut<()> + ~const Destruct, | ^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/fn_trait_refs.rs:48:27 - | -LL | T: ~const FnMut<()> + ~const Destruct, - | ^^^^^^ +error[E0277]: the trait bound `fn() -> i32 {one}: const Destruct` is not satisfied + --> $DIR/fn_trait_refs.rs:70:24 | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +LL | let test_one = test_fn(one); + | ^^^^^^^^^^^^ -error[E0015]: cannot call non-const operator in constants - --> $DIR/fn_trait_refs.rs:70:17 +error[E0277]: the trait bound `fn() -> i32 {two}: const Destruct` is not satisfied + --> $DIR/fn_trait_refs.rs:73:24 | -LL | assert!(test_one == (1, 1, 1)); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | let test_two = test_fn_mut(two); + | ^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `&T: ~const Destruct` is not satisfied + --> $DIR/fn_trait_refs.rs:39:9 | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants +LL | tester_fn(&f), + | ^^^^^^^^^^^^^ -error[E0015]: cannot call non-const operator in constants - --> $DIR/fn_trait_refs.rs:73:17 +error[E0277]: the trait bound `&T: ~const Destruct` is not satisfied + --> $DIR/fn_trait_refs.rs:41:9 | -LL | assert!(test_two == (2, 2)); - | ^^^^^^^^^^^^^^^^^^ +LL | tester_fn_mut(&f), + | ^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `&mut T: ~const Destruct` is not satisfied + --> $DIR/fn_trait_refs.rs:53:9 | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants +LL | tester_fn_mut(&mut f), + | ^^^^^^^^^^^^^^^^^^^^^ error[E0015]: cannot call non-const closure in constant functions - --> $DIR/fn_trait_refs.rs:15:5 + --> $DIR/fn_trait_refs.rs:16:5 | LL | f() | ^^^ @@ -204,17 +162,8 @@ help: consider further restricting this bound LL | T: ~const Fn<()> + ~const Destruct + ~const Fn(), | +++++++++++++ -error[E0493]: destructor of `T` cannot be evaluated at compile-time - --> $DIR/fn_trait_refs.rs:11:23 - | -LL | const fn tester_fn(f: T) -> T::Output - | ^ the destructor for this type cannot be evaluated in constant functions -... -LL | } - | - value is dropped here - error[E0015]: cannot call non-const closure in constant functions - --> $DIR/fn_trait_refs.rs:22:5 + --> $DIR/fn_trait_refs.rs:23:5 | LL | f() | ^^^ @@ -225,17 +174,8 @@ help: consider further restricting this bound LL | T: ~const FnMut<()> + ~const Destruct + ~const FnMut(), | ++++++++++++++++ -error[E0493]: destructor of `T` cannot be evaluated at compile-time - --> $DIR/fn_trait_refs.rs:18:27 - | -LL | const fn tester_fn_mut(mut f: T) -> T::Output - | ^^^^^ the destructor for this type cannot be evaluated in constant functions -... -LL | } - | - value is dropped here - error[E0015]: cannot call non-const closure in constant functions - --> $DIR/fn_trait_refs.rs:29:5 + --> $DIR/fn_trait_refs.rs:30:5 | LL | f() | ^^^ @@ -246,25 +186,7 @@ help: consider further restricting this bound LL | T: ~const FnOnce<()> + ~const FnOnce(), | +++++++++++++++++ -error[E0493]: destructor of `T` cannot be evaluated at compile-time - --> $DIR/fn_trait_refs.rs:32:21 - | -LL | const fn test_fn(mut f: T) -> (T::Output, T::Output, T::Output) - | ^^^^^ the destructor for this type cannot be evaluated in constant functions -... -LL | } - | - value is dropped here - -error[E0493]: destructor of `T` cannot be evaluated at compile-time - --> $DIR/fn_trait_refs.rs:46:25 - | -LL | const fn test_fn_mut(mut f: T) -> (T::Output, T::Output) - | ^^^^^ the destructor for this type cannot be evaluated in constant functions -... -LL | } - | - value is dropped here - -error: aborting due to 34 previous errors +error: aborting due to 25 previous errors -Some errors have detailed explanations: E0015, E0493, E0635. +Some errors have detailed explanations: E0015, E0277, E0635. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/issue-13837.rs b/tests/ui/consts/issue-13837.rs index 305512cc41ccf..85e278539b2bc 100644 --- a/tests/ui/consts/issue-13837.rs +++ b/tests/ui/consts/issue-13837.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct TestStruct { x: *const [isize; 2] diff --git a/tests/ui/consts/issue-36163.stderr b/tests/ui/consts/issue-36163.stderr index 52d3e003f0ac9..8a7a0981f4154 100644 --- a/tests/ui/consts/issue-36163.stderr +++ b/tests/ui/consts/issue-36163.stderr @@ -1,10 +1,10 @@ -error[E0391]: cycle detected when simplifying constant for the type system `Foo::{constant#0}` +error[E0391]: cycle detected when simplifying constant for the type system `Foo::B::{constant#0}` --> $DIR/issue-36163.rs:4:9 | LL | B = A, | ^ | -note: ...which requires const-evaluating + checking `Foo::{constant#0}`... +note: ...which requires const-evaluating + checking `Foo::B::{constant#0}`... --> $DIR/issue-36163.rs:4:9 | LL | B = A, @@ -19,7 +19,7 @@ note: ...which requires const-evaluating + checking `A`... | LL | const A: isize = Foo::B as isize; | ^^^^^^^^^^^^^^^ - = note: ...which again requires simplifying constant for the type system `Foo::{constant#0}`, completing the cycle + = note: ...which again requires simplifying constant for the type system `Foo::B::{constant#0}`, completing the cycle note: cycle used when checking that `Foo` is well-formed --> $DIR/issue-36163.rs:3:1 | diff --git a/tests/ui/consts/promoted-const-drop.rs b/tests/ui/consts/promoted-const-drop.rs index c6ea0d0c924da..e09c30ea7857b 100644 --- a/tests/ui/consts/promoted-const-drop.rs +++ b/tests/ui/consts/promoted-const-drop.rs @@ -3,7 +3,6 @@ struct A(); impl const Drop for A { - //~^ ERROR const `impl` for trait `Drop` which is not marked with `#[const_trait]` fn drop(&mut self) {} } diff --git a/tests/ui/consts/promoted-const-drop.stderr b/tests/ui/consts/promoted-const-drop.stderr index e015f75620690..3f2182e7d4105 100644 --- a/tests/ui/consts/promoted-const-drop.stderr +++ b/tests/ui/consts/promoted-const-drop.stderr @@ -1,14 +1,5 @@ -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/promoted-const-drop.rs:5:12 - | -LL | impl const Drop for A { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted-const-drop.rs:13:26 + --> $DIR/promoted-const-drop.rs:12:26 | LL | let _: &'static A = &A(); | ---------- ^^^ creates a temporary value which is freed while still in use @@ -19,7 +10,7 @@ LL | } | - temporary value is freed at the end of this statement error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted-const-drop.rs:14:28 + --> $DIR/promoted-const-drop.rs:13:28 | LL | let _: &'static [A] = &[C]; | ------------ ^^^ creates a temporary value which is freed while still in use @@ -28,6 +19,6 @@ LL | let _: &'static [A] = &[C]; LL | } | - temporary value is freed at the end of this statement -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/consts/promoted_const_call.stderr b/tests/ui/consts/promoted_const_call.stderr index bcb9dfb704b1d..dd70bb601c47d 100644 --- a/tests/ui/consts/promoted_const_call.stderr +++ b/tests/ui/consts/promoted_const_call.stderr @@ -1,31 +1,10 @@ -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/promoted_const_call.rs:6:12 - | -LL | impl const Drop for Panic { fn drop(&mut self) { panic!(); } } - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call.rs:10:26 - | -LL | let _: &'static _ = &id(&Panic); - | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use - | | - | type annotation requires that borrow lasts for `'static` -... -LL | }; - | - temporary value is freed at the end of this statement - -error[E0716]: temporary value dropped while borrowed +error[E0493]: destructor of `Panic` cannot be evaluated at compile-time --> $DIR/promoted_const_call.rs:10:30 | LL | let _: &'static _ = &id(&Panic); - | ---------- ^^^^^ - temporary value is freed at the end of this statement - | | | - | | creates a temporary value which is freed while still in use - | type annotation requires that borrow lasts for `'static` + | ^^^^^ - value is dropped here + | | + | the destructor for this type cannot be evaluated in constants error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_const_call.rs:16:26 @@ -69,6 +48,7 @@ LL | let _: &'static _ = &&(Panic, 0).1; LL | } | - temporary value is freed at the end of this statement -error: aborting due to 7 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0716`. +Some errors have detailed explanations: E0493, E0716. +For more information about an error, try `rustc --explain E0493`. diff --git a/tests/ui/consts/promoted_const_call2.stderr b/tests/ui/consts/promoted_const_call2.stderr index 177f7aed17df2..bdb43385d2032 100644 --- a/tests/ui/consts/promoted_const_call2.stderr +++ b/tests/ui/consts/promoted_const_call2.stderr @@ -22,7 +22,9 @@ error[E0493]: destructor of `String` cannot be evaluated at compile-time --> $DIR/promoted_const_call2.rs:4:30 | LL | let _: &'static _ = &id(&String::new()); - | ^^^^^^^^^^^^^ the destructor for this type cannot be evaluated in constants + | ^^^^^^^^^^^^^ - value is dropped here + | | + | the destructor for this type cannot be evaluated in constants error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_const_call2.rs:11:26 diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.stderr b/tests/ui/consts/qualif-indirect-mutation-fail.stderr index 433dfba2257d0..f706b7cf699d0 100644 --- a/tests/ui/consts/qualif-indirect-mutation-fail.stderr +++ b/tests/ui/consts/qualif-indirect-mutation-fail.stderr @@ -3,6 +3,9 @@ error[E0493]: destructor of `Option` cannot be evaluated at compile-time | LL | let mut x = None; | ^^^^^ the destructor for this type cannot be evaluated in constants +... +LL | }; + | - value is dropped here error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL @@ -26,6 +29,8 @@ error[E0493]: destructor of `Option` cannot be evaluated at compile-time | LL | let _z = x; | ^^ the destructor for this type cannot be evaluated in constants +LL | }; + | - value is dropped here error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL @@ -49,42 +54,62 @@ error[E0493]: destructor of `(u32, Option)` cannot be evaluated at compi | LL | let mut a: (u32, Option) = (0, None); | ^^^^^ the destructor for this type cannot be evaluated in constant functions +LL | let _ = &mut a.1; +LL | } + | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:34:9 | LL | let x: Option = None; | ^ the destructor for this type cannot be evaluated in constant functions +LL | let _ = x.is_some(); +LL | } + | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:42:9 | LL | let _y = x; | ^^ the destructor for this type cannot be evaluated in constant functions +LL | } + | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:50:9 | LL | let mut y: Option = None; | ^^^^^ the destructor for this type cannot be evaluated in constant functions +LL | std::ptr::addr_of_mut!(y); +LL | } + | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:47:9 | LL | let mut x: Option = None; | ^^^^^ the destructor for this type cannot be evaluated in constant functions +... +LL | } + | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:60:9 | LL | let y: Option = None; | ^ the destructor for this type cannot be evaluated in constant functions +LL | std::ptr::addr_of!(y); +LL | } + | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:57:9 | LL | let x: Option = None; | ^ the destructor for this type cannot be evaluated in constant functions +... +LL | } + | - value is dropped here error: aborting due to 11 previous errors diff --git a/tests/ui/consts/too_generic_eval_ice.rs b/tests/ui/consts/too_generic_eval_ice.rs index 8b3f4b714e1bd..0d46a4c8276dc 100644 --- a/tests/ui/consts/too_generic_eval_ice.rs +++ b/tests/ui/consts/too_generic_eval_ice.rs @@ -7,6 +7,7 @@ impl Foo { [5; Self::HOST_SIZE] == [6; 0] //~^ ERROR constant expression depends on a generic parameter //~| ERROR constant expression depends on a generic parameter + //~| ERROR constant expression depends on a generic parameter //~| ERROR can't compare `[{integer}; Self::HOST_SIZE]` with `[{integer}; 0]` } } diff --git a/tests/ui/consts/too_generic_eval_ice.stderr b/tests/ui/consts/too_generic_eval_ice.stderr index 58a61b938d6cb..b48be16a24c8e 100644 --- a/tests/ui/consts/too_generic_eval_ice.stderr +++ b/tests/ui/consts/too_generic_eval_ice.stderr @@ -6,6 +6,14 @@ LL | [5; Self::HOST_SIZE] == [6; 0] | = note: this may fail depending on what value the parameter takes +error: constant expression depends on a generic parameter + --> $DIR/too_generic_eval_ice.rs:7:9 + | +LL | [5; Self::HOST_SIZE] == [6; 0] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + error: constant expression depends on a generic parameter --> $DIR/too_generic_eval_ice.rs:7:30 | @@ -32,6 +40,6 @@ LL | [5; Self::HOST_SIZE] == [6; 0] `[T; N]` implements `PartialEq<[U]>` and 3 others -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/coroutine/async-gen-deduce-yield.rs b/tests/ui/coroutine/async-gen-deduce-yield.rs index aee920e977379..f85e4a52e9b96 100644 --- a/tests/ui/coroutine/async-gen-deduce-yield.rs +++ b/tests/ui/coroutine/async-gen-deduce-yield.rs @@ -1,4 +1,4 @@ -//@ compile-flags: --edition 2024 -Zunstable-options +//@ compile-flags: --edition 2024 //@ check-pass #![feature(async_iterator, gen_blocks)] diff --git a/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs b/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs index 62b9bafcd60aa..3875e26b544c5 100644 --- a/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs +++ b/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs @@ -1,4 +1,4 @@ -//@ compile-flags: --edition 2024 -Zunstable-options +//@ compile-flags: --edition 2024 //@ check-pass #![feature(async_iterator, gen_blocks, noop_waker)] diff --git a/tests/ui/coroutine/async_gen_fn.none.stderr b/tests/ui/coroutine/async_gen_fn.none.stderr index 047f4d82486d8..2fc7419ab1cb5 100644 --- a/tests/ui/coroutine/async_gen_fn.none.stderr +++ b/tests/ui/coroutine/async_gen_fn.none.stderr @@ -4,7 +4,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015 LL | async gen fn foo() {} | ^^^^^ to use `async fn`, switch to Rust 2018 or later | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found `gen` diff --git a/tests/ui/coroutine/async_gen_fn.rs b/tests/ui/coroutine/async_gen_fn.rs index e8be0434b9ef9..b9adeec3f4027 100644 --- a/tests/ui/coroutine/async_gen_fn.rs +++ b/tests/ui/coroutine/async_gen_fn.rs @@ -1,5 +1,5 @@ //@ revisions: e2024 none -//@[e2024] compile-flags: --edition 2024 -Zunstable-options +//@[e2024] edition: 2024 async gen fn foo() {} //[none]~^ ERROR: `async fn` is not permitted in Rust 2015 diff --git a/tests/ui/coroutine/async_gen_fn_iter.rs b/tests/ui/coroutine/async_gen_fn_iter.rs index 42288712c7068..3f7e7aa0ac24c 100644 --- a/tests/ui/coroutine/async_gen_fn_iter.rs +++ b/tests/ui/coroutine/async_gen_fn_iter.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options //@ run-pass #![feature(gen_blocks, async_iterator)] diff --git a/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs b/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs index 97c3d06c023e6..d0597fdd8e19e 100644 --- a/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs +++ b/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Z unstable-options #![feature(gen_blocks)] #![feature(async_closure)] diff --git a/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr b/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr index 77dc214bcecba..bdd26d39d82a0 100644 --- a/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr +++ b/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr @@ -1,5 +1,5 @@ error[E0267]: `break` inside `async` function - --> $DIR/break-inside-coroutine-issue-124495.rs:8:5 + --> $DIR/break-inside-coroutine-issue-124495.rs:7:5 | LL | async fn async_fn() { | ------------------- enclosing `async` function @@ -7,7 +7,7 @@ LL | break; | ^^^^^ cannot `break` inside `async` function error[E0267]: `break` inside `gen` function - --> $DIR/break-inside-coroutine-issue-124495.rs:12:5 + --> $DIR/break-inside-coroutine-issue-124495.rs:11:5 | LL | gen fn gen_fn() { | --------------- enclosing `gen` function @@ -15,7 +15,7 @@ LL | break; | ^^^^^ cannot `break` inside `gen` function error[E0267]: `break` inside `async gen` function - --> $DIR/break-inside-coroutine-issue-124495.rs:16:5 + --> $DIR/break-inside-coroutine-issue-124495.rs:15:5 | LL | async gen fn async_gen_fn() { | --------------------------- enclosing `async gen` function @@ -23,7 +23,7 @@ LL | break; | ^^^^^ cannot `break` inside `async gen` function error[E0267]: `break` inside `async` block - --> $DIR/break-inside-coroutine-issue-124495.rs:20:21 + --> $DIR/break-inside-coroutine-issue-124495.rs:19:21 | LL | let _ = async { break; }; | ----- ^^^^^ cannot `break` inside `async` block @@ -31,7 +31,7 @@ LL | let _ = async { break; }; | enclosing `async` block error[E0267]: `break` inside `async` closure - --> $DIR/break-inside-coroutine-issue-124495.rs:22:24 + --> $DIR/break-inside-coroutine-issue-124495.rs:21:24 | LL | let _ = async || { break; }; | -------- ^^^^^ cannot `break` inside `async` closure @@ -39,7 +39,7 @@ LL | let _ = async || { break; }; | enclosing `async` closure error[E0267]: `break` inside `gen` block - --> $DIR/break-inside-coroutine-issue-124495.rs:24:19 + --> $DIR/break-inside-coroutine-issue-124495.rs:23:19 | LL | let _ = gen { break; }; | --- ^^^^^ cannot `break` inside `gen` block @@ -47,7 +47,7 @@ LL | let _ = gen { break; }; | enclosing `gen` block error[E0267]: `break` inside `async gen` block - --> $DIR/break-inside-coroutine-issue-124495.rs:26:25 + --> $DIR/break-inside-coroutine-issue-124495.rs:25:25 | LL | let _ = async gen { break; }; | --------- ^^^^^ cannot `break` inside `async gen` block diff --git a/tests/ui/coroutine/const_gen_fn.rs b/tests/ui/coroutine/const_gen_fn.rs index 986693f33ab1b..2701139ffed93 100644 --- a/tests/ui/coroutine/const_gen_fn.rs +++ b/tests/ui/coroutine/const_gen_fn.rs @@ -1,5 +1,4 @@ //@ edition:2024 -//@ compile-flags: -Zunstable-options #![feature(gen_blocks)] diff --git a/tests/ui/coroutine/const_gen_fn.stderr b/tests/ui/coroutine/const_gen_fn.stderr index b58446ac88fd1..4f3c73d16787b 100644 --- a/tests/ui/coroutine/const_gen_fn.stderr +++ b/tests/ui/coroutine/const_gen_fn.stderr @@ -1,5 +1,5 @@ error: functions cannot be both `const` and `gen` - --> $DIR/const_gen_fn.rs:6:1 + --> $DIR/const_gen_fn.rs:5:1 | LL | const gen fn a() {} | ^^^^^-^^^---------- @@ -8,7 +8,7 @@ LL | const gen fn a() {} | `const` because of this error: functions cannot be both `const` and `async gen` - --> $DIR/const_gen_fn.rs:9:1 + --> $DIR/const_gen_fn.rs:8:1 | LL | const async gen fn b() {} | ^^^^^-^^^^^^^^^---------- diff --git a/tests/ui/coroutine/gen_block.rs b/tests/ui/coroutine/gen_block.rs index 7e87a572b9095..6734de3b667d2 100644 --- a/tests/ui/coroutine/gen_block.rs +++ b/tests/ui/coroutine/gen_block.rs @@ -1,5 +1,5 @@ //@ revisions: e2024 none -//@[e2024] compile-flags: --edition 2024 -Zunstable-options +//@[e2024] edition: 2024 #![cfg_attr(e2024, feature(gen_blocks))] #![feature(stmt_expr_attributes)] diff --git a/tests/ui/coroutine/gen_block_is_coro.rs b/tests/ui/coroutine/gen_block_is_coro.rs index c98e1e6038845..bccc3e86ee463 100644 --- a/tests/ui/coroutine/gen_block_is_coro.rs +++ b/tests/ui/coroutine/gen_block_is_coro.rs @@ -1,4 +1,5 @@ -//@compile-flags: --edition 2024 -Zunstable-options --diagnostic-width=300 +//@ edition: 2024 +//@ compile-flags: --diagnostic-width=300 #![feature(coroutines, coroutine_trait, gen_blocks)] use std::ops::Coroutine; diff --git a/tests/ui/coroutine/gen_block_is_coro.stderr b/tests/ui/coroutine/gen_block_is_coro.stderr index 083e738f3ece7..444f0eca1d54c 100644 --- a/tests/ui/coroutine/gen_block_is_coro.stderr +++ b/tests/ui/coroutine/gen_block_is_coro.stderr @@ -1,26 +1,26 @@ -error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}: Coroutine` is not satisfied - --> $DIR/gen_block_is_coro.rs:6:13 +error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}: Coroutine` is not satisfied + --> $DIR/gen_block_is_coro.rs:7:13 | LL | fn foo() -> impl Coroutine { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}` LL | gen { yield 42 } - | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}` here + | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}` here -error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}: Coroutine` is not satisfied - --> $DIR/gen_block_is_coro.rs:10:13 +error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}: Coroutine` is not satisfied + --> $DIR/gen_block_is_coro.rs:11:13 | LL | fn bar() -> impl Coroutine { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}` LL | gen { yield 42 } - | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}` here + | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}` here -error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}: Coroutine` is not satisfied - --> $DIR/gen_block_is_coro.rs:14:13 +error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}: Coroutine` is not satisfied + --> $DIR/gen_block_is_coro.rs:15:13 | LL | fn baz() -> impl Coroutine { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}` LL | gen { yield 42 } - | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}` here + | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}` here error: aborting due to 3 previous errors diff --git a/tests/ui/coroutine/gen_block_is_fused_iter.rs b/tests/ui/coroutine/gen_block_is_fused_iter.rs index f3e19a7f54f03..e4eab6195eecf 100644 --- a/tests/ui/coroutine/gen_block_is_fused_iter.rs +++ b/tests/ui/coroutine/gen_block_is_fused_iter.rs @@ -1,5 +1,5 @@ //@ revisions: next old -//@compile-flags: --edition 2024 -Zunstable-options +//@ edition: 2024 //@[next] compile-flags: -Znext-solver //@ check-pass #![feature(gen_blocks)] diff --git a/tests/ui/coroutine/gen_block_is_iter.rs b/tests/ui/coroutine/gen_block_is_iter.rs index 396d773713250..032360fbee032 100644 --- a/tests/ui/coroutine/gen_block_is_iter.rs +++ b/tests/ui/coroutine/gen_block_is_iter.rs @@ -1,5 +1,5 @@ //@ revisions: next old -//@compile-flags: --edition 2024 -Zunstable-options +//@ edition: 2024 //@[next] compile-flags: -Znext-solver //@ check-pass #![feature(gen_blocks)] diff --git a/tests/ui/coroutine/gen_block_is_no_future.rs b/tests/ui/coroutine/gen_block_is_no_future.rs index a5bb85337192a..eca8a9b6320fd 100644 --- a/tests/ui/coroutine/gen_block_is_no_future.rs +++ b/tests/ui/coroutine/gen_block_is_no_future.rs @@ -1,4 +1,4 @@ -//@compile-flags: --edition 2024 -Zunstable-options +//@ edition: 2024 #![feature(gen_blocks)] fn foo() -> impl std::future::Future { //~ ERROR is not a future diff --git a/tests/ui/coroutine/gen_block_iterate.rs b/tests/ui/coroutine/gen_block_iterate.rs index a9cb5ef3e2c8f..afeb56cc2f3f9 100644 --- a/tests/ui/coroutine/gen_block_iterate.rs +++ b/tests/ui/coroutine/gen_block_iterate.rs @@ -1,5 +1,5 @@ //@ revisions: next old -//@compile-flags: --edition 2024 -Zunstable-options +//@ edition: 2024 //@[next] compile-flags: -Znext-solver //@ run-pass #![feature(gen_blocks)] diff --git a/tests/ui/coroutine/gen_block_move.fixed b/tests/ui/coroutine/gen_block_move.fixed index 0327ca75f9e40..e58c9b3f9fe32 100644 --- a/tests/ui/coroutine/gen_block_move.fixed +++ b/tests/ui/coroutine/gen_block_move.fixed @@ -1,4 +1,4 @@ -//@ compile-flags: --edition 2024 -Zunstable-options +//@ edition: 2024 //@ run-rustfix #![feature(gen_blocks)] diff --git a/tests/ui/coroutine/gen_block_move.rs b/tests/ui/coroutine/gen_block_move.rs index 53d0149872a23..e249404a0a168 100644 --- a/tests/ui/coroutine/gen_block_move.rs +++ b/tests/ui/coroutine/gen_block_move.rs @@ -1,4 +1,4 @@ -//@ compile-flags: --edition 2024 -Zunstable-options +//@ edition: 2024 //@ run-rustfix #![feature(gen_blocks)] diff --git a/tests/ui/coroutine/gen_block_panic.rs b/tests/ui/coroutine/gen_block_panic.rs index ada56a5bd6f71..b6362d5046a3b 100644 --- a/tests/ui/coroutine/gen_block_panic.rs +++ b/tests/ui/coroutine/gen_block_panic.rs @@ -1,4 +1,4 @@ -//@compile-flags: --edition 2024 -Zunstable-options +//@ edition: 2024 //@ run-pass //@ needs-unwind #![feature(gen_blocks)] diff --git a/tests/ui/coroutine/gen_fn.rs b/tests/ui/coroutine/gen_fn.rs index d47b7e576d002..2f50d5db9acf6 100644 --- a/tests/ui/coroutine/gen_fn.rs +++ b/tests/ui/coroutine/gen_fn.rs @@ -1,5 +1,5 @@ //@ revisions: e2024 none -//@[e2024] compile-flags: --edition 2024 -Zunstable-options +//@[e2024] edition: 2024 gen fn foo() {} //[none]~^ ERROR: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `safe`, `unsafe`, or `use`, found `gen` diff --git a/tests/ui/coroutine/gen_fn_iter.rs b/tests/ui/coroutine/gen_fn_iter.rs index ae09d678fe324..9cd75551ad45c 100644 --- a/tests/ui/coroutine/gen_fn_iter.rs +++ b/tests/ui/coroutine/gen_fn_iter.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options //@ run-pass #![feature(gen_blocks)] diff --git a/tests/ui/coroutine/gen_fn_lifetime_capture.rs b/tests/ui/coroutine/gen_fn_lifetime_capture.rs index 517096d092eee..bee6c2e8803ad 100644 --- a/tests/ui/coroutine/gen_fn_lifetime_capture.rs +++ b/tests/ui/coroutine/gen_fn_lifetime_capture.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options //@ check-pass #![feature(gen_blocks)] diff --git a/tests/ui/coroutine/other-attribute-on-gen.rs b/tests/ui/coroutine/other-attribute-on-gen.rs index 0f26dc6860dd7..5f4584ee0226e 100644 --- a/tests/ui/coroutine/other-attribute-on-gen.rs +++ b/tests/ui/coroutine/other-attribute-on-gen.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options //@ run-pass #![feature(gen_blocks)] #![feature(optimize_attribute)] diff --git a/tests/ui/coroutine/return-types-diverge.rs b/tests/ui/coroutine/return-types-diverge.rs index 5b639eea09aa2..7aa8fc028ce44 100644 --- a/tests/ui/coroutine/return-types-diverge.rs +++ b/tests/ui/coroutine/return-types-diverge.rs @@ -1,4 +1,4 @@ -//@ compile-flags: --edition 2024 -Zunstable-options +//@ edition: 2024 //@ check-pass #![feature(gen_blocks)] diff --git a/tests/ui/coroutine/return-types.rs b/tests/ui/coroutine/return-types.rs index ad2080fd88b97..4fecc55053104 100644 --- a/tests/ui/coroutine/return-types.rs +++ b/tests/ui/coroutine/return-types.rs @@ -1,4 +1,4 @@ -//@ compile-flags: --edition 2024 -Zunstable-options +//@ edition: 2024 #![feature(gen_blocks)] diff --git a/tests/ui/coroutine/self_referential_gen_block.rs b/tests/ui/coroutine/self_referential_gen_block.rs index dccd83768c431..322cbf4f18a9d 100644 --- a/tests/ui/coroutine/self_referential_gen_block.rs +++ b/tests/ui/coroutine/self_referential_gen_block.rs @@ -1,4 +1,4 @@ -//@ compile-flags: --edition 2024 -Zunstable-options +//@ edition: 2024 #![feature(gen_blocks)] //! This test checks that we don't allow self-referential generators diff --git a/tests/ui/crate-leading-sep.rs b/tests/ui/crate-leading-sep.rs index fbc940aed260f..6f4dd0bcfd7f1 100644 --- a/tests/ui/crate-leading-sep.rs +++ b/tests/ui/crate-leading-sep.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(dropping_copy_types)] diff --git a/tests/ui/crate-loading/auxiliary/proc-macro.rs b/tests/ui/crate-loading/auxiliary/proc-macro.rs index ad227c069d20b..a87a2b243a1e7 100644 --- a/tests/ui/crate-loading/auxiliary/proc-macro.rs +++ b/tests/ui/crate-loading/auxiliary/proc-macro.rs @@ -1,7 +1,4 @@ -//@ force-host -//@ no-prefer-dynamic #![crate_name = "reproduction"] -#![crate_type = "proc-macro"] extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/crate-loading/cross-compiled-proc-macro.rs b/tests/ui/crate-loading/cross-compiled-proc-macro.rs index 51431c058655f..b727f22e188a0 100644 --- a/tests/ui/crate-loading/cross-compiled-proc-macro.rs +++ b/tests/ui/crate-loading/cross-compiled-proc-macro.rs @@ -1,6 +1,6 @@ //@ edition:2018 //@ compile-flags:--extern reproduction -//@ aux-build:proc-macro.rs +//@ proc-macro: proc-macro.rs //@ check-pass reproduction::mac!(); diff --git a/tests/ui/crate-method-reexport-grrrrrrr.rs b/tests/ui/crate-method-reexport-grrrrrrr.rs index 870c6851a6616..aca399f4e2090 100644 --- a/tests/ui/crate-method-reexport-grrrrrrr.rs +++ b/tests/ui/crate-method-reexport-grrrrrrr.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 // This is a regression test that the metadata for the // name_pool::methods impl in the other crate is reachable from this diff --git a/tests/ui/crate-name-attr-used.rs b/tests/ui/crate-name-attr-used.rs index 8e958aa0eaa31..5d5a58c32c799 100644 --- a/tests/ui/crate-name-attr-used.rs +++ b/tests/ui/crate-name-attr-used.rs @@ -1,7 +1,6 @@ //@ run-pass //@ compile-flags:--crate-name crate_name_attr_used -F unused-attributes -//@ pretty-expanded FIXME #23616 #![crate_name = "crate_name_attr_used"] diff --git a/tests/ui/cross-crate/cci_capture_clause.rs b/tests/ui/cross-crate/cci_capture_clause.rs index 73e1020d7cfcb..22fe49c2ba081 100644 --- a/tests/ui/cross-crate/cci_capture_clause.rs +++ b/tests/ui/cross-crate/cci_capture_clause.rs @@ -4,7 +4,6 @@ // This test makes sure we can do cross-crate inlining on functions // that use capture clauses. -//@ pretty-expanded FIXME #23616 //@ needs-threads extern crate cci_capture_clause; diff --git a/tests/ui/cross-crate/cross-crate-const-pat.rs b/tests/ui/cross-crate/cross-crate-const-pat.rs index 4ff55adb8042c..315210891609b 100644 --- a/tests/ui/cross-crate/cross-crate-const-pat.rs +++ b/tests/ui/cross-crate/cross-crate-const-pat.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:cci_const.rs -//@ pretty-expanded FIXME #23616 extern crate cci_const; diff --git a/tests/ui/cross-crate/moves-based-on-type-cross-crate.rs b/tests/ui/cross-crate/moves-based-on-type-cross-crate.rs index 640a1789cbe85..3e05717326c43 100644 --- a/tests/ui/cross-crate/moves-based-on-type-cross-crate.rs +++ b/tests/ui/cross-crate/moves-based-on-type-cross-crate.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:moves_based_on_type_lib.rs -//@ pretty-expanded FIXME #23616 extern crate moves_based_on_type_lib; use moves_based_on_type_lib::f; diff --git a/tests/ui/cross-crate/static-addresses.rs b/tests/ui/cross-crate/static-addresses.rs index 66ac467e9acd9..2783b44671d5e 100644 --- a/tests/ui/cross-crate/static-addresses.rs +++ b/tests/ui/cross-crate/static-addresses.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:xcrate_static_addresses.rs -//@ pretty-expanded FIXME #23616 extern crate xcrate_static_addresses; diff --git a/tests/ui/cross-crate/trait-lifetime-param.rs b/tests/ui/cross-crate/trait-lifetime-param.rs index 28955e62d9584..89983492fe4cb 100644 --- a/tests/ui/cross-crate/trait-lifetime-param.rs +++ b/tests/ui/cross-crate/trait-lifetime-param.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] //@ aux-build:xcrate-trait-lifetime-param.rs -//@ pretty-expanded FIXME #23616 extern crate xcrate_trait_lifetime_param as other; diff --git a/tests/ui/cross-crate/unit-struct-2.rs b/tests/ui/cross-crate/unit-struct-2.rs index c2e3a7611292f..2177a8800db1a 100644 --- a/tests/ui/cross-crate/unit-struct-2.rs +++ b/tests/ui/cross-crate/unit-struct-2.rs @@ -1,6 +1,5 @@ //@ run-pass //@ aux-build:xcrate_unit_struct.rs -//@ pretty-expanded FIXME #23616 #![allow(non_upper_case_globals)] extern crate xcrate_unit_struct; diff --git a/tests/ui/default-method-parsing.rs b/tests/ui/default-method-parsing.rs index 2580a04221fb0..84c3ab747c8ee 100644 --- a/tests/ui/default-method-parsing.rs +++ b/tests/ui/default-method-parsing.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait Foo { fn m(&self, _:isize) { } diff --git a/tests/ui/deref.rs b/tests/ui/deref.rs index b491c517d94fa..0a6f3cc81f6c1 100644 --- a/tests/ui/deref.rs +++ b/tests/ui/deref.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { let x: Box = Box::new(10); diff --git a/tests/ui/derives/auxiliary/derive-marker-tricky.rs b/tests/ui/derives/auxiliary/derive-marker-tricky.rs index 0f1c30811a2d6..f31baa43c3d13 100644 --- a/tests/ui/derives/auxiliary/derive-marker-tricky.rs +++ b/tests/ui/derives/auxiliary/derive-marker-tricky.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/derives/derive-marker-tricky.rs b/tests/ui/derives/derive-marker-tricky.rs index ad03b6c2cd276..3831bd485818d 100644 --- a/tests/ui/derives/derive-marker-tricky.rs +++ b/tests/ui/derives/derive-marker-tricky.rs @@ -2,7 +2,7 @@ // a built-in derive in non-trivial scope (e.g. in a nested module). //@ check-pass -//@ aux-build:derive-marker-tricky.rs +//@ proc-macro: derive-marker-tricky.rs extern crate derive_marker_tricky; diff --git a/tests/ui/deriving/auxiliary/another-proc-macro.rs b/tests/ui/deriving/auxiliary/another-proc-macro.rs index c992cde4066b1..47f3c5b9c4b05 100644 --- a/tests/ui/deriving/auxiliary/another-proc-macro.rs +++ b/tests/ui/deriving/auxiliary/another-proc-macro.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_quote)] extern crate proc_macro; diff --git a/tests/ui/deriving/built-in-proc-macro-scope.rs b/tests/ui/deriving/built-in-proc-macro-scope.rs index 6c473aefc5b0c..e67197b7e2051 100644 --- a/tests/ui/deriving/built-in-proc-macro-scope.rs +++ b/tests/ui/deriving/built-in-proc-macro-scope.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build: another-proc-macro.rs +//@ proc-macro: another-proc-macro.rs //@ compile-flags: -Zunpretty=expanded #![feature(derive_coerce_pointee)] diff --git a/tests/ui/deriving/built-in-proc-macro-scope.stdout b/tests/ui/deriving/built-in-proc-macro-scope.stdout index 07767dc229fd7..db97c7145ea09 100644 --- a/tests/ui/deriving/built-in-proc-macro-scope.stdout +++ b/tests/ui/deriving/built-in-proc-macro-scope.stdout @@ -1,7 +1,7 @@ #![feature(prelude_import)] #![no_std] //@ check-pass -//@ aux-build: another-proc-macro.rs +//@ proc-macro: another-proc-macro.rs //@ compile-flags: -Zunpretty=expanded #![feature(derive_coerce_pointee)] diff --git a/tests/ui/deriving/deriving-clone-enum.rs b/tests/ui/deriving/deriving-clone-enum.rs index 59301c1d094bd..96b9ba4f24c3e 100644 --- a/tests/ui/deriving/deriving-clone-enum.rs +++ b/tests/ui/deriving/deriving-clone-enum.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #[derive(Clone)] enum E { diff --git a/tests/ui/deriving/deriving-clone-generic-enum.rs b/tests/ui/deriving/deriving-clone-generic-enum.rs index 7f0dd872ffdf8..08c91c487baac 100644 --- a/tests/ui/deriving/deriving-clone-generic-enum.rs +++ b/tests/ui/deriving/deriving-clone-generic-enum.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #[derive(Clone)] enum E { diff --git a/tests/ui/deriving/deriving-clone-generic-struct.rs b/tests/ui/deriving/deriving-clone-generic-struct.rs index cbdfa8a7c9a5f..f2fc6d5e4d78f 100644 --- a/tests/ui/deriving/deriving-clone-generic-struct.rs +++ b/tests/ui/deriving/deriving-clone-generic-struct.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/deriving/deriving-clone-generic-tuple-struct.rs b/tests/ui/deriving/deriving-clone-generic-tuple-struct.rs index f0bbce707f304..178075e273d73 100644 --- a/tests/ui/deriving/deriving-clone-generic-tuple-struct.rs +++ b/tests/ui/deriving/deriving-clone-generic-tuple-struct.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #[derive(Clone)] #[allow(dead_code)] diff --git a/tests/ui/deriving/deriving-clone-struct.rs b/tests/ui/deriving/deriving-clone-struct.rs index b357aa82a2ac8..896ce51bf3d84 100644 --- a/tests/ui/deriving/deriving-clone-struct.rs +++ b/tests/ui/deriving/deriving-clone-struct.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/deriving/deriving-clone-tuple-struct.rs b/tests/ui/deriving/deriving-clone-tuple-struct.rs index 727860465fc47..622ffb7b1f49c 100644 --- a/tests/ui/deriving/deriving-clone-tuple-struct.rs +++ b/tests/ui/deriving/deriving-clone-tuple-struct.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/deriving/deriving-enum-single-variant.rs b/tests/ui/deriving/deriving-enum-single-variant.rs index dfdfef01298bb..43d229c442c45 100644 --- a/tests/ui/deriving/deriving-enum-single-variant.rs +++ b/tests/ui/deriving/deriving-enum-single-variant.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(non_camel_case_types)] pub type task_id = isize; diff --git a/tests/ui/deriving/deriving-in-macro.rs b/tests/ui/deriving/deriving-in-macro.rs index e86b40d30dcf0..493c1415c7fa2 100644 --- a/tests/ui/deriving/deriving-in-macro.rs +++ b/tests/ui/deriving/deriving-in-macro.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(non_camel_case_types)] macro_rules! define_vec { diff --git a/tests/ui/deriving/deriving-meta-multiple.rs b/tests/ui/deriving/deriving-meta-multiple.rs index 07dabd9e9c36b..7c2d3566fbf26 100644 --- a/tests/ui/deriving/deriving-meta-multiple.rs +++ b/tests/ui/deriving/deriving-meta-multiple.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_must_use)] #![allow(unused_imports)] -//@ pretty-expanded FIXME #23616 #![allow(deprecated)] use std::hash::{Hash, SipHasher}; diff --git a/tests/ui/deriving/deriving-meta.rs b/tests/ui/deriving/deriving-meta.rs index 34d31d9ef9ee6..70b5821edae14 100644 --- a/tests/ui/deriving/deriving-meta.rs +++ b/tests/ui/deriving/deriving-meta.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_must_use)] #![allow(unused_imports)] -//@ pretty-expanded FIXME #23616 #![allow(deprecated)] use std::hash::{Hash, SipHasher}; diff --git a/tests/ui/deriving/deriving-via-extension-hash-struct.rs b/tests/ui/deriving/deriving-via-extension-hash-struct.rs index ad2a84b6bf920..2b1bc9e108b13 100644 --- a/tests/ui/deriving/deriving-via-extension-hash-struct.rs +++ b/tests/ui/deriving/deriving-via-extension-hash-struct.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #[derive(Hash)] struct Foo { diff --git a/tests/ui/deriving/issue-15689-2.rs b/tests/ui/deriving/issue-15689-2.rs index 790c72f6d4d04..a1f66cc064388 100644 --- a/tests/ui/deriving/issue-15689-2.rs +++ b/tests/ui/deriving/issue-15689-2.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #[derive(Clone)] enum Test<'a> { diff --git a/tests/ui/deriving/issue-6341.rs b/tests/ui/deriving/issue-6341.rs index 5c2d0abfa8c44..83b0da9a31825 100644 --- a/tests/ui/deriving/issue-6341.rs +++ b/tests/ui/deriving/issue-6341.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 #[derive(PartialEq)] struct A { x: usize } diff --git a/tests/ui/deriving/proc-macro-attribute-mixing.rs b/tests/ui/deriving/proc-macro-attribute-mixing.rs index 80a0d068ce7dd..2c11c3f72ca59 100644 --- a/tests/ui/deriving/proc-macro-attribute-mixing.rs +++ b/tests/ui/deriving/proc-macro-attribute-mixing.rs @@ -5,7 +5,7 @@ // are in scope. //@ check-pass -//@ aux-build: another-proc-macro.rs +//@ proc-macro: another-proc-macro.rs //@ compile-flags: -Zunpretty=expanded #![feature(derive_coerce_pointee)] diff --git a/tests/ui/deriving/proc-macro-attribute-mixing.stdout b/tests/ui/deriving/proc-macro-attribute-mixing.stdout index 03128c6c957cf..ad743d013d25d 100644 --- a/tests/ui/deriving/proc-macro-attribute-mixing.stdout +++ b/tests/ui/deriving/proc-macro-attribute-mixing.stdout @@ -7,7 +7,7 @@ // are in scope. //@ check-pass -//@ aux-build: another-proc-macro.rs +//@ proc-macro: another-proc-macro.rs //@ compile-flags: -Zunpretty=expanded #![feature(derive_coerce_pointee)] diff --git a/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr b/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr index b9ceaa4af7ba0..88f7d2da47c28 100644 --- a/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr +++ b/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr @@ -5,7 +5,7 @@ LL | None = Some(3); | ^^^^ pattern `Some(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Option` help: you might want to use `if let` to ignore the variant that isn't matched | diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs index ce41ad2952bc9..dedae4365e889 100644 --- a/tests/ui/diagnostic-width/E0271.rs +++ b/tests/ui/diagnostic-width/E0271.rs @@ -1,6 +1,6 @@ //@ revisions: ascii unicode //@[ascii] compile-flags: --diagnostic-width=40 -//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode --diagnostic-width=40 +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40 //@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" trait Future { type Error; diff --git a/tests/ui/diagnostic-width/flag-human.rs b/tests/ui/diagnostic-width/flag-human.rs index 1af4165914164..8e656293b4102 100644 --- a/tests/ui/diagnostic-width/flag-human.rs +++ b/tests/ui/diagnostic-width/flag-human.rs @@ -1,6 +1,6 @@ //@ revisions: ascii unicode //@[ascii] compile-flags: --diagnostic-width=20 -//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode --diagnostic-width=20 +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=20 // This test checks that `-Z output-width` effects the human error output by restricting it to an // arbitrarily low value so that the effect is visible. diff --git a/tests/ui/diagnostic-width/long-E0308.rs b/tests/ui/diagnostic-width/long-E0308.rs index 73f81f5872a64..695852f83ac0a 100644 --- a/tests/ui/diagnostic-width/long-E0308.rs +++ b/tests/ui/diagnostic-width/long-E0308.rs @@ -1,6 +1,6 @@ //@ revisions: ascii unicode //@[ascii] compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -//@[unicode] compile-flags: -Zunstable-options=yes --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes +//@[unicode] compile-flags: -Zunstable-options --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes //@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" mod a { diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs index 61c4b31e03a62..e630db8ba42a2 100644 --- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs +++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs @@ -1,5 +1,5 @@ //@ revisions: ascii unicode -//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode // ignore-tidy-linelength fn main() { diff --git a/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs b/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs index 283506bd6c90d..de2f42a4a7292 100644 --- a/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs +++ b/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs @@ -1,5 +1,5 @@ //@ revisions: ascii unicode -//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode // ignore-tidy-linelength fn main() { diff --git a/tests/ui/diagnostic_namespace/auxiliary/proc-macro-helper.rs b/tests/ui/diagnostic_namespace/auxiliary/proc-macro-helper.rs index 4edae48923a24..3fe84317d70e8 100644 --- a/tests/ui/diagnostic_namespace/auxiliary/proc-macro-helper.rs +++ b/tests/ui/diagnostic_namespace/auxiliary/proc-macro-helper.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/diagnostic_namespace/existing_proc_macros.rs b/tests/ui/diagnostic_namespace/existing_proc_macros.rs index 014ec46f1b981..55b6b0ab441bc 100644 --- a/tests/ui/diagnostic_namespace/existing_proc_macros.rs +++ b/tests/ui/diagnostic_namespace/existing_proc_macros.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:proc-macro-helper.rs +//@ proc-macro: proc-macro-helper.rs extern crate proc_macro_helper; diff --git a/tests/ui/double-ref.rs b/tests/ui/double-ref.rs index 62591deb8689f..eecf68ff209cb 100644 --- a/tests/ui/double-ref.rs +++ b/tests/ui/double-ref.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn check_expr() { let _: & usize = &1; diff --git a/tests/ui/drop/auxiliary/edition-2024-macros.rs b/tests/ui/drop/auxiliary/edition-2024-macros.rs index 236340bfed4f4..44befbc98438f 100644 --- a/tests/ui/drop/auxiliary/edition-2024-macros.rs +++ b/tests/ui/drop/auxiliary/edition-2024-macros.rs @@ -1,5 +1,4 @@ //@ edition:2024 -//@ compile-flags: -Zunstable-options #[macro_export] macro_rules! edition_2024_block { diff --git a/tests/ui/drop/drop-on-empty-block-exit.rs b/tests/ui/drop/drop-on-empty-block-exit.rs index 63bc403a72145..107ea9022f86f 100644 --- a/tests/ui/drop/drop-on-empty-block-exit.rs +++ b/tests/ui/drop/drop-on-empty-block-exit.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(non_camel_case_types)] enum t { foo(Box), } diff --git a/tests/ui/drop/drop-on-ret.rs b/tests/ui/drop/drop-on-ret.rs index f8ce899adf088..4bd50e6a72d72 100644 --- a/tests/ui/drop/drop-on-ret.rs +++ b/tests/ui/drop/drop-on-ret.rs @@ -2,7 +2,6 @@ -//@ pretty-expanded FIXME #23616 fn f() -> isize { if true { diff --git a/tests/ui/drop/drop-uninhabited-enum.rs b/tests/ui/drop/drop-uninhabited-enum.rs index f018ffa097747..2ac6dc8e9ea3e 100644 --- a/tests/ui/drop/drop-uninhabited-enum.rs +++ b/tests/ui/drop/drop-uninhabited-enum.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 enum Foo { } diff --git a/tests/ui/drop/drop_order.rs b/tests/ui/drop/drop_order.rs index 7a999c7c330a1..d1a5b9bc5e268 100644 --- a/tests/ui/drop/drop_order.rs +++ b/tests/ui/drop/drop_order.rs @@ -2,7 +2,6 @@ //@ compile-flags: -Z validate-mir //@ revisions: edition2021 edition2024 //@ [edition2021] edition: 2021 -//@ [edition2024] compile-flags: -Z unstable-options //@ [edition2024] edition: 2024 #![feature(let_chains)] diff --git a/tests/ui/drop/drop_order_if_let_rescope.rs b/tests/ui/drop/drop_order_if_let_rescope.rs index cea84bbaa2b92..7445e3a6a5f1f 100644 --- a/tests/ui/drop/drop_order_if_let_rescope.rs +++ b/tests/ui/drop/drop_order_if_let_rescope.rs @@ -1,6 +1,6 @@ //@ run-pass //@ edition:2024 -//@ compile-flags: -Z validate-mir -Zunstable-options +//@ compile-flags: -Z validate-mir #![feature(let_chains)] diff --git a/tests/ui/drop/if-let-rescope-borrowck-suggestions.rs b/tests/ui/drop/if-let-rescope-borrowck-suggestions.rs index e055c20d777bc..a3583c48c39b7 100644 --- a/tests/ui/drop/if-let-rescope-borrowck-suggestions.rs +++ b/tests/ui/drop/if-let-rescope-borrowck-suggestions.rs @@ -1,5 +1,5 @@ //@ edition: 2024 -//@ compile-flags: -Z validate-mir -Zunstable-options +//@ compile-flags: -Z validate-mir #![deny(if_let_rescope)] diff --git a/tests/ui/drop/issue-10028.rs b/tests/ui/drop/issue-10028.rs index 4191425452249..1ca1fbf504d73 100644 --- a/tests/ui/drop/issue-10028.rs +++ b/tests/ui/drop/issue-10028.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] //@ aux-build:issue-10028.rs -//@ pretty-expanded FIXME #23616 extern crate issue_10028 as issue10028; diff --git a/tests/ui/drop/issue-2734.rs b/tests/ui/drop/issue-2734.rs index 028f86ebb3a90..4616ea1f0137d 100644 --- a/tests/ui/drop/issue-2734.rs +++ b/tests/ui/drop/issue-2734.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 trait hax { fn dummy(&self) { } diff --git a/tests/ui/drop/issue-2735.rs b/tests/ui/drop/issue-2735.rs index 8fa3ac45d08f8..cd7e0b8f46109 100644 --- a/tests/ui/drop/issue-2735.rs +++ b/tests/ui/drop/issue-2735.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 trait hax { fn dummy(&self) { } diff --git a/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr b/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr index 48b7f3e11a682..7f9a01599505b 100644 --- a/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr +++ b/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr @@ -1,5 +1,5 @@ error: `if let` assigns a shorter lifetime since Edition 2024 - --> $DIR/lint-if-let-rescope-gated.rs:27:8 + --> $DIR/lint-if-let-rescope-gated.rs:26:8 | LL | if let Some(_value) = Droppy.get() { | ^^^^^^^^^^^^^^^^^^^------^^^^^^ @@ -9,12 +9,12 @@ LL | if let Some(_value) = Droppy.get() { = warning: this changes meaning in Rust 2024 = note: for more information, see issue #124085 help: the value is now dropped here in Edition 2024 - --> $DIR/lint-if-let-rescope-gated.rs:31:5 + --> $DIR/lint-if-let-rescope-gated.rs:30:5 | LL | } else { | ^ note: the lint level is defined here - --> $DIR/lint-if-let-rescope-gated.rs:11:9 + --> $DIR/lint-if-let-rescope-gated.rs:10:9 | LL | #![deny(if_let_rescope)] | ^^^^^^^^^^^^^^ diff --git a/tests/ui/drop/lint-if-let-rescope-gated.rs b/tests/ui/drop/lint-if-let-rescope-gated.rs index ba0246573b406..f5538a37eef85 100644 --- a/tests/ui/drop/lint-if-let-rescope-gated.rs +++ b/tests/ui/drop/lint-if-let-rescope-gated.rs @@ -5,7 +5,6 @@ //@ revisions: edition2021 edition2024 //@ [edition2021] edition: 2021 //@ [edition2024] edition: 2024 -//@ [edition2024] compile-flags: -Zunstable-options //@ [edition2024] check-pass #![deny(if_let_rescope)] diff --git a/tests/ui/drop/lint-tail-expr-drop-order-gated.rs b/tests/ui/drop/lint-tail-expr-drop-order-gated.rs index 508e7bdbf99ae..361862100e6bf 100644 --- a/tests/ui/drop/lint-tail-expr-drop-order-gated.rs +++ b/tests/ui/drop/lint-tail-expr-drop-order-gated.rs @@ -3,7 +3,6 @@ // Only `cargo fix --edition 2024` shall activate this lint. //@ check-pass -//@ compile-flags: -Z unstable-options //@ edition: 2024 #![deny(tail_expr_drop_order)] diff --git a/tests/ui/drop/nondrop-cycle.rs b/tests/ui/drop/nondrop-cycle.rs index 9b32d1319c914..fbee1be179f02 100644 --- a/tests/ui/drop/nondrop-cycle.rs +++ b/tests/ui/drop/nondrop-cycle.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use std::cell::Cell; diff --git a/tests/ui/drop/tail-expr-drop-order-negative.edition2024.stderr b/tests/ui/drop/tail-expr-drop-order-negative.edition2024.stderr index bcce796570e29..2c0b238eb5f20 100644 --- a/tests/ui/drop/tail-expr-drop-order-negative.edition2024.stderr +++ b/tests/ui/drop/tail-expr-drop-order-negative.edition2024.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/tail-expr-drop-order-negative.rs:9:15 + --> $DIR/tail-expr-drop-order-negative.rs:8:15 | LL | x.replace(std::cell::RefCell::new(123).borrow()).is_some() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement diff --git a/tests/ui/drop/tail-expr-drop-order-negative.rs b/tests/ui/drop/tail-expr-drop-order-negative.rs index 5ad04d0a67ef6..3b20691f8eaa0 100644 --- a/tests/ui/drop/tail-expr-drop-order-negative.rs +++ b/tests/ui/drop/tail-expr-drop-order-negative.rs @@ -1,5 +1,4 @@ //@ revisions: edition2021 edition2024 -//@ [edition2024] compile-flags: -Zunstable-options //@ [edition2024] edition: 2024 //@ [edition2021] check-pass diff --git a/tests/ui/drop/tail-expr-drop-order.rs b/tests/ui/drop/tail-expr-drop-order.rs index 80968b823f9a7..f74530fce1e22 100644 --- a/tests/ui/drop/tail-expr-drop-order.rs +++ b/tests/ui/drop/tail-expr-drop-order.rs @@ -1,6 +1,6 @@ //@ aux-build:edition-2021-macros.rs //@ aux-build:edition-2024-macros.rs -//@ compile-flags: -Z validate-mir -Zunstable-options +//@ compile-flags: -Z validate-mir //@ edition: 2024 //@ run-pass diff --git a/tests/ui/drop/use_inline_dtor.rs b/tests/ui/drop/use_inline_dtor.rs index 03f476cff2a1b..9d3cbd0b8b4ec 100644 --- a/tests/ui/drop/use_inline_dtor.rs +++ b/tests/ui/drop/use_inline_dtor.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:inline_dtor.rs -//@ pretty-expanded FIXME #23616 extern crate inline_dtor; diff --git a/tests/ui/dropck/cleanup-arm-conditional.rs b/tests/ui/dropck/cleanup-arm-conditional.rs index 94b380801892b..31331f24d6f6b 100644 --- a/tests/ui/dropck/cleanup-arm-conditional.rs +++ b/tests/ui/dropck/cleanup-arm-conditional.rs @@ -5,7 +5,6 @@ // Test that cleanup scope for temporaries created in a match // arm is confined to the match arm itself. -//@ pretty-expanded FIXME #23616 #![feature(os)] diff --git a/tests/ui/dropck/const_drop_is_valid.rs b/tests/ui/dropck/const_drop_is_valid.rs deleted file mode 100644 index 26ef2d61deb69..0000000000000 --- a/tests/ui/dropck/const_drop_is_valid.rs +++ /dev/null @@ -1,8 +0,0 @@ -struct A(); - -impl const Drop for A {} -//~^ ERROR: const trait impls are experimental -//~| const `impl` for trait `Drop` which is not marked with `#[const_trait]` -//~| not all trait items implemented, missing: `drop` - -fn main() {} diff --git a/tests/ui/dropck/const_drop_is_valid.stderr b/tests/ui/dropck/const_drop_is_valid.stderr deleted file mode 100644 index 5837e1623a170..0000000000000 --- a/tests/ui/dropck/const_drop_is_valid.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0658]: const trait impls are experimental - --> $DIR/const_drop_is_valid.rs:3:6 - | -LL | impl const Drop for A {} - | ^^^^^ - | - = note: see issue #67792 for more information - = help: add `#![feature(const_trait_impl)]` 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: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const_drop_is_valid.rs:3:12 - | -LL | impl const Drop for A {} - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error[E0046]: not all trait items implemented, missing: `drop` - --> $DIR/const_drop_is_valid.rs:3:1 - | -LL | impl const Drop for A {} - | ^^^^^^^^^^^^^^^^^^^^^ missing `drop` in implementation - | - = help: implement the missing item: `fn drop(&mut self) { todo!() }` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0046, E0658. -For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/dupe-first-attr.rs b/tests/ui/dupe-first-attr.rs index ec9e354e73df3..c254df050c153 100644 --- a/tests/ui/dupe-first-attr.rs +++ b/tests/ui/dupe-first-attr.rs @@ -3,7 +3,6 @@ // Regression test for a problem with the first mod attribute // being applied to every mod -//@ pretty-expanded FIXME #23616 #[cfg(target_os = "linux")] mod hello {} diff --git a/tests/ui/dynamically-sized-types/dst-coercions.rs b/tests/ui/dynamically-sized-types/dst-coercions.rs index 6b3c85cf83b06..4813dda439b53 100644 --- a/tests/ui/dynamically-sized-types/dst-coercions.rs +++ b/tests/ui/dynamically-sized-types/dst-coercions.rs @@ -2,7 +2,6 @@ #![allow(unused_variables)] // Test coercions involving DST and/or raw pointers -//@ pretty-expanded FIXME #23616 struct S; trait T { fn dummy(&self) { } } //~ WARN method `dummy` is never used diff --git a/tests/ui/dynamically-sized-types/dst-coercions.stderr b/tests/ui/dynamically-sized-types/dst-coercions.stderr index e4721ce50a045..e7c48783df0ee 100644 --- a/tests/ui/dynamically-sized-types/dst-coercions.stderr +++ b/tests/ui/dynamically-sized-types/dst-coercions.stderr @@ -1,5 +1,5 @@ warning: method `dummy` is never used - --> $DIR/dst-coercions.rs:8:14 + --> $DIR/dst-coercions.rs:7:14 | LL | trait T { fn dummy(&self) { } } | - ^^^^^ diff --git a/tests/ui/early-ret-binop-add.rs b/tests/ui/early-ret-binop-add.rs index 5daf79c214c50..3fec66f35fb8b 100644 --- a/tests/ui/early-ret-binop-add.rs +++ b/tests/ui/early-ret-binop-add.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(unreachable_code)] -//@ pretty-expanded FIXME #23616 use std::ops::Add; diff --git a/tests/ui/editions/async-block-2015.rs b/tests/ui/editions/async-block-2015.rs index 3daf4930c5b4b..a079b4aad911e 100644 --- a/tests/ui/editions/async-block-2015.rs +++ b/tests/ui/editions/async-block-2015.rs @@ -1,7 +1,7 @@ async fn foo() { //~^ ERROR `async fn` is not permitted in Rust 2015 //~| NOTE to use `async fn`, switch to Rust 2018 or later -//~| HELP pass `--edition 2021` to `rustc` +//~| HELP pass `--edition 2024` to `rustc` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide let x = async {}; @@ -11,7 +11,7 @@ async fn foo() { let x = 42; //~^ ERROR expected identifier, found keyword `let` //~| NOTE expected identifier, found keyword - //~| HELP pass `--edition 2021` to `rustc` + //~| HELP pass `--edition 2024` to `rustc` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide 42 }; @@ -19,7 +19,7 @@ async fn foo() { 42 //~^ ERROR expected identifier, found `42` //~| NOTE expected identifier - //~| HELP pass `--edition 2021` to `rustc` + //~| HELP pass `--edition 2024` to `rustc` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide }; y.await; diff --git a/tests/ui/editions/async-block-2015.stderr b/tests/ui/editions/async-block-2015.stderr index b792b8c1e0dd8..574bcacc1cfa7 100644 --- a/tests/ui/editions/async-block-2015.stderr +++ b/tests/ui/editions/async-block-2015.stderr @@ -4,7 +4,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015 LL | async fn foo() { | ^^^^^ to use `async fn`, switch to Rust 2018 or later | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error: expected identifier, found keyword `let` @@ -15,7 +15,7 @@ LL | let y = async { LL | let x = 42; | ^^^ expected identifier, found keyword | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error: expected identifier, found `42` @@ -26,7 +26,7 @@ LL | let z = async { LL | 42 | ^^ expected identifier | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0422]: cannot find struct, variant or union type `async` in this scope diff --git a/tests/ui/editions/edition-cstr-2015-2018.rs b/tests/ui/editions/edition-cstr-2015-2018.rs index 4c35c48646a03..4d4274251f050 100644 --- a/tests/ui/editions/edition-cstr-2015-2018.rs +++ b/tests/ui/editions/edition-cstr-2015-2018.rs @@ -7,7 +7,7 @@ macro_rules! contain { () => { c"str" } } //~| NOTE expected one of 8 possible tokens //~| NOTE you may be trying to write a c-string literal //~| NOTE c-string literals require Rust 2021 or later - //~| HELP pass `--edition 2021` to `rustc` + //~| HELP pass `--edition 2024` to `rustc` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide fn check_macro_construct() { @@ -29,7 +29,7 @@ fn check_basic() { //~| NOTE expected one of 8 possible tokens //~| NOTE you may be trying to write a c-string literal //~| NOTE c-string literals require Rust 2021 or later - //~| HELP pass `--edition 2021` to `rustc` + //~| HELP pass `--edition 2024` to `rustc` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide } @@ -39,7 +39,7 @@ fn check_craw() { //~| NOTE expected one of 8 possible tokens //~| NOTE you may be trying to write a c-string literal //~| NOTE c-string literals require Rust 2021 or later - //~| HELP pass `--edition 2021` to `rustc` + //~| HELP pass `--edition 2024` to `rustc` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide } @@ -49,7 +49,7 @@ fn check_craw_hash() { //~| NOTE expected one of 8 possible tokens //~| NOTE you may be trying to write a c-string literal //~| NOTE c-string literals require Rust 2021 or later - //~| HELP pass `--edition 2021` to `rustc` + //~| HELP pass `--edition 2024` to `rustc` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide } diff --git a/tests/ui/editions/edition-cstr-2015-2018.stderr b/tests/ui/editions/edition-cstr-2015-2018.stderr index b864df308ef99..62cb857655200 100644 --- a/tests/ui/editions/edition-cstr-2015-2018.stderr +++ b/tests/ui/editions/edition-cstr-2015-2018.stderr @@ -6,7 +6,7 @@ LL | c"str"; | = note: you may be trying to write a c-string literal = note: c-string literals require Rust 2021 or later - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"` @@ -17,7 +17,7 @@ LL | cr"str"; | = note: you may be trying to write a c-string literal = note: c-string literals require Rust 2021 or later - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `#` @@ -28,7 +28,7 @@ LL | cr##"str"##; | = note: you may be trying to write a c-string literal = note: c-string literals require Rust 2021 or later - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"` @@ -59,7 +59,7 @@ LL | contain!(); | = note: you may be trying to write a c-string literal = note: c-string literals require Rust 2021 or later - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide = note: this error originates in the macro `contain` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.fixed b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed index 75bc598d17bd5..91d30de74c7c0 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2021.fixed +++ b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed @@ -2,7 +2,6 @@ // //@[e2021] edition: 2021 //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options // //@[e2021] run-pass //@[e2021] run-rustfix diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr index 454e88d4569b8..6fdb548c4317a 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr @@ -1,5 +1,5 @@ warning: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:17:1 + --> $DIR/never-type-fallback-breaking.rs:16:1 | LL | fn m() { | ^^^^^^ @@ -8,7 +8,7 @@ LL | fn m() { = note: for more information, see issue #123748 = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/never-type-fallback-breaking.rs:21:17 + --> $DIR/never-type-fallback-breaking.rs:20:17 | LL | true => Default::default(), | ^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | let x: () = match true { | ++++ warning: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:29:1 + --> $DIR/never-type-fallback-breaking.rs:28:1 | LL | fn q() -> Option<()> { | ^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | fn q() -> Option<()> { = note: for more information, see issue #123748 = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/never-type-fallback-breaking.rs:36:5 + --> $DIR/never-type-fallback-breaking.rs:35:5 | LL | deserialize()?; | ^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | deserialize::<()>()?; | ++++++ warning: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:46:1 + --> $DIR/never-type-fallback-breaking.rs:45:1 | LL | fn meow() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | fn meow() -> Result<(), ()> { = note: for more information, see issue #123748 = help: specify the types explicitly note: in edition 2024, the requirement `(): From` will fail - --> $DIR/never-type-fallback-breaking.rs:49:5 + --> $DIR/never-type-fallback-breaking.rs:48:5 | LL | help(1)?; | ^^^^^^^ diff --git a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr index 6258247f8b28e..9d79dfb4099fb 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `!: Default` is not satisfied - --> $DIR/never-type-fallback-breaking.rs:21:17 + --> $DIR/never-type-fallback-breaking.rs:20:17 | LL | true => Default::default(), | ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` @@ -8,7 +8,7 @@ LL | true => Default::default(), = help: did you intend to use the type `()` here instead? error[E0277]: the trait bound `!: Default` is not satisfied - --> $DIR/never-type-fallback-breaking.rs:36:5 + --> $DIR/never-type-fallback-breaking.rs:35:5 | LL | deserialize()?; | ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` @@ -16,13 +16,13 @@ LL | deserialize()?; = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) = help: did you intend to use the type `()` here instead? note: required by a bound in `deserialize` - --> $DIR/never-type-fallback-breaking.rs:32:23 + --> $DIR/never-type-fallback-breaking.rs:31:23 | LL | fn deserialize() -> Option { | ^^^^^^^ required by this bound in `deserialize` error[E0277]: the trait bound `(): From` is not satisfied - --> $DIR/never-type-fallback-breaking.rs:49:5 + --> $DIR/never-type-fallback-breaking.rs:48:5 | LL | help(1)?; | ^^^^^^^ the trait `From` is not implemented for `()` @@ -39,7 +39,7 @@ LL | help(1)?; and 4 others = note: required for `!` to implement `Into<()>` note: required by a bound in `help` - --> $DIR/never-type-fallback-breaking.rs:43:20 + --> $DIR/never-type-fallback-breaking.rs:42:20 | LL | fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result { | ^^^^^^^^ required by this bound in `help` diff --git a/tests/ui/editions/never-type-fallback-breaking.rs b/tests/ui/editions/never-type-fallback-breaking.rs index 32e83e741393d..24e33ff6bf6b7 100644 --- a/tests/ui/editions/never-type-fallback-breaking.rs +++ b/tests/ui/editions/never-type-fallback-breaking.rs @@ -2,7 +2,6 @@ // //@[e2021] edition: 2021 //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options // //@[e2021] run-pass //@[e2021] run-rustfix diff --git a/tests/ui/editions/never-type-fallback.rs b/tests/ui/editions/never-type-fallback.rs index a5b75219295c9..987fb305763f2 100644 --- a/tests/ui/editions/never-type-fallback.rs +++ b/tests/ui/editions/never-type-fallback.rs @@ -2,7 +2,6 @@ // //@[e2021] edition: 2021 //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options // //@ run-pass //@ check-run-results diff --git a/tests/ui/empty-allocation-rvalue-non-null.rs b/tests/ui/empty-allocation-rvalue-non-null.rs index 25c36679033b9..0cd4fde73eda8 100644 --- a/tests/ui/empty-allocation-rvalue-non-null.rs +++ b/tests/ui/empty-allocation-rvalue-non-null.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 pub fn main() { let x: () = *Box::new(()); diff --git a/tests/ui/empty/empty-never-array.stderr b/tests/ui/empty/empty-never-array.stderr index 0104a43553843..f9f39a6371e26 100644 --- a/tests/ui/empty/empty-never-array.stderr +++ b/tests/ui/empty/empty-never-array.stderr @@ -5,7 +5,7 @@ LL | let Helper::U(u) = Helper::T(t, []); | ^^^^^^^^^^^^ pattern `Helper::T(_, _)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `Helper` defined here --> $DIR/empty-never-array.rs:3:6 | diff --git a/tests/ui/enum/issue-1821.rs b/tests/ui/enum/issue-1821.rs index 76d60962c38be..2cfdee566a61c 100644 --- a/tests/ui/enum/issue-1821.rs +++ b/tests/ui/enum/issue-1821.rs @@ -5,7 +5,6 @@ // Issue #1821 - Don't recurse trying to typecheck this -//@ pretty-expanded FIXME #23616 enum t { foo(Vec) diff --git a/tests/ui/enum/issue-19340-1.rs b/tests/ui/enum/issue-19340-1.rs index c1ba0d23b6ff6..9793692344261 100644 --- a/tests/ui/enum/issue-19340-1.rs +++ b/tests/ui/enum/issue-19340-1.rs @@ -2,7 +2,6 @@ #![allow(unused_variables)] //@ aux-build:issue-19340-1.rs -//@ pretty-expanded FIXME #23616 extern crate issue_19340_1 as lib; diff --git a/tests/ui/enum/issue-19340-2.rs b/tests/ui/enum/issue-19340-2.rs index dd1bda78a9795..0930cd5da09ae 100644 --- a/tests/ui/enum/issue-19340-2.rs +++ b/tests/ui/enum/issue-19340-2.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 enum Homura { Madoka { diff --git a/tests/ui/error-codes/E0005.stderr b/tests/ui/error-codes/E0005.stderr index 4be37e2e45497..c643ee07a3739 100644 --- a/tests/ui/error-codes/E0005.stderr +++ b/tests/ui/error-codes/E0005.stderr @@ -5,7 +5,7 @@ LL | let Some(y) = x; | ^^^^^^^ pattern `None` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Option` help: you might want to use `let else` to handle the variant that isn't matched | diff --git a/tests/ui/error-codes/E0045.stderr b/tests/ui/error-codes/E0045.stderr index 25b2f2654da15..b8ee31a40495a 100644 --- a/tests/ui/error-codes/E0045.stderr +++ b/tests/ui/error-codes/E0045.stderr @@ -1,4 +1,4 @@ -error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl` +error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi` --> $DIR/E0045.rs:1:17 | LL | extern "Rust" { fn foo(x: u8, ...); } diff --git a/tests/ui/error-codes/E0617.rs b/tests/ui/error-codes/E0617.rs index b71ba0ed88b9f..4a38174bc6fef 100644 --- a/tests/ui/error-codes/E0617.rs +++ b/tests/ui/error-codes/E0617.rs @@ -20,7 +20,8 @@ fn main() { //~^ ERROR can't pass `u16` to variadic function //~| HELP cast the value to `c_uint` printf(::std::ptr::null(), printf); - //~^ ERROR can't pass `unsafe extern "C" fn(*const i8, ...) {printf}` to variadic function - //~| HELP cast the value to `unsafe extern "C" fn(*const i8, ...)` + //~^ ERROR can't pass a function item to a variadic function + //~| HELP a function item is zero-sized and needs to be cast into a function pointer to be used in FFI + //~| HELP use a function pointer instead } } diff --git a/tests/ui/error-codes/E0617.stderr b/tests/ui/error-codes/E0617.stderr index ea91ad0829230..b2eee1299601a 100644 --- a/tests/ui/error-codes/E0617.stderr +++ b/tests/ui/error-codes/E0617.stderr @@ -2,42 +2,69 @@ error[E0617]: can't pass `f32` to variadic function --> $DIR/E0617.rs:7:36 | LL | printf(::std::ptr::null(), 0f32); - | ^^^^ help: cast the value to `c_double`: `0f32 as c_double` + | ^^^^ + | +help: cast the value to `c_double` + | +LL | printf(::std::ptr::null(), 0f32 as c_double); + | +++++++++++ error[E0617]: can't pass `i8` to variadic function --> $DIR/E0617.rs:10:36 | LL | printf(::std::ptr::null(), 0i8); - | ^^^ help: cast the value to `c_int`: `0i8 as c_int` + | ^^^ + | +help: cast the value to `c_int` + | +LL | printf(::std::ptr::null(), 0i8 as c_int); + | ++++++++ error[E0617]: can't pass `i16` to variadic function --> $DIR/E0617.rs:13:36 | LL | printf(::std::ptr::null(), 0i16); - | ^^^^ help: cast the value to `c_int`: `0i16 as c_int` + | ^^^^ + | +help: cast the value to `c_int` + | +LL | printf(::std::ptr::null(), 0i16 as c_int); + | ++++++++ error[E0617]: can't pass `u8` to variadic function --> $DIR/E0617.rs:16:36 | LL | printf(::std::ptr::null(), 0u8); - | ^^^ help: cast the value to `c_uint`: `0u8 as c_uint` + | ^^^ + | +help: cast the value to `c_uint` + | +LL | printf(::std::ptr::null(), 0u8 as c_uint); + | +++++++++ error[E0617]: can't pass `u16` to variadic function --> $DIR/E0617.rs:19:36 | LL | printf(::std::ptr::null(), 0u16); - | ^^^^ help: cast the value to `c_uint`: `0u16 as c_uint` + | ^^^^ + | +help: cast the value to `c_uint` + | +LL | printf(::std::ptr::null(), 0u16 as c_uint); + | +++++++++ -error[E0617]: can't pass `unsafe extern "C" fn(*const i8, ...) {printf}` to variadic function +error[E0617]: can't pass a function item to a variadic function --> $DIR/E0617.rs:22:36 | LL | printf(::std::ptr::null(), printf); | ^^^^^^ | -help: cast the value to `unsafe extern "C" fn(*const i8, ...)` + = help: a function item is zero-sized and needs to be cast into a function pointer to be used in FFI + = note: for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html +help: use a function pointer instead | LL | printf(::std::ptr::null(), printf as unsafe extern "C" fn(*const i8, ...)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++++++++++++++++++++ error: aborting due to 6 previous errors diff --git a/tests/ui/error-codes/E0746.stderr b/tests/ui/error-codes/E0746.stderr index cfc747cb1e2c4..ce3e973696945 100644 --- a/tests/ui/error-codes/E0746.stderr +++ b/tests/ui/error-codes/E0746.stderr @@ -19,8 +19,11 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bar() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | - = help: if there were a single returned type, you could use `impl Trait` instead -help: box the return type, and wrap all of the returned values in `Box::new` +help: consider returning an `impl Trait` instead of a `dyn Trait` + | +LL | fn bar() -> impl Trait { + | ~~~~ +help: alternatively, box the return type, and wrap all of the returned values in `Box::new` | LL ~ fn bar() -> Box { LL | if true { diff --git a/tests/ui/error-emitter/unicode-output.rs b/tests/ui/error-emitter/unicode-output.rs index ba6db37b66c22..5c083c4e57508 100644 --- a/tests/ui/error-emitter/unicode-output.rs +++ b/tests/ui/error-emitter/unicode-output.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zunstable-options=yes --error-format=human-unicode --color=always +//@ compile-flags: -Zunstable-options --error-format=human-unicode --color=always //@ edition:2018 //@ only-linux diff --git a/tests/ui/explicit-i-suffix.rs b/tests/ui/explicit-i-suffix.rs index 29c7391521e2f..0a6ed49ae2704 100644 --- a/tests/ui/explicit-i-suffix.rs +++ b/tests/ui/explicit-i-suffix.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_must_use)] -//@ pretty-expanded FIXME #23616 pub fn main() { let x: isize = 8; diff --git a/tests/ui/expr/if/if-ret.rs b/tests/ui/expr/if/if-ret.rs index 3aad21d34a2ff..2698c5bbf6eaa 100644 --- a/tests/ui/expr/if/if-ret.rs +++ b/tests/ui/expr/if/if-ret.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_parens)] -//@ pretty-expanded FIXME #23616 fn foo() { if (return) { } } //~ WARNING unreachable block in `if` diff --git a/tests/ui/expr/if/if-ret.stderr b/tests/ui/expr/if/if-ret.stderr index 8ced271aabc2b..e5464affd2f15 100644 --- a/tests/ui/expr/if/if-ret.stderr +++ b/tests/ui/expr/if/if-ret.stderr @@ -1,5 +1,5 @@ warning: unreachable block in `if` or `while` expression - --> $DIR/if-ret.rs:6:24 + --> $DIR/if-ret.rs:5:24 | LL | fn foo() { if (return) { } } | -------- ^^^ unreachable block in `if` or `while` expression diff --git a/tests/ui/expr/scope.rs b/tests/ui/expr/scope.rs index 57321ce2aa015..3a1c8b87da8fa 100644 --- a/tests/ui/expr/scope.rs +++ b/tests/ui/expr/scope.rs @@ -1,7 +1,6 @@ //@ run-pass // Regression test for issue #762 -//@ pretty-expanded FIXME #23616 pub fn f() { } pub fn main() { return ::f(); } diff --git a/tests/ui/extern/extern-1.rs b/tests/ui/extern/extern-1.rs index c0f770ab9f2f3..226bc1effb176 100644 --- a/tests/ui/extern/extern-1.rs +++ b/tests/ui/extern/extern-1.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 extern "C" fn f() { } diff --git a/tests/ui/extern/extern-calling-convention-test.rs b/tests/ui/extern/extern-calling-convention-test.rs index 7c533df1986ed..68315ed093470 100644 --- a/tests/ui/extern/extern-calling-convention-test.rs +++ b/tests/ui/extern/extern-calling-convention-test.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:extern_calling_convention.rs -//@ pretty-expanded FIXME #23616 extern crate extern_calling_convention; diff --git a/tests/ui/extern/extern-foreign-crate.rs b/tests/ui/extern/extern-foreign-crate.rs index 939090ab5fc82..690a650136846 100644 --- a/tests/ui/extern/extern-foreign-crate.rs +++ b/tests/ui/extern/extern-foreign-crate.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 extern crate std as mystd; diff --git a/tests/ui/extern/extern-mod-abi.rs b/tests/ui/extern/extern-mod-abi.rs index 8700a379d2911..29892c468dd3b 100644 --- a/tests/ui/extern/extern-mod-abi.rs +++ b/tests/ui/extern/extern-mod-abi.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 extern "C" { fn pow(x: f64, y: f64) -> f64; diff --git a/tests/ui/extern/extern-mod-ordering-exe.rs b/tests/ui/extern/extern-mod-ordering-exe.rs index c735f6bae7a50..9f5e52e33955c 100644 --- a/tests/ui/extern/extern-mod-ordering-exe.rs +++ b/tests/ui/extern/extern-mod-ordering-exe.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:extern_mod_ordering_lib.rs -//@ pretty-expanded FIXME #23616 extern crate extern_mod_ordering_lib; diff --git a/tests/ui/extern/extern-pub.rs b/tests/ui/extern/extern-pub.rs index 80f1e295d4d40..b272bc5359fd0 100644 --- a/tests/ui/extern/extern-pub.rs +++ b/tests/ui/extern/extern-pub.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 extern "C" { pub fn free(p: *const u8); diff --git a/tests/ui/extern/extern-rust.rs b/tests/ui/extern/extern-rust.rs index bacdc7aeecb4c..b4a4a49810e66 100644 --- a/tests/ui/extern/extern-rust.rs +++ b/tests/ui/extern/extern-rust.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #[repr(C)] pub struct Foo(u32); diff --git a/tests/ui/extern/issue-10025.rs b/tests/ui/extern/issue-10025.rs index 0bdcf7c5c5875..140012f4a1613 100644 --- a/tests/ui/extern/issue-10025.rs +++ b/tests/ui/extern/issue-10025.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] unsafe extern fn foo() {} diff --git a/tests/ui/extern/issue-10763.rs b/tests/ui/extern/issue-10763.rs index 2381f22f162f2..6966f5571df74 100644 --- a/tests/ui/extern/issue-10763.rs +++ b/tests/ui/extern/issue-10763.rs @@ -1,6 +1,5 @@ //@ build-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 extern "Rust" fn foo() {} diff --git a/tests/ui/extern/issue-10764-rpass.rs b/tests/ui/extern/issue-10764-rpass.rs index 4de387e3d661d..761bf4e28b775 100644 --- a/tests/ui/extern/issue-10764-rpass.rs +++ b/tests/ui/extern/issue-10764-rpass.rs @@ -1,4 +1,3 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 extern "Rust" fn main() {} diff --git a/tests/ui/extern/issue-1251.rs b/tests/ui/extern/issue-1251.rs index 5581bddaddc16..ba42fef298c08 100644 --- a/tests/ui/extern/issue-1251.rs +++ b/tests/ui/extern/issue-1251.rs @@ -1,7 +1,6 @@ //@ build-pass #![allow(unused_attributes)] #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 mod rustrt { extern "C" { diff --git a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs new file mode 100644 index 0000000000000..7aec7455b2e6a --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs @@ -0,0 +1,23 @@ +//@ needs-asm-support +//@ compile-flags: --target s390x-unknown-linux-gnu +//@ needs-llvm-components: systemz + +#![feature(no_core, lang_items, rustc_attrs)] +#![crate_type = "rlib"] +#![no_core] + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +unsafe fn main() { + asm!("", in("v0") 0); + //~^ ERROR register class `vreg` can only be used as a clobber in stable + //~| ERROR type `i32` cannot be used with this register class +} diff --git a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr new file mode 100644 index 0000000000000..0791ce4543ca6 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr @@ -0,0 +1,23 @@ +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/feature-gate-asm_experimental_reg.rs:20:14 + | +LL | asm!("", in("v0") 0); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: type `i32` cannot be used with this register class in stable + --> $DIR/feature-gate-asm_experimental_reg.rs:20:23 + | +LL | asm!("", in("v0") 0); + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs new file mode 100644 index 0000000000000..294827f78d263 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs @@ -0,0 +1,13 @@ +//@ only-x86_64 + +#![feature(asm_goto)] + +use std::arch::asm; + +fn main() { + let mut _out: u64; + unsafe { + asm!("mov {}, 1", "jmp {}", out(reg) _out, label {}); + //~^ ERROR using both label and output operands for inline assembly is unstable + } +} 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 new file mode 100644 index 0000000000000..ff7a7d5760a7f --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.stderr @@ -0,0 +1,13 @@ +error[E0658]: using both label and output operands for inline assembly is unstable + --> $DIR/feature-gate-asm_goto_with_outputs.rs:10:52 + | +LL | asm!("mov {}, 1", "jmp {}", out(reg) _out, label {}); + | ^^^^^^^^ + | + = note: see issue #119364 for more information + = help: add `#![feature(asm_goto_with_outputs)]` 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-coroutines.rs b/tests/ui/feature-gates/feature-gate-coroutines.rs index a686357d910ad..f20dc56f12293 100644 --- a/tests/ui/feature-gates/feature-gate-coroutines.rs +++ b/tests/ui/feature-gates/feature-gate-coroutines.rs @@ -1,5 +1,5 @@ //@ revisions: e2024 none -//@[e2024] compile-flags: --edition 2024 -Zunstable-options +//@[e2024] edition: 2024 fn main() { yield true; //~ ERROR yield syntax is experimental diff --git a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr index 4836ffe172318..b596da8463f21 100644 --- a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr +++ b/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr @@ -5,7 +5,7 @@ LL | let Ok(_x) = &foo(); | ^^^^^^ pattern `&Err(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `&Result` help: you might want to use `let else` to handle the variant that isn't matched | diff --git a/tests/ui/feature-gates/feature-gate-gen_blocks.rs b/tests/ui/feature-gates/feature-gate-gen_blocks.rs index d9bfeac36ed0f..01fd922b0e999 100644 --- a/tests/ui/feature-gates/feature-gate-gen_blocks.rs +++ b/tests/ui/feature-gates/feature-gate-gen_blocks.rs @@ -1,5 +1,5 @@ //@ revisions: e2024 none -//@[e2024] compile-flags: --edition 2024 -Zunstable-options +//@[e2024] edition: 2024 fn test_gen() { gen {}; diff --git a/tests/ui/feature-gates/feature-gate-simd.rs b/tests/ui/feature-gates/feature-gate-simd.rs index e7aef5a97f2ee..9a27cb73f0072 100644 --- a/tests/ui/feature-gates/feature-gate-simd.rs +++ b/tests/ui/feature-gates/feature-gate-simd.rs @@ -1,5 +1,3 @@ -//@ pretty-expanded FIXME #23616 - #[repr(simd)] //~ ERROR SIMD types are experimental struct RGBA { rgba: [f32; 4], diff --git a/tests/ui/feature-gates/feature-gate-simd.stderr b/tests/ui/feature-gates/feature-gate-simd.stderr index b020db35a51ca..834baa0a564ea 100644 --- a/tests/ui/feature-gates/feature-gate-simd.stderr +++ b/tests/ui/feature-gates/feature-gate-simd.stderr @@ -1,5 +1,5 @@ error[E0658]: SIMD types are experimental and possibly buggy - --> $DIR/feature-gate-simd.rs:3:1 + --> $DIR/feature-gate-simd.rs:1:1 | LL | #[repr(simd)] | ^^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.rs b/tests/ui/feature-gates/feature-gate-unsafe_fields.rs new file mode 100644 index 0000000000000..8f9b411df4691 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.rs @@ -0,0 +1,25 @@ +//@ compile-flags: --crate-type=lib +//@ revisions: with_gate without_gate +//@ [with_gate] check-pass + +#![cfg_attr(with_gate, feature(unsafe_fields))] //[with_gate]~ WARNING + +#[cfg(any())] +struct Foo { + unsafe field: (), //[without_gate]~ ERROR +} + +// This should not parse as an unsafe field definition. +struct FooTuple(unsafe fn()); + +#[cfg(any())] +enum Bar { + Variant { unsafe field: () }, //[without_gate]~ ERROR + // This should not parse as an unsafe field definition. + VariantTuple(unsafe fn()), +} + +#[cfg(any())] +union Baz { + unsafe field: (), //[without_gate]~ ERROR +} diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr b/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr new file mode 100644 index 0000000000000..a7deeb057d86a --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr @@ -0,0 +1,11 @@ +warning: the feature `unsafe_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/feature-gate-unsafe_fields.rs:5:32 + | +LL | #![cfg_attr(with_gate, feature(unsafe_fields))] + | ^^^^^^^^^^^^^ + | + = note: see issue #132922 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.without_gate.stderr b/tests/ui/feature-gates/feature-gate-unsafe_fields.without_gate.stderr new file mode 100644 index 0000000000000..ad0f5fd59ac3d --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.without_gate.stderr @@ -0,0 +1,33 @@ +error[E0658]: `unsafe` fields are experimental + --> $DIR/feature-gate-unsafe_fields.rs:9:5 + | +LL | unsafe field: (), + | ^^^^^^ + | + = note: see issue #132922 for more information + = help: add `#![feature(unsafe_fields)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `unsafe` fields are experimental + --> $DIR/feature-gate-unsafe_fields.rs:17:15 + | +LL | Variant { unsafe field: () }, + | ^^^^^^ + | + = note: see issue #132922 for more information + = help: add `#![feature(unsafe_fields)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `unsafe` fields are experimental + --> $DIR/feature-gate-unsafe_fields.rs:24:5 + | +LL | unsafe field: (), + | ^^^^^^ + | + = note: see issue #132922 for more information + = help: add `#![feature(unsafe_fields)]` 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 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/filter-block-view-items.rs b/tests/ui/filter-block-view-items.rs index f582c51a3a64f..975ab19ddf25f 100644 --- a/tests/ui/filter-block-view-items.rs +++ b/tests/ui/filter-block-view-items.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { // Make sure that this view item is filtered out because otherwise it would diff --git a/tests/ui/fmt/auxiliary/format-string-proc-macro.rs b/tests/ui/fmt/auxiliary/format-string-proc-macro.rs index 5c00c9c0800c1..f473fee0987c3 100644 --- a/tests/ui/fmt/auxiliary/format-string-proc-macro.rs +++ b/tests/ui/fmt/auxiliary/format-string-proc-macro.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; diff --git a/tests/ui/fmt/format-args-capture-first-literal-is-macro.rs b/tests/ui/fmt/format-args-capture-first-literal-is-macro.rs index 3a0b7ba466625..8ba6fcc46d41f 100644 --- a/tests/ui/fmt/format-args-capture-first-literal-is-macro.rs +++ b/tests/ui/fmt/format-args-capture-first-literal-is-macro.rs @@ -1,4 +1,4 @@ -//@ aux-build:format-string-proc-macro.rs +//@ proc-macro: format-string-proc-macro.rs #[macro_use] extern crate format_string_proc_macro; diff --git a/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.rs b/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.rs index 24531e4ece457..26d483e43ae50 100644 --- a/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.rs +++ b/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.rs @@ -1,4 +1,4 @@ -//@ aux-build:format-string-proc-macro.rs +//@ proc-macro: format-string-proc-macro.rs extern crate format_string_proc_macro; diff --git a/tests/ui/fmt/format-args-capture-issue-106408.rs b/tests/ui/fmt/format-args-capture-issue-106408.rs index 7c29e37441cba..10f944dd9ba67 100644 --- a/tests/ui/fmt/format-args-capture-issue-106408.rs +++ b/tests/ui/fmt/format-args-capture-issue-106408.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:format-string-proc-macro.rs +//@ proc-macro: format-string-proc-macro.rs extern crate format_string_proc_macro; diff --git a/tests/ui/fmt/format-args-capture-macro-hygiene.rs b/tests/ui/fmt/format-args-capture-macro-hygiene.rs index 2ef81f2cd42f0..21e445624a5f9 100644 --- a/tests/ui/fmt/format-args-capture-macro-hygiene.rs +++ b/tests/ui/fmt/format-args-capture-macro-hygiene.rs @@ -1,4 +1,4 @@ -//@ aux-build:format-string-proc-macro.rs +//@ proc-macro: format-string-proc-macro.rs #[macro_use] extern crate format_string_proc_macro; diff --git a/tests/ui/fmt/format-expanded-string.rs b/tests/ui/fmt/format-expanded-string.rs index d9b96bdece382..1466dabd7f707 100644 --- a/tests/ui/fmt/format-expanded-string.rs +++ b/tests/ui/fmt/format-expanded-string.rs @@ -1,4 +1,4 @@ -//@ aux-build:format-string-proc-macro.rs +//@ proc-macro: format-string-proc-macro.rs #[macro_use] extern crate format_string_proc_macro; diff --git a/tests/ui/fmt/indoc-issue-106408.rs b/tests/ui/fmt/indoc-issue-106408.rs index 36e5c23a3945f..8c302e5b03aa1 100644 --- a/tests/ui/fmt/indoc-issue-106408.rs +++ b/tests/ui/fmt/indoc-issue-106408.rs @@ -1,4 +1,4 @@ -//@ aux-build:format-string-proc-macro.rs +//@ proc-macro: format-string-proc-macro.rs //@ check-pass extern crate format_string_proc_macro; diff --git a/tests/ui/fmt/respanned-literal-issue-106191.rs b/tests/ui/fmt/respanned-literal-issue-106191.rs index 0a127b1a0ca2a..39f09b6e63a77 100644 --- a/tests/ui/fmt/respanned-literal-issue-106191.rs +++ b/tests/ui/fmt/respanned-literal-issue-106191.rs @@ -1,4 +1,4 @@ -//@ aux-build:format-string-proc-macro.rs +//@ proc-macro: format-string-proc-macro.rs extern crate format_string_proc_macro; diff --git a/tests/ui/fn/fn-item-type.stderr b/tests/ui/fn/fn-item-type.stderr index 76cdbcceac841..5cc529543d2ef 100644 --- a/tests/ui/fn/fn-item-type.stderr +++ b/tests/ui/fn/fn-item-type.stderr @@ -17,7 +17,7 @@ LL | fn eq(x: T, y: T) {} | ^^ - ---- ---- this parameter needs to match the fn item type of `x` | | | | | `y` needs to match the fn item type of this parameter - | `x` and `y` all reference this parameter T + | `x` and `y` both reference this parameter `T` = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize` error[E0308]: mismatched types @@ -39,7 +39,7 @@ LL | fn eq(x: T, y: T) {} | ^^ - ---- ---- this parameter needs to match the fn item type of `x` | | | | | `y` needs to match the fn item type of this parameter - | `x` and `y` all reference this parameter T + | `x` and `y` both reference this parameter `T` = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize` error[E0308]: mismatched types @@ -61,7 +61,7 @@ LL | fn eq(x: T, y: T) {} | ^^ - ---- ---- this parameter needs to match the fn item type of `x` | | | | | `y` needs to match the fn item type of this parameter - | `x` and `y` all reference this parameter T + | `x` and `y` both reference this parameter `T` = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize` error[E0308]: mismatched types @@ -83,7 +83,7 @@ LL | fn eq(x: T, y: T) {} | ^^ - ---- ---- this parameter needs to match the fn item type of `x` | | | | | `y` needs to match the fn item type of this parameter - | `x` and `y` all reference this parameter T + | `x` and `y` both reference this parameter `T` = help: consider casting both fn items to fn pointers using `as fn()` error[E0308]: mismatched types @@ -105,7 +105,7 @@ LL | fn eq(x: T, y: T) {} | ^^ - ---- ---- this parameter needs to match the fn item type of `x` | | | | | `y` needs to match the fn item type of this parameter - | `x` and `y` all reference this parameter T + | `x` and `y` both reference this parameter `T` error: aborting due to 5 previous errors diff --git a/tests/ui/fn/issue-1451.rs b/tests/ui/fn/issue-1451.rs index 735b766bd0cf2..40b107ca7cc56 100644 --- a/tests/ui/fn/issue-1451.rs +++ b/tests/ui/fn/issue-1451.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #![allow(non_snake_case)] #![allow(unused_variables)] diff --git a/tests/ui/fn/param-mismatch-no-names.rs b/tests/ui/fn/param-mismatch-no-names.rs new file mode 100644 index 0000000000000..05f3de190ea92 --- /dev/null +++ b/tests/ui/fn/param-mismatch-no-names.rs @@ -0,0 +1,8 @@ +fn same_type(_: T, _: T) {} + +fn f(x: X, y: Y) { + same_type([x], Some(y)); + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/fn/param-mismatch-no-names.stderr b/tests/ui/fn/param-mismatch-no-names.stderr new file mode 100644 index 0000000000000..d9d360d5ae4f5 --- /dev/null +++ b/tests/ui/fn/param-mismatch-no-names.stderr @@ -0,0 +1,23 @@ +error[E0308]: mismatched types + --> $DIR/param-mismatch-no-names.rs:4:20 + | +LL | same_type([x], Some(y)); + | --------- --- ^^^^^^^ expected `[X; 1]`, found `Option` + | | | + | | expected all arguments to be this `[X; 1]` type because they need to match the type of this parameter + | arguments to this function are incorrect + | + = note: expected array `[X; 1]` + found enum `Option` +note: function defined here + --> $DIR/param-mismatch-no-names.rs:1:4 + | +LL | fn same_type(_: T, _: T) {} + | ^^^^^^^^^ - ---- ---- this parameter needs to match the `[X; 1]` type of parameter #1 + | | | + | | parameter #2 needs to match the `[X; 1]` type of this parameter + | parameter #1 and parameter #2 both reference this parameter `T` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/for-loop-while/break-value.rs b/tests/ui/for-loop-while/break-value.rs index 1289231fc30ff..eb9ccb21203ba 100644 --- a/tests/ui/for-loop-while/break-value.rs +++ b/tests/ui/for-loop-while/break-value.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unreachable_code)] -//@ pretty-expanded FIXME #23616 fn int_id(x: isize) -> isize { return x; } diff --git a/tests/ui/for-loop-while/issue-1257.rs b/tests/ui/for-loop-while/issue-1257.rs index cdd4c806358dc..369302f9f12e7 100644 --- a/tests/ui/for-loop-while/issue-1257.rs +++ b/tests/ui/for-loop-while/issue-1257.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main () { let mut line = "".to_string(); diff --git a/tests/ui/for-loop-while/labeled-break.rs b/tests/ui/for-loop-while/labeled-break.rs index 0dfbdc02f5b5b..9c53350f22765 100644 --- a/tests/ui/for-loop-while/labeled-break.rs +++ b/tests/ui/for-loop-while/labeled-break.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { 'foo: loop { diff --git a/tests/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs b/tests/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs index be6dc33c8bea7..31f2ecf2affa9 100644 --- a/tests/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs +++ b/tests/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(unused_assignments)] -//@ pretty-expanded FIXME #23616 #![allow(unreachable_code)] #![allow(unused_variables)] diff --git a/tests/ui/for-loop-while/liveness-move-in-loop.rs b/tests/ui/for-loop-while/liveness-move-in-loop.rs index 0ae92a78a04dd..0c35479cf12b1 100644 --- a/tests/ui/for-loop-while/liveness-move-in-loop.rs +++ b/tests/ui/for-loop-while/liveness-move-in-loop.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn take(x: isize) -> isize {x} diff --git a/tests/ui/for-loop-while/long-while.rs b/tests/ui/for-loop-while/long-while.rs index 6db06baa8738b..5b9fbb104533a 100644 --- a/tests/ui/for-loop-while/long-while.rs +++ b/tests/ui/for-loop-while/long-while.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(unused_variables)] diff --git a/tests/ui/for-loop-while/loop-diverges.rs b/tests/ui/for-loop-while/loop-diverges.rs index fdf46387795ff..77d15e3c32192 100644 --- a/tests/ui/for-loop-while/loop-diverges.rs +++ b/tests/ui/for-loop-while/loop-diverges.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_parens)] -//@ pretty-expanded FIXME #23616 /* Make sure a loop{} can be the tailexpr in the body of a diverging function */ diff --git a/tests/ui/for-loop-while/loop-label-shadowing.rs b/tests/ui/for-loop-while/loop-label-shadowing.rs index e3dfbe65d8cf0..030da69cbb79c 100644 --- a/tests/ui/for-loop-while/loop-label-shadowing.rs +++ b/tests/ui/for-loop-while/loop-label-shadowing.rs @@ -1,7 +1,6 @@ //@ run-pass // Issue #12512. -//@ pretty-expanded FIXME #23616 fn main() { let mut foo = Vec::new(); diff --git a/tests/ui/for-loop-while/loop-labeled-break-value.rs b/tests/ui/for-loop-while/loop-labeled-break-value.rs index 0ab07ffd7e22a..702bda1b90a2b 100644 --- a/tests/ui/for-loop-while/loop-labeled-break-value.rs +++ b/tests/ui/for-loop-while/loop-labeled-break-value.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn main() { 'outer: loop { diff --git a/tests/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs b/tests/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs index 531c3dc377d75..cf4474d815bf7 100644 --- a/tests/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs +++ b/tests/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 struct S; // Ensure S is moved, not copied, on assignment. diff --git a/tests/ui/for-loop-while/while-flow-graph.rs b/tests/ui/for-loop-while/while-flow-graph.rs index 9148b42a6061a..e964d0195885c 100644 --- a/tests/ui/for-loop-while/while-flow-graph.rs +++ b/tests/ui/for-loop-while/while-flow-graph.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { let x: isize = 10; while x == 10 && x == 11 { let _y = 0xf00_usize; } } diff --git a/tests/ui/foreign/foreign-mod-unused-const.rs b/tests/ui/foreign/foreign-mod-unused-const.rs index 2cc0a4f601838..4e40f92fdd415 100644 --- a/tests/ui/foreign/foreign-mod-unused-const.rs +++ b/tests/ui/foreign/foreign-mod-unused-const.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 mod foo { extern "C" { diff --git a/tests/ui/foreign/foreign2.rs b/tests/ui/foreign/foreign2.rs index 178a04255ccee..a2f8385c8454a 100644 --- a/tests/ui/foreign/foreign2.rs +++ b/tests/ui/foreign/foreign2.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] #![feature(rustc_private)] diff --git a/tests/ui/foreign/nil-decl-in-foreign.rs b/tests/ui/foreign/nil-decl-in-foreign.rs index 355278d99da5d..6adf08246e74a 100644 --- a/tests/ui/foreign/nil-decl-in-foreign.rs +++ b/tests/ui/foreign/nil-decl-in-foreign.rs @@ -3,7 +3,6 @@ #![allow(improper_ctypes)] #![allow(dead_code)] // Issue #901 -//@ pretty-expanded FIXME #23616 mod libc { extern "C" { diff --git a/tests/ui/fuel/optimization-fuel-0.rs b/tests/ui/fuel/optimization-fuel-0.rs deleted file mode 100644 index cbcb1d329a3c9..0000000000000 --- a/tests/ui/fuel/optimization-fuel-0.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ run-pass - -#![crate_name="foo"] - -use std::mem::size_of; - -//@ compile-flags: -Z fuel=foo=0 - -#[allow(dead_code)] -struct S1(u8, u16, u8); -#[allow(dead_code)] -struct S2(u8, u16, u8); - -fn main() { - assert_eq!(size_of::(), 6); - assert_eq!(size_of::(), 6); -} diff --git a/tests/ui/fuel/optimization-fuel-0.stderr b/tests/ui/fuel/optimization-fuel-0.stderr deleted file mode 100644 index f0e2ebfc37a37..0000000000000 --- a/tests/ui/fuel/optimization-fuel-0.stderr +++ /dev/null @@ -1,4 +0,0 @@ -warning: optimization-fuel-exhausted: Reorder fields of "S1" - -warning: 1 warning emitted - diff --git a/tests/ui/fuel/optimization-fuel-1.rs b/tests/ui/fuel/optimization-fuel-1.rs deleted file mode 100644 index 97edb0bd25959..0000000000000 --- a/tests/ui/fuel/optimization-fuel-1.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ run-pass - -#![crate_name="foo"] - -use std::mem::size_of; - -//@ compile-flags: -Z fuel=foo=1 - -#[allow(dead_code)] -struct S1(u8, u16, u8); -#[allow(dead_code)] -struct S2(u8, u16, u8); - -fn main() { - let optimized = (size_of::() == 4) as usize - +(size_of::() == 4) as usize; - assert_eq!(optimized, 1); -} diff --git a/tests/ui/fuel/optimization-fuel-1.stderr b/tests/ui/fuel/optimization-fuel-1.stderr deleted file mode 100644 index 53eafb05830cb..0000000000000 --- a/tests/ui/fuel/optimization-fuel-1.stderr +++ /dev/null @@ -1,4 +0,0 @@ -warning: optimization-fuel-exhausted: Reorder fields of "S2" - -warning: 1 warning emitted - diff --git a/tests/ui/fuel/print-fuel.rs b/tests/ui/fuel/print-fuel.rs deleted file mode 100644 index fd7e568bea7a0..0000000000000 --- a/tests/ui/fuel/print-fuel.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![crate_name="foo"] -#![allow(dead_code)] - -// (#55495: The --error-format is to sidestep an issue in our test harness) -//@ compile-flags: -C opt-level=0 --error-format human -Z print-fuel=foo -//@ check-pass - -struct S1(u8, u16, u8); -struct S2(u8, u16, u8); -struct S3(u8, u16, u8); - -fn main() { -} diff --git a/tests/ui/fuel/print-fuel.stderr b/tests/ui/fuel/print-fuel.stderr deleted file mode 100644 index cc88cc077bb21..0000000000000 --- a/tests/ui/fuel/print-fuel.stderr +++ /dev/null @@ -1 +0,0 @@ -Fuel used by foo: 3 diff --git a/tests/ui/functions-closures/closure-bounds-can-capture-chan.rs b/tests/ui/functions-closures/closure-bounds-can-capture-chan.rs index 4f38ea02d9cc3..318ca54ffd63f 100644 --- a/tests/ui/functions-closures/closure-bounds-can-capture-chan.rs +++ b/tests/ui/functions-closures/closure-bounds-can-capture-chan.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use std::sync::mpsc::channel; diff --git a/tests/ui/functions-closures/fn-abi.rs b/tests/ui/functions-closures/fn-abi.rs index d33158e89175c..350132f0f552d 100644 --- a/tests/ui/functions-closures/fn-abi.rs +++ b/tests/ui/functions-closures/fn-abi.rs @@ -2,7 +2,6 @@ // Ensure that declarations and types which use `extern fn` both have the same // ABI (#9309). -//@ pretty-expanded FIXME #23616 //@ aux-build:fn-abi.rs extern crate fn_abi; diff --git a/tests/ui/functions-closures/fn-bare-coerce-to-block.rs b/tests/ui/functions-closures/fn-bare-coerce-to-block.rs index 18015a41564e2..9c80463d59ed4 100644 --- a/tests/ui/functions-closures/fn-bare-coerce-to-block.rs +++ b/tests/ui/functions-closures/fn-bare-coerce-to-block.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn bare() {} diff --git a/tests/ui/functions-closures/fn-coerce-field.rs b/tests/ui/functions-closures/fn-coerce-field.rs index dd7be374c8428..7a9e1e5e82c39 100644 --- a/tests/ui/functions-closures/fn-coerce-field.rs +++ b/tests/ui/functions-closures/fn-coerce-field.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #![allow(non_camel_case_types)] struct r where F: FnOnce() { diff --git a/tests/ui/functions-closures/fn-item-type-coerce.rs b/tests/ui/functions-closures/fn-item-type-coerce.rs index e858f9e9e196f..a5a0a4995bf47 100644 --- a/tests/ui/functions-closures/fn-item-type-coerce.rs +++ b/tests/ui/functions-closures/fn-item-type-coerce.rs @@ -2,7 +2,6 @@ #![allow(unused_variables)] // Test implicit coercions from a fn item type to a fn pointer type. -//@ pretty-expanded FIXME #23616 fn foo(x: isize) -> isize { x * 2 } fn bar(x: isize) -> isize { x * 4 } diff --git a/tests/ui/functions-closures/fn-lval.rs b/tests/ui/functions-closures/fn-lval.rs index aa080f6b985f3..7b5e4d6651763 100644 --- a/tests/ui/functions-closures/fn-lval.rs +++ b/tests/ui/functions-closures/fn-lval.rs @@ -2,7 +2,6 @@ -//@ pretty-expanded FIXME #23616 fn foo(_f: fn(isize) -> isize) { } diff --git a/tests/ui/functions-closures/fn-type-infer.rs b/tests/ui/functions-closures/fn-type-infer.rs index b1624e476ef16..eb9e5b1046794 100644 --- a/tests/ui/functions-closures/fn-type-infer.rs +++ b/tests/ui/functions-closures/fn-type-infer.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(unused_variables)] diff --git a/tests/ui/generic-associated-types/issue-71176.rs b/tests/ui/generic-associated-types/issue-71176.rs index b33fda8e15443..7fffe312f4b7b 100644 --- a/tests/ui/generic-associated-types/issue-71176.rs +++ b/tests/ui/generic-associated-types/issue-71176.rs @@ -16,6 +16,8 @@ struct Holder { fn main() { Holder { - inner: Box::new(()), //~ ERROR: the trait `Provider` cannot be made into an object + inner: Box::new(()), + //~^ ERROR: the trait `Provider` cannot be made into an object + //~| ERROR: the trait `Provider` cannot be made into an object }; } diff --git a/tests/ui/generic-associated-types/issue-71176.stderr b/tests/ui/generic-associated-types/issue-71176.stderr index 15d5a3df6f276..1cd2ed0d313dc 100644 --- a/tests/ui/generic-associated-types/issue-71176.stderr +++ b/tests/ui/generic-associated-types/issue-71176.stderr @@ -80,7 +80,24 @@ LL | type A<'a>; = help: consider moving `A` to another trait = help: only type `()` implements the trait, consider using it directly instead -error: aborting due to 5 previous errors +error[E0038]: the trait `Provider` cannot be made into an object + --> $DIR/issue-71176.rs:19:16 + | +LL | inner: Box::new(()), + | ^^^^^^^^^^^^ `Provider` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-71176.rs:2:10 + | +LL | trait Provider { + | -------- this trait cannot be made into an object... +LL | type A<'a>; + | ^ ...because it contains the generic associated type `A` + = help: consider moving `A` to another trait + = help: only type `()` implements the trait, consider using it directly instead + = note: required for the cast from `Box<()>` to `Box<(dyn Provider = _> + 'static), {type error}>` + +error: aborting due to 6 previous errors Some errors have detailed explanations: E0038, E0107. For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/parse/in-trait-impl.rs b/tests/ui/generic-associated-types/parse/in-trait-impl.rs index 5ba42be358312..ef67fb18228fb 100644 --- a/tests/ui/generic-associated-types/parse/in-trait-impl.rs +++ b/tests/ui/generic-associated-types/parse/in-trait-impl.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Z parse-only +//@ compile-flags: -Z parse-crate-root-only impl Baz for T where T: Foo { type Quux<'a> = ::Bar<'a, 'static>; diff --git a/tests/ui/generic-associated-types/parse/in-trait.rs b/tests/ui/generic-associated-types/parse/in-trait.rs index 913eceec0dacf..2add908d727db 100644 --- a/tests/ui/generic-associated-types/parse/in-trait.rs +++ b/tests/ui/generic-associated-types/parse/in-trait.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Z parse-only +//@ compile-flags: -Z parse-crate-root-only use std::ops::Deref; use std::fmt::Debug; diff --git a/tests/ui/generics/generic-default-type-params-cross-crate.rs b/tests/ui/generics/generic-default-type-params-cross-crate.rs index 7da61572501ac..1b21e4cd191ad 100644 --- a/tests/ui/generics/generic-default-type-params-cross-crate.rs +++ b/tests/ui/generics/generic-default-type-params-cross-crate.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:default_type_params_xc.rs -//@ pretty-expanded FIXME #23616 extern crate default_type_params_xc; diff --git a/tests/ui/generics/generic-fn-twice.rs b/tests/ui/generics/generic-fn-twice.rs index f9e08401c6d4c..26d6f750c80f8 100644 --- a/tests/ui/generics/generic-fn-twice.rs +++ b/tests/ui/generics/generic-fn-twice.rs @@ -2,7 +2,6 @@ -//@ pretty-expanded FIXME #23616 mod foomod { pub fn foo() { } diff --git a/tests/ui/generics/generic-newtype-struct.rs b/tests/ui/generics/generic-newtype-struct.rs index a1d539c8c22e2..4cb481044f203 100644 --- a/tests/ui/generics/generic-newtype-struct.rs +++ b/tests/ui/generics/generic-newtype-struct.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 struct S(#[allow(dead_code)] T); diff --git a/tests/ui/generics/generic-tag-corruption.rs b/tests/ui/generics/generic-tag-corruption.rs index 78fdfe4ac7f2c..b7fd66a052394 100644 --- a/tests/ui/generics/generic-tag-corruption.rs +++ b/tests/ui/generics/generic-tag-corruption.rs @@ -3,7 +3,6 @@ // This used to cause memory corruption in stage 0. -//@ pretty-expanded FIXME #23616 enum thing { some(#[allow(dead_code)] K), } diff --git a/tests/ui/generics/generic-tag-local.rs b/tests/ui/generics/generic-tag-local.rs index e7c394efa0922..025827783c3e4 100644 --- a/tests/ui/generics/generic-tag-local.rs +++ b/tests/ui/generics/generic-tag-local.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 enum clam { a(#[allow(dead_code)] T), } diff --git a/tests/ui/generics/generic-tag.rs b/tests/ui/generics/generic-tag.rs index cb46c3155a305..98350e93ecebd 100644 --- a/tests/ui/generics/generic-tag.rs +++ b/tests/ui/generics/generic-tag.rs @@ -2,7 +2,6 @@ #![allow(unused_assignments)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 #![allow(unused_variables)] diff --git a/tests/ui/generics/generic-type-synonym.rs b/tests/ui/generics/generic-type-synonym.rs index 879bd91cab50e..a8a946d5ed2ad 100644 --- a/tests/ui/generics/generic-type-synonym.rs +++ b/tests/ui/generics/generic-type-synonym.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct Foo { a: T diff --git a/tests/ui/generics/mid-path-type-params.rs b/tests/ui/generics/mid-path-type-params.rs index f7dbd7890793c..5100e8e73531e 100644 --- a/tests/ui/generics/mid-path-type-params.rs +++ b/tests/ui/generics/mid-path-type-params.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct S { contents: T, diff --git a/tests/ui/generics/type-params-in-for-each.rs b/tests/ui/generics/type-params-in-for-each.rs index e98f7bbb66bc7..004b775488768 100644 --- a/tests/ui/generics/type-params-in-for-each.rs +++ b/tests/ui/generics/type-params-in-for-each.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct S { a: T, diff --git a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr index af11bc82d0c2e..65903dbe12e57 100644 --- a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr +++ b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr @@ -15,7 +15,7 @@ LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `[i32::MIN..=2_i32, ..]` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `[i32; 8]` help: you might want to use `let else` to handle the variant that isn't matched | diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr index 0f60cd397b997..aa3d2cd2d904f 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr @@ -67,7 +67,7 @@ LL | mac!(0); | ------- in this macro invocation | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr index 204ee373bc538..63258f3538313 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr @@ -94,7 +94,7 @@ LL | mac!(0); | ------- in this macro invocation | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -108,7 +108,7 @@ LL | mac!(0); | ------- in this macro invocation | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr index e2916725fbd90..62be2ef7a4d83 100644 --- a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr +++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr @@ -4,7 +4,7 @@ error: expected a pattern range bound, found an expression LL | 0..5+1 => errors_only.push(x), | ^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 5+1; diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr index f54e07c3a6370..dbe7f4482eed4 100644 --- a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr +++ b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr @@ -16,7 +16,7 @@ error: expected a pattern range bound, found an expression LL | 0..=(5+1) => errors_only.push(x), | ^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 5+1; diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr index 4951591990462..17b65c1dae548 100644 --- a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr +++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr @@ -15,7 +15,7 @@ LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `[i32::MIN..=2_i32, ..]` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `[i32; 8]` help: you might want to use `let else` to handle the variant that isn't matched | diff --git a/tests/ui/hello.rs b/tests/ui/hello.rs index d23cbb6115715..f329ee086f90c 100644 --- a/tests/ui/hello.rs +++ b/tests/ui/hello.rs @@ -5,8 +5,6 @@ //@[e2021] edition:2021 //@[e2024] edition:2024 -//@[e2024] compile-flags: -Zunstable-options - fn main() { println!("hello"); } diff --git a/tests/ui/higher-ranked/builtin-closure-like-bounds.rs b/tests/ui/higher-ranked/builtin-closure-like-bounds.rs index dee290cc4396a..c177ee6fb3a66 100644 --- a/tests/ui/higher-ranked/builtin-closure-like-bounds.rs +++ b/tests/ui/higher-ranked/builtin-closure-like-bounds.rs @@ -1,5 +1,4 @@ //@ edition:2024 -//@ compile-flags: -Zunstable-options //@ revisions: current next //@[next] compile-flags: -Znext-solver //@ check-pass diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs index 5dec55d561228..09f3f7845d950 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs @@ -6,7 +6,6 @@ // `&Typer<'tcx>` was getting an incorrect binder level, yielding // weird compilation ICEs and so forth. -//@ pretty-expanded FIXME #23616 trait Typer<'tcx> { fn method(&self, data: &'tcx isize) -> &'tcx isize { data } diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs index f28b0776fdaf7..745a2fcc4f030 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 trait Typer<'tcx> { fn method(&self, data: &'tcx isize) -> &'tcx isize { data } diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs index 0edddf9423e49..7ecba7301ef0b 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs @@ -2,7 +2,6 @@ // Test that we can parse all the various places that a `for` keyword // can appear representing universal quantification. -//@ pretty-expanded FIXME #23616 #![allow(unused_variables)] #![allow(dead_code)] diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs index b49c69d90cf57..8c63dff87825e 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 // Test that `F : Fn(isize) -> isize + Send` is interpreted as two // distinct bounds on `F`. diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs index d50fd8cb8f338..2c8d3ac0d41ca 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 // Test that `Fn(isize) -> isize + 'static` parses as `(Fn(isize) -> isize) + // 'static` and not `Fn(isize) -> (isize + 'static)`. The latter would diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs index 4a0b8362d4b04..271eedae89a16 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] // A basic test of using a higher-ranked trait bound. -//@ pretty-expanded FIXME #23616 trait FnLike { fn call(&self, arg: A) -> R; diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs index 255e5d68e50fc..7a75218da3aa9 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs @@ -4,7 +4,6 @@ // PrinterSupport<'b>`, gets properly expanded when it appears in a // closure type. This used to result in messed up De Bruijn indices. -//@ pretty-expanded FIXME #23616 trait PrinterSupport<'ast> { fn ast_map(&self) -> Option<&'ast usize> { None } diff --git a/tests/ui/hygiene/auxiliary/def-site-async-await.rs b/tests/ui/hygiene/auxiliary/def-site-async-await.rs index 41c4b871e7369..88042b484a1fc 100644 --- a/tests/ui/hygiene/auxiliary/def-site-async-await.rs +++ b/tests/ui/hygiene/auxiliary/def-site-async-await.rs @@ -1,6 +1,5 @@ //@ edition:2018 - -extern crate opaque_hygiene; +//@ proc-macro: opaque-hygiene.rs pub async fn serve() { opaque_hygiene::make_it!(); diff --git a/tests/ui/hygiene/auxiliary/opaque-hygiene.rs b/tests/ui/hygiene/auxiliary/opaque-hygiene.rs index b6192d653f56f..08dc592925aa5 100644 --- a/tests/ui/hygiene/auxiliary/opaque-hygiene.rs +++ b/tests/ui/hygiene/auxiliary/opaque-hygiene.rs @@ -1,8 +1,4 @@ -//@ force-host -//@ no-prefer-dynamic - #![feature(proc_macro_quote)] -#![crate_type = "proc-macro"] extern crate proc_macro; use proc_macro::{TokenStream, quote}; diff --git a/tests/ui/hygiene/issue-15221.rs b/tests/ui/hygiene/issue-15221.rs index ebb1a234051aa..7703cb2de4e81 100644 --- a/tests/ui/hygiene/issue-15221.rs +++ b/tests/ui/hygiene/issue-15221.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(path_statements)] -//@ pretty-expanded FIXME #23616 macro_rules! inner { ($e:pat ) => ($e) diff --git a/tests/ui/hygiene/issue-77523-def-site-async-await.rs b/tests/ui/hygiene/issue-77523-def-site-async-await.rs index 102112381d392..ad6bd5e0b78bc 100644 --- a/tests/ui/hygiene/issue-77523-def-site-async-await.rs +++ b/tests/ui/hygiene/issue-77523-def-site-async-await.rs @@ -1,5 +1,4 @@ //@ build-pass -//@ aux-build:opaque-hygiene.rs //@ aux-build:def-site-async-await.rs // Regression test for issue #77523 diff --git a/tests/ui/impl-privacy-xc-1.rs b/tests/ui/impl-privacy-xc-1.rs index 1a2af8098f59e..6a10986739cd2 100644 --- a/tests/ui/impl-privacy-xc-1.rs +++ b/tests/ui/impl-privacy-xc-1.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:impl_privacy_xc_1.rs -//@ pretty-expanded FIXME #23616 extern crate impl_privacy_xc_1; diff --git a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index 8716088ccbd26..9ed3d21c13ce6 100644 --- a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -261,8 +261,11 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bat() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | - = help: if there were a single returned type, you could use `impl Trait` instead -help: box the return type, and wrap all of the returned values in `Box::new` +help: consider returning an `impl Trait` instead of a `dyn Trait` + | +LL | fn bat() -> impl Trait { + | ~~~~ +help: alternatively, box the return type, and wrap all of the returned values in `Box::new` | LL ~ fn bat() -> Box { LL | if true { @@ -277,8 +280,11 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bay() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | - = help: if there were a single returned type, you could use `impl Trait` instead -help: box the return type, and wrap all of the returned values in `Box::new` +help: consider returning an `impl Trait` instead of a `dyn Trait` + | +LL | fn bay() -> impl Trait { + | ~~~~ +help: alternatively, box the return type, and wrap all of the returned values in `Box::new` | LL ~ fn bay() -> Box { LL | if true { diff --git a/tests/ui/impl-trait/impl-trait-plus-priority.rs b/tests/ui/impl-trait/impl-trait-plus-priority.rs index 5441a015ac0ac..5575493a17d36 100644 --- a/tests/ui/impl-trait/impl-trait-plus-priority.rs +++ b/tests/ui/impl-trait/impl-trait-plus-priority.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Z parse-only +//@ compile-flags: -Z parse-crate-root-only fn f() -> impl A + {} // OK fn f() -> impl A + B {} // OK diff --git a/tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.rs b/tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.rs new file mode 100644 index 0000000000000..30ca3d271b815 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.rs @@ -0,0 +1,30 @@ +// Make sure that we don't accidentally collect an RPITIT hidden type that does not +// hold for all instantiations of the trait signature. + +trait MkStatic { + fn mk_static(self) -> &'static str; +} + +impl MkStatic for &'static str { + fn mk_static(self) -> &'static str { self } +} + +trait Foo { + fn foo<'a: 'static, 'late>(&'late self) -> impl MkStatic; +} + +impl Foo for str { + fn foo<'a: 'static>(&'a self) -> impl MkStatic + 'static { + //~^ ERROR method not compatible with trait + self + } +} + +fn call_foo(t: &T) -> &'static str { + t.foo().mk_static() +} + +fn main() { + let s = call_foo(String::from("hello, world").as_str()); + println!("> {s}"); +} diff --git a/tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.stderr b/tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.stderr new file mode 100644 index 0000000000000..95d8699e19ff1 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/do-not-imply-from-trait-impl.stderr @@ -0,0 +1,22 @@ +error[E0308]: method not compatible with trait + --> $DIR/do-not-imply-from-trait-impl.rs:17:38 + | +LL | fn foo<'a: 'static>(&'a self) -> impl MkStatic + 'static { + | ^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch + | + = note: expected signature `fn(&'late _) -> _` + found signature `fn(&'a _) -> _` +note: the lifetime `'late` as defined here... + --> $DIR/do-not-imply-from-trait-impl.rs:13:25 + | +LL | fn foo<'a: 'static, 'late>(&'late self) -> impl MkStatic; + | ^^^^^ +note: ...does not necessarily outlive the lifetime `'a` as defined here + --> $DIR/do-not-imply-from-trait-impl.rs:17:12 + | +LL | fn foo<'a: 'static>(&'a self) -> impl MkStatic + 'static { + | ^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs b/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs index 83466535e13c6..42b33c6e31d3c 100644 --- a/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs +++ b/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs @@ -1,5 +1,5 @@ // Test for issue #132429 -//@compile-flags: -Zunstable-options --edition=2024 +//@ edition: 2024 //@check-pass use std::future::Future; diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr index 6f6b787b6fe1b..a23879eb6c376 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr @@ -11,12 +11,12 @@ note: type in trait | LL | fn early<'early, T>(x: &'early T) -> impl Sized; | ^^^^^^^^^ - = note: expected signature `fn(&T)` - found signature `fn(&'late ())` + = note: expected signature `fn(&'early T)` + found signature `fn(&())` help: change the parameter type to match the trait | -LL | fn early<'late, T>(_: &T) {} - | ~~ +LL | fn early<'late, T>(_: &'early T) {} + | ~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr index 3430055dab171..4c10422f985f1 100644 --- a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr +++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr @@ -6,9 +6,9 @@ LL | fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) { | = note: the pointer is valid for the static lifetime note: but the referenced data is only valid for the anonymous lifetime defined here - --> $DIR/rpitit-hidden-types-self-implied-wf.rs:6:18 + --> $DIR/rpitit-hidden-types-self-implied-wf.rs:2:18 | -LL | fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) { +LL | fn extend(_: &str) -> (impl Sized + '_, &'static str); | ^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr index 56b83cbca77ac..b27d7870955ed 100644 --- a/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr +++ b/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr @@ -1,14 +1,15 @@ -error[E0623]: lifetime mismatch +error[E0477]: the type `impl Future>` does not fulfill the required lifetime --> $DIR/signature-mismatch.rs:77:10 | -LL | &'a self, - | -------- this parameter and the return type are declared with different lifetimes... -... LL | ) -> impl Future> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | ...but data from `buff` is returned here + | +note: type must outlive the lifetime `'a` as defined here as required by this binding + --> $DIR/signature-mismatch.rs:73:32 + | +LL | fn async_fn_reduce_outlive<'a, 'b, T>( + | ^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0623`. +For more information about this error, try `rustc --explain E0477`. diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.rs b/tests/ui/impl-trait/in-trait/signature-mismatch.rs index 55b9a0de5ff02..a9885c6a2986b 100644 --- a/tests/ui/impl-trait/in-trait/signature-mismatch.rs +++ b/tests/ui/impl-trait/in-trait/signature-mismatch.rs @@ -75,7 +75,7 @@ impl AsyncTrait for Struct { buff: &'b [u8], t: T, ) -> impl Future> { - //[failure]~^ ERROR lifetime mismatch + //[failure]~^ ERROR the type `impl Future>` does not fulfill the required lifetime async move { let _t = t; vec![] diff --git a/tests/ui/impl-trait/issues/issue-79099.stderr b/tests/ui/impl-trait/issues/issue-79099.stderr index 6c26d5bd1b742..96825eabec7ed 100644 --- a/tests/ui/impl-trait/issues/issue-79099.stderr +++ b/tests/ui/impl-trait/issues/issue-79099.stderr @@ -6,7 +6,7 @@ LL | let f: impl core::future::Future = async { 1 }; | | | `async` blocks are only allowed in Rust 2018 or later | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0562]: `impl Trait` is not allowed in the type of variable bindings diff --git a/tests/ui/impl-trait/normalize-tait-in-const.rs b/tests/ui/impl-trait/normalize-tait-in-const.rs index 134b202d65582..1fd543b72e7cc 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.rs +++ b/tests/ui/impl-trait/normalize-tait-in-const.rs @@ -1,7 +1,7 @@ //@ known-bug: #103507 #![feature(type_alias_impl_trait)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_destruct)] use std::marker::Destruct; diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr index f9142664f1b82..bb874cbe41b33 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.stderr +++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr @@ -4,12 +4,6 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn with_positive ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { | ^^^^^^ -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/normalize-tait-in-const.rs:26:62 - | -LL | const fn with_positive ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { - | ^^^^^^ - error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/normalize-tait-in-const.rs:26:35 | @@ -18,13 +12,11 @@ LL | const fn with_positive ~const Fn(&'a Alias<'a>) + ~const Destruc | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/normalize-tait-in-const.rs:26:62 - | -LL | const fn with_positive ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { - | ^^^^^^ +error[E0277]: the trait bound `for<'a, 'b> fn(&'a foo::Alias<'b>) {foo}: const Destruct` is not satisfied + --> $DIR/normalize-tait-in-const.rs:33:5 | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +LL | with_positive(foo); + | ^^^^^^^^^^^^^^^^^^ error[E0015]: cannot call non-const closure in constant functions --> $DIR/normalize-tait-in-const.rs:27:5 @@ -38,16 +30,7 @@ help: consider further restricting this bound LL | const fn with_positive ~const Fn(&'a Alias<'a>) + ~const Destruct + ~const Fn(&foo::Alias<'_>)>(fun: F) { | ++++++++++++++++++++++++++++ -error[E0493]: destructor of `F` cannot be evaluated at compile-time - --> $DIR/normalize-tait-in-const.rs:26:79 - | -LL | const fn with_positive ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { - | ^^^ the destructor for this type cannot be evaluated in constant functions -LL | fun(filter_positive()); -LL | } - | - value is dropped here - -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0015, E0493. +Some errors have detailed explanations: E0015, E0277. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr index caaac5434c56a..6f0f287fe122e 100644 --- a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr +++ b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr @@ -74,7 +74,7 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/opaque-used-in-extraneous-argument.rs:20:5 | LL | open_parent(&old_path) - | ^^^^^^^^^^^ --------- unexpected argument of type `&impl FnOnce<{type error}, Output = {type error}> + Fn<{type error}> + 'static` + | ^^^^^^^^^^^ --------- unexpected argument of type `&impl Fn<{type error}> + FnOnce<{type error}, Output = {type error}> + 'static` | note: function defined here --> $DIR/opaque-used-in-extraneous-argument.rs:12:4 diff --git a/tests/ui/impl-trait/precise-capturing/auxiliary/foreign.rs b/tests/ui/impl-trait/precise-capturing/auxiliary/foreign.rs index 49015bc48baf2..09b7ef14e6ba0 100644 --- a/tests/ui/impl-trait/precise-capturing/auxiliary/foreign.rs +++ b/tests/ui/impl-trait/precise-capturing/auxiliary/foreign.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options use std::fmt::Display; diff --git a/tests/ui/impl-trait/precise-capturing/auxiliary/no-use-pm.rs b/tests/ui/impl-trait/precise-capturing/auxiliary/no-use-pm.rs index e197dcfef8048..fab55f11a53a9 100644 --- a/tests/ui/impl-trait/precise-capturing/auxiliary/no-use-pm.rs +++ b/tests/ui/impl-trait/precise-capturing/auxiliary/no-use-pm.rs @@ -1,11 +1,6 @@ // A proc-macro in 2015 that has an RPIT without `use<>` that would cause a // problem with 2024 capturing rules. -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/impl-trait/precise-capturing/capturing-implicit.rs b/tests/ui/impl-trait/precise-capturing/capturing-implicit.rs index 5ef8542d862e7..7b53b20ceffad 100644 --- a/tests/ui/impl-trait/precise-capturing/capturing-implicit.rs +++ b/tests/ui/impl-trait/precise-capturing/capturing-implicit.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options #![feature(rustc_attrs)] #![feature(type_alias_impl_trait)] diff --git a/tests/ui/impl-trait/precise-capturing/capturing-implicit.stderr b/tests/ui/impl-trait/precise-capturing/capturing-implicit.stderr index b14ed20bd367c..4d8c5cb40b4de 100644 --- a/tests/ui/impl-trait/precise-capturing/capturing-implicit.stderr +++ b/tests/ui/impl-trait/precise-capturing/capturing-implicit.stderr @@ -1,5 +1,5 @@ error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list - --> $DIR/capturing-implicit.rs:8:11 + --> $DIR/capturing-implicit.rs:7:11 | LL | fn foo(x: &()) -> impl IntoIterator + use<> { | ^ -------------------------------------------- lifetime captured due to being mentioned in the bounds of the `impl Trait` @@ -7,13 +7,13 @@ LL | fn foo(x: &()) -> impl IntoIterator + use<> { | this lifetime parameter is captured error: ['_: o] - --> $DIR/capturing-implicit.rs:8:19 + --> $DIR/capturing-implicit.rs:7:19 | LL | fn foo(x: &()) -> impl IntoIterator + use<> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: ['_: o] - --> $DIR/capturing-implicit.rs:8:44 + --> $DIR/capturing-implicit.rs:7:44 | LL | fn foo(x: &()) -> impl IntoIterator + use<> { | ^^^^^^^^^^ diff --git a/tests/ui/impl-trait/precise-capturing/external-macro.rs b/tests/ui/impl-trait/precise-capturing/external-macro.rs index 492e8036461a0..9d4d8a1bb119a 100644 --- a/tests/ui/impl-trait/precise-capturing/external-macro.rs +++ b/tests/ui/impl-trait/precise-capturing/external-macro.rs @@ -2,10 +2,9 @@ // has an RPIT will not fail when the call-site is 2024. // https://github.com/rust-lang/rust/issues/132917 -//@ aux-crate: no_use_pm=no-use-pm.rs +//@ proc-macro: no-use-pm.rs //@ aux-crate: no_use_macro=no-use-macro.rs //@ edition: 2024 -//@ compile-flags:-Z unstable-options //@ check-pass no_use_pm::pm_rpit!{} diff --git a/tests/ui/impl-trait/precise-capturing/foreign-2021.stderr b/tests/ui/impl-trait/precise-capturing/foreign-2021.stderr index 2a17ef72912a0..cd9ed0fb8851c 100644 --- a/tests/ui/impl-trait/precise-capturing/foreign-2021.stderr +++ b/tests/ui/impl-trait/precise-capturing/foreign-2021.stderr @@ -16,7 +16,7 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has LL | let h = foreign::hello(&x); | ^^^^^^^^^^^^^^^^^^ help: if you can modify this crate, add a precise capturing bound to avoid overcapturing: `+ use<>` - --> $DIR/auxiliary/foreign.rs:6:31 + --> $DIR/auxiliary/foreign.rs:5:31 | LL | pub fn hello(x: &Vec) -> impl Display { 0 } | ^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.rs b/tests/ui/impl-trait/precise-capturing/migration-note.rs index 1d98750f6dde2..36db07e5764f5 100644 --- a/tests/ui/impl-trait/precise-capturing/migration-note.rs +++ b/tests/ui/impl-trait/precise-capturing/migration-note.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options use std::fmt::Display; diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.stderr b/tests/ui/impl-trait/precise-capturing/migration-note.stderr index a859a114dbc55..c9403532dfa35 100644 --- a/tests/ui/impl-trait/precise-capturing/migration-note.stderr +++ b/tests/ui/impl-trait/precise-capturing/migration-note.stderr @@ -1,5 +1,5 @@ error[E0597]: `x` does not live long enough - --> $DIR/migration-note.rs:183:17 + --> $DIR/migration-note.rs:182:17 | LL | let x = vec![0]; | - binding `x` declared here @@ -14,7 +14,7 @@ LL | } | - `x` dropped here while still borrowed error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable - --> $DIR/migration-note.rs:20:5 + --> $DIR/migration-note.rs:19:5 | LL | let a = display_len(&x); | -- immutable borrow occurs here @@ -26,7 +26,7 @@ LL | println!("{a}"); | --- immutable borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:17:13 + --> $DIR/migration-note.rs:16:13 | LL | let a = display_len(&x); | ^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | fn display_len(x: &Vec) -> impl Display + use { | ++++++++ error[E0597]: `x` does not live long enough - --> $DIR/migration-note.rs:30:25 + --> $DIR/migration-note.rs:29:25 | LL | let x = vec![1]; | - binding `x` declared here @@ -51,7 +51,7 @@ LL | } | - `x` dropped here while still borrowed | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:30:13 + --> $DIR/migration-note.rs:29:13 | LL | let a = display_len(&x); | ^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | fn display_len(x: &Vec) -> impl Display + use { | ++++++++ error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/migration-note.rs:49:8 + --> $DIR/migration-note.rs:48:8 | LL | let x = vec![1]; | - binding `x` declared here @@ -76,7 +76,7 @@ LL | } | - borrow might be used here, when `a` is dropped and runs the destructor for type `impl std::fmt::Display` | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:44:13 + --> $DIR/migration-note.rs:43:13 | LL | let a = display_len(&x); | ^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | let a = display_len(&x.clone()); | ++++++++ error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/migration-note.rs:67:5 + --> $DIR/migration-note.rs:66:5 | LL | let a = display_len_mut(&mut x); | ------ first mutable borrow occurs here @@ -102,7 +102,7 @@ LL | println!("{a}"); | --- first borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:64:13 + --> $DIR/migration-note.rs:63:13 | LL | let a = display_len_mut(&mut x); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -112,7 +112,7 @@ LL | fn display_len_mut(x: &mut Vec) -> impl Display + use { | ++++++++ error[E0597]: `x` does not live long enough - --> $DIR/migration-note.rs:77:29 + --> $DIR/migration-note.rs:76:29 | LL | let mut x = vec![1]; | ----- binding `x` declared here @@ -127,7 +127,7 @@ LL | } | - `x` dropped here while still borrowed | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:77:13 + --> $DIR/migration-note.rs:76:13 | LL | let a = display_len_mut(&mut x); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -137,7 +137,7 @@ LL | fn display_len_mut(x: &mut Vec) -> impl Display + use { | ++++++++ error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/migration-note.rs:96:8 + --> $DIR/migration-note.rs:95:8 | LL | let mut x = vec![1]; | ----- binding `x` declared here @@ -152,7 +152,7 @@ LL | } | - borrow might be used here, when `a` is dropped and runs the destructor for type `impl std::fmt::Display` | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:91:13 + --> $DIR/migration-note.rs:90:13 | LL | let a = display_len_mut(&mut x); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | let a = display_len_mut(&mut x.clone()); | ++++++++ error[E0506]: cannot assign to `s.f` because it is borrowed - --> $DIR/migration-note.rs:116:5 + --> $DIR/migration-note.rs:115:5 | LL | let a = display_field(&s.f); | ---- `s.f` is borrowed here @@ -178,7 +178,7 @@ LL | println!("{a}"); | --- borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:113:13 + --> $DIR/migration-note.rs:112:13 | LL | let a = display_field(&s.f); | ^^^^^^^^^^^^^^^^^^^ @@ -188,7 +188,7 @@ LL | fn display_field(t: &T) -> impl Display + use { | ++++++++ error[E0506]: cannot assign to `s.f` because it is borrowed - --> $DIR/migration-note.rs:132:5 + --> $DIR/migration-note.rs:131:5 | LL | let a = display_field(&mut s.f); | -------- `s.f` is borrowed here @@ -200,7 +200,7 @@ LL | println!("{a}"); | --- borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:129:13 + --> $DIR/migration-note.rs:128:13 | LL | let a = display_field(&mut s.f); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -210,7 +210,7 @@ LL | fn display_field(t: &T) -> impl Display + use { | ++++++++ error[E0503]: cannot use `s.f` because it was mutably borrowed - --> $DIR/migration-note.rs:144:5 + --> $DIR/migration-note.rs:143:5 | LL | let a = display_field(&mut s.f); | -------- `s.f` is borrowed here @@ -222,7 +222,7 @@ LL | println!("{a}"); | --- borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:141:13 + --> $DIR/migration-note.rs:140:13 | LL | let a = display_field(&mut s.f); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -232,7 +232,7 @@ LL | fn display_field(t: &T) -> impl Display + use { | ++++++++ error[E0597]: `z.f` does not live long enough - --> $DIR/migration-note.rs:160:25 + --> $DIR/migration-note.rs:159:25 | LL | let z = Z { f: vec![1] }; | - binding `z` declared here @@ -248,7 +248,7 @@ LL | } | = note: values in a scope are dropped in the opposite order they are defined note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:160:13 + --> $DIR/migration-note.rs:159:13 | LL | x = display_len(&z.f); | ^^^^^^^^^^^^^^^^^ @@ -258,7 +258,7 @@ LL | fn display_len(x: &Vec) -> impl Display + use { | ++++++++ error[E0716]: temporary value dropped while borrowed - --> $DIR/migration-note.rs:171:40 + --> $DIR/migration-note.rs:170:40 | LL | let x = { let x = display_len(&mut vec![0]); x }; | ^^^^^^^ - - borrow later used here @@ -268,7 +268,7 @@ LL | let x = { let x = display_len(&mut vec![0]); x }; | = note: consider using a `let` binding to create a longer lived value note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:171:23 + --> $DIR/migration-note.rs:170:23 | LL | let x = { let x = display_len(&mut vec![0]); x }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,7 +279,7 @@ LL | fn display_len(x: &Vec) -> impl Display + use { | ++++++++ error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/migration-note.rs:199:10 + --> $DIR/migration-note.rs:198:10 | LL | let x = String::new(); | - binding `x` declared here @@ -294,12 +294,12 @@ LL | } | - borrow might be used here, when `y` is dropped and runs the destructor for type `impl Sized` | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:196:13 + --> $DIR/migration-note.rs:195:13 | LL | let y = capture_apit(&x); | ^^^^^^^^^^^^^^^^ note: you could use a `use<...>` bound to explicitly specify captures, but argument-position `impl Trait`s are not nameable - --> $DIR/migration-note.rs:190:21 + --> $DIR/migration-note.rs:189:21 | LL | fn capture_apit(x: &impl Sized) -> impl Sized {} | ^^^^^^^^^^ diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rs b/tests/ui/impl-trait/precise-capturing/redundant.rs index e19d935f5b0d4..075d7c70ac653 100644 --- a/tests/ui/impl-trait/precise-capturing/redundant.rs +++ b/tests/ui/impl-trait/precise-capturing/redundant.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zunstable-options --edition=2024 +//@ edition: 2024 //@ check-pass #![feature(precise_capturing_in_traits)] diff --git a/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.stderr b/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.stderr index e1856b929106e..360f0d7e7f37f 100644 --- a/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.stderr +++ b/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.stderr @@ -1,10 +1,11 @@ error: return type captures more lifetimes than trait definition --> $DIR/rpitit-impl-captures-too-much.rs:10:39 | +LL | fn hello(self_: Invariant<'_>) -> impl Sized + use; + | -- this lifetime was captured +... LL | fn hello(self_: Invariant<'_>) -> impl Sized + use<'_> {} - | -- ^^^^^^^^^^^^^^^^^^^^ - | | - | this lifetime was captured + | ^^^^^^^^^^^^^^^^^^^^ | note: hidden type must only reference lifetimes captured by this impl trait --> $DIR/rpitit-impl-captures-too-much.rs:6:39 diff --git a/tests/ui/impl-trait/transmute/in-defining-scope.rs b/tests/ui/impl-trait/transmute/in-defining-scope.rs index b9a9dbc10a5b4..4c8e1852a9104 100644 --- a/tests/ui/impl-trait/transmute/in-defining-scope.rs +++ b/tests/ui/impl-trait/transmute/in-defining-scope.rs @@ -1,5 +1,5 @@ -// This causes a query cycle due to using `Reveal::All`, -// in #119821 const eval was changed to always use `Reveal::All` +// This causes a query cycle due to using `TypingEnv::PostAnalysis`, +// in #119821 const eval was changed to always use this mode. // // See that PR for more details. use std::mem::transmute; diff --git a/tests/ui/impl-trait/unsized_coercion.next.stderr b/tests/ui/impl-trait/unsized_coercion.next.stderr index 4cebd26a5bee6..bea5ddb0aefcc 100644 --- a/tests/ui/impl-trait/unsized_coercion.next.stderr +++ b/tests/ui/impl-trait/unsized_coercion.next.stderr @@ -1,35 +1,11 @@ error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/unsized_coercion.rs:15:17 + --> $DIR/unsized_coercion.rs:14:17 | LL | let x = hello(); | ^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `dyn Trait` -error[E0308]: mismatched types - --> $DIR/unsized_coercion.rs:19:5 - | -LL | fn hello() -> Box { - | --------------- - | | | - | | the expected opaque type - | expected `Box` because of return type -... -LL | Box::new(1u32) - | ^^^^^^^^^^^^^^ types differ - | - = note: expected struct `Box` - found struct `Box` - -error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/unsized_coercion.rs:12:1 - | -LL | fn hello() -> Box { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `dyn Trait` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/unsized_coercion.rs b/tests/ui/impl-trait/unsized_coercion.rs index b3791b38abc2d..2cbf0d25d7ec6 100644 --- a/tests/ui/impl-trait/unsized_coercion.rs +++ b/tests/ui/impl-trait/unsized_coercion.rs @@ -10,13 +10,12 @@ trait Trait {} impl Trait for u32 {} fn hello() -> Box { - //[next]~^ ERROR the size for values of type `dyn Trait` cannot be known at compilation time if true { let x = hello(); //[next]~^ ERROR: the size for values of type `dyn Trait` cannot be known at compilation time let y: Box = x; } - Box::new(1u32) //[next]~ ERROR: mismatched types + Box::new(1u32) } fn main() {} diff --git a/tests/ui/impl-trait/unsized_coercion3.next.stderr b/tests/ui/impl-trait/unsized_coercion3.next.stderr index d1e1809cf1656..28771e01813ae 100644 --- a/tests/ui/impl-trait/unsized_coercion3.next.stderr +++ b/tests/ui/impl-trait/unsized_coercion3.next.stderr @@ -1,35 +1,11 @@ error[E0277]: the trait bound `dyn Send: Trait` is not satisfied - --> $DIR/unsized_coercion3.rs:14:17 + --> $DIR/unsized_coercion3.rs:13:17 | LL | let x = hello(); | ^^^^^^^ the trait `Trait` is not implemented for `dyn Send` | = help: the trait `Trait` is implemented for `u32` -error[E0308]: mismatched types - --> $DIR/unsized_coercion3.rs:19:5 - | -LL | fn hello() -> Box { - | ------------------------ - | | | - | | the expected opaque type - | expected `Box` because of return type -... -LL | Box::new(1u32) - | ^^^^^^^^^^^^^^ types differ - | - = note: expected struct `Box` - found struct `Box` - -error[E0277]: the trait bound `dyn Send: Trait` is not satisfied - --> $DIR/unsized_coercion3.rs:11:1 - | -LL | fn hello() -> Box { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Send` - | - = help: the trait `Trait` is implemented for `u32` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/unsized_coercion3.old.stderr b/tests/ui/impl-trait/unsized_coercion3.old.stderr index 3bb9f9c209510..52a72b84a8dd6 100644 --- a/tests/ui/impl-trait/unsized_coercion3.old.stderr +++ b/tests/ui/impl-trait/unsized_coercion3.old.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time - --> $DIR/unsized_coercion3.rs:16:32 + --> $DIR/unsized_coercion3.rs:15:32 | LL | let y: Box = x; | ^ doesn't have a size known at compile-time diff --git a/tests/ui/impl-trait/unsized_coercion3.rs b/tests/ui/impl-trait/unsized_coercion3.rs index c1dd5350e229a..ebfbb2955de55 100644 --- a/tests/ui/impl-trait/unsized_coercion3.rs +++ b/tests/ui/impl-trait/unsized_coercion3.rs @@ -9,7 +9,6 @@ trait Trait {} impl Trait for u32 {} fn hello() -> Box { - //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied if true { let x = hello(); //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied @@ -17,7 +16,6 @@ fn hello() -> Box { //[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know } Box::new(1u32) - //[next]~^ ERROR: mismatched types } fn main() {} diff --git a/tests/ui/impl-trait/variance.e2024.stderr b/tests/ui/impl-trait/variance.e2024.stderr index 011ab3259c477..361a165da66f3 100644 --- a/tests/ui/impl-trait/variance.e2024.stderr +++ b/tests/ui/impl-trait/variance.e2024.stderr @@ -1,23 +1,23 @@ error: ['a: *, 'a: o] - --> $DIR/variance.rs:14:36 + --> $DIR/variance.rs:13:36 | LL | fn not_captured_early<'a: 'a>() -> impl Sized {} | ^^^^^^^^^^ error: ['a: *, 'a: o] - --> $DIR/variance.rs:19:32 + --> $DIR/variance.rs:18:32 | LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: ['a: o] - --> $DIR/variance.rs:21:40 + --> $DIR/variance.rs:20:40 | LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} | ^^^^^^^^^^ error: ['a: o] - --> $DIR/variance.rs:26:36 + --> $DIR/variance.rs:25:36 | LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/variance.new.stderr b/tests/ui/impl-trait/variance.new.stderr index 011ab3259c477..361a165da66f3 100644 --- a/tests/ui/impl-trait/variance.new.stderr +++ b/tests/ui/impl-trait/variance.new.stderr @@ -1,23 +1,23 @@ error: ['a: *, 'a: o] - --> $DIR/variance.rs:14:36 + --> $DIR/variance.rs:13:36 | LL | fn not_captured_early<'a: 'a>() -> impl Sized {} | ^^^^^^^^^^ error: ['a: *, 'a: o] - --> $DIR/variance.rs:19:32 + --> $DIR/variance.rs:18:32 | LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: ['a: o] - --> $DIR/variance.rs:21:40 + --> $DIR/variance.rs:20:40 | LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} | ^^^^^^^^^^ error: ['a: o] - --> $DIR/variance.rs:26:36 + --> $DIR/variance.rs:25:36 | LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/variance.old.stderr b/tests/ui/impl-trait/variance.old.stderr index ac3bcd2723fb3..578d6fd14cd20 100644 --- a/tests/ui/impl-trait/variance.old.stderr +++ b/tests/ui/impl-trait/variance.old.stderr @@ -1,23 +1,23 @@ error: ['a: *] - --> $DIR/variance.rs:14:36 + --> $DIR/variance.rs:13:36 | LL | fn not_captured_early<'a: 'a>() -> impl Sized {} | ^^^^^^^^^^ error: ['a: *, 'a: o] - --> $DIR/variance.rs:19:32 + --> $DIR/variance.rs:18:32 | LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [] - --> $DIR/variance.rs:21:40 + --> $DIR/variance.rs:20:40 | LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} | ^^^^^^^^^^ error: ['a: o] - --> $DIR/variance.rs:26:36 + --> $DIR/variance.rs:25:36 | LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/variance.rs b/tests/ui/impl-trait/variance.rs index 43f7207a90423..1e359f033ff52 100644 --- a/tests/ui/impl-trait/variance.rs +++ b/tests/ui/impl-trait/variance.rs @@ -1,6 +1,5 @@ //@ revisions: old new e2024 //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Z unstable-options #![cfg_attr(new, feature(lifetime_capture_rules_2024))] diff --git a/tests/ui/imports/export-glob-imports-target.rs b/tests/ui/imports/export-glob-imports-target.rs index 0133e8a94b516..6fde9fef0b67d 100644 --- a/tests/ui/imports/export-glob-imports-target.rs +++ b/tests/ui/imports/export-glob-imports-target.rs @@ -7,7 +7,6 @@ // Modified to not use export since it's going away. --pcw -//@ pretty-expanded FIXME #23616 mod foo { use foo::bar::*; diff --git a/tests/ui/imports/export-multi.rs b/tests/ui/imports/export-multi.rs index b52e952f33c4a..4f7f7d3a6c035 100644 --- a/tests/ui/imports/export-multi.rs +++ b/tests/ui/imports/export-multi.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use m::f; use m::g; diff --git a/tests/ui/imports/import-crate-with-invalid-spans/main.rs b/tests/ui/imports/import-crate-with-invalid-spans/main.rs index 3234cf304f740..ed042f74f3f71 100644 --- a/tests/ui/imports/import-crate-with-invalid-spans/main.rs +++ b/tests/ui/imports/import-crate-with-invalid-spans/main.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:crate_with_invalid_spans.rs -//@ pretty-expanded FIXME #23616 extern crate crate_with_invalid_spans; diff --git a/tests/ui/imports/import-from.rs b/tests/ui/imports/import-from.rs index c5ff4b3abc618..128002e0e2abc 100644 --- a/tests/ui/imports/import-from.rs +++ b/tests/ui/imports/import-from.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use spam::{ham, eggs}; diff --git a/tests/ui/imports/import-in-block.rs b/tests/ui/imports/import-in-block.rs index c17e2cffa51b5..2588ea7702363 100644 --- a/tests/ui/imports/import-in-block.rs +++ b/tests/ui/imports/import-in-block.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { use std::mem::replace; diff --git a/tests/ui/imports/import-trailing-comma.rs b/tests/ui/imports/import-trailing-comma.rs index 3803b56487f81..4147357a22b09 100644 --- a/tests/ui/imports/import-trailing-comma.rs +++ b/tests/ui/imports/import-trailing-comma.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use foo::bar::{baz, quux,}; diff --git a/tests/ui/imports/reexport-star.rs b/tests/ui/imports/reexport-star.rs index 3e41f12fa2d87..461dc23b4dcde 100644 --- a/tests/ui/imports/reexport-star.rs +++ b/tests/ui/imports/reexport-star.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 mod a { pub fn f() {} diff --git a/tests/ui/imports/use-mod.rs b/tests/ui/imports/use-mod.rs index 065079b21e529..cabea16e725d7 100644 --- a/tests/ui/imports/use-mod.rs +++ b/tests/ui/imports/use-mod.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_imports)] -//@ pretty-expanded FIXME #23616 pub use foo::bar::{self, First}; use self::bar::Second; diff --git a/tests/ui/inference/array-len-mismatch.stderr b/tests/ui/inference/array-len-mismatch.stderr index 7358e47839725..7146e3803d536 100644 --- a/tests/ui/inference/array-len-mismatch.stderr +++ b/tests/ui/inference/array-len-mismatch.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/array-len-mismatch.rs:6:26 | LL | let wrong: [u8; 3] = [10, 20]; - | ------- ^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements + | ------- ^^^^^^^^ expected an array with a size of 3, found one with a size of 2 | | | | | help: consider specifying the actual array length: `2` | expected due to this @@ -11,7 +11,7 @@ error[E0308]: mismatched types --> $DIR/array-len-mismatch.rs:9:26 | LL | let wrong: [u8; 3] = returns_arr(); - | ------- ^^^^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements + | ------- ^^^^^^^^^^^^^ expected an array with a size of 3, found one with a size of 2 | | | | | help: consider specifying the actual array length: `2` | expected due to this diff --git a/tests/ui/inference/infer-fn-tail-expr.rs b/tests/ui/inference/infer-fn-tail-expr.rs index 31b71e49bd6f7..e97522ed526c0 100644 --- a/tests/ui/inference/infer-fn-tail-expr.rs +++ b/tests/ui/inference/infer-fn-tail-expr.rs @@ -4,7 +4,6 @@ // issue #680 -//@ pretty-expanded FIXME #23616 fn f() -> Vec { Vec::new() } diff --git a/tests/ui/inference/newlambdas-ret-infer.rs b/tests/ui/inference/newlambdas-ret-infer.rs index 893b62e967ddb..980a2fdd905f6 100644 --- a/tests/ui/inference/newlambdas-ret-infer.rs +++ b/tests/ui/inference/newlambdas-ret-infer.rs @@ -4,7 +4,6 @@ // Test that the lambda kind is inferred correctly as a return // expression -//@ pretty-expanded FIXME #23616 fn unique() -> Box { return Box::new(|| ()); } diff --git a/tests/ui/inference/newlambdas-ret-infer2.rs b/tests/ui/inference/newlambdas-ret-infer2.rs index cad8b02910b1a..40d45d3569c1b 100644 --- a/tests/ui/inference/newlambdas-ret-infer2.rs +++ b/tests/ui/inference/newlambdas-ret-infer2.rs @@ -4,7 +4,6 @@ // Test that the lambda kind is inferred correctly as a return // expression -//@ pretty-expanded FIXME #23616 fn unique() -> Box { Box::new(|| ()) } diff --git a/tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs b/tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs index a2970cb5c805f..b87c4b14abc59 100644 --- a/tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs +++ b/tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{Ident, Group, TokenStream, TokenTree as Tt}; diff --git a/tests/ui/inherent-impls-overlap-check/no-overlap.rs b/tests/ui/inherent-impls-overlap-check/no-overlap.rs index 85565a221ac2f..df60031bae033 100644 --- a/tests/ui/inherent-impls-overlap-check/no-overlap.rs +++ b/tests/ui/inherent-impls-overlap-check/no-overlap.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:repeat.rs +//@ proc-macro: repeat.rs // This tests the allocating algo branch of the // inherent impls overlap checker. diff --git a/tests/ui/inherent-impls-overlap-check/overlap.rs b/tests/ui/inherent-impls-overlap-check/overlap.rs index 3265394369816..114035a13b634 100644 --- a/tests/ui/inherent-impls-overlap-check/overlap.rs +++ b/tests/ui/inherent-impls-overlap-check/overlap.rs @@ -1,4 +1,4 @@ -//@ aux-build:repeat.rs +//@ proc-macro: repeat.rs #![allow(unused)] diff --git a/tests/ui/invalid-compile-flags/fuel.rs b/tests/ui/invalid-compile-flags/fuel.rs deleted file mode 100644 index 855aa8581223a..0000000000000 --- a/tests/ui/invalid-compile-flags/fuel.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ revisions: incremental threads -//@ dont-check-compiler-stderr -// -//@ [threads] compile-flags: -Zfuel=a=1 -Zthreads=2 -//@ [threads] error-pattern:optimization fuel is incompatible with multiple threads -// -//@ [incremental] incremental -//@ [incremental] compile-flags: -Zprint-fuel=a -//@ [incremental] error-pattern:optimization fuel is incompatible with incremental compilation - -fn main() {} diff --git a/tests/ui/issue-15924.rs b/tests/ui/issue-15924.rs index 77e1ae697c579..eb2aef9cee12b 100644 --- a/tests/ui/issue-15924.rs +++ b/tests/ui/issue-15924.rs @@ -2,7 +2,6 @@ #![allow(unused_imports)] #![allow(unused_must_use)] -//@ pretty-expanded FIXME #23616 use std::fmt; use std::marker::PhantomData; diff --git a/tests/ui/issues/issue-10228.rs b/tests/ui/issues/issue-10228.rs index 7934afc7b9b3f..a59ccf926f9c2 100644 --- a/tests/ui/issues/issue-10228.rs +++ b/tests/ui/issues/issue-10228.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 enum StdioContainer { CreatePipe(bool) diff --git a/tests/ui/issues/issue-10456.rs b/tests/ui/issues/issue-10456.rs index a43cc5d36f1e2..51c740fd72937 100644 --- a/tests/ui/issues/issue-10456.rs +++ b/tests/ui/issues/issue-10456.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 pub struct Foo; diff --git a/tests/ui/issues/issue-10638.rs b/tests/ui/issues/issue-10638.rs index f82023f2da558..c6c6939bda539 100644 --- a/tests/ui/issues/issue-10638.rs +++ b/tests/ui/issues/issue-10638.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { //// I am not a doc comment! diff --git a/tests/ui/issues/issue-10683.rs b/tests/ui/issues/issue-10683.rs index 675a8323fc42f..5657ec1864b2e 100644 --- a/tests/ui/issues/issue-10683.rs +++ b/tests/ui/issues/issue-10683.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 static NAME: &'static str = "hello world"; diff --git a/tests/ui/issues/issue-10718.rs b/tests/ui/issues/issue-10718.rs index 5d3cf2621acd1..68ac0bbe49fbc 100644 --- a/tests/ui/issues/issue-10718.rs +++ b/tests/ui/issues/issue-10718.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn f(p: F) { p(); diff --git a/tests/ui/issues/issue-10767.rs b/tests/ui/issues/issue-10767.rs index 7d74f1e901721..2060d15b4c787 100644 --- a/tests/ui/issues/issue-10767.rs +++ b/tests/ui/issues/issue-10767.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { fn f() { diff --git a/tests/ui/issues/issue-10806.rs b/tests/ui/issues/issue-10806.rs index 731edc8335d6e..72d99ae3a795e 100644 --- a/tests/ui/issues/issue-10806.rs +++ b/tests/ui/issues/issue-10806.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_imports)] -//@ pretty-expanded FIXME #23616 pub fn foo() -> isize { 3 diff --git a/tests/ui/issues/issue-10853.rs b/tests/ui/issues/issue-10853.rs index 0b0bcb710ade1..4c22393d9c0a3 100644 --- a/tests/ui/issues/issue-10853.rs +++ b/tests/ui/issues/issue-10853.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 #![deny(missing_docs)] #![doc="module"] diff --git a/tests/ui/issues/issue-10902.rs b/tests/ui/issues/issue-10902.rs index 72f08ec3f9489..7cdf8808aa028 100644 --- a/tests/ui/issues/issue-10902.rs +++ b/tests/ui/issues/issue-10902.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub mod two_tuple { pub trait T { fn dummy(&self) { } } diff --git a/tests/ui/issues/issue-11085.rs b/tests/ui/issues/issue-11085.rs index f646ba35cbfae..d0703b0639542 100644 --- a/tests/ui/issues/issue-11085.rs +++ b/tests/ui/issues/issue-11085.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/issues/issue-11205.rs b/tests/ui/issues/issue-11205.rs index f21a52050ffde..8530514f0edf7 100644 --- a/tests/ui/issues/issue-11205.rs +++ b/tests/ui/issues/issue-11205.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/issues/issue-11224.rs b/tests/ui/issues/issue-11224.rs index 3a504604b6a9d..a7255e6299f98 100644 --- a/tests/ui/issues/issue-11224.rs +++ b/tests/ui/issues/issue-11224.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-11224.rs -//@ pretty-expanded FIXME #23616 extern crate issue_11224 as unused; diff --git a/tests/ui/issues/issue-11384.rs b/tests/ui/issues/issue-11384.rs index 0d1cce71958e3..ad0affa4b0d25 100644 --- a/tests/ui/issues/issue-11384.rs +++ b/tests/ui/issues/issue-11384.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait Common { fn dummy(&self) { } } diff --git a/tests/ui/issues/issue-11529.rs b/tests/ui/issues/issue-11529.rs index db7ff85d46b0f..73940c22be4ce 100644 --- a/tests/ui/issues/issue-11529.rs +++ b/tests/ui/issues/issue-11529.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-11529.rs -//@ pretty-expanded FIXME #23616 extern crate issue_11529 as a; diff --git a/tests/ui/issues/issue-11820.rs b/tests/ui/issues/issue-11820.rs index 372ce2c2a1616..ada844f8ee121 100644 --- a/tests/ui/issues/issue-11820.rs +++ b/tests/ui/issues/issue-11820.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(noop_method_call)] diff --git a/tests/ui/issues/issue-11869.rs b/tests/ui/issues/issue-11869.rs index 606a0c7b9d9f4..dd752227bbec7 100644 --- a/tests/ui/issues/issue-11869.rs +++ b/tests/ui/issues/issue-11869.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct A { a: String diff --git a/tests/ui/issues/issue-12612.rs b/tests/ui/issues/issue-12612.rs index 0ffe7422fb310..ec0f3926aa5d3 100644 --- a/tests/ui/issues/issue-12612.rs +++ b/tests/ui/issues/issue-12612.rs @@ -3,7 +3,6 @@ //@ aux-build:issue-12612-1.rs //@ aux-build:issue-12612-2.rs -//@ pretty-expanded FIXME #23616 extern crate issue_12612_1 as foo; extern crate issue_12612_2 as bar; diff --git a/tests/ui/issues/issue-12660.rs b/tests/ui/issues/issue-12660.rs index 997c10ae5cf8f..3aa3426519afc 100644 --- a/tests/ui/issues/issue-12660.rs +++ b/tests/ui/issues/issue-12660.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-12660-aux.rs -//@ pretty-expanded FIXME #23616 extern crate issue12660aux; diff --git a/tests/ui/issues/issue-12729.rs b/tests/ui/issues/issue-12729.rs index 43e692b895ade..74014981df5de 100644 --- a/tests/ui/issues/issue-12729.rs +++ b/tests/ui/issues/issue-12729.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub struct Foo; diff --git a/tests/ui/issues/issue-12909.rs b/tests/ui/issues/issue-12909.rs index 3af8c07d7a76e..f2c33806aae88 100644 --- a/tests/ui/issues/issue-12909.rs +++ b/tests/ui/issues/issue-12909.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 use std::collections::HashMap; diff --git a/tests/ui/issues/issue-13105.rs b/tests/ui/issues/issue-13105.rs index 1ef9a6b7e33c3..0dd78372a2690 100644 --- a/tests/ui/issues/issue-13105.rs +++ b/tests/ui/issues/issue-13105.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait Foo { #[allow(anonymous_parameters)] diff --git a/tests/ui/issues/issue-13167.rs b/tests/ui/issues/issue-13167.rs index 15ee02b9cd458..5f733e8594888 100644 --- a/tests/ui/issues/issue-13167.rs +++ b/tests/ui/issues/issue-13167.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver diff --git a/tests/ui/issues/issue-13214.rs b/tests/ui/issues/issue-13214.rs index 7144094d8c25c..8140ec943a01f 100644 --- a/tests/ui/issues/issue-13214.rs +++ b/tests/ui/issues/issue-13214.rs @@ -3,7 +3,6 @@ // defining static with struct that contains enum // with &'static str variant used to cause ICE -//@ pretty-expanded FIXME #23616 pub enum Foo { Bar, diff --git a/tests/ui/issues/issue-13405.rs b/tests/ui/issues/issue-13405.rs index b2b26ab39c57b..80b298d2f37aa 100644 --- a/tests/ui/issues/issue-13405.rs +++ b/tests/ui/issues/issue-13405.rs @@ -1,7 +1,6 @@ //@ check-pass #![allow(dead_code)] #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 struct Foo<'a> { i: &'a bool, diff --git a/tests/ui/issues/issue-13620.rs b/tests/ui/issues/issue-13620.rs index 0225114e6c38b..4d9db3aa7ceda 100644 --- a/tests/ui/issues/issue-13620.rs +++ b/tests/ui/issues/issue-13620.rs @@ -2,7 +2,6 @@ //@ aux-build:issue-13620-1.rs //@ aux-build:issue-13620-2.rs -//@ pretty-expanded FIXME #23616 extern crate issue_13620_2 as crate2; diff --git a/tests/ui/issues/issue-13665.rs b/tests/ui/issues/issue-13665.rs index 3d5cffa98552c..e1d8be16f4500 100644 --- a/tests/ui/issues/issue-13665.rs +++ b/tests/ui/issues/issue-13665.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn foo<'r>() { let maybe_value_ref: Option<&'r u8> = None; diff --git a/tests/ui/issues/issue-13703.rs b/tests/ui/issues/issue-13703.rs index 9748ab3719ef5..b385e6b9d2efd 100644 --- a/tests/ui/issues/issue-13703.rs +++ b/tests/ui/issues/issue-13703.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 pub struct Foo<'a, 'b: 'a> { foo: &'a &'b isize } pub fn foo<'a, 'b>(x: Foo<'a, 'b>, _o: Option<& & ()>) { let _y = x.foo; } diff --git a/tests/ui/issues/issue-13763.rs b/tests/ui/issues/issue-13763.rs index 3044c671169c1..67b9bdc5f038a 100644 --- a/tests/ui/issues/issue-13763.rs +++ b/tests/ui/issues/issue-13763.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 mod u8 { pub const BITS: usize = 8; diff --git a/tests/ui/issues/issue-13775.rs b/tests/ui/issues/issue-13775.rs index 1d7a40b72d331..500ec6782a8b1 100644 --- a/tests/ui/issues/issue-13775.rs +++ b/tests/ui/issues/issue-13775.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait Foo { #[allow(anonymous_parameters)] diff --git a/tests/ui/issues/issue-13808.rs b/tests/ui/issues/issue-13808.rs index 91b771c6a68c2..d2961b35f2e76 100644 --- a/tests/ui/issues/issue-13808.rs +++ b/tests/ui/issues/issue-13808.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 struct Foo<'a> { listener: Box, diff --git a/tests/ui/issues/issue-14082.rs b/tests/ui/issues/issue-14082.rs index 116002415dfa6..16556e1d26003 100644 --- a/tests/ui/issues/issue-14082.rs +++ b/tests/ui/issues/issue-14082.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 #![allow(unused_imports, dead_code)] diff --git a/tests/ui/issues/issue-14254.rs b/tests/ui/issues/issue-14254.rs index 9175ac8f92e05..90ad375c262ab 100644 --- a/tests/ui/issues/issue-14254.rs +++ b/tests/ui/issues/issue-14254.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait Foo: Sized { fn bar(&self); diff --git a/tests/ui/issues/issue-14330.rs b/tests/ui/issues/issue-14330.rs index f6461c834a5e4..11199db5901f3 100644 --- a/tests/ui/issues/issue-14330.rs +++ b/tests/ui/issues/issue-14330.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(unused_imports)] -//@ pretty-expanded FIXME #23616 #[macro_use] extern crate std as std2; diff --git a/tests/ui/issues/issue-14393.rs b/tests/ui/issues/issue-14393.rs index b7e64d6dca6ab..69c3fc15d3141 100644 --- a/tests/ui/issues/issue-14393.rs +++ b/tests/ui/issues/issue-14393.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn main() { match ("", 1_usize) { diff --git a/tests/ui/issues/issue-14399.rs b/tests/ui/issues/issue-14399.rs index cb768f63baaae..a539e270fb011 100644 --- a/tests/ui/issues/issue-14399.rs +++ b/tests/ui/issues/issue-14399.rs @@ -4,7 +4,6 @@ // value was coerced to a trait object. (v.clone() returns Box // which is coerced to Box). -//@ pretty-expanded FIXME #23616 #[derive(Clone)] struct B1; diff --git a/tests/ui/issues/issue-14399.stderr b/tests/ui/issues/issue-14399.stderr index d226ece6fb0b6..5821c3cc3899a 100644 --- a/tests/ui/issues/issue-14399.stderr +++ b/tests/ui/issues/issue-14399.stderr @@ -1,5 +1,5 @@ warning: method `foo` is never used - --> $DIR/issue-14399.rs:12:14 + --> $DIR/issue-14399.rs:11:14 | LL | trait A { fn foo(&self) {} } | - ^^^ diff --git a/tests/ui/issues/issue-14421.rs b/tests/ui/issues/issue-14421.rs index 4acbce66b6f1d..b7038584fcea6 100644 --- a/tests/ui/issues/issue-14421.rs +++ b/tests/ui/issues/issue-14421.rs @@ -3,7 +3,6 @@ //@ aux-build:issue-14421.rs -//@ pretty-expanded FIXME #23616 extern crate issue_14421 as bug_lib; diff --git a/tests/ui/issues/issue-14422.rs b/tests/ui/issues/issue-14422.rs index ed9e72390c55a..b7bb2caa7f088 100644 --- a/tests/ui/issues/issue-14422.rs +++ b/tests/ui/issues/issue-14422.rs @@ -3,7 +3,6 @@ //@ aux-build:issue-14422.rs -//@ pretty-expanded FIXME #23616 extern crate issue_14422 as bug_lib; diff --git a/tests/ui/issues/issue-14919.rs b/tests/ui/issues/issue-14919.rs index 8a8324e57eabf..3a834b13d07c0 100644 --- a/tests/ui/issues/issue-14919.rs +++ b/tests/ui/issues/issue-14919.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_must_use)] #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 trait Matcher { fn next_match(&mut self) -> Option<(usize, usize)>; diff --git a/tests/ui/issues/issue-14959.rs b/tests/ui/issues/issue-14959.rs index 401bd82ded352..57af1207ff9c7 100644 --- a/tests/ui/issues/issue-14959.rs +++ b/tests/ui/issues/issue-14959.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 #![feature(fn_traits, unboxed_closures)] diff --git a/tests/ui/issues/issue-15043.rs b/tests/ui/issues/issue-15043.rs index b00c878086dca..a9bb46b649b00 100644 --- a/tests/ui/issues/issue-15043.rs +++ b/tests/ui/issues/issue-15043.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(warnings)] diff --git a/tests/ui/issues/issue-15444.rs b/tests/ui/issues/issue-15444.rs index a9a33bd5de458..14708c7733c64 100644 --- a/tests/ui/issues/issue-15444.rs +++ b/tests/ui/issues/issue-15444.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 trait MyTrait { fn foo(&self); diff --git a/tests/ui/issues/issue-15562.rs b/tests/ui/issues/issue-15562.rs index faa46cd5ece59..d3a8f24c51b7e 100644 --- a/tests/ui/issues/issue-15562.rs +++ b/tests/ui/issues/issue-15562.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-15562.rs -//@ pretty-expanded FIXME #23616 extern crate issue_15562 as i; diff --git a/tests/ui/issues/issue-15774.rs b/tests/ui/issues/issue-15774.rs index 383003b2dd78b..8eb327a0d5e7a 100644 --- a/tests/ui/issues/issue-15774.rs +++ b/tests/ui/issues/issue-15774.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![deny(warnings)] #![allow(unused_imports)] diff --git a/tests/ui/issues/issue-16256.rs b/tests/ui/issues/issue-16256.rs index f5873331c2d28..1024e4511d639 100644 --- a/tests/ui/issues/issue-16256.rs +++ b/tests/ui/issues/issue-16256.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn main() { let mut buf = Vec::new(); diff --git a/tests/ui/issues/issue-16256.stderr b/tests/ui/issues/issue-16256.stderr index d920530b57c69..75c3ec1bd1c7f 100644 --- a/tests/ui/issues/issue-16256.stderr +++ b/tests/ui/issues/issue-16256.stderr @@ -1,5 +1,5 @@ warning: unused closure that must be used - --> $DIR/issue-16256.rs:6:5 + --> $DIR/issue-16256.rs:5:5 | LL | |c: u8| buf.push(c); | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-16441.rs b/tests/ui/issues/issue-16441.rs index 21608cf04c31d..58cfb3892975b 100644 --- a/tests/ui/issues/issue-16441.rs +++ b/tests/ui/issues/issue-16441.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct Empty; diff --git a/tests/ui/issues/issue-16452.rs b/tests/ui/issues/issue-16452.rs index 07dbf4729e6f7..4ab74f0905976 100644 --- a/tests/ui/issues/issue-16452.rs +++ b/tests/ui/issues/issue-16452.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn main() { if true { return } diff --git a/tests/ui/issues/issue-16643.rs b/tests/ui/issues/issue-16643.rs index e00978ce66aae..6cef11ffa8761 100644 --- a/tests/ui/issues/issue-16643.rs +++ b/tests/ui/issues/issue-16643.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-16643.rs -//@ pretty-expanded FIXME #23616 extern crate issue_16643 as i; diff --git a/tests/ui/issues/issue-16783.rs b/tests/ui/issues/issue-16783.rs index a69ecb353bb3c..2ecc42b579d50 100644 --- a/tests/ui/issues/issue-16783.rs +++ b/tests/ui/issues/issue-16783.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 pub fn main() { let x = [1, 2, 3]; diff --git a/tests/ui/issues/issue-16922-rpass.rs b/tests/ui/issues/issue-16922-rpass.rs index 6cce4179b7cd7..f7ffcfb1d94e3 100644 --- a/tests/ui/issues/issue-16922-rpass.rs +++ b/tests/ui/issues/issue-16922-rpass.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use std::any::Any; diff --git a/tests/ui/issues/issue-17121.rs b/tests/ui/issues/issue-17121.rs index 0a788b317cdb9..6bb89a4aa7b43 100644 --- a/tests/ui/issues/issue-17121.rs +++ b/tests/ui/issues/issue-17121.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 use std::fs::File; use std::io::{self, BufReader, Read}; diff --git a/tests/ui/issues/issue-17322.rs b/tests/ui/issues/issue-17322.rs index 71ff38a01453d..014e6b718f149 100644 --- a/tests/ui/issues/issue-17322.rs +++ b/tests/ui/issues/issue-17322.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use std::io::{self, Write}; diff --git a/tests/ui/issues/issue-17351.rs b/tests/ui/issues/issue-17351.rs index 15bff07f6e541..86049377198c1 100644 --- a/tests/ui/issues/issue-17351.rs +++ b/tests/ui/issues/issue-17351.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 trait Str { fn foo(&self) {} } //~ WARN method `foo` is never used impl Str for str {} diff --git a/tests/ui/issues/issue-17351.stderr b/tests/ui/issues/issue-17351.stderr index 3242d578dabce..e4c84ab9315ab 100644 --- a/tests/ui/issues/issue-17351.stderr +++ b/tests/ui/issues/issue-17351.stderr @@ -1,5 +1,5 @@ warning: method `foo` is never used - --> $DIR/issue-17351.rs:4:16 + --> $DIR/issue-17351.rs:3:16 | LL | trait Str { fn foo(&self) {} } | --- ^^^ diff --git a/tests/ui/issues/issue-17361.rs b/tests/ui/issues/issue-17361.rs index 1b1eeb5a25243..6f6fc42db3835 100644 --- a/tests/ui/issues/issue-17361.rs +++ b/tests/ui/issues/issue-17361.rs @@ -1,7 +1,6 @@ //@ run-pass // Test that HIR ty lowering doesn't forget about mutability of `&mut str`. -//@ pretty-expanded FIXME #23616 fn main() { fn foo(_: &mut T) {} diff --git a/tests/ui/issues/issue-17732.rs b/tests/ui/issues/issue-17732.rs index 4bf7ee286e156..e093ed7f41fb0 100644 --- a/tests/ui/issues/issue-17732.rs +++ b/tests/ui/issues/issue-17732.rs @@ -1,7 +1,6 @@ //@ check-pass #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 trait Person { type string; diff --git a/tests/ui/issues/issue-17771.rs b/tests/ui/issues/issue-17771.rs index d7c0ea3eb2a6f..2e27cfceb8c35 100644 --- a/tests/ui/issues/issue-17771.rs +++ b/tests/ui/issues/issue-17771.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 trait Aaa { fn dummy(&self) { } } diff --git a/tests/ui/issues/issue-17904.rs b/tests/ui/issues/issue-17904.rs index 5eaa306e80ef0..fba71f70dd98e 100644 --- a/tests/ui/issues/issue-17904.rs +++ b/tests/ui/issues/issue-17904.rs @@ -3,7 +3,6 @@ // Test that we can parse where clauses on various forms of tuple // structs. -//@ pretty-expanded FIXME #23616 struct Bar(T) where T: Copy; struct Bleh(T, U) where T: Copy, U: Sized; diff --git a/tests/ui/issues/issue-18110.rs b/tests/ui/issues/issue-18110.rs index 8ab9be1953124..6d563a5bae1c9 100644 --- a/tests/ui/issues/issue-18110.rs +++ b/tests/ui/issues/issue-18110.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unreachable_code)] -//@ pretty-expanded FIXME #23616 fn main() { ({return},); diff --git a/tests/ui/issues/issue-18188.rs b/tests/ui/issues/issue-18188.rs index b99e6aea6bd75..b3b008229a53a 100644 --- a/tests/ui/issues/issue-18188.rs +++ b/tests/ui/issues/issue-18188.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 pub trait Promisable: Send + Sync {} impl Promisable for T {} diff --git a/tests/ui/issues/issue-18232.rs b/tests/ui/issues/issue-18232.rs index 5ace22311928f..d526a67950cf6 100644 --- a/tests/ui/issues/issue-18232.rs +++ b/tests/ui/issues/issue-18232.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 struct Cursor<'a>(::std::marker::PhantomData<&'a ()>); diff --git a/tests/ui/issues/issue-18353.rs b/tests/ui/issues/issue-18353.rs index a9c0b3bcdbd5e..378caa9f36976 100644 --- a/tests/ui/issues/issue-18353.rs +++ b/tests/ui/issues/issue-18353.rs @@ -3,7 +3,6 @@ // Test that wrapping an unsized struct in an enum which gets optimised does // not ICE. -//@ pretty-expanded FIXME #23616 struct Str { f: [u8] diff --git a/tests/ui/issues/issue-18501.rs b/tests/ui/issues/issue-18501.rs index 559428d4d08dc..54e53e434c465 100644 --- a/tests/ui/issues/issue-18501.rs +++ b/tests/ui/issues/issue-18501.rs @@ -4,7 +4,6 @@ // translating the def ID of the trait during AST decoding. //@ aux-build:issue-18501.rs -//@ pretty-expanded FIXME #23616 extern crate issue_18501 as issue; diff --git a/tests/ui/issues/issue-18539.rs b/tests/ui/issues/issue-18539.rs index eaf8294aa478a..66f0dabb73a25 100644 --- a/tests/ui/issues/issue-18539.rs +++ b/tests/ui/issues/issue-18539.rs @@ -2,7 +2,6 @@ // Test that coercing bare fn's that return a zero sized type to // a closure doesn't cause an LLVM ERROR -//@ pretty-expanded FIXME #23616 struct Foo; diff --git a/tests/ui/issues/issue-18685.rs b/tests/ui/issues/issue-18685.rs index cea60e6f4f254..3dab341f615c7 100644 --- a/tests/ui/issues/issue-18685.rs +++ b/tests/ui/issues/issue-18685.rs @@ -2,7 +2,6 @@ // Test that the self param space is not used in a conflicting // manner by unboxed closures within a default method on a trait -//@ pretty-expanded FIXME #23616 trait Tr { fn foo(&self); diff --git a/tests/ui/issues/issue-18711.rs b/tests/ui/issues/issue-18711.rs index c62f83004ae51..1d5e3349a6d42 100644 --- a/tests/ui/issues/issue-18711.rs +++ b/tests/ui/issues/issue-18711.rs @@ -2,7 +2,6 @@ // Test that we don't panic on a RefCell borrow conflict in certain // code paths involving unboxed closures. -//@ pretty-expanded FIXME #23616 //@ aux-build:issue-18711.rs extern crate issue_18711 as issue; diff --git a/tests/ui/issues/issue-18906.rs b/tests/ui/issues/issue-18906.rs index 95ad8073955e9..84b0f5a178825 100644 --- a/tests/ui/issues/issue-18906.rs +++ b/tests/ui/issues/issue-18906.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub trait Borrow { fn borrow(&self) -> &Borrowed; diff --git a/tests/ui/issues/issue-19037.rs b/tests/ui/issues/issue-19037.rs index 961ef69a3b96d..7f88a89a65702 100644 --- a/tests/ui/issues/issue-19037.rs +++ b/tests/ui/issues/issue-19037.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct Str([u8]); diff --git a/tests/ui/issues/issue-19127.rs b/tests/ui/issues/issue-19127.rs index dd0526592e48f..2172c631b841d 100644 --- a/tests/ui/issues/issue-19127.rs +++ b/tests/ui/issues/issue-19127.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 fn foo T>(f: F) {} fn id<'a>(input: &'a u8) -> &'a u8 { input } diff --git a/tests/ui/issues/issue-19293.rs b/tests/ui/issues/issue-19293.rs index 7a971a59c3d84..42effe303d036 100644 --- a/tests/ui/issues/issue-19293.rs +++ b/tests/ui/issues/issue-19293.rs @@ -1,6 +1,5 @@ //@ run-pass //@ aux-build:issue-19293.rs -//@ pretty-expanded FIXME #23616 extern crate issue_19293; use issue_19293::{Foo, MyEnum}; diff --git a/tests/ui/issues/issue-19398.rs b/tests/ui/issues/issue-19398.rs index 751fffb174487..473e43650c2c5 100644 --- a/tests/ui/issues/issue-19398.rs +++ b/tests/ui/issues/issue-19398.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait T { unsafe extern "Rust" fn foo(&self); diff --git a/tests/ui/issues/issue-19479.rs b/tests/ui/issues/issue-19479.rs index 2818be310be05..ed586b7655028 100644 --- a/tests/ui/issues/issue-19479.rs +++ b/tests/ui/issues/issue-19479.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait Base { fn dummy(&self) { } diff --git a/tests/ui/issues/issue-19499.rs b/tests/ui/issues/issue-19499.rs index 0bd70865211a2..d2a6862e05c4f 100644 --- a/tests/ui/issues/issue-19499.rs +++ b/tests/ui/issues/issue-19499.rs @@ -7,7 +7,6 @@ // reasonable examples) let to ambiguity errors about not being able // to infer sufficient type information. -//@ pretty-expanded FIXME #23616 fn main() { let n = 0; diff --git a/tests/ui/issues/issue-19631.rs b/tests/ui/issues/issue-19631.rs index a20df9c9d4cd1..d13ac216e36ea 100644 --- a/tests/ui/issues/issue-19631.rs +++ b/tests/ui/issues/issue-19631.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 trait PoolManager { type C; diff --git a/tests/ui/issues/issue-19632.rs b/tests/ui/issues/issue-19632.rs index 53e25112ecc42..a99ab5f5ebe1d 100644 --- a/tests/ui/issues/issue-19632.rs +++ b/tests/ui/issues/issue-19632.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 trait PoolManager { type C; diff --git a/tests/ui/issues/issue-19850.rs b/tests/ui/issues/issue-19850.rs index 5e8ba2d4881f2..485b1a763900b 100644 --- a/tests/ui/issues/issue-19850.rs +++ b/tests/ui/issues/issue-19850.rs @@ -3,7 +3,6 @@ // Test that `::Output` and `Self::Output` are accepted as type annotations in let // bindings -//@ pretty-expanded FIXME #23616 trait Int { fn one() -> Self; diff --git a/tests/ui/issues/issue-20009.rs b/tests/ui/issues/issue-20009.rs index ed884d1283420..4d091f3a962c6 100644 --- a/tests/ui/issues/issue-20009.rs +++ b/tests/ui/issues/issue-20009.rs @@ -1,7 +1,6 @@ //@ check-pass // Check that associated types are `Sized` -//@ pretty-expanded FIXME #23616 trait Trait { type Output; diff --git a/tests/ui/issues/issue-20313-rpass.rs b/tests/ui/issues/issue-20313-rpass.rs index 66ba97b1074f0..a9cd0cbd88ed4 100644 --- a/tests/ui/issues/issue-20313-rpass.rs +++ b/tests/ui/issues/issue-20313-rpass.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #![feature(link_llvm_intrinsics)] extern "C" { diff --git a/tests/ui/issues/issue-20389.rs b/tests/ui/issues/issue-20389.rs index 7d3b49ee25f4c..e201663afc522 100644 --- a/tests/ui/issues/issue-20389.rs +++ b/tests/ui/issues/issue-20389.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] //@ aux-build:issue-20389.rs -//@ pretty-expanded FIXME #23616 extern crate issue_20389; diff --git a/tests/ui/issues/issue-20396.rs b/tests/ui/issues/issue-20396.rs index 46a06bb8e3c71..4a7b57903b5ae 100644 --- a/tests/ui/issues/issue-20396.rs +++ b/tests/ui/issues/issue-20396.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/issues/issue-20414.rs b/tests/ui/issues/issue-20414.rs index ea086c2fbebb8..070e0f451a57b 100644 --- a/tests/ui/issues/issue-20414.rs +++ b/tests/ui/issues/issue-20414.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 trait Trait { fn method(self) -> isize; diff --git a/tests/ui/issues/issue-20575.rs b/tests/ui/issues/issue-20575.rs index f8ff8b7d23d9b..b213b79d37cab 100644 --- a/tests/ui/issues/issue-20575.rs +++ b/tests/ui/issues/issue-20575.rs @@ -1,7 +1,6 @@ //@ run-pass // Test that overloaded calls work with zero arity closures -//@ pretty-expanded FIXME #23616 fn main() { let functions: [Box Option<()>>; 1] = [Box::new(|| None)]; diff --git a/tests/ui/issues/issue-20644.rs b/tests/ui/issues/issue-20644.rs index f71e1a5ba8f9a..5f7e4054f7765 100644 --- a/tests/ui/issues/issue-20644.rs +++ b/tests/ui/issues/issue-20644.rs @@ -6,7 +6,6 @@ // A reduced version of the rustbook ice. The problem this encountered // had to do with codegen ignoring binders. -//@ pretty-expanded FIXME #23616 #![feature(os)] diff --git a/tests/ui/issues/issue-2074.rs b/tests/ui/issues/issue-2074.rs index ebf0de4348cac..b6e3fb1fa23aa 100644 --- a/tests/ui/issues/issue-2074.rs +++ b/tests/ui/issues/issue-2074.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(non_camel_case_types)] diff --git a/tests/ui/issues/issue-21033.rs b/tests/ui/issues/issue-21033.rs index 4ddc7a1db5800..e6b13eb3f4b01 100644 --- a/tests/ui/issues/issue-21033.rs +++ b/tests/ui/issues/issue-21033.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_mut)] #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 #![feature(box_patterns)] diff --git a/tests/ui/issues/issue-21245.rs b/tests/ui/issues/issue-21245.rs index f25ebf718b16b..b7c694763c6c2 100644 --- a/tests/ui/issues/issue-21245.rs +++ b/tests/ui/issues/issue-21245.rs @@ -5,7 +5,6 @@ // insufficient type propagation caused the type of the iterator to be // incorrectly unified with the `*const` type to which it is coerced. -//@ pretty-expanded FIXME #23616 use std::ptr; diff --git a/tests/ui/issues/issue-21402.rs b/tests/ui/issues/issue-21402.rs index 28d1e1a0d7739..fa0ece3ec3b18 100644 --- a/tests/ui/issues/issue-21402.rs +++ b/tests/ui/issues/issue-21402.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #[derive(Hash)] struct Foo { diff --git a/tests/ui/issues/issue-2170-exe.rs b/tests/ui/issues/issue-2170-exe.rs index 9e3586afbbc97..b66843d48cad6 100644 --- a/tests/ui/issues/issue-2170-exe.rs +++ b/tests/ui/issues/issue-2170-exe.rs @@ -1,6 +1,5 @@ //@ run-pass //@ aux-build:issue-2170-lib.rs -//@ pretty-expanded FIXME #23616 extern crate issue_2170_lib; diff --git a/tests/ui/issues/issue-21891.rs b/tests/ui/issues/issue-21891.rs index 1feb0daa2d175..0da6071cdac4b 100644 --- a/tests/ui/issues/issue-21891.rs +++ b/tests/ui/issues/issue-21891.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_upper_case_globals)] -//@ pretty-expanded FIXME #23616 static foo: [usize; 3] = [1, 2, 3]; diff --git a/tests/ui/issues/issue-2190-1.rs b/tests/ui/issues/issue-2190-1.rs index 5b2890c89fbcf..8db4a84aac860 100644 --- a/tests/ui/issues/issue-2190-1.rs +++ b/tests/ui/issues/issue-2190-1.rs @@ -2,7 +2,6 @@ #![allow(unused_must_use)] #![allow(non_upper_case_globals)] -//@ pretty-expanded FIXME #23616 //@ ignore-emscripten no threads use std::thread::Builder; diff --git a/tests/ui/issues/issue-21909.rs b/tests/ui/issues/issue-21909.rs index bbf654cb2088e..ffc75f1f08cdd 100644 --- a/tests/ui/issues/issue-21909.rs +++ b/tests/ui/issues/issue-21909.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait A { fn dummy(&self, arg: X); diff --git a/tests/ui/issues/issue-22346.rs b/tests/ui/issues/issue-22346.rs index 42280a7ddb630..710dc0acda7e9 100644 --- a/tests/ui/issues/issue-22346.rs +++ b/tests/ui/issues/issue-22346.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 // This used to cause an ICE because the retslot for the "return" had the wrong type fn testcase<'a>() -> Box + 'a> { diff --git a/tests/ui/issues/issue-22356.rs b/tests/ui/issues/issue-22356.rs index 6b0024ee0ee6f..b7c5c2a59327e 100644 --- a/tests/ui/issues/issue-22356.rs +++ b/tests/ui/issues/issue-22356.rs @@ -1,7 +1,6 @@ //@ check-pass #![allow(type_alias_bounds)] -//@ pretty-expanded FIXME #23616 use std::marker::PhantomData; diff --git a/tests/ui/issues/issue-22426.rs b/tests/ui/issues/issue-22426.rs index d5254528a1283..0857ac9dfb4d1 100644 --- a/tests/ui/issues/issue-22426.rs +++ b/tests/ui/issues/issue-22426.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn main() { match 42 { diff --git a/tests/ui/issues/issue-22577.rs b/tests/ui/issues/issue-22577.rs index 09857c95e1ba6..0fa284cc7c0c2 100644 --- a/tests/ui/issues/issue-22577.rs +++ b/tests/ui/issues/issue-22577.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 use std::{fs, net}; diff --git a/tests/ui/issues/issue-22629.rs b/tests/ui/issues/issue-22629.rs index 0a75d3dd15203..22da414650f85 100644 --- a/tests/ui/issues/issue-22629.rs +++ b/tests/ui/issues/issue-22629.rs @@ -3,7 +3,6 @@ // Test transitive analysis for associated types. Collected types // should be normalized and new obligations generated. -//@ pretty-expanded FIXME #23616 use std::borrow::{ToOwned, Cow}; diff --git a/tests/ui/issues/issue-22777.rs b/tests/ui/issues/issue-22777.rs index 56b385a16919c..c95bb9cc3bb99 100644 --- a/tests/ui/issues/issue-22777.rs +++ b/tests/ui/issues/issue-22777.rs @@ -3,7 +3,6 @@ // can successfully deal with a "deep" structure, which the drop-check // was hitting a recursion limit on at one point. -//@ pretty-expanded FIXME #23616 #![allow(non_camel_case_types)] diff --git a/tests/ui/issues/issue-2284.rs b/tests/ui/issues/issue-2284.rs index 281dce913ad20..358331ecd9a4c 100644 --- a/tests/ui/issues/issue-2284.rs +++ b/tests/ui/issues/issue-2284.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 trait Send { fn f(&self); diff --git a/tests/ui/issues/issue-23024.rs b/tests/ui/issues/issue-23024.rs index 25220dc3e611c..1b072dd7b69c0 100644 --- a/tests/ui/issues/issue-23024.rs +++ b/tests/ui/issues/issue-23024.rs @@ -8,5 +8,4 @@ fn main() println!("{:?}",(vfnfer[0] as dyn Fn)(3)); //~^ ERROR the precise format of `Fn`-family traits' //~| ERROR missing generics for trait `Fn` - //~| ERROR the value of the associated type `Output` in `FnOnce` } diff --git a/tests/ui/issues/issue-23024.stderr b/tests/ui/issues/issue-23024.stderr index 62278a51be635..51db0414f3a39 100644 --- a/tests/ui/issues/issue-23024.stderr +++ b/tests/ui/issues/issue-23024.stderr @@ -19,13 +19,7 @@ help: add missing generic argument LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); | ++++++ -error[E0191]: the value of the associated type `Output` in `FnOnce` must be specified - --> $DIR/issue-23024.rs:8:39 - | -LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); - | ^^ help: specify the associated type: `Fn::` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0107, E0191, E0658. +Some errors have detailed explanations: E0107, E0658. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/issues/issue-2311.rs b/tests/ui/issues/issue-2311.rs index dc2fb394f83ca..5388e634c096f 100644 --- a/tests/ui/issues/issue-2311.rs +++ b/tests/ui/issues/issue-2311.rs @@ -1,7 +1,6 @@ //@ check-pass #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 trait clam { fn get(self) -> A; } trait foo { diff --git a/tests/ui/issues/issue-2316-c.rs b/tests/ui/issues/issue-2316-c.rs index 52e2995ec5871..f800d4723ffd2 100644 --- a/tests/ui/issues/issue-2316-c.rs +++ b/tests/ui/issues/issue-2316-c.rs @@ -2,7 +2,6 @@ //@ aux-build:issue-2316-a.rs //@ aux-build:issue-2316-b.rs -//@ pretty-expanded FIXME #23616 extern crate issue_2316_b; use issue_2316_b::cloth; diff --git a/tests/ui/issues/issue-2380-b.rs b/tests/ui/issues/issue-2380-b.rs index 722b463de09f6..503698f88c620 100644 --- a/tests/ui/issues/issue-2380-b.rs +++ b/tests/ui/issues/issue-2380-b.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-2380.rs -//@ pretty-expanded FIXME #23616 extern crate a; diff --git a/tests/ui/issues/issue-2383.rs b/tests/ui/issues/issue-2383.rs index eecbaa2562e89..5d60018ae673b 100644 --- a/tests/ui/issues/issue-2383.rs +++ b/tests/ui/issues/issue-2383.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use std::collections::VecDeque; diff --git a/tests/ui/issues/issue-2414-c.rs b/tests/ui/issues/issue-2414-c.rs index 1437a4199dc22..ac75c5c51051c 100644 --- a/tests/ui/issues/issue-2414-c.rs +++ b/tests/ui/issues/issue-2414-c.rs @@ -2,7 +2,6 @@ //@ aux-build:issue-2414-a.rs //@ aux-build:issue-2414-b.rs -//@ pretty-expanded FIXME #23616 extern crate b; diff --git a/tests/ui/issues/issue-2445-b.rs b/tests/ui/issues/issue-2445-b.rs index 8f52c0f47a594..3a54c62a771b3 100644 --- a/tests/ui/issues/issue-2445-b.rs +++ b/tests/ui/issues/issue-2445-b.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 struct c1 { x: T, diff --git a/tests/ui/issues/issue-2445.rs b/tests/ui/issues/issue-2445.rs index da82a489c1e57..e6c33a8fd0160 100644 --- a/tests/ui/issues/issue-2445.rs +++ b/tests/ui/issues/issue-2445.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 struct c1 { x: T, diff --git a/tests/ui/issues/issue-2463.rs b/tests/ui/issues/issue-2463.rs index 7650da845e34d..8fff9763bd9e2 100644 --- a/tests/ui/issues/issue-2463.rs +++ b/tests/ui/issues/issue-2463.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct Pair { f: isize, g: isize } diff --git a/tests/ui/issues/issue-2472.rs b/tests/ui/issues/issue-2472.rs index afebc7b16e5cb..f8f539ed1d19d 100644 --- a/tests/ui/issues/issue-2472.rs +++ b/tests/ui/issues/issue-2472.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-2472-b.rs -//@ pretty-expanded FIXME #23616 extern crate issue_2472_b; diff --git a/tests/ui/issues/issue-2487-a.rs b/tests/ui/issues/issue-2487-a.rs index 6cdb9f2afe25a..d38616929faeb 100644 --- a/tests/ui/issues/issue-2487-a.rs +++ b/tests/ui/issues/issue-2487-a.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 struct socket { sock: isize, diff --git a/tests/ui/issues/issue-2502.rs b/tests/ui/issues/issue-2502.rs index d857099e7b9c4..dfc0995104ea6 100644 --- a/tests/ui/issues/issue-2502.rs +++ b/tests/ui/issues/issue-2502.rs @@ -3,7 +3,6 @@ #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 struct font<'a> { fontbuf: &'a Vec , diff --git a/tests/ui/issues/issue-2526-a.rs b/tests/ui/issues/issue-2526-a.rs index 62e687f7f3faa..379146d02b3de 100644 --- a/tests/ui/issues/issue-2526-a.rs +++ b/tests/ui/issues/issue-2526-a.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-2526.rs -//@ pretty-expanded FIXME #23616 #![allow(unused_imports)] diff --git a/tests/ui/issues/issue-2550.rs b/tests/ui/issues/issue-2550.rs index 4fc5ba1f7b284..450db9be627e0 100644 --- a/tests/ui/issues/issue-2550.rs +++ b/tests/ui/issues/issue-2550.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_snake_case)] -//@ pretty-expanded FIXME #23616 struct C { x: usize, diff --git a/tests/ui/issues/issue-25901.rs b/tests/ui/issues/issue-25901.rs index 85e12463a903d..eae038c71a0ea 100644 --- a/tests/ui/issues/issue-25901.rs +++ b/tests/ui/issues/issue-25901.rs @@ -2,7 +2,7 @@ struct A; struct B; static S: &'static B = &A; -//~^ ERROR cannot perform deref coercion +//~^ ERROR cannot call conditionally-const method use std::ops::Deref; diff --git a/tests/ui/issues/issue-25901.stderr b/tests/ui/issues/issue-25901.stderr index bcbc805908ffd..655a8b78c6a1e 100644 --- a/tests/ui/issues/issue-25901.stderr +++ b/tests/ui/issues/issue-25901.stderr @@ -1,23 +1,13 @@ -error[E0015]: cannot perform deref coercion on `A` in statics +error[E0658]: cannot call conditionally-const method `::deref` in statics --> $DIR/issue-25901.rs:4:24 | LL | static S: &'static B = &A; | ^^ | - = note: attempting to deref into `B` -note: deref defined here - --> $DIR/issue-25901.rs:10:5 - | -LL | type Target = B; - | ^^^^^^^^^^^ -note: impl defined here, but it is not `const` - --> $DIR/issue-25901.rs:9:1 - | -LL | impl Deref for A { - | ^^^^^^^^^^^^^^^^ - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` + = note: see issue #67792 for more information + = help: add `#![feature(const_trait_impl)]` 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 E0015`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/issues/issue-2642.rs b/tests/ui/issues/issue-2642.rs index d7d97b847999e..ad5721495090f 100644 --- a/tests/ui/issues/issue-2642.rs +++ b/tests/ui/issues/issue-2642.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn f() { let _x: usize = loop { loop { break; } }; diff --git a/tests/ui/issues/issue-2708.rs b/tests/ui/issues/issue-2708.rs index 68ac4bc343c3f..09d19f87aa647 100644 --- a/tests/ui/issues/issue-2708.rs +++ b/tests/ui/issues/issue-2708.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_snake_case)] -//@ pretty-expanded FIXME #23616 diff --git a/tests/ui/issues/issue-3012-2.rs b/tests/ui/issues/issue-3012-2.rs index 913f92fa8e204..fd090d5e7b50e 100644 --- a/tests/ui/issues/issue-3012-2.rs +++ b/tests/ui/issues/issue-3012-2.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-3012-1.rs -//@ pretty-expanded FIXME #23616 extern crate socketlib; diff --git a/tests/ui/issues/issue-3026.rs b/tests/ui/issues/issue-3026.rs index 9d1c0f5a34122..05dc46c3cc096 100644 --- a/tests/ui/issues/issue-3026.rs +++ b/tests/ui/issues/issue-3026.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use std::collections::HashMap; diff --git a/tests/ui/issues/issue-3037.rs b/tests/ui/issues/issue-3037.rs index 166f4b91cbc39..933b450ac8ea7 100644 --- a/tests/ui/issues/issue-3037.rs +++ b/tests/ui/issues/issue-3037.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #![allow(non_camel_case_types)] enum what { } diff --git a/tests/ui/issues/issue-3052.rs b/tests/ui/issues/issue-3052.rs index 4aa785e797f34..ab3519fe7147b 100644 --- a/tests/ui/issues/issue-3052.rs +++ b/tests/ui/issues/issue-3052.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 type Connection = Box) + 'static>; diff --git a/tests/ui/issues/issue-3136-b.rs b/tests/ui/issues/issue-3136-b.rs index 2995c96ebb911..bd6ea732643f1 100644 --- a/tests/ui/issues/issue-3136-b.rs +++ b/tests/ui/issues/issue-3136-b.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-3136-a.rs -//@ pretty-expanded FIXME #23616 extern crate issue_3136_a; diff --git a/tests/ui/issues/issue-3149.rs b/tests/ui/issues/issue-3149.rs index b0abd5996b1e9..76744213d51da 100644 --- a/tests/ui/issues/issue-3149.rs +++ b/tests/ui/issues/issue-3149.rs @@ -1,7 +1,6 @@ //@ check-pass #![allow(dead_code)] #![allow(non_snake_case)] -//@ pretty-expanded FIXME #23616 fn Matrix4(m11: T, m12: T, m13: T, m14: T, m21: T, m22: T, m23: T, m24: T, diff --git a/tests/ui/issues/issue-3220.rs b/tests/ui/issues/issue-3220.rs index 62a979b47c7f8..2f5ca82b2fac3 100644 --- a/tests/ui/issues/issue-3220.rs +++ b/tests/ui/issues/issue-3220.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 struct thing { x: isize, } diff --git a/tests/ui/issues/issue-3429.rs b/tests/ui/issues/issue-3429.rs index 38ea7df1aa030..39d657573db76 100644 --- a/tests/ui/issues/issue-3429.rs +++ b/tests/ui/issues/issue-3429.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { let x = 1_usize; diff --git a/tests/ui/issues/issue-34373.rs b/tests/ui/issues/issue-34373.rs index dc20c5589b33f..707aa8cf33833 100644 --- a/tests/ui/issues/issue-34373.rs +++ b/tests/ui/issues/issue-34373.rs @@ -6,7 +6,6 @@ trait Trait { pub struct Foo>>; //~ ERROR cycle detected //~^ ERROR `T` is never used -//~| ERROR `Trait` cannot be made into an object type DefaultFoo = Foo; fn main() { diff --git a/tests/ui/issues/issue-34373.stderr b/tests/ui/issues/issue-34373.stderr index 4e8e7c61fee89..0636555821730 100644 --- a/tests/ui/issues/issue-34373.stderr +++ b/tests/ui/issues/issue-34373.stderr @@ -5,7 +5,7 @@ LL | pub struct Foo>>; | ^^^^^^^^^^ | note: ...which requires expanding type alias `DefaultFoo`... - --> $DIR/issue-34373.rs:10:19 + --> $DIR/issue-34373.rs:9:19 | LL | type DefaultFoo = Foo; | ^^^ @@ -17,28 +17,6 @@ LL | pub struct Foo>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/issue-34373.rs:7:24 - | -LL | pub struct Foo>>; - | ^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/issue-34373.rs:4:8 - | -LL | trait Trait { - | ----- this trait cannot be made into an object... -LL | fn foo(_: T) {} - | ^^^ ...because associated function `foo` has no `self` parameter -help: consider turning `foo` into a method by giving it a `&self` argument - | -LL | fn foo(&self, _: T) {} - | ++++++ -help: alternatively, consider constraining `foo` so it does not apply to trait objects - | -LL | fn foo(_: T) where Self: Sized {} - | +++++++++++++++++ - error[E0392]: type parameter `T` is never used --> $DIR/issue-34373.rs:7:16 | @@ -48,7 +26,7 @@ LL | pub struct Foo>>; = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0038, E0391, E0392. -For more information about an error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0391, E0392. +For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/issues/issue-3500.rs b/tests/ui/issues/issue-3500.rs index 038707ef1ecc7..0860d0f592600 100644 --- a/tests/ui/issues/issue-3500.rs +++ b/tests/ui/issues/issue-3500.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { let x = &Some(1); diff --git a/tests/ui/issues/issue-3656.rs b/tests/ui/issues/issue-3656.rs index 975695e497f5b..15ad3232555bb 100644 --- a/tests/ui/issues/issue-3656.rs +++ b/tests/ui/issues/issue-3656.rs @@ -5,7 +5,6 @@ // Incorrect struct size computation in the FFI, because of not taking // the alignment of elements into account. -//@ pretty-expanded FIXME #23616 use std::ffi::{c_uint, c_void}; diff --git a/tests/ui/issues/issue-3874.rs b/tests/ui/issues/issue-3874.rs index 737f2c69e1edc..251e8e1da6d34 100644 --- a/tests/ui/issues/issue-3874.rs +++ b/tests/ui/issues/issue-3874.rs @@ -1,6 +1,5 @@ //@ build-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 enum PureCounter { PureCounterVariant(usize) } diff --git a/tests/ui/issues/issue-3888-2.rs b/tests/ui/issues/issue-3888-2.rs index c06d20961c2a5..39b7126f06926 100644 --- a/tests/ui/issues/issue-3888-2.rs +++ b/tests/ui/issues/issue-3888-2.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn vec_peek<'r, T>(v: &'r [T]) -> &'r [T] { &v[1..5] diff --git a/tests/ui/issues/issue-39211.rs b/tests/ui/issues/issue-39211.rs index 6f3834d51a1ad..ab86afc34102b 100644 --- a/tests/ui/issues/issue-39211.rs +++ b/tests/ui/issues/issue-39211.rs @@ -8,6 +8,7 @@ trait Mat { fn m() { let a = [3; M::Row::DIM]; //~^ ERROR constant expression depends on a generic parameter + //~| ERROR constant expression depends on a generic parameter } fn main() { } diff --git a/tests/ui/issues/issue-39211.stderr b/tests/ui/issues/issue-39211.stderr index 15c9a80bb3526..2124bc667ff5f 100644 --- a/tests/ui/issues/issue-39211.stderr +++ b/tests/ui/issues/issue-39211.stderr @@ -6,5 +6,13 @@ LL | let a = [3; M::Row::DIM]; | = note: this may fail depending on what value the parameter takes -error: aborting due to 1 previous error +error: constant expression depends on a generic parameter + --> $DIR/issue-39211.rs:9:13 + | +LL | let a = [3; M::Row::DIM]; + | ^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-3979-2.rs b/tests/ui/issues/issue-3979-2.rs index 620090bc3ecd4..98b6e85225db5 100644 --- a/tests/ui/issues/issue-3979-2.rs +++ b/tests/ui/issues/issue-3979-2.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait A { fn a_method(&self); diff --git a/tests/ui/issues/issue-3991.rs b/tests/ui/issues/issue-3991.rs index 97bddb9250a06..e69c693ed49ea 100644 --- a/tests/ui/issues/issue-3991.rs +++ b/tests/ui/issues/issue-3991.rs @@ -1,7 +1,6 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct HasNested { nest: Vec > , diff --git a/tests/ui/issues/issue-4208.rs b/tests/ui/issues/issue-4208.rs index 1691bec980b26..84938bea022d1 100644 --- a/tests/ui/issues/issue-4208.rs +++ b/tests/ui/issues/issue-4208.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] //@ aux-build:issue-4208-cc.rs -//@ pretty-expanded FIXME #23616 extern crate numeric; use numeric::{sin, Angle}; diff --git a/tests/ui/issues/issue-4228.rs b/tests/ui/issues/issue-4228.rs index 8ae8a84dac972..362d5925c7085 100644 --- a/tests/ui/issues/issue-4228.rs +++ b/tests/ui/issues/issue-4228.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 struct Foo; diff --git a/tests/ui/issues/issue-4333.rs b/tests/ui/issues/issue-4333.rs index 9b45e1665beac..dccaa6f68bd03 100644 --- a/tests/ui/issues/issue-4333.rs +++ b/tests/ui/issues/issue-4333.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_must_use)] -//@ pretty-expanded FIXME #23616 use std::io; diff --git a/tests/ui/issues/issue-4387.rs b/tests/ui/issues/issue-4387.rs index 1299c4fcc3a8d..10f607aacbd2d 100644 --- a/tests/ui/issues/issue-4387.rs +++ b/tests/ui/issues/issue-4387.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { let _foo = [0; 2*4]; diff --git a/tests/ui/issues/issue-4464.rs b/tests/ui/issues/issue-4464.rs index a2d6ed718c298..7b3df9af223e5 100644 --- a/tests/ui/issues/issue-4464.rs +++ b/tests/ui/issues/issue-4464.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn broken(v: &[u8], i: usize, j: usize) -> &[u8] { &v[i..j] } diff --git a/tests/ui/issues/issue-4542.rs b/tests/ui/issues/issue-4542.rs index bd63246fa33a3..15fd31d92d297 100644 --- a/tests/ui/issues/issue-4542.rs +++ b/tests/ui/issues/issue-4542.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use std::env; diff --git a/tests/ui/issues/issue-4545.rs b/tests/ui/issues/issue-4545.rs index 6a2f04e4511a0..dfb89136cbd22 100644 --- a/tests/ui/issues/issue-4545.rs +++ b/tests/ui/issues/issue-4545.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-4545.rs -//@ pretty-expanded FIXME #23616 extern crate issue_4545 as somelib; pub fn main() { somelib::mk::(); } diff --git a/tests/ui/issues/issue-4735.rs b/tests/ui/issues/issue-4735.rs index 1223e15b2d9e8..1ca145bae420d 100644 --- a/tests/ui/issues/issue-4735.rs +++ b/tests/ui/issues/issue-4735.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use std::mem::transmute; diff --git a/tests/ui/issues/issue-4759.rs b/tests/ui/issues/issue-4759.rs index 49fe5f9275948..4b49442b4010f 100644 --- a/tests/ui/issues/issue-4759.rs +++ b/tests/ui/issues/issue-4759.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(non_shorthand_field_patterns)] struct T { a: Box } diff --git a/tests/ui/issues/issue-4830.rs b/tests/ui/issues/issue-4830.rs index 364def61da846..d48c13fd10b1d 100644 --- a/tests/ui/issues/issue-4830.rs +++ b/tests/ui/issues/issue-4830.rs @@ -1,7 +1,6 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub struct Scheduler { /// The event loop used to drive the scheduler and perform I/O diff --git a/tests/ui/issues/issue-4875.rs b/tests/ui/issues/issue-4875.rs index 3b09331873cce..5068399ff0db7 100644 --- a/tests/ui/issues/issue-4875.rs +++ b/tests/ui/issues/issue-4875.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] // regression test for issue 4875 -//@ pretty-expanded FIXME #23616 pub struct Foo { data: T, diff --git a/tests/ui/issues/issue-5192.rs b/tests/ui/issues/issue-5192.rs index 8911e7a733b14..be5d70f09b3c0 100644 --- a/tests/ui/issues/issue-5192.rs +++ b/tests/ui/issues/issue-5192.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub trait EventLoop { fn dummy(&self) { } diff --git a/tests/ui/issues/issue-5315.rs b/tests/ui/issues/issue-5315.rs index 64a48b9e84234..29a6f8f2934a1 100644 --- a/tests/ui/issues/issue-5315.rs +++ b/tests/ui/issues/issue-5315.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 struct A(#[allow(dead_code)] bool); diff --git a/tests/ui/issues/issue-5518.rs b/tests/ui/issues/issue-5518.rs index 4e1049f02fbc3..333185c482fe4 100644 --- a/tests/ui/issues/issue-5518.rs +++ b/tests/ui/issues/issue-5518.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-5518.rs -//@ pretty-expanded FIXME #23616 extern crate issue_5518 as other; diff --git a/tests/ui/issues/issue-5550.rs b/tests/ui/issues/issue-5550.rs index e967590c65057..41de8ee5d32c9 100644 --- a/tests/ui/issues/issue-5550.rs +++ b/tests/ui/issues/issue-5550.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_assignments)] -//@ pretty-expanded FIXME #23616 pub fn main() { let s: String = "foobar".to_string(); diff --git a/tests/ui/issues/issue-5554.rs b/tests/ui/issues/issue-5554.rs index 532d1b4092e70..7d219a0df7093 100644 --- a/tests/ui/issues/issue-5554.rs +++ b/tests/ui/issues/issue-5554.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub struct X { diff --git a/tests/ui/issues/issue-55587.stderr b/tests/ui/issues/issue-55587.stderr index eec6426a29950..7a5d0e281007f 100644 --- a/tests/ui/issues/issue-55587.stderr +++ b/tests/ui/issues/issue-55587.stderr @@ -4,7 +4,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated function LL | let Path::new(); | ^^^^^^^^^^^ `fn` calls are not allowed in patterns | - = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html + = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-5572.rs b/tests/ui/issues/issue-5572.rs index 8a4c867f58514..f27744ef0ac7a 100644 --- a/tests/ui/issues/issue-5572.rs +++ b/tests/ui/issues/issue-5572.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn foo(_t: T) { } diff --git a/tests/ui/issues/issue-5718.rs b/tests/ui/issues/issue-5718.rs index c30061298d179..234fb2e222278 100644 --- a/tests/ui/issues/issue-5718.rs +++ b/tests/ui/issues/issue-5718.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 struct Element; diff --git a/tests/ui/issues/issue-5741.rs b/tests/ui/issues/issue-5741.rs index dad16dd39e235..af4702ec22ca9 100644 --- a/tests/ui/issues/issue-5741.rs +++ b/tests/ui/issues/issue-5741.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(while_true)] #![allow(unreachable_code)] diff --git a/tests/ui/issues/issue-5754.rs b/tests/ui/issues/issue-5754.rs index 2b61da02c3045..0aa0988295948 100644 --- a/tests/ui/issues/issue-5754.rs +++ b/tests/ui/issues/issue-5754.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(improper_ctypes)] -//@ pretty-expanded FIXME #23616 struct TwoDoubles { r: f64, diff --git a/tests/ui/issues/issue-5884.rs b/tests/ui/issues/issue-5884.rs index 17cb4133632ab..559b897395d02 100644 --- a/tests/ui/issues/issue-5884.rs +++ b/tests/ui/issues/issue-5884.rs @@ -1,6 +1,5 @@ //@ build-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub struct Foo { a: isize, diff --git a/tests/ui/issues/issue-5900.rs b/tests/ui/issues/issue-5900.rs index 986a8233ef2aa..14b7b8f815a01 100644 --- a/tests/ui/issues/issue-5900.rs +++ b/tests/ui/issues/issue-5900.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub mod foo { use super::Bar; diff --git a/tests/ui/issues/issue-5950.rs b/tests/ui/issues/issue-5950.rs index a0822459ad148..6015560fcf8a9 100644 --- a/tests/ui/issues/issue-5950.rs +++ b/tests/ui/issues/issue-5950.rs @@ -1,6 +1,5 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 pub use local as local_alias; diff --git a/tests/ui/issues/issue-5988.rs b/tests/ui/issues/issue-5988.rs index 801a5edca08f3..b7527d9bea803 100644 --- a/tests/ui/issues/issue-5988.rs +++ b/tests/ui/issues/issue-5988.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 trait B { fn f(&self); diff --git a/tests/ui/issues/issue-6117.rs b/tests/ui/issues/issue-6117.rs index 4fa99d955c935..3ccf67b031991 100644 --- a/tests/ui/issues/issue-6117.rs +++ b/tests/ui/issues/issue-6117.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 enum Either { Left(T), Right(U) } diff --git a/tests/ui/issues/issue-6318.rs b/tests/ui/issues/issue-6318.rs index 3b17754ffdc36..d3f08285a93b3 100644 --- a/tests/ui/issues/issue-6318.rs +++ b/tests/ui/issues/issue-6318.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub enum Thing { A(Box) diff --git a/tests/ui/issues/issue-6557.rs b/tests/ui/issues/issue-6557.rs index 89ebb0610dd37..64a025a294f68 100644 --- a/tests/ui/issues/issue-6557.rs +++ b/tests/ui/issues/issue-6557.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #![feature(box_patterns)] diff --git a/tests/ui/issues/issue-6898.rs b/tests/ui/issues/issue-6898.rs index cc0fe35fc8839..c810acaf61baa 100644 --- a/tests/ui/issues/issue-6898.rs +++ b/tests/ui/issues/issue-6898.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 use std::mem; diff --git a/tests/ui/issues/issue-6919.rs b/tests/ui/issues/issue-6919.rs index 3aa66882c1920..7fb8a2f33bc9c 100644 --- a/tests/ui/issues/issue-6919.rs +++ b/tests/ui/issues/issue-6919.rs @@ -2,7 +2,6 @@ #![allow(unused_attributes)] //@ aux-build:iss.rs -//@ pretty-expanded FIXME #23616 extern crate issue6919_3; diff --git a/tests/ui/issues/issue-7178.rs b/tests/ui/issues/issue-7178.rs index 153ce2cf05711..408ce0b03eb82 100644 --- a/tests/ui/issues/issue-7178.rs +++ b/tests/ui/issues/issue-7178.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-7178.rs -//@ pretty-expanded FIXME #23616 extern crate issue_7178 as cross_crate_self; diff --git a/tests/ui/issues/issue-7268.rs b/tests/ui/issues/issue-7268.rs index 99b780bcf5c49..a3bc1bc344626 100644 --- a/tests/ui/issues/issue-7268.rs +++ b/tests/ui/issues/issue-7268.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn foo(_: T) {} diff --git a/tests/ui/issues/issue-7344.rs b/tests/ui/issues/issue-7344.rs index 9503037723e5b..406b24634f55e 100644 --- a/tests/ui/issues/issue-7344.rs +++ b/tests/ui/issues/issue-7344.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_must_use)] -//@ pretty-expanded FIXME #23616 #![allow(unreachable_code)] diff --git a/tests/ui/issues/issue-7519-match-unit-in-arg.rs b/tests/ui/issues/issue-7519-match-unit-in-arg.rs index 2b5f1b7f16959..a7cea577b2248 100644 --- a/tests/ui/issues/issue-7519-match-unit-in-arg.rs +++ b/tests/ui/issues/issue-7519-match-unit-in-arg.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 /* #7519 ICE pattern matching unit in function argument diff --git a/tests/ui/issues/issue-7660.rs b/tests/ui/issues/issue-7660.rs index 4b0f7d84b75e5..104cdad8f7bb7 100644 --- a/tests/ui/issues/issue-7660.rs +++ b/tests/ui/issues/issue-7660.rs @@ -3,7 +3,6 @@ // Regression test for issue 7660 // rvalue lifetime too short when equivalent `match` works -//@ pretty-expanded FIXME #23616 use std::collections::HashMap; diff --git a/tests/ui/issues/issue-7673-cast-generically-implemented-trait.rs b/tests/ui/issues/issue-7673-cast-generically-implemented-trait.rs index 742152b6c8162..edba3284e3175 100644 --- a/tests/ui/issues/issue-7673-cast-generically-implemented-trait.rs +++ b/tests/ui/issues/issue-7673-cast-generically-implemented-trait.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 /* diff --git a/tests/ui/issues/issue-7899.rs b/tests/ui/issues/issue-7899.rs index a2aee240da7a3..4b69f3e3d89aa 100644 --- a/tests/ui/issues/issue-7899.rs +++ b/tests/ui/issues/issue-7899.rs @@ -2,7 +2,6 @@ #![allow(unused_variables)] //@ aux-build:issue-7899.rs -//@ pretty-expanded FIXME #23616 extern crate issue_7899 as testcrate; diff --git a/tests/ui/issues/issue-8044.rs b/tests/ui/issues/issue-8044.rs index b965e0bbb1077..3c10bbca6342b 100644 --- a/tests/ui/issues/issue-8044.rs +++ b/tests/ui/issues/issue-8044.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-8044.rs -//@ pretty-expanded FIXME #23616 extern crate issue_8044 as minimal; use minimal::{BTree, leaf}; diff --git a/tests/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs b/tests/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs index 88d56185f6bda..6a03404cdca71 100644 --- a/tests/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs +++ b/tests/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 /* diff --git a/tests/ui/issues/issue-8248.rs b/tests/ui/issues/issue-8248.rs index c34575df368c9..95f626658cc67 100644 --- a/tests/ui/issues/issue-8248.rs +++ b/tests/ui/issues/issue-8248.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 trait A { fn dummy(&self) { } //~ WARN method `dummy` is never used diff --git a/tests/ui/issues/issue-8248.stderr b/tests/ui/issues/issue-8248.stderr index a0098bcb771ae..8570bfaefadbe 100644 --- a/tests/ui/issues/issue-8248.stderr +++ b/tests/ui/issues/issue-8248.stderr @@ -1,5 +1,5 @@ warning: method `dummy` is never used - --> $DIR/issue-8248.rs:5:8 + --> $DIR/issue-8248.rs:4:8 | LL | trait A { | - method in this trait diff --git a/tests/ui/issues/issue-8249.rs b/tests/ui/issues/issue-8249.rs index 67a42619316cc..2364fc14d31ac 100644 --- a/tests/ui/issues/issue-8249.rs +++ b/tests/ui/issues/issue-8249.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 trait A { fn dummy(&self) { } diff --git a/tests/ui/issues/issue-8259.rs b/tests/ui/issues/issue-8259.rs index f790e1a2155df..e843f7f9c5083 100644 --- a/tests/ui/issues/issue-8259.rs +++ b/tests/ui/issues/issue-8259.rs @@ -4,7 +4,6 @@ //@ aux-build:issue-8259.rs -//@ pretty-expanded FIXME #23616 extern crate issue_8259 as other; static a: other::Foo<'static> = other::Foo::A; diff --git a/tests/ui/issues/issue-8398.rs b/tests/ui/issues/issue-8398.rs index 6f91b1dbb28ae..7d100b855fd1a 100644 --- a/tests/ui/issues/issue-8398.rs +++ b/tests/ui/issues/issue-8398.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub trait Writer { fn write(&mut self, b: &[u8]) -> Result<(), ()>; diff --git a/tests/ui/issues/issue-8401.rs b/tests/ui/issues/issue-8401.rs index b72616bb28f24..1df63516fb0be 100644 --- a/tests/ui/issues/issue-8401.rs +++ b/tests/ui/issues/issue-8401.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-8401.rs -//@ pretty-expanded FIXME #23616 extern crate issue_8401; diff --git a/tests/ui/issues/issue-8506.rs b/tests/ui/issues/issue-8506.rs index 48abd7efc7b91..30a789a3e27bf 100644 --- a/tests/ui/issues/issue-8506.rs +++ b/tests/ui/issues/issue-8506.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(non_upper_case_globals)] #![allow(dead_code)] diff --git a/tests/ui/issues/issue-8578.rs b/tests/ui/issues/issue-8578.rs index e081d7a541521..9baa2f70a02db 100644 --- a/tests/ui/issues/issue-8578.rs +++ b/tests/ui/issues/issue-8578.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] #![allow(non_upper_case_globals)] -//@ pretty-expanded FIXME #23616 pub struct UninterpretedOption_NamePart { name_part: Option, diff --git a/tests/ui/issues/issue-8783.rs b/tests/ui/issues/issue-8783.rs index a7c96b69b1893..d0ff79f8ac800 100644 --- a/tests/ui/issues/issue-8783.rs +++ b/tests/ui/issues/issue-8783.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 struct X { pub x: usize } impl Default for X { diff --git a/tests/ui/issues/issue-9110.rs b/tests/ui/issues/issue-9110.rs index 9aeda7d5b1b90..47533dc43b594 100644 --- a/tests/ui/issues/issue-9110.rs +++ b/tests/ui/issues/issue-9110.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #![allow(non_snake_case)] macro_rules! silly_macro { diff --git a/tests/ui/issues/issue-9123.rs b/tests/ui/issues/issue-9123.rs index e554a8c8ff29f..bbf6c13341c27 100644 --- a/tests/ui/issues/issue-9123.rs +++ b/tests/ui/issues/issue-9123.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-9123.rs -//@ pretty-expanded FIXME #23616 extern crate issue_9123; diff --git a/tests/ui/issues/issue-9155.rs b/tests/ui/issues/issue-9155.rs index e177c5978005c..dfd9dea20090a 100644 --- a/tests/ui/issues/issue-9155.rs +++ b/tests/ui/issues/issue-9155.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-9155.rs -//@ pretty-expanded FIXME #23616 extern crate issue_9155; diff --git a/tests/ui/issues/issue-9249.rs b/tests/ui/issues/issue-9249.rs index 893d01637de30..b98ba050521aa 100644 --- a/tests/ui/issues/issue-9249.rs +++ b/tests/ui/issues/issue-9249.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 static DATA:&'static [&'static str] = &["my string"]; fn main() { } diff --git a/tests/ui/issues/issue-9382.rs b/tests/ui/issues/issue-9382.rs index 4b37e5b381f53..27f9ab577437f 100644 --- a/tests/ui/issues/issue-9382.rs +++ b/tests/ui/issues/issue-9382.rs @@ -1,6 +1,3 @@ -//@ pretty-expanded FIXME #23616 - - //@ run-pass #![allow(dead_code)] diff --git a/tests/ui/issues/issue-9719.rs b/tests/ui/issues/issue-9719.rs index e48c020328a8a..904768c934144 100644 --- a/tests/ui/issues/issue-9719.rs +++ b/tests/ui/issues/issue-9719.rs @@ -1,6 +1,5 @@ //@ build-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 mod a { pub enum Enum { diff --git a/tests/ui/issues/issue-9906.rs b/tests/ui/issues/issue-9906.rs index b425df4975f1c..50417d3e45613 100644 --- a/tests/ui/issues/issue-9906.rs +++ b/tests/ui/issues/issue-9906.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-9906.rs -//@ pretty-expanded FIXME #23616 extern crate issue_9906 as testmod; diff --git a/tests/ui/issues/issue-9942.rs b/tests/ui/issues/issue-9942.rs index 76c9090330669..6332d9b3e080a 100644 --- a/tests/ui/issues/issue-9942.rs +++ b/tests/ui/issues/issue-9942.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { const S: usize = 23 as usize; [0; S]; () diff --git a/tests/ui/issues/issue-9951.rs b/tests/ui/issues/issue-9951.rs index 42a65c701f76c..2cd7cd4f4302b 100644 --- a/tests/ui/issues/issue-9951.rs +++ b/tests/ui/issues/issue-9951.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(unused_variables)] diff --git a/tests/ui/issues/issue-9951.stderr b/tests/ui/issues/issue-9951.stderr index 475f2817914d3..62ed9f3e0cc07 100644 --- a/tests/ui/issues/issue-9951.stderr +++ b/tests/ui/issues/issue-9951.stderr @@ -1,5 +1,5 @@ warning: method `noop` is never used - --> $DIR/issue-9951.rs:7:6 + --> $DIR/issue-9951.rs:6:6 | LL | trait Bar { | --- method in this trait diff --git a/tests/ui/issues/issue-9968.rs b/tests/ui/issues/issue-9968.rs index 5ceea056634a1..89e60ba5ac7fe 100644 --- a/tests/ui/issues/issue-9968.rs +++ b/tests/ui/issues/issue-9968.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-9968.rs -//@ pretty-expanded FIXME #23616 extern crate issue_9968 as lib; diff --git a/tests/ui/item-name-overload.rs b/tests/ui/item-name-overload.rs index 54aa470e59ea1..dd2925aa53fe4 100644 --- a/tests/ui/item-name-overload.rs +++ b/tests/ui/item-name-overload.rs @@ -4,7 +4,6 @@ -//@ pretty-expanded FIXME #23616 mod foo { pub fn baz() { } diff --git a/tests/ui/iterators/into-iter-on-boxed-slices-2024.rs b/tests/ui/iterators/into-iter-on-boxed-slices-2024.rs index ffd6f022bc6de..6e9b38be0801b 100644 --- a/tests/ui/iterators/into-iter-on-boxed-slices-2024.rs +++ b/tests/ui/iterators/into-iter-on-boxed-slices-2024.rs @@ -1,6 +1,5 @@ //@ check-pass //@ edition:2024 -//@ compile-flags: -Zunstable-options use std::ops::Deref; use std::rc::Rc; diff --git a/tests/ui/iterators/into-iterator-type-inference-shift.rs b/tests/ui/iterators/into-iterator-type-inference-shift.rs index b550dc27f5c60..6b07a6bcb0a7a 100644 --- a/tests/ui/iterators/into-iterator-type-inference-shift.rs +++ b/tests/ui/iterators/into-iterator-type-inference-shift.rs @@ -8,7 +8,6 @@ // propagation yet, and so we just saw a type variable, yielding an // error. -//@ pretty-expanded FIXME #23616 trait IntoIterator { type Iter: Iterator; diff --git a/tests/ui/kinds-in-metadata.rs b/tests/ui/kinds-in-metadata.rs index d557f949c763c..58dffba861d57 100644 --- a/tests/ui/kinds-in-metadata.rs +++ b/tests/ui/kinds-in-metadata.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:kinds_in_metadata.rs -//@ pretty-expanded FIXME #23616 /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ diff --git a/tests/ui/layout/aggregate-lang/struct-align.rs b/tests/ui/layout/aggregate-lang/struct-align.rs new file mode 100644 index 0000000000000..f3b88a6d85d3e --- /dev/null +++ b/tests/ui/layout/aggregate-lang/struct-align.rs @@ -0,0 +1,29 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-size-align +//@ edition: 2018 + +#[repr(align(64))] +#[derive(Copy, Clone)] +#[allow(dead_code)] +pub struct Overaligned(u8); + +#[allow(dead_code)] +struct ReprRustStruct { + x: i32, + y: [u32; 4], + z: f32, + a: u128, + b: Overaligned, +} + +fn test_alignment_contains_all_fields() { + assert!(core::mem::align_of::() >= core::mem::align_of::()); + assert!(core::mem::align_of::() >= core::mem::align_of::<[u32; 4]>()); + assert!(core::mem::align_of::() >= core::mem::align_of::()); + assert!(core::mem::align_of::() >= core::mem::align_of::()); + assert!(core::mem::align_of::() >= core::mem::align_of::()); +} + +fn main() { + test_alignment_contains_all_fields(); +} diff --git a/tests/ui/layout/aggregate-lang/struct-offsets.rs b/tests/ui/layout/aggregate-lang/struct-offsets.rs new file mode 100644 index 0000000000000..ca199bdfeb104 --- /dev/null +++ b/tests/ui/layout/aggregate-lang/struct-offsets.rs @@ -0,0 +1,78 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-offsets +//@ edition: 2018 + +#[repr(align(64))] +#[derive(Copy, Clone)] +#[allow(dead_code)] +pub struct Overaligned(u8); + +#[allow(dead_code)] +struct ReprRustStruct { + x: i32, + y: [u32; 4], + z: f32, + a: u128, + b: Overaligned, +} + +macro_rules! span_of { + ($ty:ty , $field:tt) => {{ + let __field = unsafe { ::core::mem::zeroed::<$ty>() }; + + ( + core::mem::offset_of!($ty, $field), + core::mem::offset_of!($ty, $field) + core::mem::size_of_val(&__field.$field), + ) + }}; +} + +fn test_fields_make_sense(a: &(usize, usize)) { + assert!(a.0 <= a.1); +} + +// order is `begin, end` +fn test_non_overlapping(a: &(usize, usize), b: &(usize, usize)) { + assert!((a.1 <= b.0) || (b.1 <= a.0)); +} + +fn test_fields_non_overlapping() { + let fields = [ + span_of!(ReprRustStruct, x), + span_of!(ReprRustStruct, y), + span_of!(ReprRustStruct, z), + span_of!(ReprRustStruct, a), + span_of!(ReprRustStruct, b), + ]; + + test_fields_make_sense(&fields[0]); + test_fields_make_sense(&fields[1]); + test_fields_make_sense(&fields[2]); + test_fields_make_sense(&fields[3]); + test_fields_make_sense(&fields[4]); + + test_non_overlapping(&fields[0], &fields[1]); + test_non_overlapping(&fields[0], &fields[2]); + test_non_overlapping(&fields[0], &fields[3]); + test_non_overlapping(&fields[0], &fields[4]); + test_non_overlapping(&fields[1], &fields[2]); + test_non_overlapping(&fields[2], &fields[3]); + test_non_overlapping(&fields[2], &fields[4]); + test_non_overlapping(&fields[3], &fields[4]); +} + +fn test_fields_aligned() { + assert_eq!((core::mem::offset_of!(ReprRustStruct, x) % (core::mem::align_of::())), 0); + assert_eq!((core::mem::offset_of!(ReprRustStruct, y) % (core::mem::align_of::<[u32; 4]>())), 0); + assert_eq!((core::mem::offset_of!(ReprRustStruct, z) % (core::mem::align_of::())), 0); + assert_eq!((core::mem::offset_of!(ReprRustStruct, a) % (core::mem::align_of::())), 0); + assert_eq!( + (core::mem::offset_of!(ReprRustStruct, b) % (core::mem::align_of::())), + 0 + ); +} + +fn main() { + test_fields_non_overlapping(); + test_fields_aligned(); +} diff --git a/tests/ui/layout/aggregate-lang/struct-size.rs b/tests/ui/layout/aggregate-lang/struct-size.rs new file mode 100644 index 0000000000000..f9fb605c32486 --- /dev/null +++ b/tests/ui/layout/aggregate-lang/struct-size.rs @@ -0,0 +1,50 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-size-align +//@ edition: 2018 + +#[allow(dead_code)] +struct ReprRustStruct { + x: i32, + y: [u32; 4], + z: f32, + a: u128, +} + +fn test_size_contains_all_types() { + assert!( + core::mem::size_of::() + >= (core::mem::size_of::() + + core::mem::size_of::<[u32; 4]>() + + core::mem::size_of::() + + core::mem::size_of::()) + ); +} + +fn test_size_contains_all_fields() { + assert!( + (core::mem::offset_of!(ReprRustStruct, x) + core::mem::size_of::()) + <= core::mem::size_of::() + ); + assert!( + (core::mem::offset_of!(ReprRustStruct, y) + core::mem::size_of::<[u32; 4]>()) + <= core::mem::size_of::() + ); + assert!( + (core::mem::offset_of!(ReprRustStruct, z) + core::mem::size_of::()) + <= core::mem::size_of::() + ); + assert!( + (core::mem::offset_of!(ReprRustStruct, a) + core::mem::size_of::()) + <= core::mem::size_of::() + ); +} + +fn test_size_modulo_align() { + assert_eq!(core::mem::size_of::() % core::mem::align_of::(), 0); +} + +fn main() { + test_size_contains_all_fields(); + test_size_contains_all_types(); + test_size_modulo_align(); +} diff --git a/tests/ui/layout/aggregate-lang/union-align.rs b/tests/ui/layout/aggregate-lang/union-align.rs new file mode 100644 index 0000000000000..03825f1df2137 --- /dev/null +++ b/tests/ui/layout/aggregate-lang/union-align.rs @@ -0,0 +1,29 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-size-align +//@ edition: 2018 + +#[repr(align(64))] +#[derive(Copy, Clone)] +#[allow(dead_code)] +pub struct Overaligned(u8); + +#[allow(dead_code)] +union ReprRustUnion { + x: i32, + y: [u32; 4], + z: f32, + a: u128, + b: Overaligned, +} + +fn test_alignment_contains_all_fields() { + assert!(core::mem::align_of::() >= core::mem::align_of::()); + assert!(core::mem::align_of::() >= core::mem::align_of::<[u32; 4]>()); + assert!(core::mem::align_of::() >= core::mem::align_of::()); + assert!(core::mem::align_of::() >= core::mem::align_of::()); + assert!(core::mem::align_of::() >= core::mem::align_of::()); +} + +fn main() { + test_alignment_contains_all_fields(); +} diff --git a/tests/ui/layout/aggregate-lang/union-offsets.rs b/tests/ui/layout/aggregate-lang/union-offsets.rs new file mode 100644 index 0000000000000..29ab0a9ce5490 --- /dev/null +++ b/tests/ui/layout/aggregate-lang/union-offsets.rs @@ -0,0 +1,32 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-offsets +//@ edition: 2018 + +#[repr(align(64))] +#[derive(Copy, Clone)] +#[allow(dead_code)] +pub struct Overaligned(u8); + +#[allow(dead_code)] +union ReprRustUnion { + x: i32, + y: [u32; 4], + z: f32, + a: u128, + b: Overaligned, +} + +fn test_fields_aligned() { + assert_eq!((core::mem::offset_of!(ReprRustUnion, x) % (core::mem::align_of::())), 0); + assert_eq!((core::mem::offset_of!(ReprRustUnion, y) % (core::mem::align_of::<[u32; 4]>())), 0); + assert_eq!((core::mem::offset_of!(ReprRustUnion, z) % (core::mem::align_of::())), 0); + assert_eq!((core::mem::offset_of!(ReprRustUnion, a) % (core::mem::align_of::())), 0); + assert_eq!( + (core::mem::offset_of!(ReprRustUnion, b) % (core::mem::align_of::())), + 0 + ); +} + +fn main() { + test_fields_aligned(); +} diff --git a/tests/ui/layout/aggregate-lang/union-size.rs b/tests/ui/layout/aggregate-lang/union-size.rs new file mode 100644 index 0000000000000..6d1b51b172db1 --- /dev/null +++ b/tests/ui/layout/aggregate-lang/union-size.rs @@ -0,0 +1,47 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-size-align +//@ edition: 2018 + +#[allow(dead_code)] +union ReprRustUnion { + x: i32, + y: [u32; 4], + z: f32, + a: u128, +} + +fn test_size_contains_each_type() { + assert!(core::mem::size_of::() <= core::mem::size_of::()); + assert!(core::mem::size_of::<[u32; 4]>() <= core::mem::size_of::()); + assert!(core::mem::size_of::() <= core::mem::size_of::()); + assert!(core::mem::size_of::() <= core::mem::size_of::()); +} + +fn test_size_contains_all_fields() { + assert!( + (core::mem::offset_of!(ReprRustUnion, x) + core::mem::size_of::()) + <= core::mem::size_of::() + ); + assert!( + (core::mem::offset_of!(ReprRustUnion, y) + core::mem::size_of::<[u32; 4]>()) + <= core::mem::size_of::() + ); + assert!( + (core::mem::offset_of!(ReprRustUnion, z) + core::mem::size_of::()) + <= core::mem::size_of::() + ); + assert!( + (core::mem::offset_of!(ReprRustUnion, a) + core::mem::size_of::()) + <= core::mem::size_of::() + ); +} + +fn test_size_modulo_align() { + assert_eq!(core::mem::size_of::() % core::mem::align_of::(), 0); +} + +fn main() { + test_size_contains_each_type(); + test_size_contains_all_fields(); + test_size_modulo_align(); +} diff --git a/tests/ui/layout/ice-type-error-in-tail-124031.rs b/tests/ui/layout/ice-type-error-in-tail-124031.rs index 0a2be11740358..ecd6f3d56f3f4 100644 --- a/tests/ui/layout/ice-type-error-in-tail-124031.rs +++ b/tests/ui/layout/ice-type-error-in-tail-124031.rs @@ -1,3 +1,5 @@ +//@ normalize-stderr-test: "\d+ bits" -> "$$BITS bits" + // Regression test for issue #124031 // Checks that we don't ICE when the tail // of an ADT has a type error @@ -16,5 +18,6 @@ struct Other { fn main() { unsafe { std::mem::transmute::, Option<&Other>>(None); + //~^ ERROR cannot transmute between types of different sizes } } diff --git a/tests/ui/layout/ice-type-error-in-tail-124031.stderr b/tests/ui/layout/ice-type-error-in-tail-124031.stderr index 57dc83f92dfda..a066e8574dc50 100644 --- a/tests/ui/layout/ice-type-error-in-tail-124031.stderr +++ b/tests/ui/layout/ice-type-error-in-tail-124031.stderr @@ -1,5 +1,5 @@ error[E0046]: not all trait items implemented, missing: `RefTarget` - --> $DIR/ice-type-error-in-tail-124031.rs:9:1 + --> $DIR/ice-type-error-in-tail-124031.rs:11:1 | LL | type RefTarget; | -------------- `RefTarget` from trait @@ -7,6 +7,16 @@ LL | type RefTarget; LL | impl Trait for () {} | ^^^^^^^^^^^^^^^^^ missing `RefTarget` in implementation -error: aborting due to 1 previous error +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/ice-type-error-in-tail-124031.rs:20:9 + | +LL | std::mem::transmute::, Option<&Other>>(None); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `Option<()>` ($BITS bits) + = note: target type: `Option<&Other>` ($BITS bits) + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0046`. +Some errors have detailed explanations: E0046, E0512. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs b/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs new file mode 100644 index 0000000000000..6ded9118700c0 --- /dev/null +++ b/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs @@ -0,0 +1,18 @@ +// regression test for #127351 + +#![feature(lazy_type_alias)] +//~^ WARN the feature `lazy_type_alias` is incomplete + +type ExplicitTypeOutlives = T; + +pub struct Warns { + _significant_drop: ExplicitTypeOutlives, + //~^ ERROR missing generics for type alias `ExplicitTypeOutlives` + field: String, +} + +pub fn test(w: Warns) { + let _ = || drop(w.field); +} + +fn main() {} diff --git a/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr b/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr new file mode 100644 index 0000000000000..3a5ded60241b1 --- /dev/null +++ b/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr @@ -0,0 +1,28 @@ +warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/bad-lazy-type-alias.rs:3:12 + | +LL | #![feature(lazy_type_alias)] + | ^^^^^^^^^^^^^^^ + | + = note: see issue #112792 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0107]: missing generics for type alias `ExplicitTypeOutlives` + --> $DIR/bad-lazy-type-alias.rs:9:24 + | +LL | _significant_drop: ExplicitTypeOutlives, + | ^^^^^^^^^^^^^^^^^^^^ expected 1 generic argument + | +note: type alias defined here, with 1 generic parameter: `T` + --> $DIR/bad-lazy-type-alias.rs:6:6 + | +LL | type ExplicitTypeOutlives = T; + | ^^^^^^^^^^^^^^^^^^^^ - +help: add missing generic argument + | +LL | _significant_drop: ExplicitTypeOutlives, + | +++ + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/let-else/uninitialized-refutable-let-issue-123844.stderr b/tests/ui/let-else/uninitialized-refutable-let-issue-123844.stderr index 13312306c07b7..58f9e267db372 100644 --- a/tests/ui/let-else/uninitialized-refutable-let-issue-123844.stderr +++ b/tests/ui/let-else/uninitialized-refutable-let-issue-123844.stderr @@ -5,7 +5,7 @@ LL | let Some(x); | ^^^^^^^ pattern `None` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Option` error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/auxiliary/issue-91763-aux.rs b/tests/ui/lifetimes/auxiliary/issue-91763-aux.rs index 35ef6fc019dd6..4e4b7f61f1ef4 100644 --- a/tests/ui/lifetimes/auxiliary/issue-91763-aux.rs +++ b/tests/ui/lifetimes/auxiliary/issue-91763-aux.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - //#![feature(proc_macro_diagnostic, proc_macro_span, proc_macro_def_site)] extern crate proc_macro; diff --git a/tests/ui/lifetimes/issue-91763.rs b/tests/ui/lifetimes/issue-91763.rs index 5df69cff3be7d..6abb64db5feba 100644 --- a/tests/ui/lifetimes/issue-91763.rs +++ b/tests/ui/lifetimes/issue-91763.rs @@ -1,4 +1,4 @@ -//@ aux-build:issue-91763-aux.rs +//@ proc-macro: issue-91763-aux.rs #![deny(elided_lifetimes_in_paths)] diff --git a/tests/ui/lifetimes/raw/gen-lt.e2024.stderr b/tests/ui/lifetimes/raw/gen-lt.e2024.stderr index 232453df8ef65..0f184853ecef3 100644 --- a/tests/ui/lifetimes/raw/gen-lt.e2024.stderr +++ b/tests/ui/lifetimes/raw/gen-lt.e2024.stderr @@ -1,5 +1,5 @@ error: lifetimes cannot use keyword names - --> $DIR/gen-lt.rs:11:11 + --> $DIR/gen-lt.rs:10:11 | LL | fn gen_lt<'gen>() {} | ^^^^ diff --git a/tests/ui/lifetimes/raw/gen-lt.rs b/tests/ui/lifetimes/raw/gen-lt.rs index 4f3ede5b4a2eb..3c33dc285f07a 100644 --- a/tests/ui/lifetimes/raw/gen-lt.rs +++ b/tests/ui/lifetimes/raw/gen-lt.rs @@ -2,7 +2,6 @@ //@[e2021] edition:2021 //@[e2024] edition:2024 -//@[e2024] compile-flags: -Zunstable-options //@[e2021] check-pass diff --git a/tests/ui/lifetimes/refcell-in-tail-expr.edition2021.stderr b/tests/ui/lifetimes/refcell-in-tail-expr.edition2021.stderr index 157a1c5e09b07..6d7000a1370e4 100644 --- a/tests/ui/lifetimes/refcell-in-tail-expr.edition2021.stderr +++ b/tests/ui/lifetimes/refcell-in-tail-expr.edition2021.stderr @@ -1,5 +1,5 @@ error[E0597]: `cell` does not live long enough - --> $DIR/refcell-in-tail-expr.rs:10:27 + --> $DIR/refcell-in-tail-expr.rs:9:27 | LL | let cell = std::cell::RefCell::new(0u8); | ---- binding `cell` declared here diff --git a/tests/ui/lifetimes/refcell-in-tail-expr.rs b/tests/ui/lifetimes/refcell-in-tail-expr.rs index 595e951f3731b..2cca7acbf5a42 100644 --- a/tests/ui/lifetimes/refcell-in-tail-expr.rs +++ b/tests/ui/lifetimes/refcell-in-tail-expr.rs @@ -1,7 +1,6 @@ //@ revisions: edition2021 edition2024 //@ [edition2021] edition: 2021 //@ [edition2024] edition: 2024 -//@ [edition2024] compile-flags: -Zunstable-options //@ [edition2024] check-pass fn main() { diff --git a/tests/ui/lifetimes/shorter-tail-expr-lifetime.edition2021.stderr b/tests/ui/lifetimes/shorter-tail-expr-lifetime.edition2021.stderr index 3c074c5c3a2cb..ac23c67a8e119 100644 --- a/tests/ui/lifetimes/shorter-tail-expr-lifetime.edition2021.stderr +++ b/tests/ui/lifetimes/shorter-tail-expr-lifetime.edition2021.stderr @@ -1,5 +1,5 @@ error[E0597]: `c` does not live long enough - --> $DIR/shorter-tail-expr-lifetime.rs:8:5 + --> $DIR/shorter-tail-expr-lifetime.rs:7:5 | LL | let c = std::cell::RefCell::new(".."); | - binding `c` declared here diff --git a/tests/ui/lifetimes/shorter-tail-expr-lifetime.rs b/tests/ui/lifetimes/shorter-tail-expr-lifetime.rs index 4195a8b6c32bd..25c530d43919e 100644 --- a/tests/ui/lifetimes/shorter-tail-expr-lifetime.rs +++ b/tests/ui/lifetimes/shorter-tail-expr-lifetime.rs @@ -1,5 +1,4 @@ //@ revisions: edition2021 edition2024 -//@ [edition2024] compile-flags: -Zunstable-options //@ [edition2024] edition: 2024 //@ [edition2024] run-pass diff --git a/tests/ui/lifetimes/tail-expr-in-nested-expr.rs b/tests/ui/lifetimes/tail-expr-in-nested-expr.rs index 2ac97aff2b098..741cdacdb1d5f 100644 --- a/tests/ui/lifetimes/tail-expr-in-nested-expr.rs +++ b/tests/ui/lifetimes/tail-expr-in-nested-expr.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options fn main() { let _ = { String::new().as_str() }.len(); diff --git a/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr b/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr index 96e88eaca9225..6770da091ce8d 100644 --- a/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr +++ b/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/tail-expr-in-nested-expr.rs:5:15 + --> $DIR/tail-expr-in-nested-expr.rs:4:15 | LL | let _ = { String::new().as_str() }.len(); | ^^^^^^^^^^^^^--------- diff --git a/tests/ui/lifetimes/tail-expr-lock-poisoning.rs b/tests/ui/lifetimes/tail-expr-lock-poisoning.rs index ec74596a08da4..6af6655149bd9 100644 --- a/tests/ui/lifetimes/tail-expr-lock-poisoning.rs +++ b/tests/ui/lifetimes/tail-expr-lock-poisoning.rs @@ -1,6 +1,5 @@ //@ revisions: edition2021 edition2024 //@ ignore-wasm no panic or subprocess support -//@ [edition2024] compile-flags: -Zunstable-options //@ [edition2024] edition: 2024 //@ run-pass //@ needs-unwind diff --git a/tests/ui/lifetimes/temporary-lifetime-extension.rs b/tests/ui/lifetimes/temporary-lifetime-extension.rs index d03027cf4a321..86c478af317c9 100644 --- a/tests/ui/lifetimes/temporary-lifetime-extension.rs +++ b/tests/ui/lifetimes/temporary-lifetime-extension.rs @@ -15,7 +15,6 @@ //@ revisions: edition2021 edition2024 //@ [edition2021] edition: 2021 //@ [edition2024] edition: 2024 -//@ [edition2024] compile-flags: -Z unstable-options fn temp() -> (String, i32) { (String::from("Hello"), 1) diff --git a/tests/ui/linkage-attr/issue-12133-1.rs b/tests/ui/linkage-attr/issue-12133-1.rs index dc3f7f33da145..f545db67e9244 100644 --- a/tests/ui/linkage-attr/issue-12133-1.rs +++ b/tests/ui/linkage-attr/issue-12133-1.rs @@ -2,7 +2,6 @@ //@ aux-build:issue-12133-rlib.rs //@ aux-build:issue-12133-dylib.rs -//@ pretty-expanded FIXME #23616 extern crate issue_12133_rlib as a; extern crate issue_12133_dylib as b; diff --git a/tests/ui/linkage-attr/issue-12133-2.rs b/tests/ui/linkage-attr/issue-12133-2.rs index 55742a1b3838d..bc2dd84e0f7b9 100644 --- a/tests/ui/linkage-attr/issue-12133-2.rs +++ b/tests/ui/linkage-attr/issue-12133-2.rs @@ -3,7 +3,6 @@ //@ aux-build:issue-12133-dylib.rs //@ no-prefer-dynamic -//@ pretty-expanded FIXME #23616 extern crate issue_12133_rlib as a; extern crate issue_12133_dylib as b; diff --git a/tests/ui/linkage-attr/issue-12133-3.rs b/tests/ui/linkage-attr/issue-12133-3.rs index a34c075d64dae..473d5774c162f 100644 --- a/tests/ui/linkage-attr/issue-12133-3.rs +++ b/tests/ui/linkage-attr/issue-12133-3.rs @@ -6,7 +6,6 @@ //@ ignore-musl //@ needs-dynamic-linking -//@ pretty-expanded FIXME #23616 extern crate issue_12133_dylib2 as other; diff --git a/tests/ui/lint/auxiliary/add-impl.rs b/tests/ui/lint/auxiliary/add-impl.rs index 7ee4a4e4fde64..d0f2baf94bff4 100644 --- a/tests/ui/lint/auxiliary/add-impl.rs +++ b/tests/ui/lint/auxiliary/add-impl.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/lint/dead-code/leading-underscore.rs b/tests/ui/lint/dead-code/leading-underscore.rs index 0ef123efc2405..0c5fecb27a841 100644 --- a/tests/ui/lint/dead-code/leading-underscore.rs +++ b/tests/ui/lint/dead-code/leading-underscore.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![deny(dead_code)] diff --git a/tests/ui/lint/group-forbid-always-trumps-cli.stderr b/tests/ui/lint/forbid-always-trumps-cli.allow-first-group.stderr similarity index 82% rename from tests/ui/lint/group-forbid-always-trumps-cli.stderr rename to tests/ui/lint/forbid-always-trumps-cli.allow-first-group.stderr index ed1242eacfce7..07773ee4ddfea 100644 --- a/tests/ui/lint/group-forbid-always-trumps-cli.stderr +++ b/tests/ui/lint/forbid-always-trumps-cli.allow-first-group.stderr @@ -1,5 +1,5 @@ error: unused variable: `x` - --> $DIR/group-forbid-always-trumps-cli.rs:4:9 + --> $DIR/forbid-always-trumps-cli.rs:15:9 | LL | let x = 1; | ^ help: if this is intentional, prefix it with an underscore: `_x` diff --git a/tests/ui/lint/forbid-always-trumps-cli.allow-first-lint.stderr b/tests/ui/lint/forbid-always-trumps-cli.allow-first-lint.stderr new file mode 100644 index 0000000000000..cf357ef8ca8f9 --- /dev/null +++ b/tests/ui/lint/forbid-always-trumps-cli.allow-first-lint.stderr @@ -0,0 +1,10 @@ +error: unused variable: `x` + --> $DIR/forbid-always-trumps-cli.rs:15:9 + | +LL | let x = 1; + | ^ help: if this is intentional, prefix it with an underscore: `_x` + | + = note: requested on the command line with `-F unused-variables` + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix1.stderr b/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix1.stderr new file mode 100644 index 0000000000000..07773ee4ddfea --- /dev/null +++ b/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix1.stderr @@ -0,0 +1,10 @@ +error: unused variable: `x` + --> $DIR/forbid-always-trumps-cli.rs:15:9 + | +LL | let x = 1; + | ^ help: if this is intentional, prefix it with an underscore: `_x` + | + = note: `-F unused-variables` implied by `-F unused` + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix2.stderr b/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix2.stderr new file mode 100644 index 0000000000000..cf357ef8ca8f9 --- /dev/null +++ b/tests/ui/lint/forbid-always-trumps-cli.allow-first-mix2.stderr @@ -0,0 +1,10 @@ +error: unused variable: `x` + --> $DIR/forbid-always-trumps-cli.rs:15:9 + | +LL | let x = 1; + | ^ help: if this is intentional, prefix it with an underscore: `_x` + | + = note: requested on the command line with `-F unused-variables` + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/forbid-always-trumps-cli.forbid-first-group.stderr b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-group.stderr new file mode 100644 index 0000000000000..07773ee4ddfea --- /dev/null +++ b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-group.stderr @@ -0,0 +1,10 @@ +error: unused variable: `x` + --> $DIR/forbid-always-trumps-cli.rs:15:9 + | +LL | let x = 1; + | ^ help: if this is intentional, prefix it with an underscore: `_x` + | + = note: `-F unused-variables` implied by `-F unused` + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/forbid-always-trumps-cli.forbid-first-lint.stderr b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-lint.stderr new file mode 100644 index 0000000000000..cf357ef8ca8f9 --- /dev/null +++ b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-lint.stderr @@ -0,0 +1,10 @@ +error: unused variable: `x` + --> $DIR/forbid-always-trumps-cli.rs:15:9 + | +LL | let x = 1; + | ^ help: if this is intentional, prefix it with an underscore: `_x` + | + = note: requested on the command line with `-F unused-variables` + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix1.stderr b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix1.stderr new file mode 100644 index 0000000000000..07773ee4ddfea --- /dev/null +++ b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix1.stderr @@ -0,0 +1,10 @@ +error: unused variable: `x` + --> $DIR/forbid-always-trumps-cli.rs:15:9 + | +LL | let x = 1; + | ^ help: if this is intentional, prefix it with an underscore: `_x` + | + = note: `-F unused-variables` implied by `-F unused` + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix2.stderr b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix2.stderr new file mode 100644 index 0000000000000..cf357ef8ca8f9 --- /dev/null +++ b/tests/ui/lint/forbid-always-trumps-cli.forbid-first-mix2.stderr @@ -0,0 +1,10 @@ +error: unused variable: `x` + --> $DIR/forbid-always-trumps-cli.rs:15:9 + | +LL | let x = 1; + | ^ help: if this is intentional, prefix it with an underscore: `_x` + | + = note: requested on the command line with `-F unused-variables` + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/forbid-always-trumps-cli.rs b/tests/ui/lint/forbid-always-trumps-cli.rs new file mode 100644 index 0000000000000..d94cc2e8efef9 --- /dev/null +++ b/tests/ui/lint/forbid-always-trumps-cli.rs @@ -0,0 +1,17 @@ +//! Ensure that "forbid" always trumps" allow" in CLI arguments, no matter the order +//! and no matter whether it is used with a lint group vs an individual lint. +// ignore-tidy-linelength +//@ revisions: forbid-first-group allow-first-group forbid-first-lint allow-first-lint forbid-first-mix1 allow-first-mix1 forbid-first-mix2 allow-first-mix2 +//@[forbid-first-group] compile-flags: -F unused -A unused +//@[allow-first-group] compile-flags: -A unused -F unused +//@[forbid-first-lint] compile-flags: -F unused_variables -A unused_variables +//@[allow-first-lint] compile-flags: -A unused_variables -F unused_variables +//@[forbid-first-mix1] compile-flags: -F unused -A unused_variables +//@[allow-first-mix1] compile-flags: -A unused_variables -F unused +//@[forbid-first-mix2] compile-flags: -F unused_variables -A unused +//@[allow-first-mix2] compile-flags: -A unused -F unused_variables + +fn main() { + let x = 1; + //~^ ERROR unused variable: `x` +} diff --git a/tests/ui/lint/group-forbid-always-trumps-cli.rs b/tests/ui/lint/group-forbid-always-trumps-cli.rs deleted file mode 100644 index 4b63452bf5d46..0000000000000 --- a/tests/ui/lint/group-forbid-always-trumps-cli.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ compile-flags: -F unused -A unused - -fn main() { - let x = 1; - //~^ ERROR unused variable: `x` -} diff --git a/tests/ui/lint/issue-14837.rs b/tests/ui/lint/issue-14837.rs index 73c63cde2baa8..829df15ae5157 100644 --- a/tests/ui/lint/issue-14837.rs +++ b/tests/ui/lint/issue-14837.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 #[deny(dead_code)] pub enum Foo { diff --git a/tests/ui/lint/issue-1866.rs b/tests/ui/lint/issue-1866.rs index 386aeeb6ad015..4a571fbeb024d 100644 --- a/tests/ui/lint/issue-1866.rs +++ b/tests/ui/lint/issue-1866.rs @@ -3,7 +3,6 @@ #![allow(non_camel_case_types)] #![warn(clashing_extern_declarations)] -//@ pretty-expanded FIXME #23616 mod a { pub type rust_task = usize; diff --git a/tests/ui/lint/issue-1866.stderr b/tests/ui/lint/issue-1866.stderr index d19a134966831..3ea9d2096586f 100644 --- a/tests/ui/lint/issue-1866.stderr +++ b/tests/ui/lint/issue-1866.stderr @@ -1,5 +1,5 @@ warning: `rust_task_is_unwinding` redeclared with a different signature - --> $DIR/issue-1866.rs:23:13 + --> $DIR/issue-1866.rs:22:13 | LL | pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool; | ------------------------------------------------------------ `rust_task_is_unwinding` previously declared here diff --git a/tests/ui/lint/issue-20343.rs b/tests/ui/lint/issue-20343.rs index 24e8062b1f37f..da353c985c9a0 100644 --- a/tests/ui/lint/issue-20343.rs +++ b/tests/ui/lint/issue-20343.rs @@ -2,7 +2,6 @@ #![allow(unused_variables)] // Regression test for Issue #20343. -//@ pretty-expanded FIXME #23616 #![deny(dead_code)] diff --git a/tests/ui/lint/issue-79546-fuel-ice.rs b/tests/ui/lint/issue-79546-fuel-ice.rs deleted file mode 100644 index dbee924d26e70..0000000000000 --- a/tests/ui/lint/issue-79546-fuel-ice.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Regression test for the ICE described in #79546. - -//@ compile-flags: --cap-lints=allow -Zfuel=issue79546=0 -//@ check-pass -#![crate_name="issue79546"] - -struct S; -fn main() {} diff --git a/tests/ui/lint/lint-non-camel-case-with-trailing-underscores.rs b/tests/ui/lint/lint-non-camel-case-with-trailing-underscores.rs index 30091253f4d56..178ee0e6663ed 100644 --- a/tests/ui/lint/lint-non-camel-case-with-trailing-underscores.rs +++ b/tests/ui/lint/lint-non-camel-case-with-trailing-underscores.rs @@ -3,7 +3,6 @@ #![allow(dead_code)] // This is ok because we often use the trailing underscore to mean 'prime' -//@ pretty-expanded FIXME #23616 #[forbid(non_camel_case_types)] type Foo_ = isize; diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-no-lowercase-equivalent.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-no-lowercase-equivalent.rs index a43d2974ff3ff..7622f8b0454db 100644 --- a/tests/ui/lint/non-snake-case/lint-non-snake-case-no-lowercase-equivalent.rs +++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-no-lowercase-equivalent.rs @@ -1,7 +1,6 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #![deny(non_snake_case)] diff --git a/tests/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs b/tests/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs index 2a58af0fedcc5..72303f12b7e49 100644 --- a/tests/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs +++ b/tests/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs @@ -1,6 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic -#![crate_type="proc-macro"] #![crate_name="redundant_semi_proc_macro"] extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs b/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs index 33c7e26ba4725..3469614aab042 100644 --- a/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs +++ b/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs @@ -1,4 +1,4 @@ -//@ aux-build:redundant-semi-proc-macro-def.rs +//@ proc-macro: redundant-semi-proc-macro-def.rs #![deny(redundant_semicolons)] extern crate redundant_semi_proc_macro; diff --git a/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr b/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr index d42aa1d613ffa..1ec440b4e45b2 100644 --- a/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr +++ b/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr @@ -1,4 +1,4 @@ -TokenStream [Ident { ident: "fn", span: #0 bytes(199..201) }, Ident { ident: "span_preservation", span: #0 bytes(202..219) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(219..221) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "let", span: #0 bytes(229..232) }, Ident { ident: "tst", span: #0 bytes(233..236) }, Punct { ch: '=', spacing: Alone, span: #0 bytes(237..238) }, Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(239..242) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(242..243) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(243..244) }, Ident { ident: "match", span: #0 bytes(290..295) }, Ident { ident: "tst", span: #0 bytes(296..299) }, Group { delimiter: Brace, stream: TokenStream [Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(484..487) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(488..489) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(489..490) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(491..493) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(493..494) }, Ident { ident: "_", span: #0 bytes(503..504) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(505..506) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(506..507) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(508..510) }], span: #0 bytes(300..516) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(516..517) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(517..518) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(518..519) }], span: #0 bytes(223..563) }] +TokenStream [Ident { ident: "fn", span: #0 bytes(201..203) }, Ident { ident: "span_preservation", span: #0 bytes(204..221) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(221..223) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "let", span: #0 bytes(231..234) }, Ident { ident: "tst", span: #0 bytes(235..238) }, Punct { ch: '=', spacing: Alone, span: #0 bytes(239..240) }, Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(241..244) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(244..245) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(245..246) }, Ident { ident: "match", span: #0 bytes(292..297) }, Ident { ident: "tst", span: #0 bytes(298..301) }, Group { delimiter: Brace, stream: TokenStream [Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(486..489) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(490..491) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(491..492) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(493..495) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(495..496) }, Ident { ident: "_", span: #0 bytes(505..506) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(507..508) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(508..509) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(510..512) }], span: #0 bytes(302..518) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(518..519) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(519..520) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(520..521) }], span: #0 bytes(225..565) }] error: unnecessary trailing semicolon --> $DIR/redundant-semi-proc-macro.rs:9:19 | diff --git a/tests/ui/lint/static-mut-refs.e2021.stderr b/tests/ui/lint/static-mut-refs.e2021.stderr index 09f560652e7bf..5a4e712b3c0df 100644 --- a/tests/ui/lint/static-mut-refs.e2021.stderr +++ b/tests/ui/lint/static-mut-refs.e2021.stderr @@ -1,5 +1,5 @@ warning: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:39:18 + --> $DIR/static-mut-refs.rs:38:18 | LL | let _y = &X; | ^^ shared reference to mutable static @@ -13,7 +13,7 @@ LL | let _y = &raw const X; | ~~~~~~~~~~ warning: creating a mutable reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:43:18 + --> $DIR/static-mut-refs.rs:42:18 | LL | let _y = &mut X; | ^^^^^^ mutable reference to mutable static @@ -26,7 +26,7 @@ LL | let _y = &raw mut X; | ~~~~~~~~ warning: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:51:22 + --> $DIR/static-mut-refs.rs:50:22 | LL | let ref _a = X; | ^ shared reference to mutable static @@ -35,7 +35,7 @@ LL | let ref _a = X; = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives warning: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:55:25 + --> $DIR/static-mut-refs.rs:54:25 | LL | let (_b, _c) = (&X, &Y); | ^^ shared reference to mutable static @@ -48,7 +48,7 @@ LL | let (_b, _c) = (&raw const X, &Y); | ~~~~~~~~~~ warning: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:55:29 + --> $DIR/static-mut-refs.rs:54:29 | LL | let (_b, _c) = (&X, &Y); | ^^ shared reference to mutable static @@ -61,7 +61,7 @@ LL | let (_b, _c) = (&X, &raw const Y); | ~~~~~~~~~~ warning: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:61:13 + --> $DIR/static-mut-refs.rs:60:13 | LL | foo(&X); | ^^ shared reference to mutable static @@ -74,7 +74,7 @@ LL | foo(&raw const X); | ~~~~~~~~~~ warning: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:67:17 + --> $DIR/static-mut-refs.rs:66:17 | LL | let _ = Z.len(); | ^^^^^^^ shared reference to mutable static @@ -83,7 +83,7 @@ LL | let _ = Z.len(); = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives warning: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:73:33 + --> $DIR/static-mut-refs.rs:72:33 | LL | let _ = format!("{:?}", Z); | ^ shared reference to mutable static @@ -92,7 +92,7 @@ LL | let _ = format!("{:?}", Z); = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives warning: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:77:18 + --> $DIR/static-mut-refs.rs:76:18 | LL | let _v = &A.value; | ^^^^^^^^ shared reference to mutable static @@ -105,7 +105,7 @@ LL | let _v = &raw const A.value; | ~~~~~~~~~~ warning: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:81:18 + --> $DIR/static-mut-refs.rs:80:18 | LL | let _s = &A.s.value; | ^^^^^^^^^^ shared reference to mutable static @@ -118,7 +118,7 @@ LL | let _s = &raw const A.s.value; | ~~~~~~~~~~ warning: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:85:22 + --> $DIR/static-mut-refs.rs:84:22 | LL | let ref _v = A.value; | ^^^^^^^ shared reference to mutable static @@ -127,7 +127,7 @@ LL | let ref _v = A.value; = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives warning: creating a mutable reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:15:14 + --> $DIR/static-mut-refs.rs:14:14 | LL | &mut ($x.0) | ^^^^^^ mutable reference to mutable static diff --git a/tests/ui/lint/static-mut-refs.e2024.stderr b/tests/ui/lint/static-mut-refs.e2024.stderr index 2d2a4f7afe00f..1b549272bd5f5 100644 --- a/tests/ui/lint/static-mut-refs.e2024.stderr +++ b/tests/ui/lint/static-mut-refs.e2024.stderr @@ -1,5 +1,5 @@ error: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:39:18 + --> $DIR/static-mut-refs.rs:38:18 | LL | let _y = &X; | ^^ shared reference to mutable static @@ -13,7 +13,7 @@ LL | let _y = &raw const X; | ~~~~~~~~~~ error: creating a mutable reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:43:18 + --> $DIR/static-mut-refs.rs:42:18 | LL | let _y = &mut X; | ^^^^^^ mutable reference to mutable static @@ -26,7 +26,7 @@ LL | let _y = &raw mut X; | ~~~~~~~~ error: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:51:22 + --> $DIR/static-mut-refs.rs:50:22 | LL | let ref _a = X; | ^ shared reference to mutable static @@ -35,7 +35,7 @@ LL | let ref _a = X; = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives error: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:55:25 + --> $DIR/static-mut-refs.rs:54:25 | LL | let (_b, _c) = (&X, &Y); | ^^ shared reference to mutable static @@ -48,7 +48,7 @@ LL | let (_b, _c) = (&raw const X, &Y); | ~~~~~~~~~~ error: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:55:29 + --> $DIR/static-mut-refs.rs:54:29 | LL | let (_b, _c) = (&X, &Y); | ^^ shared reference to mutable static @@ -61,7 +61,7 @@ LL | let (_b, _c) = (&X, &raw const Y); | ~~~~~~~~~~ error: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:61:13 + --> $DIR/static-mut-refs.rs:60:13 | LL | foo(&X); | ^^ shared reference to mutable static @@ -74,7 +74,7 @@ LL | foo(&raw const X); | ~~~~~~~~~~ error: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:67:17 + --> $DIR/static-mut-refs.rs:66:17 | LL | let _ = Z.len(); | ^^^^^^^ shared reference to mutable static @@ -83,7 +83,7 @@ LL | let _ = Z.len(); = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives error: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:73:33 + --> $DIR/static-mut-refs.rs:72:33 | LL | let _ = format!("{:?}", Z); | ^ shared reference to mutable static @@ -92,7 +92,7 @@ LL | let _ = format!("{:?}", Z); = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives error: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:77:18 + --> $DIR/static-mut-refs.rs:76:18 | LL | let _v = &A.value; | ^^^^^^^^ shared reference to mutable static @@ -105,7 +105,7 @@ LL | let _v = &raw const A.value; | ~~~~~~~~~~ error: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:81:18 + --> $DIR/static-mut-refs.rs:80:18 | LL | let _s = &A.s.value; | ^^^^^^^^^^ shared reference to mutable static @@ -118,7 +118,7 @@ LL | let _s = &raw const A.s.value; | ~~~~~~~~~~ error: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:85:22 + --> $DIR/static-mut-refs.rs:84:22 | LL | let ref _v = A.value; | ^^^^^^^ shared reference to mutable static @@ -127,7 +127,7 @@ LL | let ref _v = A.value; = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives error: creating a mutable reference to mutable static is discouraged - --> $DIR/static-mut-refs.rs:15:14 + --> $DIR/static-mut-refs.rs:14:14 | LL | &mut ($x.0) | ^^^^^^ mutable reference to mutable static diff --git a/tests/ui/lint/static-mut-refs.rs b/tests/ui/lint/static-mut-refs.rs index 3d84d7dbf40de..1040dfcae7a95 100644 --- a/tests/ui/lint/static-mut-refs.rs +++ b/tests/ui/lint/static-mut-refs.rs @@ -6,7 +6,6 @@ //@ [e2021] run-pass //@ [e2024] edition:2024 -//@ [e2024] compile-flags: -Zunstable-options static mut FOO: (u32, u32) = (1, 2); diff --git a/tests/ui/lint/unsafe_code/auxiliary/forge_unsafe_block.rs b/tests/ui/lint/unsafe_code/auxiliary/forge_unsafe_block.rs index 6849e9170c15c..b00f5838749dd 100644 --- a/tests/ui/lint/unsafe_code/auxiliary/forge_unsafe_block.rs +++ b/tests/ui/lint/unsafe_code/auxiliary/forge_unsafe_block.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{Delimiter, Group, Ident, Span, TokenStream, TokenTree}; diff --git a/tests/ui/lint/unsafe_code/forge_unsafe_block.rs b/tests/ui/lint/unsafe_code/forge_unsafe_block.rs index 6392849f91595..93b2b60647d6a 100644 --- a/tests/ui/lint/unsafe_code/forge_unsafe_block.rs +++ b/tests/ui/lint/unsafe_code/forge_unsafe_block.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:forge_unsafe_block.rs +//@ proc-macro: forge_unsafe_block.rs #[macro_use] extern crate forge_unsafe_block; diff --git a/tests/ui/lint/unused-qualification-in-derive-expansion.rs b/tests/ui/lint/unused-qualification-in-derive-expansion.rs index 5cea9086d12d4..b2067e22c4443 100644 --- a/tests/ui/lint/unused-qualification-in-derive-expansion.rs +++ b/tests/ui/lint/unused-qualification-in-derive-expansion.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:add-impl.rs +//@ proc-macro: add-impl.rs #![forbid(unused_qualifications)] diff --git a/tests/ui/lint/warn-ctypes-inhibit.rs b/tests/ui/lint/warn-ctypes-inhibit.rs index e3952dd00492a..0f401150adf64 100644 --- a/tests/ui/lint/warn-ctypes-inhibit.rs +++ b/tests/ui/lint/warn-ctypes-inhibit.rs @@ -3,7 +3,6 @@ #![allow(dead_code)] //@ compile-flags:-D improper-ctypes -//@ pretty-expanded FIXME #23616 #![allow(improper_ctypes)] mod libc { diff --git a/tests/ui/list.rs b/tests/ui/list.rs index 7e5c2d8548b50..443c4c9f28f88 100644 --- a/tests/ui/list.rs +++ b/tests/ui/list.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 enum list { #[allow(dead_code)] cons(isize, Box), nil, } diff --git a/tests/ui/liveness/liveness-assign-imm-local-after-ret.rs b/tests/ui/liveness/liveness-assign-imm-local-after-ret.rs index 298181e5529d9..ebdb5658537d2 100644 --- a/tests/ui/liveness/liveness-assign-imm-local-after-ret.rs +++ b/tests/ui/liveness/liveness-assign-imm-local-after-ret.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unreachable_code)] -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/loops/issue-1974.rs b/tests/ui/loops/issue-1974.rs index ea67b2541de8c..9416f09c6e3dc 100644 --- a/tests/ui/loops/issue-1974.rs +++ b/tests/ui/loops/issue-1974.rs @@ -1,7 +1,6 @@ //@ run-pass // Issue 1974 // Don't double free the condition allocation -//@ pretty-expanded FIXME #23616 pub fn main() { let s = "hej".to_string(); diff --git a/tests/ui/loops/loop-else-break-with-value.stderr b/tests/ui/loops/loop-else-break-with-value.stderr index ca18f0fdd7f32..da3276c8cd358 100644 --- a/tests/ui/loops/loop-else-break-with-value.stderr +++ b/tests/ui/loops/loop-else-break-with-value.stderr @@ -21,7 +21,7 @@ LL | let Some(1) = loop { | ^^^^^^^ pattern `None` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Option` help: you might want to use `if let` to ignore the variant that isn't matched | diff --git a/tests/ui/macros/auxiliary/hello_macro.rs b/tests/ui/macros/auxiliary/hello_macro.rs index 10f474bd1b395..79125a1f86e3a 100644 --- a/tests/ui/macros/auxiliary/hello_macro.rs +++ b/tests/ui/macros/auxiliary/hello_macro.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_quote)] extern crate proc_macro; diff --git a/tests/ui/macros/auxiliary/issue-100199.rs b/tests/ui/macros/auxiliary/issue-100199.rs index 9ee9a2f503942..f05c4f0722cfb 100644 --- a/tests/ui/macros/auxiliary/issue-100199.rs +++ b/tests/ui/macros/auxiliary/issue-100199.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_quote)] extern crate proc_macro; diff --git a/tests/ui/macros/auxiliary/proc_macro_def.rs b/tests/ui/macros/auxiliary/proc_macro_def.rs index 6574bf184fb75..38a1f6fa3c13b 100644 --- a/tests/ui/macros/auxiliary/proc_macro_def.rs +++ b/tests/ui/macros/auxiliary/proc_macro_def.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_quote)] extern crate proc_macro; diff --git a/tests/ui/macros/auxiliary/proc_macro_sequence.rs b/tests/ui/macros/auxiliary/proc_macro_sequence.rs index de2efdfecf147..0f5435401711e 100644 --- a/tests/ui/macros/auxiliary/proc_macro_sequence.rs +++ b/tests/ui/macros/auxiliary/proc_macro_sequence.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_span, proc_macro_quote)] extern crate proc_macro; diff --git a/tests/ui/macros/defined-later-issue-121061-2.stderr b/tests/ui/macros/defined-later-issue-121061-2.stderr index aa6ef33853193..2ec590d46ed2c 100644 --- a/tests/ui/macros/defined-later-issue-121061-2.stderr +++ b/tests/ui/macros/defined-later-issue-121061-2.stderr @@ -4,7 +4,7 @@ error: cannot find macro `something_later` in this scope LL | something_later!(); | ^^^^^^^^^^^^^^^ consider moving the definition of `something_later` before this call | -note: a macro with the same name exists, but it appears later at here +note: a macro with the same name exists, but it appears later --> $DIR/defined-later-issue-121061-2.rs:6:18 | LL | macro_rules! something_later { diff --git a/tests/ui/macros/defined-later-issue-121061.stderr b/tests/ui/macros/defined-later-issue-121061.stderr index 65cb53432a932..7b3496991afec 100644 --- a/tests/ui/macros/defined-later-issue-121061.stderr +++ b/tests/ui/macros/defined-later-issue-121061.stderr @@ -4,7 +4,7 @@ error: cannot find macro `something_later` in this scope LL | something_later!(); | ^^^^^^^^^^^^^^^ consider moving the definition of `something_later` before this call | -note: a macro with the same name exists, but it appears later at here +note: a macro with the same name exists, but it appears later --> $DIR/defined-later-issue-121061.rs:5:14 | LL | macro_rules! something_later { diff --git a/tests/ui/macros/expr_2021_implicit_in_2024.rs b/tests/ui/macros/expr_2021_implicit_in_2024.rs index b3f7a31a802dd..f2eee1aa272de 100644 --- a/tests/ui/macros/expr_2021_implicit_in_2024.rs +++ b/tests/ui/macros/expr_2021_implicit_in_2024.rs @@ -1,4 +1,4 @@ -//@ compile-flags: --edition=2024 -Zunstable-options +//@ edition: 2024 //@ aux-build:expr_2021_implicit.rs //@ check-pass diff --git a/tests/ui/macros/expr_2021_inline_const.rs b/tests/ui/macros/expr_2021_inline_const.rs index 312256f1879c3..257f5b2f8cf98 100644 --- a/tests/ui/macros/expr_2021_inline_const.rs +++ b/tests/ui/macros/expr_2021_inline_const.rs @@ -1,6 +1,6 @@ //@ revisions: edi2021 edi2024 -//@[edi2024]compile-flags: --edition=2024 -Z unstable-options -//@[edi2021]compile-flags: --edition=2021 +//@[edi2024] edition: 2024 +//@[edi2021] edition: 2021 // This test ensures that the inline const match only on edition 2024 macro_rules! m2021 { diff --git a/tests/ui/macros/expr_2024_underscore_expr.rs b/tests/ui/macros/expr_2024_underscore_expr.rs index 6f8ec139109bb..1d45d60c13644 100644 --- a/tests/ui/macros/expr_2024_underscore_expr.rs +++ b/tests/ui/macros/expr_2024_underscore_expr.rs @@ -1,6 +1,6 @@ //@ revisions: edi2021 edi2024 -//@[edi2024]compile-flags: --edition=2024 -Z unstable-options -//@[edi2021]compile-flags: --edition=2021 +//@[edi2024] edition: 2024 +//@[edi2021] edition: 2021 // This test ensures that the `_` tok is considered an // expression on edition 2024. macro_rules! m2021 { diff --git a/tests/ui/macros/issue-100199.rs b/tests/ui/macros/issue-100199.rs index b1bcc535d74af..78a6ff149e2aa 100644 --- a/tests/ui/macros/issue-100199.rs +++ b/tests/ui/macros/issue-100199.rs @@ -5,7 +5,7 @@ struct Foo {} // an unexpected dummy span (lo == 0 == hi) while attempting to print a // suggestion. -//@ aux-build: issue-100199.rs +//@ proc-macro: issue-100199.rs extern crate issue_100199; diff --git a/tests/ui/macros/issue-8851.rs b/tests/ui/macros/issue-8851.rs index 4a398d15997f6..0198f3f358e0e 100644 --- a/tests/ui/macros/issue-8851.rs +++ b/tests/ui/macros/issue-8851.rs @@ -5,7 +5,6 @@ // doesn't cause capture. Making this macro hygienic (as I've done) // could very well make this test case completely pointless.... -//@ pretty-expanded FIXME #23616 enum T { A(isize), diff --git a/tests/ui/macros/log_syntax-trace_macros-macro-locations.rs b/tests/ui/macros/log_syntax-trace_macros-macro-locations.rs index 85a65300eaf6d..adf5448ffc09d 100644 --- a/tests/ui/macros/log_syntax-trace_macros-macro-locations.rs +++ b/tests/ui/macros/log_syntax-trace_macros-macro-locations.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![feature(trace_macros, log_syntax)] diff --git a/tests/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs b/tests/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs index 08fe2c928302e..e80c712b03dc5 100644 --- a/tests/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs +++ b/tests/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 macro_rules! four { () => (4) diff --git a/tests/ui/macros/macro-missing-fragment.e2015.stderr b/tests/ui/macros/macro-missing-fragment.e2015.stderr index a068dc5c054f0..3d32f203d4a2e 100644 --- a/tests/ui/macros/macro-missing-fragment.e2015.stderr +++ b/tests/ui/macros/macro-missing-fragment.e2015.stderr @@ -1,11 +1,11 @@ error: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:9:20 + --> $DIR/macro-missing-fragment.rs:8:20 | LL | ( $( any_token $field_rust_type )* ) => {}; | ^^^^^^^^^^^^^^^^ warning: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:9:20 + --> $DIR/macro-missing-fragment.rs:8:20 | LL | ( $( any_token $field_rust_type )* ) => {}; | ^^^^^^^^^^^^^^^^ @@ -13,13 +13,13 @@ LL | ( $( any_token $field_rust_type )* ) => {}; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 note: the lint level is defined here - --> $DIR/macro-missing-fragment.rs:6:9 + --> $DIR/macro-missing-fragment.rs:5:9 | LL | #![warn(missing_fragment_specifier)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:19:7 + --> $DIR/macro-missing-fragment.rs:18:7 | LL | ( $name ) => {}; | ^^^^^ @@ -28,7 +28,7 @@ LL | ( $name ) => {}; = note: for more information, see issue #40107 warning: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:26:7 + --> $DIR/macro-missing-fragment.rs:25:7 | LL | ( $name ) => {}; | ^^^^^ @@ -40,7 +40,7 @@ error: aborting due to 1 previous error; 3 warnings emitted Future incompatibility report: Future breakage diagnostic: warning: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:9:20 + --> $DIR/macro-missing-fragment.rs:8:20 | LL | ( $( any_token $field_rust_type )* ) => {}; | ^^^^^^^^^^^^^^^^ @@ -48,14 +48,14 @@ LL | ( $( any_token $field_rust_type )* ) => {}; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 note: the lint level is defined here - --> $DIR/macro-missing-fragment.rs:6:9 + --> $DIR/macro-missing-fragment.rs:5:9 | LL | #![warn(missing_fragment_specifier)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: warning: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:19:7 + --> $DIR/macro-missing-fragment.rs:18:7 | LL | ( $name ) => {}; | ^^^^^ @@ -63,14 +63,14 @@ LL | ( $name ) => {}; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 note: the lint level is defined here - --> $DIR/macro-missing-fragment.rs:6:9 + --> $DIR/macro-missing-fragment.rs:5:9 | LL | #![warn(missing_fragment_specifier)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: warning: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:26:7 + --> $DIR/macro-missing-fragment.rs:25:7 | LL | ( $name ) => {}; | ^^^^^ @@ -78,7 +78,7 @@ LL | ( $name ) => {}; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 note: the lint level is defined here - --> $DIR/macro-missing-fragment.rs:6:9 + --> $DIR/macro-missing-fragment.rs:5:9 | LL | #![warn(missing_fragment_specifier)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/macros/macro-missing-fragment.e2024.stderr b/tests/ui/macros/macro-missing-fragment.e2024.stderr index 0dc48e0c7b219..a9195063a5b92 100644 --- a/tests/ui/macros/macro-missing-fragment.e2024.stderr +++ b/tests/ui/macros/macro-missing-fragment.e2024.stderr @@ -1,5 +1,5 @@ error: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:9:20 + --> $DIR/macro-missing-fragment.rs:8:20 | LL | ( $( any_token $field_rust_type )* ) => {}; | ^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | ( $( any_token $field_rust_type:spec )* ) => {}; | +++++ error: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:19:7 + --> $DIR/macro-missing-fragment.rs:18:7 | LL | ( $name ) => {}; | ^^^^^ @@ -25,7 +25,7 @@ LL | ( $name:spec ) => {}; | +++++ error: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:26:7 + --> $DIR/macro-missing-fragment.rs:25:7 | LL | ( $name ) => {}; | ^^^^^ @@ -38,7 +38,7 @@ LL | ( $name:spec ) => {}; | +++++ error: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:9:20 + --> $DIR/macro-missing-fragment.rs:8:20 | LL | ( $( any_token $field_rust_type )* ) => {}; | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/macros/macro-missing-fragment.rs b/tests/ui/macros/macro-missing-fragment.rs index b7da87ae610f2..42387e8dbbf4f 100644 --- a/tests/ui/macros/macro-missing-fragment.rs +++ b/tests/ui/macros/macro-missing-fragment.rs @@ -1,7 +1,6 @@ //@ revisions: e2015 e2024 //@[e2015] edition:2015 //@[e2024] edition:2024 -//@[e2024] compile-flags: -Zunstable-options #![warn(missing_fragment_specifier)] diff --git a/tests/ui/macros/macro-nt-list.rs b/tests/ui/macros/macro-nt-list.rs index 7a6bc6a8d73df..b7b260c5398cb 100644 --- a/tests/ui/macros/macro-nt-list.rs +++ b/tests/ui/macros/macro-nt-list.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 macro_rules! list { ( ($($id:ident),*) ) => (()); diff --git a/tests/ui/macros/macro-quote-test.rs b/tests/ui/macros/macro-quote-test.rs index dd7b10f6322ac..a4b667b4af6fb 100644 --- a/tests/ui/macros/macro-quote-test.rs +++ b/tests/ui/macros/macro-quote-test.rs @@ -1,7 +1,7 @@ // Test that a macro can emit delimiters with nothing inside - `()`, `{}` //@ run-pass -//@ aux-build:hello_macro.rs +//@ proc-macro: hello_macro.rs extern crate hello_macro; diff --git a/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.rs b/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.rs new file mode 100644 index 0000000000000..a2e1398c61e66 --- /dev/null +++ b/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.rs @@ -0,0 +1,9 @@ +#![crate_type = "lib"] + +macro_rules! sample { () => {} } + +#[sample] //~ ERROR cannot find attribute `sample` in this scope +#[derive(sample)] //~ ERROR cannot find derive macro `sample` in this scope + //~| ERROR cannot find derive macro `sample` in this scope + //~| ERROR cannot find derive macro `sample` in this scope +pub struct S {} diff --git a/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.stderr b/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.stderr new file mode 100644 index 0000000000000..e5b913b208dca --- /dev/null +++ b/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.stderr @@ -0,0 +1,42 @@ +error: cannot find derive macro `sample` in this scope + --> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:6:10 + | +LL | macro_rules! sample { () => {} } + | ------ `sample` exists, but a declarative macro cannot be used as a derive macro +... +LL | #[derive(sample)] + | ^^^^^^ + +error: cannot find attribute `sample` in this scope + --> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:5:3 + | +LL | macro_rules! sample { () => {} } + | ------ `sample` exists, but a declarative macro cannot be used as an attribute macro +LL | +LL | #[sample] + | ^^^^^^ + +error: cannot find derive macro `sample` in this scope + --> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:6:10 + | +LL | macro_rules! sample { () => {} } + | ------ `sample` exists, but a declarative macro cannot be used as a derive macro +... +LL | #[derive(sample)] + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: cannot find derive macro `sample` in this scope + --> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:6:10 + | +LL | macro_rules! sample { () => {} } + | ------ `sample` exists, but a declarative macro cannot be used as a derive macro +... +LL | #[derive(sample)] + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/macros/macro_with_super_2.rs b/tests/ui/macros/macro_with_super_2.rs index 5353405ca578e..5e7ec2515497d 100644 --- a/tests/ui/macros/macro_with_super_2.rs +++ b/tests/ui/macros/macro_with_super_2.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:macro_with_super_1.rs -//@ pretty-expanded FIXME #23616 #[macro_use] extern crate macro_with_super_1; diff --git a/tests/ui/macros/metavar_cross_edition_recursive_macros.rs b/tests/ui/macros/metavar_cross_edition_recursive_macros.rs index 9a5b92f503297..ae1bc00236f0f 100644 --- a/tests/ui/macros/metavar_cross_edition_recursive_macros.rs +++ b/tests/ui/macros/metavar_cross_edition_recursive_macros.rs @@ -1,4 +1,4 @@ -//@ compile-flags: --edition=2024 -Z unstable-options +//@ edition: 2024 //@ aux-build: metavar_2018.rs //@ known-bug: #130484 //@ run-pass diff --git a/tests/ui/macros/parse-complex-macro-invoc-op.rs b/tests/ui/macros/parse-complex-macro-invoc-op.rs index bbb9b0270f260..27ead36f69d8c 100644 --- a/tests/ui/macros/parse-complex-macro-invoc-op.rs +++ b/tests/ui/macros/parse-complex-macro-invoc-op.rs @@ -8,7 +8,6 @@ // Test parsing binary operators after macro invocations. -//@ pretty-expanded FIXME #23616 #![feature(macro_rules)] diff --git a/tests/ui/macros/proc_macro.rs b/tests/ui/macros/proc_macro.rs index 8fea4ca282cf8..b73f311253692 100644 --- a/tests/ui/macros/proc_macro.rs +++ b/tests/ui/macros/proc_macro.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:proc_macro_def.rs +//@ proc-macro: proc_macro_def.rs extern crate proc_macro_def; diff --git a/tests/ui/macros/pub-item-inside-macro.rs b/tests/ui/macros/pub-item-inside-macro.rs index b05d8539d5849..c37945a2d672a 100644 --- a/tests/ui/macros/pub-item-inside-macro.rs +++ b/tests/ui/macros/pub-item-inside-macro.rs @@ -1,7 +1,6 @@ //@ run-pass // Issue #14660 -//@ pretty-expanded FIXME #23616 mod bleh { macro_rules! foo { diff --git a/tests/ui/macros/pub-method-inside-macro.rs b/tests/ui/macros/pub-method-inside-macro.rs index c4f9acc637d3c..dd4e6fda8be9b 100644 --- a/tests/ui/macros/pub-method-inside-macro.rs +++ b/tests/ui/macros/pub-method-inside-macro.rs @@ -1,7 +1,6 @@ //@ run-pass // Issue #17436 -//@ pretty-expanded FIXME #23616 mod bleh { macro_rules! foo { diff --git a/tests/ui/macros/same-sequence-span.rs b/tests/ui/macros/same-sequence-span.rs index 67f6b6ad1cda0..dfaf669a769a6 100644 --- a/tests/ui/macros/same-sequence-span.rs +++ b/tests/ui/macros/same-sequence-span.rs @@ -1,4 +1,4 @@ -//@ aux-build:proc_macro_sequence.rs +//@ proc-macro: proc_macro_sequence.rs // Regression test for issue #62831: Check that multiple sequences with the same span in the // left-hand side of a macro definition behave as if they had unique spans, and in particular that diff --git a/tests/ui/macros/same-sequence-span.stderr b/tests/ui/macros/same-sequence-span.stderr index 3242a32e2f4dd..ff32ef9438614 100644 --- a/tests/ui/macros/same-sequence-span.stderr +++ b/tests/ui/macros/same-sequence-span.stderr @@ -17,9 +17,9 @@ LL | $(= $z:tt)* error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments --> $DIR/same-sequence-span.rs:19:1 | -LL | | } +LL | | macro_rules! manual_foo { | |_________________________________^ not allowed after `expr` fragments -LL | +... LL | proc_macro_sequence::make_foo!(); | ^------------------------------- | | diff --git a/tests/ui/match/match-fn-call.stderr b/tests/ui/match/match-fn-call.stderr index 297aa4cd95def..a3d61947080c0 100644 --- a/tests/ui/match/match-fn-call.stderr +++ b/tests/ui/match/match-fn-call.stderr @@ -4,7 +4,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated function LL | Path::new("foo") => println!("foo"), | ^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns | - = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html + = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html error[E0164]: expected tuple struct or tuple variant, found associated function `Path::new` --> $DIR/match-fn-call.rs:8:9 @@ -12,7 +12,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated function LL | Path::new("bar") => println!("bar"), | ^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns | - = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html + = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html error: aborting due to 2 previous errors diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs index 7cbe8e0943ae4..bc12d69b10531 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options // gate-test-ref_pat_eat_one_layer_2024_structural pub fn main() { diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr index b3ea60252ac47..132fe421a18d8 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:6:22 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:5:22 | LL | if let Some(Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -14,7 +14,7 @@ LL | if let Some(Some(x)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:11:23 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:10:23 | LL | let _: &u32 = x; | ---- ^ expected `&u32`, found integer @@ -27,7 +27,7 @@ LL | let _: &u32 = &x; | + error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:14:23 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:13:23 | LL | if let Some(Some(&&x)) = &Some(Some(&0)) { | ^^ --------------- this expression has type `&Option>` @@ -43,7 +43,7 @@ LL + if let Some(Some(&x)) = &Some(Some(&0)) { | error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:18:17 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:17:17 | LL | if let Some(&Some(x)) = &Some(Some(0)) { | ^^^^^^^^ -------------- this expression has type `&Option>` @@ -54,7 +54,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:22:22 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` @@ -64,7 +64,7 @@ LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:22:22 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ @@ -74,7 +74,7 @@ LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:26:22 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:25:22 | LL | if let Some(Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -89,7 +89,7 @@ LL | if let Some(Some(x)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:30:27 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:29:27 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -104,7 +104,7 @@ LL | if let Some(&mut Some(x)) = &Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:34:23 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23 | LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -114,7 +114,7 @@ LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:34:23 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23 | LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { | ^^^^^^ diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs index c6a699d2ff8a9..b145446de0a1c 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs @@ -1,6 +1,5 @@ //@ run-pass //@ edition: 2024 -//@ compile-flags: -Zunstable-options //@ revisions: classic structural both #![allow(incomplete_features)] #![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))] diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr index 0215df98ea16b..f8672d755b959 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:8:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -10,7 +10,7 @@ LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:11:23 | LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -21,7 +21,7 @@ LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:15:27 | LL | let _: &mut u32 = x; | -------- ^ types differ in mutability @@ -32,7 +32,7 @@ LL | let _: &mut u32 = x; found reference `&{integer}` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:18:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -43,7 +43,7 @@ LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:29 | LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { | ^^^^^^ ------------------------- this expression has type `&Option>>` @@ -54,7 +54,7 @@ LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:17 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:24:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` @@ -65,7 +65,7 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:17 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:27:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` @@ -76,7 +76,7 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9 | LL | let &mut _ = &&0; | ^^^^^^ --- this expression has type `&&{integer}` @@ -87,7 +87,7 @@ LL | let &mut _ = &&0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:34:9 | LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` @@ -98,7 +98,7 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:9 | LL | let &mut _ = &&mut 0; | ^^^^^^ ------- this expression has type `&&mut {integer}` @@ -109,7 +109,7 @@ LL | let &mut _ = &&mut 0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:48:9 | LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; | ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` @@ -120,7 +120,7 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:51:14 | LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; | ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}` @@ -131,7 +131,7 @@ LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; found mutable reference `&mut _` error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:60:13 | LL | let Foo(mut a) = &Foo(0); | ^^^^ @@ -141,7 +141,7 @@ LL | let Foo(mut a) = &Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:64:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^ @@ -151,14 +151,14 @@ LL | let Foo(mut a) = &mut Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0277]: the trait bound `&_: main::Ref` is not satisfied - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:82:14 | LL | let &_ = generic(); | ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_` | = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]` note: required by a bound in `generic` - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:68:19 | LL | fn generic() -> R { | ^^^ required by this bound in `generic` diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr index 9428b32c4affd..a37316b3097b0 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:8:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^ @@ -11,7 +11,7 @@ LL | if let Some(&Some(&_)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:11:23 | LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { | ^^^^^ @@ -23,7 +23,7 @@ LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:15:27 | LL | let _: &mut u32 = x; | -------- ^ types differ in mutability @@ -34,7 +34,7 @@ LL | let _: &mut u32 = x; found reference `&{integer}` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:18:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ @@ -46,7 +46,7 @@ LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:29 | LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { | ^^^^^ @@ -58,7 +58,7 @@ LL | if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:17 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:24:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -70,7 +70,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:17 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:27:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -82,7 +82,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9 | LL | let &mut _ = &&0; | ^^^^^^ --- this expression has type `&&{integer}` @@ -93,7 +93,7 @@ LL | let &mut _ = &&0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:34:9 | LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` @@ -104,7 +104,7 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:38:17 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:37:17 | LL | if let Some(&mut Some(&_)) = &Some(&mut Some(0)) { | ^^^^^ @@ -116,7 +116,7 @@ LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:42:22 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:41:22 | LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { | ^^^^^ @@ -128,7 +128,7 @@ LL | if let Some(Some(&x)) = &Some(Some(&mut 0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:9 | LL | let &mut _ = &&mut 0; | ^^^^^^ ------- this expression has type `&&mut {integer}` @@ -139,7 +139,7 @@ LL | let &mut _ = &&mut 0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:48:9 | LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; | ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` @@ -150,7 +150,7 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:51:14 | LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; | ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}` @@ -161,7 +161,7 @@ LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; found mutable reference `&mut _` error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:60:13 | LL | let Foo(mut a) = &Foo(0); | ^^^^ @@ -171,7 +171,7 @@ LL | let Foo(mut a) = &Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:64:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^ @@ -181,14 +181,14 @@ LL | let Foo(mut a) = &mut Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0277]: the trait bound `&_: main::Ref` is not satisfied - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:82:14 | LL | let &_ = generic(); | ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_` | = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]` note: required by a bound in `generic` - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:68:19 | LL | fn generic() -> R { | ^^^ required by this bound in `generic` diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs index d23e9c8083d9f..fd616807b285c 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options //@ revisions: classic structural both #![allow(incomplete_features)] #![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))] diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr index 56dad6050305b..2f62e9974fa3f 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:8:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -10,7 +10,7 @@ LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:11:23 | LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -21,7 +21,7 @@ LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:15:27 | LL | let _: &mut u32 = x; | -------- ^ types differ in mutability @@ -32,7 +32,7 @@ LL | let _: &mut u32 = x; found reference `&{integer}` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:18:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -43,7 +43,7 @@ LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:29 | LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { | ^^^^^^ ------------------------- this expression has type `&Option>>` @@ -54,7 +54,7 @@ LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:17 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:24:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` @@ -65,7 +65,7 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:17 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:27:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` @@ -76,7 +76,7 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9 | LL | let &mut _ = &&0; | ^^^^^^ --- this expression has type `&&{integer}` @@ -87,7 +87,7 @@ LL | let &mut _ = &&0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:34:9 | LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` @@ -98,7 +98,7 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:9 | LL | let &mut _ = &&mut 0; | ^^^^^^ ------- this expression has type `&&mut {integer}` @@ -109,7 +109,7 @@ LL | let &mut _ = &&mut 0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:48:9 | LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; | ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` @@ -120,7 +120,7 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:51:14 | LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; | ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}` @@ -131,7 +131,7 @@ LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:55:17 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:54:17 | LL | if let Some(&mut _) = &mut Some(&0) { | ^^^^^^ ------------- this expression has type `&mut Option<&{integer}>` @@ -142,7 +142,7 @@ LL | if let Some(&mut _) = &mut Some(&0) { found mutable reference `&mut _` error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:60:13 | LL | let Foo(mut a) = &Foo(0); | ^^^^ @@ -152,7 +152,7 @@ LL | let Foo(mut a) = &Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:64:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^ @@ -162,14 +162,14 @@ LL | let Foo(mut a) = &mut Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0277]: the trait bound `&_: main::Ref` is not satisfied - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:82:14 | LL | let &_ = generic(); | ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_` | = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]` note: required by a bound in `generic` - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:68:19 | LL | fn generic() -> R { | ^^^ required by this bound in `generic` diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs index 3cdf47c1dbfe1..79403b1936528 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options #![allow(incomplete_features)] #![feature(ref_pat_eat_one_layer_2024)] diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr index 8b86fa65c4d8f..52f4c09e5c024 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of a shared reference - --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:7:29 + --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:6:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | if let Some(&Some(ref x)) = Some(&Some(&mut 0)) { | +++ error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:12:10 + --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:11:10 | LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed index bc7a58a382d60..e69d169966b52 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options //@ run-rustfix #![allow(incomplete_features)] #![feature(ref_pat_eat_one_layer_2024)] diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs index c6d72b0a9d777..a300cbcd4df52 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options //@ run-rustfix #![allow(incomplete_features)] #![feature(ref_pat_eat_one_layer_2024)] diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr index 964e9f36596bd..8e135b65253fd 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:8:31 + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:7:31 | LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | - ^ @@ -7,7 +7,7 @@ LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:13:31 + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:12:31 | LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | - ^ @@ -15,7 +15,7 @@ LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:21:15 + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:20:15 | LL | let &pat!(x) = &mut 0; | - ^ @@ -23,7 +23,7 @@ LL | let &pat!(x) = &mut 0; | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:19 + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:24:19 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | - ^ @@ -31,7 +31,7 @@ LL | let &(ref mut a, ref mut b) = &mut (true, false); | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:30 + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:24:30 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | - ^ diff --git a/tests/ui/methods/method-early-bound-lifetimes-on-self.rs b/tests/ui/methods/method-early-bound-lifetimes-on-self.rs index 8721dd85ac785..ec7abe1280d85 100644 --- a/tests/ui/methods/method-early-bound-lifetimes-on-self.rs +++ b/tests/ui/methods/method-early-bound-lifetimes-on-self.rs @@ -2,7 +2,6 @@ // Check that we successfully handle methods where the `self` type has // an early-bound lifetime. Issue #18208. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/methods/method-normalize-bounds-issue-20604.rs b/tests/ui/methods/method-normalize-bounds-issue-20604.rs index b3979e75b6120..ea18fe14d157a 100644 --- a/tests/ui/methods/method-normalize-bounds-issue-20604.rs +++ b/tests/ui/methods/method-normalize-bounds-issue-20604.rs @@ -9,7 +9,6 @@ // winnowing stage of method resolution failed to handle an associated // type projection. -//@ pretty-expanded FIXME #23616 #![feature(associated_types)] diff --git a/tests/ui/methods/method-recursive-blanket-impl.rs b/tests/ui/methods/method-recursive-blanket-impl.rs index 09bbfffcd5533..547e57885e036 100644 --- a/tests/ui/methods/method-recursive-blanket-impl.rs +++ b/tests/ui/methods/method-recursive-blanket-impl.rs @@ -6,7 +6,6 @@ // know not to stop at the blanket, we have to recursively evaluate // the `T:Foo` bound. -//@ pretty-expanded FIXME #23616 use std::marker::Sized; diff --git a/tests/ui/methods/method-recursive-blanket-impl.stderr b/tests/ui/methods/method-recursive-blanket-impl.stderr index 9797a8f6c8308..e358f80d3ff50 100644 --- a/tests/ui/methods/method-recursive-blanket-impl.stderr +++ b/tests/ui/methods/method-recursive-blanket-impl.stderr @@ -1,5 +1,5 @@ warning: trait `Foo` is never used - --> $DIR/method-recursive-blanket-impl.rs:14:7 + --> $DIR/method-recursive-blanket-impl.rs:13:7 | LL | trait Foo { | ^^^ diff --git a/tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs b/tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs index 373439d255957..2ef2848c21641 100644 --- a/tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs +++ b/tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs @@ -2,7 +2,6 @@ // Test that we select between traits A and B. To do that, we must // consider the `Sized` bound. -//@ pretty-expanded FIXME #23616 trait A { //~ WARN trait `A` is never used fn foo(self); diff --git a/tests/ui/methods/method-two-traits-distinguished-via-where-clause.stderr b/tests/ui/methods/method-two-traits-distinguished-via-where-clause.stderr index 0a60c6242bb2d..fa87ce5cc49ff 100644 --- a/tests/ui/methods/method-two-traits-distinguished-via-where-clause.stderr +++ b/tests/ui/methods/method-two-traits-distinguished-via-where-clause.stderr @@ -1,5 +1,5 @@ warning: trait `A` is never used - --> $DIR/method-two-traits-distinguished-via-where-clause.rs:7:7 + --> $DIR/method-two-traits-distinguished-via-where-clause.rs:6:7 | LL | trait A { | ^ diff --git a/tests/ui/mir-dataflow/def-inits-1.rs b/tests/ui/mir-dataflow/def-inits-1.rs deleted file mode 100644 index 30460824a1678..0000000000000 --- a/tests/ui/mir-dataflow/def-inits-1.rs +++ /dev/null @@ -1,51 +0,0 @@ -// General test of maybe_uninits state computed by MIR dataflow. - -#![feature(core_intrinsics, rustc_attrs)] - -use std::intrinsics::rustc_peek; -use std::mem::{drop, replace}; - -struct S(i32); - -#[rustc_mir(rustc_peek_definite_init,stop_after_dataflow)] -fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S { - let ret; - // `ret` starts off uninitialized - rustc_peek(&ret); //~ ERROR rustc_peek: bit not set - - // All function formal parameters start off initialized. - - rustc_peek(&x); - rustc_peek(&y); - rustc_peek(&z); - - ret = if test { - ::std::mem::replace(x, y) - } else { - z = y; - z - }; - - // `z` may be uninitialized here. - rustc_peek(&z); //~ ERROR rustc_peek: bit not set - - // `y` is definitely uninitialized here. - rustc_peek(&y); //~ ERROR rustc_peek: bit not set - - // `x` is still (definitely) initialized (replace above is a reborrow). - rustc_peek(&x); - - ::std::mem::drop(x); - - // `x` is *definitely* uninitialized here - rustc_peek(&x); //~ ERROR rustc_peek: bit not set - - // `ret` is now definitely initialized (via `if` above). - rustc_peek(&ret); - - ret -} -fn main() { - foo(true, &mut S(13), S(14), S(15)); - foo(false, &mut S(13), S(14), S(15)); -} diff --git a/tests/ui/mir-dataflow/def-inits-1.stderr b/tests/ui/mir-dataflow/def-inits-1.stderr deleted file mode 100644 index e2bddb54d9ba8..0000000000000 --- a/tests/ui/mir-dataflow/def-inits-1.stderr +++ /dev/null @@ -1,28 +0,0 @@ -error: rustc_peek: bit not set - --> $DIR/def-inits-1.rs:14:5 - | -LL | rustc_peek(&ret); - | ^^^^^^^^^^^^^^^^ - -error: rustc_peek: bit not set - --> $DIR/def-inits-1.rs:30:5 - | -LL | rustc_peek(&z); - | ^^^^^^^^^^^^^^ - -error: rustc_peek: bit not set - --> $DIR/def-inits-1.rs:33:5 - | -LL | rustc_peek(&y); - | ^^^^^^^^^^^^^^ - -error: rustc_peek: bit not set - --> $DIR/def-inits-1.rs:41:5 - | -LL | rustc_peek(&x); - | ^^^^^^^^^^^^^^ - -error: stop_after_dataflow ended compilation - -error: aborting due to 5 previous errors - diff --git a/tests/ui/mir/issue-112269.stderr b/tests/ui/mir/issue-112269.stderr index adb662c98a7e8..80f329e2ce026 100644 --- a/tests/ui/mir/issue-112269.stderr +++ b/tests/ui/mir/issue-112269.stderr @@ -7,7 +7,7 @@ LL | let x: i32 = 3; | ^ patterns `i32::MIN..=3_i32` and `5_i32..=i32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` help: introduce a variable instead | @@ -23,7 +23,7 @@ LL | let y = 4; | ^ patterns `i32::MIN..=2_i32` and `4_i32..=i32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` help: introduce a variable instead | diff --git a/tests/ui/mir/mir_let_chains_drop_order.rs b/tests/ui/mir/mir_let_chains_drop_order.rs index 92199625207e9..8991c6db7b98f 100644 --- a/tests/ui/mir/mir_let_chains_drop_order.rs +++ b/tests/ui/mir/mir_let_chains_drop_order.rs @@ -2,7 +2,6 @@ //@ needs-unwind //@ revisions: edition2021 edition2024 //@ [edition2021] edition: 2021 -//@ [edition2024] compile-flags: -Z unstable-options //@ [edition2024] edition: 2024 // See `mir_drop_order.rs` for more information diff --git a/tests/ui/mir/validate/needs-reveal-all.rs b/tests/ui/mir/validate/needs-reveal-all.rs index be2f5dd322fb6..7d793ebbba6dd 100644 --- a/tests/ui/mir/validate/needs-reveal-all.rs +++ b/tests/ui/mir/validate/needs-reveal-all.rs @@ -1,8 +1,8 @@ -// Regression test for #105009. the issue here was that even after the `RevealAll` pass, +// Regression test for #105009. the issue here was that even after the `PostAnalysisNormalize` pass, // `validate` still used `Reveal::UserFacing`. This meant that it now ends up comparing // opaque types with their revealed version, resulting in an ICE. // -// We're using these flags to run the `RevealAll` pass while making it less likely to +// We're using these flags to run the `PostAnalysisNormalize` pass while making it less likely to // accidentally removing the assignment from `Foo` to `Foo`. //@ compile-flags: -Zinline_mir=yes -Zmir-opt-level=0 -Zvalidate-mir diff --git a/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr index a845dfabe93b7..0a86f884e70db 100644 --- a/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr +++ b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr @@ -14,7 +14,7 @@ LL | fn foo(a: T, b: T) {} | ^^^ - ---- ---- this parameter needs to match the integer type of `a` | | | | | `b` needs to match the integer type of this parameter - | `a` and `b` all reference this parameter T + | `a` and `b` both reference this parameter `T` error[E0308]: arguments to this function are incorrect --> $DIR/generic-mismatch-reporting-issue-116615.rs:8:5 @@ -38,7 +38,7 @@ LL | fn foo_multi_same(a: T, b: T, c: T, d: T, e: T, f: i32) {} | | | | this parameter needs to match the `&str` type of `a` and `b` | | | `c`, `d` and `e` need to match the `&str` type of this parameter | | `c`, `d` and `e` need to match the `&str` type of this parameter - | `a`, `b`, `c`, `d` and `e` all reference this parameter T + | `a`, `b`, `c`, `d` and `e` all reference this parameter `T` error[E0308]: arguments to this function are incorrect --> $DIR/generic-mismatch-reporting-issue-116615.rs:10:5 @@ -65,8 +65,8 @@ LL | fn foo_multi_generics(a: T, b: T, c: T, d: T, e: T, f: S, g: S) {} | | | | | `d` and `e` need to match the `&str` type of this parameter | | | | `d` and `e` need to match the `&str` type of this parameter | | | `d` and `e` need to match the `&str` type of this parameter - | | `a`, `b`, `c`, `d` and `e` all reference this parameter T - | `f` and `g` all reference this parameter S + | | `a`, `b`, `c`, `d` and `e` all reference this parameter `T` + | `f` and `g` both reference this parameter `S` error[E0308]: arguments to this function are incorrect --> $DIR/generic-mismatch-reporting-issue-116615.rs:12:5 @@ -90,7 +90,7 @@ LL | fn foo_multi_same(a: T, b: T, c: T, d: T, e: T, f: i32) {} | | | | this parameter needs to match the `&str` type of `a`, `d` and `e` | | | this parameter needs to match the `&str` type of `a`, `d` and `e` | | `b` and `c` need to match the `&str` type of this parameter - | `a`, `b`, `c`, `d` and `e` all reference this parameter T + | `a`, `b`, `c`, `d` and `e` all reference this parameter `T` error: aborting due to 4 previous errors diff --git a/tests/ui/modules/issue-13872.rs b/tests/ui/modules/issue-13872.rs index 5589d2d4f68c1..a29f378c844cb 100644 --- a/tests/ui/modules/issue-13872.rs +++ b/tests/ui/modules/issue-13872.rs @@ -3,7 +3,6 @@ //@ aux-build:issue-13872-2.rs //@ aux-build:issue-13872-3.rs -//@ pretty-expanded FIXME #23616 extern crate issue_13872_3 as other; diff --git a/tests/ui/modules/mod-view-items.rs b/tests/ui/modules/mod-view-items.rs index 462071b7b126e..2d25c83f36237 100644 --- a/tests/ui/modules/mod-view-items.rs +++ b/tests/ui/modules/mod-view-items.rs @@ -5,7 +5,6 @@ // pretty-print such view items. If that happens again, this should // begin failing. -//@ pretty-expanded FIXME #23616 mod m { pub fn f() -> Vec { Vec::new() } diff --git a/tests/ui/moves/move-nullary-fn.rs b/tests/ui/moves/move-nullary-fn.rs index 8c7bcf395e7ac..0480d2b10454e 100644 --- a/tests/ui/moves/move-nullary-fn.rs +++ b/tests/ui/moves/move-nullary-fn.rs @@ -1,6 +1,5 @@ //@ run-pass // Issue #922 -//@ pretty-expanded FIXME #23616 fn f2(_thing: F) where F: FnOnce() { } diff --git a/tests/ui/multiline-comment.rs b/tests/ui/multiline-comment.rs index bf86250c1f897..9817488203221 100644 --- a/tests/ui/multiline-comment.rs +++ b/tests/ui/multiline-comment.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 /* * This is a multi-line oldcomment. diff --git a/tests/ui/mutual-recursion-group.rs b/tests/ui/mutual-recursion-group.rs index dc6d216f8d9ba..f83150af7dc85 100644 --- a/tests/ui/mutual-recursion-group.rs +++ b/tests/ui/mutual-recursion-group.rs @@ -3,7 +3,6 @@ #![allow(non_camel_case_types)] #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 enum colour { red, green, blue, } diff --git a/tests/ui/nested-block-comment.rs b/tests/ui/nested-block-comment.rs index 07414345c38ec..008df27e0e2a2 100644 --- a/tests/ui/nested-block-comment.rs +++ b/tests/ui/nested-block-comment.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 /* This test checks that nested comments are supported diff --git a/tests/ui/never_type/exhaustive_patterns.stderr b/tests/ui/never_type/exhaustive_patterns.stderr index 1314cbc52f881..1f22b9e619867 100644 --- a/tests/ui/never_type/exhaustive_patterns.stderr +++ b/tests/ui/never_type/exhaustive_patterns.stderr @@ -5,7 +5,7 @@ LL | let Either::A(()) = foo(); | ^^^^^^^^^^^^^ pattern `Either::B(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `Either<(), !>` defined here --> $DIR/exhaustive_patterns.rs:9:6 | diff --git a/tests/ui/never_type/expr-empty-ret.rs b/tests/ui/never_type/expr-empty-ret.rs index 5d315934e0049..e6af5bd3153f7 100644 --- a/tests/ui/never_type/expr-empty-ret.rs +++ b/tests/ui/never_type/expr-empty-ret.rs @@ -3,7 +3,6 @@ #![allow(dead_code)] // Issue #521 -//@ pretty-expanded FIXME #23616 fn f() { let _x = match true { diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr index 03bb0ca5f3a02..ec1483b0aaebf 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr @@ -1,5 +1,5 @@ warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:12:18 | LL | unsafe { mem::zeroed() } | ^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL | unsafe { mem::zeroed::<()>() } | ++++++ warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:29:13 | LL | core::mem::transmute(Zst) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | core::mem::transmute::<_, ()>(Zst) | +++++++++ warning: never type fallback affects this union access - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:46:18 | LL | unsafe { Union { a: () }.b } | ^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | unsafe { Union { a: () }.b } = help: specify the type explicitly warning: never type fallback affects this raw pointer dereference - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:58:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:57:18 | LL | unsafe { *ptr::from_ref(&()).cast() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | unsafe { *ptr::from_ref(&()).cast::<()>() } | ++++++ warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:78:18 | LL | unsafe { internally_create(x) } | ^^^^^^^^^^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL | unsafe { internally_create::<()>(x) } | ++++++ warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:96:18 | LL | unsafe { zeroed() } | ^^^^^^^^ @@ -80,7 +80,7 @@ LL | let zeroed = mem::zeroed::<()>; | ++++++ warning: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:91:22 | LL | let zeroed = mem::zeroed; | ^^^^^^^^^^^ @@ -94,7 +94,7 @@ LL | let zeroed = mem::zeroed::<()>; | ++++++ warning: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:114:17 | LL | let f = internally_create; | ^^^^^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL | let f = internally_create::<()>; | ++++++ warning: never type fallback affects this call to an `unsafe` method - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:139:13 | LL | S(marker::PhantomData).create_out_of_thin_air() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL | S(marker::PhantomData).create_out_of_thin_air() = help: specify the type explicitly warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:158:19 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:157:19 | LL | match send_message::<_ /* ?0 */>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr index cf12d699f2e92..790facee09e67 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr @@ -1,5 +1,5 @@ error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:12:18 | LL | unsafe { mem::zeroed() } | ^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL | unsafe { mem::zeroed::<()>() } | ++++++ error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:29:13 | LL | core::mem::transmute(Zst) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | core::mem::transmute::<_, ()>(Zst) | +++++++++ error: never type fallback affects this union access - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:46:18 | LL | unsafe { Union { a: () }.b } | ^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | unsafe { Union { a: () }.b } = help: specify the type explicitly error: never type fallback affects this raw pointer dereference - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:58:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:57:18 | LL | unsafe { *ptr::from_ref(&()).cast() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | unsafe { *ptr::from_ref(&()).cast::<()>() } | ++++++ error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:78:18 | LL | unsafe { internally_create(x) } | ^^^^^^^^^^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL | unsafe { internally_create::<()>(x) } | ++++++ error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:96:18 | LL | unsafe { zeroed() } | ^^^^^^^^ @@ -80,7 +80,7 @@ LL | let zeroed = mem::zeroed::<()>; | ++++++ error: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:91:22 | LL | let zeroed = mem::zeroed; | ^^^^^^^^^^^ @@ -94,7 +94,7 @@ LL | let zeroed = mem::zeroed::<()>; | ++++++ error: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:114:17 | LL | let f = internally_create; | ^^^^^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL | let f = internally_create::<()>; | ++++++ error: never type fallback affects this call to an `unsafe` method - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:139:13 | LL | S(marker::PhantomData).create_out_of_thin_air() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL | S(marker::PhantomData).create_out_of_thin_air() = help: specify the type explicitly error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:158:19 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:157:19 | LL | match send_message::<_ /* ?0 */>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL | match send_message::<() /* ?0 */>() { | ~~ warning: the type `!` does not permit zero-initialization - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:12:18 | LL | unsafe { mem::zeroed() } | ^^^^^^^^^^^^^ this code causes undefined behavior when executed diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs index 19b51eea2f570..97e7a2f56bdaa 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs @@ -2,7 +2,6 @@ //@[e2015] check-pass //@[e2024] check-fail //@[e2024] edition:2024 -//@[e2024] compile-flags: -Zunstable-options use std::{marker, mem, ptr}; diff --git a/tests/ui/nll/issue-54556-niconii.edition2021.stderr b/tests/ui/nll/issue-54556-niconii.edition2021.stderr index abee09ed95037..8bd559034b091 100644 --- a/tests/ui/nll/issue-54556-niconii.edition2021.stderr +++ b/tests/ui/nll/issue-54556-niconii.edition2021.stderr @@ -1,5 +1,5 @@ error[E0597]: `counter` does not live long enough - --> $DIR/issue-54556-niconii.rs:28:20 + --> $DIR/issue-54556-niconii.rs:27:20 | LL | let counter = Mutex; | ------- binding `counter` declared here diff --git a/tests/ui/nll/issue-54556-niconii.rs b/tests/ui/nll/issue-54556-niconii.rs index f01e0523cbf9d..9d37adede6adb 100644 --- a/tests/ui/nll/issue-54556-niconii.rs +++ b/tests/ui/nll/issue-54556-niconii.rs @@ -9,7 +9,6 @@ //@ revisions: edition2021 edition2024 //@ [edition2021] edition: 2021 //@ [edition2024] edition: 2024 -//@ [edition2024] compile-flags: -Z unstable-options //@ [edition2024] check-pass struct Mutex; diff --git a/tests/ui/nll/user-annotations/region-error-ice-109072.rs b/tests/ui/nll/user-annotations/region-error-ice-109072.rs index bcdc6651cf5bb..3f2ad3ccbf582 100644 --- a/tests/ui/nll/user-annotations/region-error-ice-109072.rs +++ b/tests/ui/nll/user-annotations/region-error-ice-109072.rs @@ -11,5 +11,4 @@ impl Lt<'missing> for () { //~ ERROR undeclared lifetime fn main() { let _: <() as Lt<'_>>::T = &(); - //~^ ERROR the trait bound `(): Lt<'_>` is not satisfied } diff --git a/tests/ui/nll/user-annotations/region-error-ice-109072.stderr b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr index c187c17d98c68..d90971bed25ba 100644 --- a/tests/ui/nll/user-annotations/region-error-ice-109072.stderr +++ b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr @@ -21,13 +21,6 @@ help: consider introducing lifetime `'missing` here LL | impl<'missing> Lt<'missing> for () { | ++++++++++ -error[E0277]: the trait bound `(): Lt<'_>` is not satisfied - --> $DIR/region-error-ice-109072.rs:13:13 - | -LL | let _: <() as Lt<'_>>::T = &(); - | ^^ the trait `Lt<'_>` is not implemented for `()` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0261, E0277. -For more information about an error, try `rustc --explain E0261`. +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/numbers-arithmetic/int.rs b/tests/ui/numbers-arithmetic/int.rs index edc7f72944405..42f8e50d6efaf 100644 --- a/tests/ui/numbers-arithmetic/int.rs +++ b/tests/ui/numbers-arithmetic/int.rs @@ -2,6 +2,5 @@ -//@ pretty-expanded FIXME #23616 pub fn main() { let _x: isize = 10; } diff --git a/tests/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs b/tests/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs index 406ed4704581b..2cbbdfc6479f1 100644 --- a/tests/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs +++ b/tests/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn foo(_: *const ()) {} diff --git a/tests/ui/numbers-arithmetic/integer-literal-suffix-inference.rs b/tests/ui/numbers-arithmetic/integer-literal-suffix-inference.rs index 97c10bc3c560b..ed59bba119606 100644 --- a/tests/ui/numbers-arithmetic/integer-literal-suffix-inference.rs +++ b/tests/ui/numbers-arithmetic/integer-literal-suffix-inference.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { fn id_i8(n: i8) -> i8 { n } diff --git a/tests/ui/numbers-arithmetic/uint.rs b/tests/ui/numbers-arithmetic/uint.rs index c64361c2726c7..c2087b5a06c63 100644 --- a/tests/ui/numbers-arithmetic/uint.rs +++ b/tests/ui/numbers-arithmetic/uint.rs @@ -2,6 +2,5 @@ -//@ pretty-expanded FIXME #23616 pub fn main() { let _x: usize = 10 as usize; } diff --git a/tests/ui/object-lifetime/object-lifetime-default-default-to-static.rs b/tests/ui/object-lifetime/object-lifetime-default-default-to-static.rs index edbd9f35d4dfa..23e5852335611 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-default-to-static.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-default-to-static.rs @@ -2,7 +2,6 @@ // Test that `Box` is equivalent to `Box`, both in // fields and fn arguments. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs b/tests/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs index 986fc83679934..040ac1f891326 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs @@ -2,7 +2,6 @@ // Test that the lifetime of the enclosing `&` is used for the object // lifetime bound. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs index 3c88f2b9f3765..c3f3101155cf1 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs @@ -2,7 +2,6 @@ // Test that the lifetime from the enclosing `&` is "inherited" // through the `Box` struct. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs index 412695f708670..db4f9a40235d4 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs @@ -2,7 +2,6 @@ // Test that the lifetime of the enclosing `&` is used for the object // lifetime bound. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs index 591f843a284a2..5163ff1c2455a 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs @@ -2,7 +2,6 @@ // Test that the lifetime from the enclosing `&` is "inherited" // through the `MyBox` struct. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-rptr.rs b/tests/ui/object-lifetime/object-lifetime-default-from-rptr.rs index bc47b8d46a11e..556bde784152d 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-from-rptr.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-from-rptr.rs @@ -2,7 +2,6 @@ // Test that the lifetime of the enclosing `&` is used for the object // lifetime bound. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/object-lifetime/object-lifetime-default-inferred.rs b/tests/ui/object-lifetime/object-lifetime-default-inferred.rs index 53b9c4886450e..5abe09e272920 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-inferred.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-inferred.rs @@ -2,7 +2,6 @@ // Test that even with prior inferred parameters, object lifetimes of objects after are still // valid. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] #![feature(generic_arg_infer)] diff --git a/tests/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr b/tests/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr index fdb1a9bb4b78e..7044b8e035ad8 100644 --- a/tests/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr +++ b/tests/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr @@ -5,7 +5,7 @@ LL | let (0 | (1 | 2)) = 0; | ^^^^^^^^^^^ patterns `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` help: you might want to use `if let` to ignore the variants that aren't matched | diff --git a/tests/ui/output-slot-variants.rs b/tests/ui/output-slot-variants.rs index c545b2504cb8f..97757e74fc4ea 100644 --- a/tests/ui/output-slot-variants.rs +++ b/tests/ui/output-slot-variants.rs @@ -3,7 +3,6 @@ #![allow(dead_code)] #![allow(unused_assignments)] #![allow(unknown_lints)] -//@ pretty-expanded FIXME #23616 #![allow(dead_assignment)] #![allow(unused_variables)] diff --git a/tests/ui/overloaded/fixup-deref-mut.rs b/tests/ui/overloaded/fixup-deref-mut.rs index 2879554bb94be..f8d3e678f0c0b 100644 --- a/tests/ui/overloaded/fixup-deref-mut.rs +++ b/tests/ui/overloaded/fixup-deref-mut.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 use std::ops::{Deref, DerefMut}; diff --git a/tests/ui/overloaded/issue-14958.rs b/tests/ui/overloaded/issue-14958.rs index 3df4732d9ada9..a4e5c8e3562e4 100644 --- a/tests/ui/overloaded/issue-14958.rs +++ b/tests/ui/overloaded/issue-14958.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![feature(fn_traits, unboxed_closures)] diff --git a/tests/ui/overloaded/issue-14958.stderr b/tests/ui/overloaded/issue-14958.stderr index cc97730239c30..e4f527319e7af 100644 --- a/tests/ui/overloaded/issue-14958.stderr +++ b/tests/ui/overloaded/issue-14958.stderr @@ -1,5 +1,5 @@ warning: method `dummy` is never used - --> $DIR/issue-14958.rs:6:16 + --> $DIR/issue-14958.rs:5:16 | LL | trait Foo { fn dummy(&self) { }} | --- ^^^^^ diff --git a/tests/ui/overloaded/overloaded-calls-param-vtables.rs b/tests/ui/overloaded/overloaded-calls-param-vtables.rs index 7b89b45eb9b95..b82e2ab05bedf 100644 --- a/tests/ui/overloaded/overloaded-calls-param-vtables.rs +++ b/tests/ui/overloaded/overloaded-calls-param-vtables.rs @@ -1,7 +1,6 @@ //@ run-pass // Tests that nested vtables work with overloaded calls. -//@ pretty-expanded FIXME #23616 #![feature(unboxed_closures, fn_traits)] diff --git a/tests/ui/panic-handler/weak-lang-item-2.rs b/tests/ui/panic-handler/weak-lang-item-2.rs index 2acaff3ab7127..5291f3c440335 100644 --- a/tests/ui/panic-handler/weak-lang-item-2.rs +++ b/tests/ui/panic-handler/weak-lang-item-2.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:weak-lang-items.rs -//@ pretty-expanded FIXME #23616 extern crate weak_lang_items as other; diff --git a/tests/ui/panics/issue-47429-short-backtraces.rs b/tests/ui/panics/issue-47429-short-backtraces.rs index 97d2e22574af3..0d216fdd6530f 100644 --- a/tests/ui/panics/issue-47429-short-backtraces.rs +++ b/tests/ui/panics/issue-47429-short-backtraces.rs @@ -6,6 +6,12 @@ //@ check-run-results //@ exec-env:RUST_BACKTRACE=1 +// This is needed to avoid test output differences across std being built with v0 symbols vs legacy +// symbols. +//@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +// And this is for differences between std with and without debuginfo. +//@ normalize-stderr-test: "\n +at [^\n]+" -> "" + //@ ignore-msvc see #62897 and `backtrace-debuginfo.rs` test //@ ignore-android FIXME #17520 //@ ignore-openbsd no support for libbacktrace without filename @@ -14,11 +20,6 @@ //@ ignore-sgx no subprocess support //@ ignore-fuchsia Backtraces not symbolized -// NOTE(eddyb) output differs between symbol mangling schemes -//@ revisions: legacy v0 -//@ [legacy] compile-flags: -Zunstable-options -Csymbol-mangling-version=legacy -//@ [v0] compile-flags: -Csymbol-mangling-version=v0 - fn main() { panic!() } diff --git a/tests/ui/panics/issue-47429-short-backtraces.legacy.run.stderr b/tests/ui/panics/issue-47429-short-backtraces.run.stderr similarity index 98% rename from tests/ui/panics/issue-47429-short-backtraces.legacy.run.stderr rename to tests/ui/panics/issue-47429-short-backtraces.run.stderr index dce91ce59e3a1..1078a2fbc9025 100644 --- a/tests/ui/panics/issue-47429-short-backtraces.legacy.run.stderr +++ b/tests/ui/panics/issue-47429-short-backtraces.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/issue-47429-short-backtraces.rs:23:5: +thread 'main' panicked at $DIR/issue-47429-short-backtraces.rs:24:5: explicit panic stack backtrace: 0: std::panicking::begin_panic diff --git a/tests/ui/panics/issue-47429-short-backtraces.v0.run.stderr b/tests/ui/panics/issue-47429-short-backtraces.v0.run.stderr deleted file mode 100644 index f458c7acb39fd..0000000000000 --- a/tests/ui/panics/issue-47429-short-backtraces.v0.run.stderr +++ /dev/null @@ -1,6 +0,0 @@ -thread 'main' panicked at $DIR/issue-47429-short-backtraces.rs:23:5: -explicit panic -stack backtrace: - 0: std::panicking::begin_panic::<&str> - 1: issue_47429_short_backtraces::main -note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. diff --git a/tests/ui/panics/runtime-switch.rs b/tests/ui/panics/runtime-switch.rs index a4ef0dcd8a237..10dce25090932 100644 --- a/tests/ui/panics/runtime-switch.rs +++ b/tests/ui/panics/runtime-switch.rs @@ -6,6 +6,12 @@ //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 +// This is needed to avoid test output differences across std being built with v0 symbols vs legacy +// symbols. +//@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +// And this is for differences between std with and without debuginfo. +//@ normalize-stderr-test: "\n +at [^\n]+" -> "" + //@ ignore-msvc see #62897 and `backtrace-debuginfo.rs` test //@ ignore-android FIXME #17520 //@ ignore-openbsd no support for libbacktrace without filename @@ -14,11 +20,6 @@ //@ ignore-sgx no subprocess support //@ ignore-fuchsia Backtrace not symbolized -// NOTE(eddyb) output differs between symbol mangling schemes -//@ revisions: legacy v0 -//@ [legacy] compile-flags: -Zunstable-options -Csymbol-mangling-version=legacy -//@ [v0] compile-flags: -Csymbol-mangling-version=v0 - #![feature(panic_backtrace_config)] fn main() { diff --git a/tests/ui/panics/runtime-switch.legacy.run.stderr b/tests/ui/panics/runtime-switch.run.stderr similarity index 76% rename from tests/ui/panics/runtime-switch.legacy.run.stderr rename to tests/ui/panics/runtime-switch.run.stderr index bd05b6cc00fb1..abbb91eba60e0 100644 --- a/tests/ui/panics/runtime-switch.legacy.run.stderr +++ b/tests/ui/panics/runtime-switch.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/runtime-switch.rs:26:5: +thread 'main' panicked at $DIR/runtime-switch.rs:27:5: explicit panic stack backtrace: 0: std::panicking::begin_panic diff --git a/tests/ui/panics/runtime-switch.v0.run.stderr b/tests/ui/panics/runtime-switch.v0.run.stderr deleted file mode 100644 index 2078c356d5cd7..0000000000000 --- a/tests/ui/panics/runtime-switch.v0.run.stderr +++ /dev/null @@ -1,6 +0,0 @@ -thread 'main' panicked at $DIR/runtime-switch.rs:26:5: -explicit panic -stack backtrace: - 0: std::panicking::begin_panic::<&str> - 1: runtime_switch::main -note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.rs b/tests/ui/panics/short-ice-remove-middle-frames-2.rs index 6caad2212d491..c2f04cd122c73 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames-2.rs +++ b/tests/ui/panics/short-ice-remove-middle-frames-2.rs @@ -9,6 +9,11 @@ //@ ignore-sgx Backtraces not symbolized //@ ignore-fuchsia Backtraces not symbolized //@ ignore-msvc the `__rust_{begin,end}_short_backtrace` symbols aren't reliable. +// This is needed to avoid test output differences across std being built with v0 symbols vs legacy +// symbols. +//@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +// And this is for differences between std with and without debuginfo. +//@ normalize-stderr-test: "\n +at [^\n]+" -> "" /// This test case make sure that we can have multiple pairs of `__rust_{begin,end}_short_backtrace` diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr index 2b648a0cad2ea..67577f3568e91 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr +++ b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:56:5: +thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:61:5: debug!!! stack backtrace: 0: std::panicking::begin_panic diff --git a/tests/ui/panics/short-ice-remove-middle-frames.rs b/tests/ui/panics/short-ice-remove-middle-frames.rs index 5f275d13cc4cb..c035e7e69bc63 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames.rs +++ b/tests/ui/panics/short-ice-remove-middle-frames.rs @@ -10,6 +10,11 @@ //@ ignore-fuchsia Backtraces not symbolized //@ ignore-msvc the `__rust_{begin,end}_short_backtrace` symbols aren't reliable. +// This is needed to avoid test output differences across std being built with v0 symbols vs legacy +// symbols. +//@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +// And this is for differences between std with and without debuginfo. +//@ normalize-stderr-test: "\n +at [^\n]+" -> "" #[inline(never)] fn __rust_begin_short_backtrace T>(f: F) -> T { diff --git a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr index 5b37268409679..63fa466ab24ad 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr +++ b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:52:5: +thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:57:5: debug!!! stack backtrace: 0: std::panicking::begin_panic diff --git a/tests/ui/parser/assoc/assoc-oddities-1.rs b/tests/ui/parser/assoc/assoc-oddities-1.rs index 246546ac03420..c1b305a4eeb24 100644 --- a/tests/ui/parser/assoc/assoc-oddities-1.rs +++ b/tests/ui/parser/assoc/assoc-oddities-1.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Z parse-only +//@ compile-flags: -Z parse-crate-root-only fn main() { // following lines below parse and must not fail diff --git a/tests/ui/parser/assoc/assoc-oddities-2.rs b/tests/ui/parser/assoc/assoc-oddities-2.rs index aee2af41d62a6..82cf7d79c0d57 100644 --- a/tests/ui/parser/assoc/assoc-oddities-2.rs +++ b/tests/ui/parser/assoc/assoc-oddities-2.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Z parse-only +//@ compile-flags: -Z parse-crate-root-only fn main() { // see assoc-oddities-1 for explanation diff --git a/tests/ui/parser/bad-name.stderr b/tests/ui/parser/bad-name.stderr index 5ca248380ee5b..a336923f4fd89 100644 --- a/tests/ui/parser/bad-name.stderr +++ b/tests/ui/parser/bad-name.stderr @@ -10,7 +10,7 @@ error: expected a pattern, found an expression LL | let x.y::.z foo; | ^^^^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error: expected one of `(`, `.`, `::`, `:`, `;`, `=`, `?`, `|`, or an operator, found `foo` --> $DIR/bad-name.rs:2:22 diff --git a/tests/ui/parser/bounds-type.rs b/tests/ui/parser/bounds-type.rs index 7cee6def32f83..ec0e83c314e1d 100644 --- a/tests/ui/parser/bounds-type.rs +++ b/tests/ui/parser/bounds-type.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Z parse-only +//@ compile-flags: -Z parse-crate-root-only //@ edition: 2021 struct S< diff --git a/tests/ui/parser/help-set-edition-ice-122130.stderr b/tests/ui/parser/help-set-edition-ice-122130.stderr index fe4d212f2db65..700b1ec911b30 100644 --- a/tests/ui/parser/help-set-edition-ice-122130.stderr +++ b/tests/ui/parser/help-set-edition-ice-122130.stderr @@ -6,7 +6,7 @@ LL | s#[c"owned_box"] | = note: you may be trying to write a c-string literal = note: c-string literals require Rust 2021 or later - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error: expected item, found `"owned_box"` diff --git a/tests/ui/parser/impl-qpath.rs b/tests/ui/parser/impl-qpath.rs index d7c4989b6e4c4..fed026792c9d1 100644 --- a/tests/ui/parser/impl-qpath.rs +++ b/tests/ui/parser/impl-qpath.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Z parse-only +//@ compile-flags: -Z parse-crate-root-only impl <*const u8>::AssocTy {} // OK impl ::AssocTy {} // OK diff --git a/tests/ui/parser/issues/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs b/tests/ui/parser/issues/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs index 44697afcfed6e..2df0b3a17dcf0 100644 --- a/tests/ui/parser/issues/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs +++ b/tests/ui/parser/issues/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/parser/issues/issue-17904.rs b/tests/ui/parser/issues/issue-17904.rs index 6f77d4bb086fb..99a3b13989885 100644 --- a/tests/ui/parser/issues/issue-17904.rs +++ b/tests/ui/parser/issues/issue-17904.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zparse-only +//@ compile-flags: -Zparse-crate-root-only struct Baz where U: Eq(U); //This is parsed as the new Fn* style parenthesis syntax. struct Baz where U: Eq(U) -> R; // Notice this parses as well. diff --git a/tests/ui/parser/issues/issue-21475.rs b/tests/ui/parser/issues/issue-21475.rs index 27248179ef4a0..43dc7c53a7085 100644 --- a/tests/ui/parser/issues/issue-21475.rs +++ b/tests/ui/parser/issues/issue-21475.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_imports, overlapping_range_endpoints)] -//@ pretty-expanded FIXME #23616 use m::{START, END}; diff --git a/tests/ui/parser/issues/issue-24197.stderr b/tests/ui/parser/issues/issue-24197.stderr index c92e165b23b65..4eadc897d88c8 100644 --- a/tests/ui/parser/issues/issue-24197.stderr +++ b/tests/ui/parser/issues/issue-24197.stderr @@ -4,7 +4,7 @@ error: expected a pattern, found an expression LL | let buf[0] = 0; | ^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-24375.stderr b/tests/ui/parser/issues/issue-24375.stderr index fef3fcde7b799..03cd33f18751c 100644 --- a/tests/ui/parser/issues/issue-24375.stderr +++ b/tests/ui/parser/issues/issue-24375.stderr @@ -4,7 +4,7 @@ error: expected a pattern, found an expression LL | tmp[0] => {} | ^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == tmp[0] => {} diff --git a/tests/ui/parser/issues/issue-7222.rs b/tests/ui/parser/issues/issue-7222.rs index 6f6b34f4f4867..d601731dc7734 100644 --- a/tests/ui/parser/issues/issue-7222.rs +++ b/tests/ui/parser/issues/issue-7222.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { const FOO: f64 = 10.0; diff --git a/tests/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs b/tests/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs index 51bb04dba1921..461890e63e37b 100644 --- a/tests/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs +++ b/tests/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs @@ -1,4 +1,4 @@ -//@ aux-build:issue-89971-outer-attr-following-inner-attr-ice.rs +//@ proc-macro: issue-89971-outer-attr-following-inner-attr-ice.rs #[macro_use] extern crate issue_89971_outer_attr_following_inner_attr_ice; diff --git a/tests/ui/parser/mut-patterns.rs b/tests/ui/parser/mut-patterns.rs index b8610c4e19050..45968a516e3d9 100644 --- a/tests/ui/parser/mut-patterns.rs +++ b/tests/ui/parser/mut-patterns.rs @@ -15,6 +15,10 @@ pub fn main() { //~^ ERROR `mut` on a binding may not be repeated //~| remove the additional `mut`s + let mut mut mut mut mut x = 0; + //~^ ERROR `mut` on a binding may not be repeated + //~| remove the additional `mut`s + struct Foo { x: isize } let mut Foo { x: x } = Foo { x: 3 }; //~^ ERROR `mut` must be attached to each individual binding diff --git a/tests/ui/parser/mut-patterns.stderr b/tests/ui/parser/mut-patterns.stderr index f4f11b88d3615..ad19a60af34ee 100644 --- a/tests/ui/parser/mut-patterns.stderr +++ b/tests/ui/parser/mut-patterns.stderr @@ -45,11 +45,23 @@ LL | let mut mut x = 0; help: remove the additional `mut`s | LL - let mut mut x = 0; -LL + let mut x = 0; +LL + let mut x = 0; + | + +error: `mut` on a binding may not be repeated + --> $DIR/mut-patterns.rs:18:13 + | +LL | let mut mut mut mut mut x = 0; + | ^^^^^^^^^^^^^^^ + | +help: remove the additional `mut`s + | +LL - let mut mut mut mut mut x = 0; +LL + let mut x = 0; | error: `mut` must be attached to each individual binding - --> $DIR/mut-patterns.rs:19:9 + --> $DIR/mut-patterns.rs:23:9 | LL | let mut Foo { x: x } = Foo { x: 3 }; | ^^^^^^^^^^^^^^^^ @@ -61,7 +73,7 @@ LL | let Foo { x: mut x } = Foo { x: 3 }; | ~~~~~~~~~~~~~~~~ error: `mut` must be attached to each individual binding - --> $DIR/mut-patterns.rs:23:9 + --> $DIR/mut-patterns.rs:27:9 | LL | let mut Foo { x } = Foo { x: 3 }; | ^^^^^^^^^^^^^ @@ -73,7 +85,7 @@ LL | let Foo { mut x } = Foo { x: 3 }; | ~~~~~~~~~~~~~ error: `mut` on a binding may not be repeated - --> $DIR/mut-patterns.rs:28:13 + --> $DIR/mut-patterns.rs:32:13 | LL | let mut mut yield(become, await) = r#yield(0, 0); | ^^^ @@ -81,11 +93,11 @@ LL | let mut mut yield(become, await) = r#yield(0, 0); help: remove the additional `mut`s | LL - let mut mut yield(become, await) = r#yield(0, 0); -LL + let mut yield(become, await) = r#yield(0, 0); +LL + let mut yield(become, await) = r#yield(0, 0); | error: expected identifier, found reserved keyword `yield` - --> $DIR/mut-patterns.rs:28:17 + --> $DIR/mut-patterns.rs:32:17 | LL | let mut mut yield(become, await) = r#yield(0, 0); | ^^^^^ expected identifier, found reserved keyword @@ -96,7 +108,7 @@ LL | let mut mut r#yield(become, await) = r#yield(0, 0); | ++ error: expected identifier, found reserved keyword `become` - --> $DIR/mut-patterns.rs:28:23 + --> $DIR/mut-patterns.rs:32:23 | LL | let mut mut yield(become, await) = r#yield(0, 0); | ^^^^^^ expected identifier, found reserved keyword @@ -107,7 +119,7 @@ LL | let mut mut yield(r#become, await) = r#yield(0, 0); | ++ error: expected identifier, found keyword `await` - --> $DIR/mut-patterns.rs:28:31 + --> $DIR/mut-patterns.rs:32:31 | LL | let mut mut yield(become, await) = r#yield(0, 0); | ^^^^^ expected identifier, found keyword @@ -118,7 +130,7 @@ LL | let mut mut yield(become, r#await) = r#yield(0, 0); | ++ error: `mut` must be followed by a named binding - --> $DIR/mut-patterns.rs:28:9 + --> $DIR/mut-patterns.rs:32:9 | LL | let mut mut yield(become, await) = r#yield(0, 0); | ^^^^^^^^ @@ -131,7 +143,7 @@ LL + let yield(become, await) = r#yield(0, 0); | error: `mut` must be attached to each individual binding - --> $DIR/mut-patterns.rs:37:9 + --> $DIR/mut-patterns.rs:41:9 | LL | let mut W(mut a, W(b, W(ref c, W(d, B { box f })))) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -143,7 +155,7 @@ LL | let W(mut a, W(mut b, W(ref c, W(mut d, B { box mut f })))) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: expected identifier, found `x` - --> $DIR/mut-patterns.rs:44:21 + --> $DIR/mut-patterns.rs:48:21 | LL | let mut $p = 0; | ^^ expected identifier @@ -153,5 +165,5 @@ LL | foo!(x); | = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 13 previous errors +error: aborting due to 14 previous errors diff --git a/tests/ui/parser/parse-assoc-type-lt.rs b/tests/ui/parser/parse-assoc-type-lt.rs index f1823ce96b932..48e1423023ecc 100644 --- a/tests/ui/parser/parse-assoc-type-lt.rs +++ b/tests/ui/parser/parse-assoc-type-lt.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait Foo { type T; diff --git a/tests/ui/parser/pat-lt-bracket-5.stderr b/tests/ui/parser/pat-lt-bracket-5.stderr index a2a972652d188..c68aefa0546d3 100644 --- a/tests/ui/parser/pat-lt-bracket-5.stderr +++ b/tests/ui/parser/pat-lt-bracket-5.stderr @@ -4,7 +4,7 @@ error: expected a pattern, found an expression LL | let v[0] = v[1]; | ^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error[E0425]: cannot find value `v` in this scope --> $DIR/pat-lt-bracket-5.rs:2:16 diff --git a/tests/ui/parser/pat-lt-bracket-6.stderr b/tests/ui/parser/pat-lt-bracket-6.stderr index 14ae602fedfa1..0274809f800c5 100644 --- a/tests/ui/parser/pat-lt-bracket-6.stderr +++ b/tests/ui/parser/pat-lt-bracket-6.stderr @@ -4,7 +4,7 @@ error: expected a pattern, found an expression LL | let Test(&desc[..]) = x; | ^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error[E0308]: mismatched types --> $DIR/pat-lt-bracket-6.rs:10:30 diff --git a/tests/ui/parser/pat-ranges-3.stderr b/tests/ui/parser/pat-ranges-3.stderr index ef080368e19ca..fcda924d98c51 100644 --- a/tests/ui/parser/pat-ranges-3.stderr +++ b/tests/ui/parser/pat-ranges-3.stderr @@ -4,7 +4,7 @@ error: expected a pattern range bound, found an expression LL | let 10 ..= 10 + 3 = 12; | ^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error: expected a pattern range bound, found an expression --> $DIR/pat-ranges-3.rs:7:9 @@ -12,7 +12,7 @@ error: expected a pattern range bound, found an expression LL | let 10 - 3 ..= 10 = 8; | ^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error: aborting due to 2 previous errors diff --git a/tests/ui/parser/recover/recover-pat-exprs.stderr b/tests/ui/parser/recover/recover-pat-exprs.stderr index 6cb3753de8d17..041dfd647ad07 100644 --- a/tests/ui/parser/recover/recover-pat-exprs.stderr +++ b/tests/ui/parser/recover/recover-pat-exprs.stderr @@ -4,7 +4,7 @@ error: expected a pattern, found an expression LL | x.y => (), | ^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == x.y => (), @@ -27,7 +27,7 @@ error: expected a pattern, found an expression LL | x.0 => (), | ^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == x.0 => (), @@ -51,7 +51,7 @@ error: expected a pattern, found an expression LL | x._0 => (), | ^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == x._0 => (), @@ -76,7 +76,7 @@ error: expected a pattern, found an expression LL | x.0.1 => (), | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == x.0.1 => (), @@ -101,7 +101,7 @@ error: expected a pattern, found an expression LL | x.4.y.17.__z => (), | ^^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == x.4.y.17.__z => (), @@ -156,7 +156,7 @@ error: expected a pattern, found an expression LL | x[0] => (), | ^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == x[0] => (), @@ -178,7 +178,7 @@ error: expected a pattern, found an expression LL | x[..] => (), | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == x[..] => (), @@ -228,7 +228,7 @@ error: expected a pattern, found an expression LL | x.f() => (), | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == x.f() => (), @@ -250,7 +250,7 @@ error: expected a pattern, found an expression LL | x._f() => (), | ^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == x._f() => (), @@ -273,7 +273,7 @@ error: expected a pattern, found an expression LL | x? => (), | ^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == x? => (), @@ -297,7 +297,7 @@ error: expected a pattern, found an expression LL | ().f() => (), | ^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == ().f() => (), @@ -322,7 +322,7 @@ error: expected a pattern, found an expression LL | (0, x)?.f() => (), | ^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == (0, x)?.f() => (), @@ -347,7 +347,7 @@ error: expected a pattern, found an expression LL | x.f().g() => (), | ^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == x.f().g() => (), @@ -372,7 +372,7 @@ error: expected a pattern, found an expression LL | 0.f()?.g()?? => (), | ^^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == 0.f()?.g()?? => (), @@ -397,7 +397,7 @@ error: expected a pattern, found an expression LL | x as usize => (), | ^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == x as usize => (), @@ -419,7 +419,7 @@ error: expected a pattern, found an expression LL | 0 as usize => (), | ^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == 0 as usize => (), @@ -442,7 +442,7 @@ error: expected a pattern, found an expression LL | x.f().0.4 as f32 => (), | ^^^^^^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == x.f().0.4 as f32 => (), @@ -466,7 +466,7 @@ error: expected a pattern, found an expression LL | 1 + 1 => (), | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == 1 + 1 => (), @@ -488,7 +488,7 @@ error: expected a pattern, found an expression LL | (1 + 2) * 3 => (), | ^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == (1 + 2) * 3 => (), @@ -511,7 +511,7 @@ error: expected a pattern, found an expression LL | x.0 > 2 => (), | ^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == (x.0 > 2) => (), @@ -536,7 +536,7 @@ error: expected a pattern, found an expression LL | x.0 == 2 => (), | ^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == (x.0 == 2) => (), @@ -561,7 +561,7 @@ error: expected a pattern, found an expression LL | (x, y.0 > 2) if x != 0 => (), | ^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to the match arm guard | LL | (x, val) if x != 0 && val == (y.0 > 2) => (), @@ -583,7 +583,7 @@ error: expected a pattern, found an expression LL | (x, y.0 > 2) if x != 0 || x != 1 => (), | ^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to the match arm guard | LL | (x, val) if (x != 0 || x != 1) && val == (y.0 > 2) => (), @@ -623,7 +623,7 @@ error: expected a pattern, found an expression LL | u8::MAX.abs() => (), | ^^^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == u8::MAX.abs() => (), @@ -645,7 +645,7 @@ error: expected a pattern, found an expression LL | z @ w @ v.u() => (), | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | z @ w @ val if val == v.u() => (), @@ -670,7 +670,7 @@ error: expected a pattern, found an expression LL | y.ilog(3) => (), | ^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == y.ilog(3) => (), @@ -695,7 +695,7 @@ error: expected a pattern, found an expression LL | n + 1 => (), | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == n + 1 => (), @@ -720,7 +720,7 @@ error: expected a pattern, found an expression LL | ("".f() + 14 * 8) => (), | ^^^^^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | (val) if val == "".f() + 14 * 8 => (), @@ -745,7 +745,7 @@ error: expected a pattern, found an expression LL | f?() => (), | ^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | val if val == f?() => (), @@ -770,7 +770,7 @@ error: expected a pattern, found an expression LL | let 1 + 1 = 2; | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error: expected one of `)`, `,`, `@`, or `|`, found `*` --> $DIR/recover-pat-exprs.rs:104:28 @@ -787,7 +787,7 @@ error: expected a pattern, found an expression LL | (1 + 2) * 3 => (), | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error: expected a pattern, found an expression --> $DIR/recover-pat-exprs.rs:75:5 @@ -795,7 +795,7 @@ error: expected a pattern, found an expression LL | 1 + 2 * PI.cos() => 2, | ^^^^^^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error: expected a pattern, found an expression --> $DIR/recover-pat-exprs.rs:83:9 @@ -803,7 +803,7 @@ error: expected a pattern, found an expression LL | x.sqrt() @ .. => (), | ^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error: aborting due to 45 previous errors diff --git a/tests/ui/parser/recover/recover-pat-issues.stderr b/tests/ui/parser/recover/recover-pat-issues.stderr index 17cb7b4aead80..bdd0b2b260e7f 100644 --- a/tests/ui/parser/recover/recover-pat-issues.stderr +++ b/tests/ui/parser/recover/recover-pat-issues.stderr @@ -4,7 +4,7 @@ error: expected a pattern, found an expression LL | Foo("hi".to_owned()) => true, | ^^^^^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | Foo(val) if val == "hi".to_owned() => true, @@ -26,7 +26,7 @@ error: expected a pattern, found an expression LL | Bar { baz: "hi".to_owned() } => true, | ^^^^^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | Bar { baz } if baz == "hi".to_owned() => true, @@ -48,7 +48,7 @@ error: expected a pattern, found an expression LL | &["foo".to_string()] => {} | ^^^^^^^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider moving the expression to a match arm guard | LL | &[val] if val == "foo".to_string() => {} @@ -70,7 +70,7 @@ error: expected a pattern, found an expression LL | if let Some(MAGIC.0 as usize) = None:: {} | ^^^^^^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = MAGIC.0 as usize; @@ -87,7 +87,7 @@ error: expected a pattern, found an expression LL | if let (-1.some(4)) = (0, Some(4)) {} | ^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = -1.some(4); @@ -104,7 +104,7 @@ error: expected a pattern, found an expression LL | if let (-1.Some(4)) = (0, Some(4)) {} | ^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = -1.Some(4); diff --git a/tests/ui/parser/recover/recover-pat-lets.stderr b/tests/ui/parser/recover/recover-pat-lets.stderr index b481813b24621..55252729d7baa 100644 --- a/tests/ui/parser/recover/recover-pat-lets.stderr +++ b/tests/ui/parser/recover/recover-pat-lets.stderr @@ -4,7 +4,7 @@ error: expected a pattern, found an expression LL | let x.expect("foo"); | ^^^^^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error: expected a pattern, found an expression --> $DIR/recover-pat-lets.rs:7:9 @@ -12,7 +12,7 @@ error: expected a pattern, found an expression LL | let x.unwrap(): u32; | ^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error: expected a pattern, found an expression --> $DIR/recover-pat-lets.rs:10:9 @@ -20,7 +20,7 @@ error: expected a pattern, found an expression LL | let x[0] = 1; | ^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error: expected a pattern, found an expression --> $DIR/recover-pat-lets.rs:13:14 @@ -28,7 +28,7 @@ error: expected a pattern, found an expression LL | let Some(1 + 1) = x else { | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 1 + 1; @@ -45,7 +45,7 @@ error: expected a pattern, found an expression LL | if let Some(1 + 1) = x { | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 1 + 1; diff --git a/tests/ui/parser/recover/recover-pat-ranges.stderr b/tests/ui/parser/recover/recover-pat-ranges.stderr index 0a9b54474689a..e8f323596d0fa 100644 --- a/tests/ui/parser/recover/recover-pat-ranges.stderr +++ b/tests/ui/parser/recover/recover-pat-ranges.stderr @@ -88,7 +88,7 @@ error: expected a pattern range bound, found an expression LL | ..=1 + 2 => (), | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 1 + 2; @@ -109,7 +109,7 @@ error: expected a pattern range bound, found an expression LL | (-4 + 0).. => (), | ^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = -4 + 0; @@ -130,7 +130,7 @@ error: expected a pattern range bound, found an expression LL | (1 + 4)...1 * 2 => (), | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 1 + 4; @@ -151,7 +151,7 @@ error: expected a pattern range bound, found an expression LL | (1 + 4)...1 * 2 => (), | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 1 * 2; @@ -172,7 +172,7 @@ error: expected a pattern range bound, found an expression LL | 0.x()..="y".z() => (), | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 0.x(); @@ -193,7 +193,7 @@ error: expected a pattern range bound, found an expression LL | 0.x()..="y".z() => (), | ^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = "y".z(); diff --git a/tests/ui/parser/recover/recover-pat-wildcards.stderr b/tests/ui/parser/recover/recover-pat-wildcards.stderr index 8d4212ed389dd..81a9920f6a243 100644 --- a/tests/ui/parser/recover/recover-pat-wildcards.stderr +++ b/tests/ui/parser/recover/recover-pat-wildcards.stderr @@ -77,7 +77,7 @@ error: expected a pattern range bound, found an expression LL | 4..=(2 + _) => () | ^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 2 + _; diff --git a/tests/ui/parser/recover/recover-range-pats.stderr b/tests/ui/parser/recover/recover-range-pats.stderr index b8e91c2344aff..5c134bd4a82ab 100644 --- a/tests/ui/parser/recover/recover-range-pats.stderr +++ b/tests/ui/parser/recover/recover-range-pats.stderr @@ -613,7 +613,7 @@ LL | mac2!(0, 1); | ----------- in this macro invocation | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -627,7 +627,7 @@ LL | mac2!(0, 1); | ----------- in this macro invocation | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -641,7 +641,7 @@ LL | mac2!(0, 1); | ----------- in this macro invocation | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -655,7 +655,7 @@ LL | mac!(0); | ------- in this macro invocation | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -669,7 +669,7 @@ LL | mac!(0); | ------- in this macro invocation | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -683,7 +683,7 @@ LL | mac!(0); | ------- in this macro invocation | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -697,7 +697,7 @@ LL | mac!(0); | ------- in this macro invocation | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -711,7 +711,7 @@ LL | mac!(0); | ------- in this macro invocation | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -725,7 +725,7 @@ LL | mac!(0); | ------- in this macro invocation | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/path.rs b/tests/ui/path.rs index cd6962ac3e0c7..bd7b99ac01ad5 100644 --- a/tests/ui/path.rs +++ b/tests/ui/path.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 mod foo { pub fn bar(_offset: usize) { } diff --git a/tests/ui/pattern/fn-in-pat.stderr b/tests/ui/pattern/fn-in-pat.stderr index 41ea4df72a2ff..90b1dff32ce56 100644 --- a/tests/ui/pattern/fn-in-pat.stderr +++ b/tests/ui/pattern/fn-in-pat.stderr @@ -4,7 +4,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated function LL | A::new() => (), | ^^^^^^^^ `fn` calls are not allowed in patterns | - = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html + = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html error: aborting due to 1 previous error diff --git a/tests/ui/pattern/issue-106552.stderr b/tests/ui/pattern/issue-106552.stderr index 96f3d68458fa4..6d9a989f182ea 100644 --- a/tests/ui/pattern/issue-106552.stderr +++ b/tests/ui/pattern/issue-106552.stderr @@ -5,7 +5,7 @@ LL | let 5 = 6; | ^ patterns `i32::MIN..=4_i32` and `6_i32..=i32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` help: you might want to use `if let` to ignore the variants that aren't matched | @@ -23,7 +23,7 @@ LL | let x @ 5 = 6; | ^ patterns `i32::MIN..=4_i32` and `6_i32..=i32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` help: you might want to use `let else` to handle the variants that aren't matched | diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024.rs b/tests/ui/pattern/mut_preserve_binding_mode_2024.rs index 19aa73573b46b..a4afcb2e5111c 100644 --- a/tests/ui/pattern/mut_preserve_binding_mode_2024.rs +++ b/tests/ui/pattern/mut_preserve_binding_mode_2024.rs @@ -1,6 +1,5 @@ //@ run-pass //@ edition: 2024 -//@ compile-flags: -Zunstable-options #![feature(mut_ref, ref_pat_eat_one_layer_2024)] #![allow(incomplete_features, unused)] diff --git a/tests/ui/pattern/pattern-binding-disambiguation.stderr b/tests/ui/pattern/pattern-binding-disambiguation.stderr index 61c32b6a17bdf..3ba63b4d253c4 100644 --- a/tests/ui/pattern/pattern-binding-disambiguation.stderr +++ b/tests/ui/pattern/pattern-binding-disambiguation.stderr @@ -87,7 +87,7 @@ LL | let UnitVariant = UnitVariant; | ^^^^^^^^^^^ patterns `E::TupleVariant` and `E::BracedVariant { }` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `E` defined here --> $DIR/pattern-binding-disambiguation.rs:5:6 | diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs index 0b70e4404abce..daa9b7368fd0e 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Z unstable-options // This contains a binding in edition 2024, so if matched with a reference binding mode it will end // up with a `mut ref mut` binding mode. We use this to test the migration lint on patterns with diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs index a822c90ab6e5a..50b716a111138 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs @@ -1,6 +1,5 @@ //@ check-fail //@ edition: 2024 -//@ compile-flags: -Zunstable-options #![deny(rust_2024_incompatible_pat)] fn main() {} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr index 33e4f0021b7ba..92058095f84a2 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/min_match_ergonomics_fail.rs:24:20 + --> $DIR/min_match_ergonomics_fail.rs:23:20 | LL | test_pat_on_type![(&x,): &(T,)]; | ^^ ----- expected due to this @@ -15,7 +15,7 @@ LL + test_pat_on_type![(x,): &(T,)]; | error[E0308]: mismatched types - --> $DIR/min_match_ergonomics_fail.rs:26:20 + --> $DIR/min_match_ergonomics_fail.rs:25:20 | LL | test_pat_on_type![(&x,): &(&mut T,)]; | ^^ ---------- expected due to this @@ -31,7 +31,7 @@ LL + test_pat_on_type![(x,): &(&mut T,)]; | error[E0308]: mismatched types - --> $DIR/min_match_ergonomics_fail.rs:27:20 + --> $DIR/min_match_ergonomics_fail.rs:26:20 | LL | test_pat_on_type![(&mut x,): &(&T,)]; | ^^^^^^ ------ expected due to this @@ -41,7 +41,7 @@ LL | test_pat_on_type![(&mut x,): &(&T,)]; = note: expected reference `&T` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/min_match_ergonomics_fail.rs:27:20 + --> $DIR/min_match_ergonomics_fail.rs:26:20 | LL | test_pat_on_type![(&mut x,): &(&T,)]; | ^^^^^^ @@ -52,7 +52,7 @@ LL + test_pat_on_type![(x,): &(&T,)]; | error[E0308]: mismatched types - --> $DIR/min_match_ergonomics_fail.rs:29:20 + --> $DIR/min_match_ergonomics_fail.rs:28:20 | LL | test_pat_on_type![(&x,): &&mut &(T,)]; | ^^ ----------- expected due to this @@ -68,7 +68,7 @@ LL + test_pat_on_type![(x,): &&mut &(T,)]; | error[E0308]: mismatched types - --> $DIR/min_match_ergonomics_fail.rs:30:29 + --> $DIR/min_match_ergonomics_fail.rs:29:29 | LL | test_pat_on_type![Foo { f: (&x,) }: Foo]; | ^^ --- expected due to this @@ -84,7 +84,7 @@ LL + test_pat_on_type![Foo { f: (x,) }: Foo]; | error[E0308]: mismatched types - --> $DIR/min_match_ergonomics_fail.rs:31:29 + --> $DIR/min_match_ergonomics_fail.rs:30:29 | LL | test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; | ^^ -------- expected due to this @@ -100,7 +100,7 @@ LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo]; | error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:25:19 + --> $DIR/min_match_ergonomics_fail.rs:24:19 | LL | test_pat_on_type![(&x,): &(&T,)]; | -^^^^ @@ -108,7 +108,7 @@ LL | test_pat_on_type![(&x,): &(&T,)]; | help: desugar the match ergonomics: `&` error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:28:19 + --> $DIR/min_match_ergonomics_fail.rs:27:19 | LL | test_pat_on_type![(&mut x,): &(&mut T,)]; | -^^^^^^^^ @@ -116,7 +116,7 @@ LL | test_pat_on_type![(&mut x,): &(&mut T,)]; | help: desugar the match ergonomics: `&` error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:32:19 + --> $DIR/min_match_ergonomics_fail.rs:31:19 | LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; | -^^^^^^^^^^^^^^^ @@ -124,7 +124,7 @@ LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; | help: desugar the match ergonomics: `&` error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:33:19 + --> $DIR/min_match_ergonomics_fail.rs:32:19 | LL | test_pat_on_type![(mut x,): &(T,)]; | -^^^^^^^ @@ -132,7 +132,7 @@ LL | test_pat_on_type![(mut x,): &(T,)]; | help: desugar the match ergonomics: `&` error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:34:19 + --> $DIR/min_match_ergonomics_fail.rs:33:19 | LL | test_pat_on_type![(ref x,): &(T,)]; | -^^^^^^^ @@ -140,7 +140,7 @@ LL | test_pat_on_type![(ref x,): &(T,)]; | help: desugar the match ergonomics: `&` error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:35:19 + --> $DIR/min_match_ergonomics_fail.rs:34:19 | LL | test_pat_on_type![(ref mut x,): &mut (T,)]; | -^^^^^^^^^^^ @@ -148,7 +148,7 @@ LL | test_pat_on_type![(ref mut x,): &mut (T,)]; | help: desugar the match ergonomics: `&mut` error: patterns are not allowed to reset the default binding mode in edition 2024 - --> $DIR/min_match_ergonomics_fail.rs:44:9 + --> $DIR/min_match_ergonomics_fail.rs:43:9 | LL | (&x,) => x, | -^^^^ diff --git a/tests/ui/pattern/self-ctor-133272.rs b/tests/ui/pattern/self-ctor-133272.rs new file mode 100644 index 0000000000000..ad64d6b88cd91 --- /dev/null +++ b/tests/ui/pattern/self-ctor-133272.rs @@ -0,0 +1,21 @@ +//! Regression test for , where a `ref Self` ctor +//! makes it possible to hit a `delayed_bug` that was converted into a `span_bug` in +//! , and hitting this reveals that we did not have +//! test coverage for this specific code pattern (heh) previously. +//! +//! # References +//! +//! - ICE bug report: . +//! - Previous PR to change `delayed_bug` -> `span_bug`: +//! +#![crate_type = "lib"] + +struct Foo; + +impl Foo { + fn fun() { + let S { ref Self } = todo!(); + //~^ ERROR expected identifier, found keyword `Self` + //~| ERROR cannot find struct, variant or union type `S` in this scope + } +} diff --git a/tests/ui/pattern/self-ctor-133272.stderr b/tests/ui/pattern/self-ctor-133272.stderr new file mode 100644 index 0000000000000..bca55a43d9c08 --- /dev/null +++ b/tests/ui/pattern/self-ctor-133272.stderr @@ -0,0 +1,15 @@ +error: expected identifier, found keyword `Self` + --> $DIR/self-ctor-133272.rs:17:21 + | +LL | let S { ref Self } = todo!(); + | ^^^^ expected identifier, found keyword + +error[E0422]: cannot find struct, variant or union type `S` in this scope + --> $DIR/self-ctor-133272.rs:17:13 + | +LL | let S { ref Self } = todo!(); + | ^ not found in this scope + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0422`. diff --git a/tests/ui/pattern/skipped-ref-pats-issue-125058.rs b/tests/ui/pattern/skipped-ref-pats-issue-125058.rs index b733e5fda0a26..2b587ecb91f30 100644 --- a/tests/ui/pattern/skipped-ref-pats-issue-125058.rs +++ b/tests/ui/pattern/skipped-ref-pats-issue-125058.rs @@ -1,6 +1,5 @@ //@ run-pass //@ edition: 2024 -//@ compile-flags: -Zunstable-options #![allow(incomplete_features)] #![feature(ref_pat_eat_one_layer_2024)] diff --git a/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr b/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr index cee1cc673c7e6..f7fd4a4cc292a 100644 --- a/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr +++ b/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr @@ -1,5 +1,5 @@ warning: struct `Foo` is never constructed - --> $DIR/skipped-ref-pats-issue-125058.rs:8:8 + --> $DIR/skipped-ref-pats-issue-125058.rs:7:8 | LL | struct Foo; | ^^^ @@ -7,7 +7,7 @@ LL | struct Foo; = note: `#[warn(dead_code)]` on by default warning: unused closure that must be used - --> $DIR/skipped-ref-pats-issue-125058.rs:12:5 + --> $DIR/skipped-ref-pats-issue-125058.rs:11:5 | LL | / || { LL | | diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr index ec08e22e2ca07..4a435bcc8bad9 100644 --- a/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr +++ b/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr @@ -54,7 +54,7 @@ LL | let None = *x; | ^^^^ pattern `Some(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: pattern `Some(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future = note: the matched value is of type `Option` help: you might want to use `if let` to ignore the variant that isn't matched diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr b/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr index ec08e22e2ca07..4a435bcc8bad9 100644 --- a/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr +++ b/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr @@ -54,7 +54,7 @@ LL | let None = *x; | ^^^^ pattern `Some(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: pattern `Some(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future = note: the matched value is of type `Option` help: you might want to use `if let` to ignore the variant that isn't matched diff --git a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr index c6e41c1875fa7..23821decd6e43 100644 --- a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr +++ b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr @@ -150,7 +150,7 @@ LL | let Ok(_x) = res_u32_never.as_ref(); | ^^^^^^ pattern `Err(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Result<&u32, &!>` help: you might want to use `let else` to handle the variant that isn't matched | diff --git a/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr b/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr index 2e5511527d59c..cf37bf67e860b 100644 --- a/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr +++ b/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr @@ -126,7 +126,7 @@ LL | let Ok(_x) = res_u32_never.as_ref(); | ^^^^^^ pattern `Err(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Result<&u32, &!>` help: you might want to use `let else` to handle the variant that isn't matched | @@ -140,7 +140,7 @@ LL | let Ok(_x) = &res_u32_never; | ^^^^^^ pattern `&Err(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `&Result` help: you might want to use `let else` to handle the variant that isn't matched | diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr index 3f312d46c7ee8..84aefe7d96370 100644 --- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr +++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr @@ -104,7 +104,7 @@ LL | let Ok(_x) = res_u32_never.as_ref(); | ^^^^^^ pattern `Err(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Result<&u32, &!>` help: you might want to use `let else` to handle the variant that isn't matched | @@ -118,7 +118,7 @@ LL | let Ok(_x) = &res_u32_never; | ^^^^^^ pattern `&Err(!)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `&Result` help: you might want to use `let else` to handle the variant that isn't matched | @@ -239,7 +239,7 @@ LL | let Ok(_) = *ptr_result_never_err; | ^^^^^ pattern `Err(!)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Result` help: you might want to use `if let` to ignore the variant that isn't matched | diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr index bba50dab27b04..f3af74c16c30f 100644 --- a/tests/ui/pattern/usefulness/empty-types.normal.stderr +++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr @@ -95,7 +95,7 @@ LL | let Ok(_x) = res_u32_never.as_ref(); | ^^^^^^ pattern `Err(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Result<&u32, &!>` help: you might want to use `let else` to handle the variant that isn't matched | @@ -109,7 +109,7 @@ LL | let Ok(_x) = &res_u32_never; | ^^^^^^ pattern `&Err(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `&Result` help: you might want to use `let else` to handle the variant that isn't matched | @@ -230,7 +230,7 @@ LL | let Ok(_) = *ptr_result_never_err; | ^^^^^ pattern `Err(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Result` help: you might want to use `if let` to ignore the variant that isn't matched | diff --git a/tests/ui/pattern/usefulness/irrefutable-unit.rs b/tests/ui/pattern/usefulness/irrefutable-unit.rs index b4e72c0aa2ac4..9a48b1a8679b7 100644 --- a/tests/ui/pattern/usefulness/irrefutable-unit.rs +++ b/tests/ui/pattern/usefulness/irrefutable-unit.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { let ((),()) = ((),()); diff --git a/tests/ui/pattern/usefulness/issue-31561.stderr b/tests/ui/pattern/usefulness/issue-31561.stderr index cc72056582844..ba7ae3fa9a003 100644 --- a/tests/ui/pattern/usefulness/issue-31561.stderr +++ b/tests/ui/pattern/usefulness/issue-31561.stderr @@ -5,7 +5,7 @@ LL | let Thing::Foo(y) = Thing::Foo(1); | ^^^^^^^^^^^^^ patterns `Thing::Bar` and `Thing::Baz` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `Thing` defined here --> $DIR/issue-31561.rs:1:6 | diff --git a/tests/ui/pattern/usefulness/nested-exhaustive-match.rs b/tests/ui/pattern/usefulness/nested-exhaustive-match.rs index 51b05c9a1116e..23782a49b5bbe 100644 --- a/tests/ui/pattern/usefulness/nested-exhaustive-match.rs +++ b/tests/ui/pattern/usefulness/nested-exhaustive-match.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct Foo { foo: bool, bar: Option, baz: isize } diff --git a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.rs b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.rs index 1d1ea8e496466..d0a8a10f2f371 100644 --- a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.rs +++ b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.rs @@ -44,7 +44,7 @@ fn by_val(e: E) { //~^ ERROR refutable pattern in local binding //~| patterns `E::B` and `E::C` not covered //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with - //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html //~| NOTE the matched value is of type `E` } @@ -60,7 +60,7 @@ fn by_ref_once(e: &E) { //~^ ERROR refutable pattern in local binding //~| patterns `&E::B` and `&E::C` not covered //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with - //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html //~| NOTE the matched value is of type `&E` } @@ -76,7 +76,7 @@ fn by_ref_thrice(e: & &mut &E) { //~^ ERROR refutable pattern in local binding //~| patterns `&&mut &E::B` and `&&mut &E::C` not covered //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with - //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html //~| NOTE the matched value is of type `&&mut &E` } @@ -103,7 +103,7 @@ fn ref_pat(e: Opt) { //~| NOTE the matched value is of type `Opt` //~| NOTE pattern `Opt::None` not covered //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with - //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html } fn main() {} diff --git a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr index a9e55fa53a68e..48d7a636055dc 100644 --- a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr +++ b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr @@ -29,7 +29,7 @@ LL | let E::A = e; | ^^^^ patterns `E::B` and `E::C` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `E` defined here --> $DIR/non-exhaustive-defined-here.rs:8:6 | @@ -78,7 +78,7 @@ LL | let E::A = e; | ^^^^ patterns `&E::B` and `&E::C` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `E` defined here --> $DIR/non-exhaustive-defined-here.rs:8:6 | @@ -127,7 +127,7 @@ LL | let E::A = e; | ^^^^ patterns `&&mut &E::B` and `&&mut &E::C` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `E` defined here --> $DIR/non-exhaustive-defined-here.rs:8:6 | @@ -173,7 +173,7 @@ LL | let Opt::Some(ref _x) = e; | ^^^^^^^^^^^^^^^^^ pattern `Opt::None` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `Opt` defined here --> $DIR/non-exhaustive-defined-here.rs:83:6 | diff --git a/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr b/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr index e66cd11302387..23a5d895d6c1a 100644 --- a/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr +++ b/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr @@ -13,7 +13,7 @@ LL | let (1, (Some(1), 2..=3)) = (1, (None, 2)); | ^^^^^^^^^^^^^^^^^^^^^ patterns `(i32::MIN..=0_i32, _)` and `(2_i32..=i32::MAX, _)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `(i32, (Option, i32))` help: you might want to use `if let` to ignore the variants that aren't matched | diff --git a/tests/ui/privacy/priv-impl-prim-ty.rs b/tests/ui/privacy/priv-impl-prim-ty.rs index f4c4973f61baf..ea1145f3c3473 100644 --- a/tests/ui/privacy/priv-impl-prim-ty.rs +++ b/tests/ui/privacy/priv-impl-prim-ty.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:priv-impl-prim-ty.rs -//@ pretty-expanded FIXME #23616 extern crate priv_impl_prim_ty as bar; diff --git a/tests/ui/privacy/privacy-ns.rs b/tests/ui/privacy/privacy-ns.rs index 10d5e7222177b..ab3d79e40f918 100644 --- a/tests/ui/privacy/privacy-ns.rs +++ b/tests/ui/privacy/privacy-ns.rs @@ -5,7 +5,6 @@ // Check we do the correct privacy checks when we import a name and there is an // item with that name in both the value and type namespaces. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] #![allow(unused_imports)] diff --git a/tests/ui/privacy/privacy-reexport.rs b/tests/ui/privacy/privacy-reexport.rs index df642a57372e0..74ac7cdce94fe 100644 --- a/tests/ui/privacy/privacy-reexport.rs +++ b/tests/ui/privacy/privacy-reexport.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:privacy_reexport.rs -//@ pretty-expanded FIXME #23616 extern crate privacy_reexport; diff --git a/tests/ui/privacy/privacy1-rpass.rs b/tests/ui/privacy/privacy1-rpass.rs index 10bc2492bc807..546492c870947 100644 --- a/tests/ui/privacy/privacy1-rpass.rs +++ b/tests/ui/privacy/privacy1-rpass.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub mod test2 { // This used to generate an ICE (make sure that default functions are diff --git a/tests/ui/privacy/private-method-rpass.rs b/tests/ui/privacy/private-method-rpass.rs index 2ec29327d462f..f62dd682d2bc4 100644 --- a/tests/ui/privacy/private-method-rpass.rs +++ b/tests/ui/privacy/private-method-rpass.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 struct cat { meows : usize, diff --git a/tests/ui/privacy/pub-extern-privacy.rs b/tests/ui/privacy/pub-extern-privacy.rs index dc5e8951bfc00..0f9131685b0e2 100644 --- a/tests/ui/privacy/pub-extern-privacy.rs +++ b/tests/ui/privacy/pub-extern-privacy.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use std::mem::transmute; diff --git a/tests/ui/privacy/pub-use-xcrate.rs b/tests/ui/privacy/pub-use-xcrate.rs index 96c650d0c6843..76891161aed75 100644 --- a/tests/ui/privacy/pub-use-xcrate.rs +++ b/tests/ui/privacy/pub-use-xcrate.rs @@ -2,7 +2,6 @@ //@ aux-build:pub_use_xcrate1.rs //@ aux-build:pub_use_xcrate2.rs -//@ pretty-expanded FIXME #23616 extern crate pub_use_xcrate2; diff --git a/tests/ui/privacy/pub_use_mods_xcrate_exe.rs b/tests/ui/privacy/pub_use_mods_xcrate_exe.rs index 12b16c8cec8ec..f986bfb76e117 100644 --- a/tests/ui/privacy/pub_use_mods_xcrate_exe.rs +++ b/tests/ui/privacy/pub_use_mods_xcrate_exe.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:pub_use_mods_xcrate.rs -//@ pretty-expanded FIXME #23616 #![allow(unused_imports)] diff --git a/tests/ui/proc-macro/add-impl.rs b/tests/ui/proc-macro/add-impl.rs index 7780c39f0c14b..2299f05c2e7fa 100644 --- a/tests/ui/proc-macro/add-impl.rs +++ b/tests/ui/proc-macro/add-impl.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:add-impl.rs +//@ proc-macro: add-impl.rs #[macro_use] extern crate add_impl; diff --git a/tests/ui/proc-macro/allowed-attr-stmt-expr.rs b/tests/ui/proc-macro/allowed-attr-stmt-expr.rs index c5e3ffa1672ab..10c2d3f9d1316 100644 --- a/tests/ui/proc-macro/allowed-attr-stmt-expr.rs +++ b/tests/ui/proc-macro/allowed-attr-stmt-expr.rs @@ -1,5 +1,5 @@ -//@ aux-build:attr-stmt-expr.rs -//@ aux-build:test-macros.rs +//@ proc-macro: attr-stmt-expr.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug //@ check-pass diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs-test.rs b/tests/ui/proc-macro/ambiguous-builtin-attrs-test.rs index 3f191cba74583..8ee2223822a3c 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs-test.rs +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs-test.rs @@ -1,4 +1,4 @@ -//@ aux-build:builtin-attrs.rs +//@ proc-macro: builtin-attrs.rs //@ compile-flags:--test #![feature(decl_macro, test)] diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs.rs b/tests/ui/proc-macro/ambiguous-builtin-attrs.rs index c82663541a795..edc7748eff3da 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs.rs +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs.rs @@ -1,5 +1,5 @@ //@ edition:2018 -//@ aux-build:builtin-attrs.rs +//@ proc-macro: builtin-attrs.rs #![feature(decl_macro)] //~ ERROR `feature` is ambiguous extern crate builtin_attrs; diff --git a/tests/ui/proc-macro/amputate-span.fixed b/tests/ui/proc-macro/amputate-span.fixed index 0fdaf01357c76..9742f585d499b 100644 --- a/tests/ui/proc-macro/amputate-span.fixed +++ b/tests/ui/proc-macro/amputate-span.fixed @@ -1,4 +1,4 @@ -//@ aux-build:amputate-span.rs +//@ proc-macro: amputate-span.rs //@ run-rustfix //@ edition:2018 //@ compile-flags: --extern amputate_span diff --git a/tests/ui/proc-macro/amputate-span.rs b/tests/ui/proc-macro/amputate-span.rs index 7081660bc29f6..6cdde46962ebe 100644 --- a/tests/ui/proc-macro/amputate-span.rs +++ b/tests/ui/proc-macro/amputate-span.rs @@ -1,4 +1,4 @@ -//@ aux-build:amputate-span.rs +//@ proc-macro: amputate-span.rs //@ run-rustfix //@ edition:2018 //@ compile-flags: --extern amputate_span diff --git a/tests/ui/proc-macro/append-impl.rs b/tests/ui/proc-macro/append-impl.rs index f5163e965a03f..c0f208460b297 100644 --- a/tests/ui/proc-macro/append-impl.rs +++ b/tests/ui/proc-macro/append-impl.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:append-impl.rs +//@ proc-macro: append-impl.rs #![allow(warnings)] diff --git a/tests/ui/proc-macro/attr-args.rs b/tests/ui/proc-macro/attr-args.rs index ed7e96bcc89cf..1d3e0f725d250 100644 --- a/tests/ui/proc-macro/attr-args.rs +++ b/tests/ui/proc-macro/attr-args.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:attr-args.rs +//@ proc-macro: attr-args.rs #![allow(warnings)] diff --git a/tests/ui/proc-macro/attr-cfg.rs b/tests/ui/proc-macro/attr-cfg.rs index 4679807ad79ad..af0c6e1b5410e 100644 --- a/tests/ui/proc-macro/attr-cfg.rs +++ b/tests/ui/proc-macro/attr-cfg.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:attr-cfg.rs +//@ proc-macro: attr-cfg.rs //@ revisions: foo bar extern crate attr_cfg; diff --git a/tests/ui/proc-macro/attr-complex-fn.rs b/tests/ui/proc-macro/attr-complex-fn.rs index 7baf469d7d0ff..bf100401a65fc 100644 --- a/tests/ui/proc-macro/attr-complex-fn.rs +++ b/tests/ui/proc-macro/attr-complex-fn.rs @@ -1,6 +1,6 @@ //@ check-pass //@ compile-flags: -Z span-debug --error-format human -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![feature(stmt_expr_attributes)] #![feature(custom_inner_attributes)] diff --git a/tests/ui/proc-macro/attr-invalid-exprs.rs b/tests/ui/proc-macro/attr-invalid-exprs.rs index ec0b79469a457..f476858a32ba1 100644 --- a/tests/ui/proc-macro/attr-invalid-exprs.rs +++ b/tests/ui/proc-macro/attr-invalid-exprs.rs @@ -1,6 +1,6 @@ //! Attributes producing expressions in invalid locations -//@ aux-build:attr-stmt-expr.rs +//@ proc-macro: attr-stmt-expr.rs #![feature(proc_macro_hygiene)] #![feature(stmt_expr_attributes)] diff --git a/tests/ui/proc-macro/attr-on-trait.rs b/tests/ui/proc-macro/attr-on-trait.rs index 659b461f7593c..e95760a837c05 100644 --- a/tests/ui/proc-macro/attr-on-trait.rs +++ b/tests/ui/proc-macro/attr-on-trait.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:attr-on-trait.rs +//@ proc-macro: attr-on-trait.rs extern crate attr_on_trait; diff --git a/tests/ui/proc-macro/attr-stmt-expr-rpass.rs b/tests/ui/proc-macro/attr-stmt-expr-rpass.rs index 18e477f012961..c4188bde30940 100644 --- a/tests/ui/proc-macro/attr-stmt-expr-rpass.rs +++ b/tests/ui/proc-macro/attr-stmt-expr-rpass.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:attr-stmt-expr-rpass.rs +//@ proc-macro: attr-stmt-expr-rpass.rs #![feature(stmt_expr_attributes, proc_macro_hygiene)] diff --git a/tests/ui/proc-macro/attr-stmt-expr.rs b/tests/ui/proc-macro/attr-stmt-expr.rs index f33c686f284cd..1ed2bd048e60e 100644 --- a/tests/ui/proc-macro/attr-stmt-expr.rs +++ b/tests/ui/proc-macro/attr-stmt-expr.rs @@ -1,5 +1,5 @@ -//@ aux-build:attr-stmt-expr.rs -//@ aux-build:test-macros.rs +//@ proc-macro: attr-stmt-expr.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug #![feature(proc_macro_hygiene)] diff --git a/tests/ui/proc-macro/attribute-after-derive.rs b/tests/ui/proc-macro/attribute-after-derive.rs index 3120b23e97ee8..f2e2eb12a195e 100644 --- a/tests/ui/proc-macro/attribute-after-derive.rs +++ b/tests/ui/proc-macro/attribute-after-derive.rs @@ -3,7 +3,7 @@ //@ check-pass //@ compile-flags: -Z span-debug -//@ aux-build: test-macros.rs +//@ proc-macro: test-macros.rs #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/tests/ui/proc-macro/attribute-spans-preserved.rs b/tests/ui/proc-macro/attribute-spans-preserved.rs index 946b16a0c80eb..4d5b93797e6e7 100644 --- a/tests/ui/proc-macro/attribute-spans-preserved.rs +++ b/tests/ui/proc-macro/attribute-spans-preserved.rs @@ -1,4 +1,4 @@ -//@ aux-build:attribute-spans-preserved.rs +//@ proc-macro: attribute-spans-preserved.rs extern crate attribute_spans_preserved as foo; diff --git a/tests/ui/proc-macro/attribute-with-error.rs b/tests/ui/proc-macro/attribute-with-error.rs index 5e81a9c70116b..d44d558badd1e 100644 --- a/tests/ui/proc-macro/attribute-with-error.rs +++ b/tests/ui/proc-macro/attribute-with-error.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![feature(custom_inner_attributes)] diff --git a/tests/ui/proc-macro/attributes-included.rs b/tests/ui/proc-macro/attributes-included.rs index 47fd21fdd2493..73d1c1a8f05ae 100644 --- a/tests/ui/proc-macro/attributes-included.rs +++ b/tests/ui/proc-macro/attributes-included.rs @@ -1,4 +1,4 @@ -//@ aux-build:attributes-included.rs +//@ proc-macro: attributes-included.rs //@ check-pass #![warn(unused)] diff --git a/tests/ui/proc-macro/attributes-on-definitions.rs b/tests/ui/proc-macro/attributes-on-definitions.rs index 187d1be236408..d9700434b51ae 100644 --- a/tests/ui/proc-macro/attributes-on-definitions.rs +++ b/tests/ui/proc-macro/attributes-on-definitions.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:attributes-on-definitions.rs +//@ proc-macro: attributes-on-definitions.rs #![forbid(unsafe_code)] diff --git a/tests/ui/proc-macro/attributes-on-modules-fail.rs b/tests/ui/proc-macro/attributes-on-modules-fail.rs index 9b2eb703eacca..80300b47c5fc1 100644 --- a/tests/ui/proc-macro/attributes-on-modules-fail.rs +++ b/tests/ui/proc-macro/attributes-on-modules-fail.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/attributes-on-modules.rs b/tests/ui/proc-macro/attributes-on-modules.rs index 26c8d8e113b5a..f1be7e44a4794 100644 --- a/tests/ui/proc-macro/attributes-on-modules.rs +++ b/tests/ui/proc-macro/attributes-on-modules.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/auxiliary/add-impl.rs b/tests/ui/proc-macro/auxiliary/add-impl.rs index 23a86e76ef9bd..327e6065ef2d1 100644 --- a/tests/ui/proc-macro/auxiliary/add-impl.rs +++ b/tests/ui/proc-macro/auxiliary/add-impl.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/amputate-span.rs b/tests/ui/proc-macro/auxiliary/amputate-span.rs index c1ab0477ba2a8..969176eaa6737 100644 --- a/tests/ui/proc-macro/auxiliary/amputate-span.rs +++ b/tests/ui/proc-macro/auxiliary/amputate-span.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/api/mod.rs b/tests/ui/proc-macro/auxiliary/api/proc_macro_api_tests.rs similarity index 76% rename from tests/ui/proc-macro/auxiliary/api/mod.rs rename to tests/ui/proc-macro/auxiliary/api/proc_macro_api_tests.rs index e0a381cb6c1a7..abd667d8ce1d0 100644 --- a/tests/ui/proc-macro/auxiliary/api/mod.rs +++ b/tests/ui/proc-macro/auxiliary/api/proc_macro_api_tests.rs @@ -1,9 +1,5 @@ -//@ force-host -//@ no-prefer-dynamic //@ edition: 2021 -#![crate_type = "proc-macro"] -#![crate_name = "proc_macro_api_tests"] #![feature(proc_macro_span)] #![deny(dead_code)] // catch if a test function is never called diff --git a/tests/ui/proc-macro/auxiliary/append-impl.rs b/tests/ui/proc-macro/auxiliary/append-impl.rs index 30657d2738e1d..e286f01a97114 100644 --- a/tests/ui/proc-macro/auxiliary/append-impl.rs +++ b/tests/ui/proc-macro/auxiliary/append-impl.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/assert-span-pos.rs b/tests/ui/proc-macro/auxiliary/assert-span-pos.rs index 8935ce2bc0ae6..6459d2169a997 100644 --- a/tests/ui/proc-macro/auxiliary/assert-span-pos.rs +++ b/tests/ui/proc-macro/auxiliary/assert-span-pos.rs @@ -1,8 +1,4 @@ -//@ force-host -//@ no-prefer-dynamic - #![feature(proc_macro_diagnostic, proc_macro_span)] -#![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/attr-args.rs b/tests/ui/proc-macro/auxiliary/attr-args.rs index 1fac41c37217c..6a1041603f15c 100644 --- a/tests/ui/proc-macro/auxiliary/attr-args.rs +++ b/tests/ui/proc-macro/auxiliary/attr-args.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/attr-cfg.rs b/tests/ui/proc-macro/auxiliary/attr-cfg.rs index 3645128b50907..0e62593251217 100644 --- a/tests/ui/proc-macro/auxiliary/attr-cfg.rs +++ b/tests/ui/proc-macro/auxiliary/attr-cfg.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/attr-on-trait.rs b/tests/ui/proc-macro/auxiliary/attr-on-trait.rs index c4581359da127..012243febce0d 100644 --- a/tests/ui/proc-macro/auxiliary/attr-on-trait.rs +++ b/tests/ui/proc-macro/auxiliary/attr-on-trait.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs b/tests/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs index c8b7aa412b52f..022f10e561526 100644 --- a/tests/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs +++ b/tests/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/attr-stmt-expr.rs b/tests/ui/proc-macro/auxiliary/attr-stmt-expr.rs index 888aab848d478..7efeda16b9cd1 100644 --- a/tests/ui/proc-macro/auxiliary/attr-stmt-expr.rs +++ b/tests/ui/proc-macro/auxiliary/attr-stmt-expr.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/attribute-spans-preserved.rs b/tests/ui/proc-macro/auxiliary/attribute-spans-preserved.rs index d06903c270890..76cf959279cf9 100644 --- a/tests/ui/proc-macro/auxiliary/attribute-spans-preserved.rs +++ b/tests/ui/proc-macro/auxiliary/attribute-spans-preserved.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/attributes-included.rs b/tests/ui/proc-macro/auxiliary/attributes-included.rs index cc29818380b6a..3a129c8185efb 100644 --- a/tests/ui/proc-macro/auxiliary/attributes-included.rs +++ b/tests/ui/proc-macro/auxiliary/attributes-included.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{TokenStream, TokenTree, Delimiter, Literal, Spacing, Group}; diff --git a/tests/ui/proc-macro/auxiliary/attributes-on-definitions.rs b/tests/ui/proc-macro/auxiliary/attributes-on-definitions.rs index c7e6e681da30f..ef981ba850021 100644 --- a/tests/ui/proc-macro/auxiliary/attributes-on-definitions.rs +++ b/tests/ui/proc-macro/auxiliary/attributes-on-definitions.rs @@ -1,11 +1,6 @@ -//@ force-host -//@ no-prefer-dynamic - #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/bang-macro.rs b/tests/ui/proc-macro/auxiliary/bang-macro.rs index 361643aa8e5ef..3ac30ab8e3289 100644 --- a/tests/ui/proc-macro/auxiliary/bang-macro.rs +++ b/tests/ui/proc-macro/auxiliary/bang-macro.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/bang_proc_macro2.rs b/tests/ui/proc-macro/auxiliary/bang_proc_macro2.rs index 3df2676ddab71..7a094c2d47734 100644 --- a/tests/ui/proc-macro/auxiliary/bang_proc_macro2.rs +++ b/tests/ui/proc-macro/auxiliary/bang_proc_macro2.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/builtin-attrs.rs b/tests/ui/proc-macro/auxiliary/builtin-attrs.rs index bd634b4f41cd6..9743ec78c9675 100644 --- a/tests/ui/proc-macro/auxiliary/builtin-attrs.rs +++ b/tests/ui/proc-macro/auxiliary/builtin-attrs.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/call-deprecated.rs b/tests/ui/proc-macro/auxiliary/call-deprecated.rs index 8864de17ed3b6..28919ab29ece0 100644 --- a/tests/ui/proc-macro/auxiliary/call-deprecated.rs +++ b/tests/ui/proc-macro/auxiliary/call-deprecated.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/call-site.rs b/tests/ui/proc-macro/auxiliary/call-site.rs index ce0fc70c1a6ce..8201ec5c48fe8 100644 --- a/tests/ui/proc-macro/auxiliary/call-site.rs +++ b/tests/ui/proc-macro/auxiliary/call-site.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/cond_plugin.rs b/tests/ui/proc-macro/auxiliary/cond_plugin.rs index c6cdc8ce8baf0..9858be230c95e 100644 --- a/tests/ui/proc-macro/auxiliary/cond_plugin.rs +++ b/tests/ui/proc-macro/auxiliary/cond_plugin.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_quote)] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/count_compound_ops.rs b/tests/ui/proc-macro/auxiliary/count_compound_ops.rs index 86c27f2d818bd..c5a1c561976eb 100644 --- a/tests/ui/proc-macro/auxiliary/count_compound_ops.rs +++ b/tests/ui/proc-macro/auxiliary/count_compound_ops.rs @@ -1,8 +1,4 @@ -//@ force-host -//@ no-prefer-dynamic - #![feature(proc_macro_quote)] -#![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs b/tests/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs index eab7d903e91c3..0f50aedcd9eb8 100644 --- a/tests/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs +++ b/tests/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/custom-quote.rs b/tests/ui/proc-macro/auxiliary/custom-quote.rs index 88800596ce562..bccbed8a6b492 100644 --- a/tests/ui/proc-macro/auxiliary/custom-quote.rs +++ b/tests/ui/proc-macro/auxiliary/custom-quote.rs @@ -1,9 +1,6 @@ -//@ force-host -//@ no-prefer-dynamic // ignore-tidy-linelength #![feature(proc_macro_quote)] -#![crate_type = "proc-macro"] extern crate proc_macro; use std::iter::FromIterator; diff --git a/tests/ui/proc-macro/auxiliary/derive-a.rs b/tests/ui/proc-macro/auxiliary/derive-a.rs index 50e963a0a4167..89d0263c9e283 100644 --- a/tests/ui/proc-macro/auxiliary/derive-a.rs +++ b/tests/ui/proc-macro/auxiliary/derive-a.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/derive-atob.rs b/tests/ui/proc-macro/auxiliary/derive-atob.rs index 8a1f81450fa86..0ed625657712a 100644 --- a/tests/ui/proc-macro/auxiliary/derive-atob.rs +++ b/tests/ui/proc-macro/auxiliary/derive-atob.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/derive-attr-cfg.rs b/tests/ui/proc-macro/auxiliary/derive-attr-cfg.rs index b9c0b5e6f7763..cb60c182a43c2 100644 --- a/tests/ui/proc-macro/auxiliary/derive-attr-cfg.rs +++ b/tests/ui/proc-macro/auxiliary/derive-attr-cfg.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/derive-b-rpass.rs b/tests/ui/proc-macro/auxiliary/derive-b-rpass.rs index 82f0b4f19eda7..de2935eb9c1de 100644 --- a/tests/ui/proc-macro/auxiliary/derive-b-rpass.rs +++ b/tests/ui/proc-macro/auxiliary/derive-b-rpass.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/derive-b.rs b/tests/ui/proc-macro/auxiliary/derive-b.rs index 0b2cf31b0591b..efdb785c23bea 100644 --- a/tests/ui/proc-macro/auxiliary/derive-b.rs +++ b/tests/ui/proc-macro/auxiliary/derive-b.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/derive-bad.rs b/tests/ui/proc-macro/auxiliary/derive-bad.rs index 3fd2bfc4b63a7..bd25478fb1de0 100644 --- a/tests/ui/proc-macro/auxiliary/derive-bad.rs +++ b/tests/ui/proc-macro/auxiliary/derive-bad.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/derive-clona.rs b/tests/ui/proc-macro/auxiliary/derive-clona.rs index 83bcc5b08be83..b38bf31dbccbf 100644 --- a/tests/ui/proc-macro/auxiliary/derive-clona.rs +++ b/tests/ui/proc-macro/auxiliary/derive-clona.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/derive-ctod.rs b/tests/ui/proc-macro/auxiliary/derive-ctod.rs index 78b1b8615b0bb..1e08ec612621c 100644 --- a/tests/ui/proc-macro/auxiliary/derive-ctod.rs +++ b/tests/ui/proc-macro/auxiliary/derive-ctod.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/derive-foo.rs b/tests/ui/proc-macro/auxiliary/derive-foo.rs index 5c63c3937e4be..22fbc4bc54f12 100644 --- a/tests/ui/proc-macro/auxiliary/derive-foo.rs +++ b/tests/ui/proc-macro/auxiliary/derive-foo.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs b/tests/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs index d09ff6cadc57e..da474cf5614b9 100644 --- a/tests/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs +++ b/tests/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/derive-helper-shadowing.rs b/tests/ui/proc-macro/auxiliary/derive-helper-shadowing.rs index d1f5b67cf85bf..32136f79ff286 100644 --- a/tests/ui/proc-macro/auxiliary/derive-helper-shadowing.rs +++ b/tests/ui/proc-macro/auxiliary/derive-helper-shadowing.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/derive-nothing.rs b/tests/ui/proc-macro/auxiliary/derive-nothing.rs index adf9b4e83fdfa..eefa2c40ac36d 100644 --- a/tests/ui/proc-macro/auxiliary/derive-nothing.rs +++ b/tests/ui/proc-macro/auxiliary/derive-nothing.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/derive-same-struct.rs b/tests/ui/proc-macro/auxiliary/derive-same-struct.rs index bfdd71e9a15fd..8e7bcb6aaba8a 100644 --- a/tests/ui/proc-macro/auxiliary/derive-same-struct.rs +++ b/tests/ui/proc-macro/auxiliary/derive-same-struct.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/derive-two-attrs.rs b/tests/ui/proc-macro/auxiliary/derive-two-attrs.rs index 24a88dceb4b5d..532c72dacffc8 100644 --- a/tests/ui/proc-macro/auxiliary/derive-two-attrs.rs +++ b/tests/ui/proc-macro/auxiliary/derive-two-attrs.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/derive-union.rs b/tests/ui/proc-macro/auxiliary/derive-union.rs index 8bf7041ebad27..da4132604a78b 100644 --- a/tests/ui/proc-macro/auxiliary/derive-union.rs +++ b/tests/ui/proc-macro/auxiliary/derive-union.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/derive-unstable-2.rs b/tests/ui/proc-macro/auxiliary/derive-unstable-2.rs index f80a2cfdd9927..4bc56efecdbf5 100644 --- a/tests/ui/proc-macro/auxiliary/derive-unstable-2.rs +++ b/tests/ui/proc-macro/auxiliary/derive-unstable-2.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/derive-unstable.rs b/tests/ui/proc-macro/auxiliary/derive-unstable.rs index c92df49191b69..8ba3a06e3549e 100644 --- a/tests/ui/proc-macro/auxiliary/derive-unstable.rs +++ b/tests/ui/proc-macro/auxiliary/derive-unstable.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/double.rs b/tests/ui/proc-macro/auxiliary/double.rs index ffde0bce24515..b6d952437ea1f 100644 --- a/tests/ui/proc-macro/auxiliary/double.rs +++ b/tests/ui/proc-macro/auxiliary/double.rs @@ -1,10 +1,5 @@ -//@ force-host -//@ no-prefer-dynamic - #![feature(proc_macro_quote)] -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/duplicate.rs b/tests/ui/proc-macro/auxiliary/duplicate.rs index bcbb1c7474c8e..0474aed22665f 100644 --- a/tests/ui/proc-macro/auxiliary/duplicate.rs +++ b/tests/ui/proc-macro/auxiliary/duplicate.rs @@ -1,8 +1,4 @@ -//@ force-host -//@ no-prefer-dynamic - #![deny(unused)] -#![crate_type = "proc-macro"] extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/edition-gated-async-move-syntax.rs b/tests/ui/proc-macro/auxiliary/edition-gated-async-move-syntax.rs index da6584e31e5fa..9347a2e975b26 100644 --- a/tests/ui/proc-macro/auxiliary/edition-gated-async-move-syntax.rs +++ b/tests/ui/proc-macro/auxiliary/edition-gated-async-move-syntax.rs @@ -1,12 +1,7 @@ -//@ force-host -//@ no-prefer-dynamic - // Proc macro helper for issue #89699, used by tests/ui/proc-macro/edition-gated-async-move- // syntax-issue89699.rs, emitting an `async move` closure. This syntax is only available in // editions 2018 and up, but is used in edition 2015 in the test. -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/edition-imports-2015.rs b/tests/ui/proc-macro/auxiliary/edition-imports-2015.rs index c33736a74a707..6d584f4e6abf7 100644 --- a/tests/ui/proc-macro/auxiliary/edition-imports-2015.rs +++ b/tests/ui/proc-macro/auxiliary/edition-imports-2015.rs @@ -1,8 +1,4 @@ //@ edition:2015 -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/empty-crate.rs b/tests/ui/proc-macro/auxiliary/empty-crate.rs index c502cd921cc8c..5e15112a9cbfc 100644 --- a/tests/ui/proc-macro/auxiliary/empty-crate.rs +++ b/tests/ui/proc-macro/auxiliary/empty-crate.rs @@ -1,5 +1 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![deny(unused_variables)] diff --git a/tests/ui/proc-macro/auxiliary/env.rs b/tests/ui/proc-macro/auxiliary/env.rs index da9aaa5cb5629..d01e3b42d4ce3 100644 --- a/tests/ui/proc-macro/auxiliary/env.rs +++ b/tests/ui/proc-macro/auxiliary/env.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_tracked_env)] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/expand-expr.rs b/tests/ui/proc-macro/auxiliary/expand-expr.rs index 68d0843be5abf..78c9fa75d9ff2 100644 --- a/tests/ui/proc-macro/auxiliary/expand-expr.rs +++ b/tests/ui/proc-macro/auxiliary/expand-expr.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![deny(warnings)] #![feature(proc_macro_expand, proc_macro_span)] diff --git a/tests/ui/proc-macro/auxiliary/expand-with-a-macro.rs b/tests/ui/proc-macro/auxiliary/expand-with-a-macro.rs index 9096fd7139756..c6281a42d2a15 100644 --- a/tests/ui/proc-macro/auxiliary/expand-with-a-macro.rs +++ b/tests/ui/proc-macro/auxiliary/expand-with-a-macro.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![deny(warnings)] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/first-second.rs b/tests/ui/proc-macro/auxiliary/first-second.rs index c8c1defa9f100..110d054add718 100644 --- a/tests/ui/proc-macro/auxiliary/first-second.rs +++ b/tests/ui/proc-macro/auxiliary/first-second.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{TokenStream, TokenTree, Group, Delimiter}; diff --git a/tests/ui/proc-macro/auxiliary/gen-lifetime-token.rs b/tests/ui/proc-macro/auxiliary/gen-lifetime-token.rs index fb05c97833c3d..b0728b8a0b8a8 100644 --- a/tests/ui/proc-macro/auxiliary/gen-lifetime-token.rs +++ b/tests/ui/proc-macro/auxiliary/gen-lifetime-token.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/gen-macro-rules-hygiene.rs b/tests/ui/proc-macro/auxiliary/gen-macro-rules-hygiene.rs index 9d6767dc11f56..40ecf4ef70467 100644 --- a/tests/ui/proc-macro/auxiliary/gen-macro-rules-hygiene.rs +++ b/tests/ui/proc-macro/auxiliary/gen-macro-rules-hygiene.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/gen-macro-rules.rs b/tests/ui/proc-macro/auxiliary/gen-macro-rules.rs index d2f82c52c5898..855cb1d7095c5 100644 --- a/tests/ui/proc-macro/auxiliary/gen-macro-rules.rs +++ b/tests/ui/proc-macro/auxiliary/gen-macro-rules.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/generate-dollar-ident.rs b/tests/ui/proc-macro/auxiliary/generate-dollar-ident.rs index 855084be84d35..28d35c82148e6 100644 --- a/tests/ui/proc-macro/auxiliary/generate-dollar-ident.rs +++ b/tests/ui/proc-macro/auxiliary/generate-dollar-ident.rs @@ -1,8 +1,4 @@ -//@ force-host -//@ no-prefer-dynamic - #![feature(proc_macro_quote)] -#![crate_type = "proc-macro"] extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/generate-mod.rs b/tests/ui/proc-macro/auxiliary/generate-mod.rs index 2ef1faffaa661..62710bd1e2df4 100644 --- a/tests/ui/proc-macro/auxiliary/generate-mod.rs +++ b/tests/ui/proc-macro/auxiliary/generate-mod.rs @@ -1,10 +1,6 @@ //@ run-pass -//@ force-host -//@ no-prefer-dynamic //@ ignore-pass -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/helper-attr.rs b/tests/ui/proc-macro/auxiliary/helper-attr.rs index 79ccefd98440c..ee2968688f9c7 100644 --- a/tests/ui/proc-macro/auxiliary/helper-attr.rs +++ b/tests/ui/proc-macro/auxiliary/helper-attr.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; // Doesn't do anything, but has a helper attribute. diff --git a/tests/ui/proc-macro/auxiliary/hygiene_example.rs b/tests/ui/proc-macro/auxiliary/hygiene_example.rs index f7e7e0b5751ee..b690dbfaae723 100644 --- a/tests/ui/proc-macro/auxiliary/hygiene_example.rs +++ b/tests/ui/proc-macro/auxiliary/hygiene_example.rs @@ -1,3 +1,5 @@ +//@ proc-macro: hygiene_example_codegen.rs + extern crate hygiene_example_codegen; pub use hygiene_example_codegen::hello; diff --git a/tests/ui/proc-macro/auxiliary/hygiene_example_codegen.rs b/tests/ui/proc-macro/auxiliary/hygiene_example_codegen.rs index e324e3f312966..dde997bf3ea3d 100644 --- a/tests/ui/proc-macro/auxiliary/hygiene_example_codegen.rs +++ b/tests/ui/proc-macro/auxiliary/hygiene_example_codegen.rs @@ -1,8 +1,4 @@ -//@ force-host -//@ no-prefer-dynamic - #![feature(proc_macro_quote)] -#![crate_type = "proc-macro"] extern crate proc_macro as proc_macro_renamed; // This does not break `quote!` diff --git a/tests/ui/proc-macro/auxiliary/invalid-punct-ident.rs b/tests/ui/proc-macro/auxiliary/invalid-punct-ident.rs index 19b3632dc3fd3..47d0608646704 100644 --- a/tests/ui/proc-macro/auxiliary/invalid-punct-ident.rs +++ b/tests/ui/proc-macro/auxiliary/invalid-punct-ident.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_raw_ident)] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/is-available.rs b/tests/ui/proc-macro/auxiliary/is-available.rs index f1d0e3c78f5be..1eeffa50913b2 100644 --- a/tests/ui/proc-macro/auxiliary/is-available.rs +++ b/tests/ui/proc-macro/auxiliary/is-available.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{Literal, TokenStream, TokenTree}; diff --git a/tests/ui/proc-macro/auxiliary/issue-104884.rs b/tests/ui/proc-macro/auxiliary/issue-104884.rs index 55d0d76ad184e..64922d997b6fc 100644 --- a/tests/ui/proc-macro/auxiliary/issue-104884.rs +++ b/tests/ui/proc-macro/auxiliary/issue-104884.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/issue-107113.rs b/tests/ui/proc-macro/auxiliary/issue-107113.rs index 5662277acce53..f7c2c856435ba 100644 --- a/tests/ui/proc-macro/auxiliary/issue-107113.rs +++ b/tests/ui/proc-macro/auxiliary/issue-107113.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/issue-118809.rs b/tests/ui/proc-macro/auxiliary/issue-118809.rs index f662f623b190c..2751b16b6b553 100644 --- a/tests/ui/proc-macro/auxiliary/issue-118809.rs +++ b/tests/ui/proc-macro/auxiliary/issue-118809.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/issue-38586.rs b/tests/ui/proc-macro/auxiliary/issue-38586.rs index e2bba3e13d10a..7e30ba371d1d7 100644 --- a/tests/ui/proc-macro/auxiliary/issue-38586.rs +++ b/tests/ui/proc-macro/auxiliary/issue-38586.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; #[proc_macro_derive(A)] diff --git a/tests/ui/proc-macro/auxiliary/issue-39889.rs b/tests/ui/proc-macro/auxiliary/issue-39889.rs index b1659d6168e6c..e4975fddd4c6e 100644 --- a/tests/ui/proc-macro/auxiliary/issue-39889.rs +++ b/tests/ui/proc-macro/auxiliary/issue-39889.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/issue-42708.rs b/tests/ui/proc-macro/auxiliary/issue-42708.rs index ed5ba53034109..c055409ba0619 100644 --- a/tests/ui/proc-macro/auxiliary/issue-42708.rs +++ b/tests/ui/proc-macro/auxiliary/issue-42708.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/issue-50061.rs b/tests/ui/proc-macro/auxiliary/issue-50061.rs index 9ecbb383d4be5..9137a78f53075 100644 --- a/tests/ui/proc-macro/auxiliary/issue-50061.rs +++ b/tests/ui/proc-macro/auxiliary/issue-50061.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/issue-50493.rs b/tests/ui/proc-macro/auxiliary/issue-50493.rs index e9ad86005339d..22bf1428e568b 100644 --- a/tests/ui/proc-macro/auxiliary/issue-50493.rs +++ b/tests/ui/proc-macro/auxiliary/issue-50493.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/issue-59191.rs b/tests/ui/proc-macro/auxiliary/issue-59191.rs index 40ba0063e4392..84b156d61e5f6 100644 --- a/tests/ui/proc-macro/auxiliary/issue-59191.rs +++ b/tests/ui/proc-macro/auxiliary/issue-59191.rs @@ -1,8 +1,4 @@ //@ edition:2018 -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/issue-66286.rs b/tests/ui/proc-macro/auxiliary/issue-66286.rs index d224dcda5901c..a317e68a3d7f0 100644 --- a/tests/ui/proc-macro/auxiliary/issue-66286.rs +++ b/tests/ui/proc-macro/auxiliary/issue-66286.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/issue-75801.rs b/tests/ui/proc-macro/auxiliary/issue-75801.rs index bd553b7ab8460..f1554f0fe7503 100644 --- a/tests/ui/proc-macro/auxiliary/issue-75801.rs +++ b/tests/ui/proc-macro/auxiliary/issue-75801.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/issue-79242.rs b/tests/ui/proc-macro/auxiliary/issue-79242.rs index 7b24e5a2ef223..165318d67b060 100644 --- a/tests/ui/proc-macro/auxiliary/issue-79242.rs +++ b/tests/ui/proc-macro/auxiliary/issue-79242.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/issue-79825.rs b/tests/ui/proc-macro/auxiliary/issue-79825.rs index 4326712458bc0..912a3c2147c5b 100644 --- a/tests/ui/proc-macro/auxiliary/issue-79825.rs +++ b/tests/ui/proc-macro/auxiliary/issue-79825.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/issue-83510.rs b/tests/ui/proc-macro/auxiliary/issue-83510.rs index 6e8e2d1f78029..50bdd36607d59 100644 --- a/tests/ui/proc-macro/auxiliary/issue-83510.rs +++ b/tests/ui/proc-macro/auxiliary/issue-83510.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/issue-91800-macro.rs b/tests/ui/proc-macro/auxiliary/issue-91800-macro.rs index a638a33cf2573..e6f91a52de5df 100644 --- a/tests/ui/proc-macro/auxiliary/issue-91800-macro.rs +++ b/tests/ui/proc-macro/auxiliary/issue-91800-macro.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/lifetimes-rpass.rs b/tests/ui/proc-macro/auxiliary/lifetimes-rpass.rs index 4f605ed07b351..d487d8f989c97 100644 --- a/tests/ui/proc-macro/auxiliary/lifetimes-rpass.rs +++ b/tests/ui/proc-macro/auxiliary/lifetimes-rpass.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/lifetimes.rs b/tests/ui/proc-macro/auxiliary/lifetimes.rs index 79885a92f6847..5d7ebecf83238 100644 --- a/tests/ui/proc-macro/auxiliary/lifetimes.rs +++ b/tests/ui/proc-macro/auxiliary/lifetimes.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/macro-only-syntax.rs b/tests/ui/proc-macro/auxiliary/macro-only-syntax.rs index 501a03985cb39..4971de284b760 100644 --- a/tests/ui/proc-macro/auxiliary/macro-only-syntax.rs +++ b/tests/ui/proc-macro/auxiliary/macro-only-syntax.rs @@ -1,6 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - // These are tests for syntax that is accepted by the Rust parser but // unconditionally rejected semantically after macro expansion. Attribute macros // are permitted to accept such syntax as long as they replace it with something @@ -9,7 +6,6 @@ // We also inspect some of the spans to verify the syntax is not triggering the // lossy string reparse hack (https://github.com/rust-lang/rust/issues/43081). -#![crate_type = "proc-macro"] #![feature(proc_macro_span)] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/macro_rules_edition_pm.rs b/tests/ui/proc-macro/auxiliary/macro_rules_edition_pm.rs new file mode 100644 index 0000000000000..fb244d09d9cb5 --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/macro_rules_edition_pm.rs @@ -0,0 +1,37 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn make_edition_macro(_input: TokenStream) -> TokenStream { + "macro_rules! edition { + ($_:expr) => { + 2024 + }; + (const {}) => { + 2021 + }; + } + " + .parse() + .unwrap() +} + +#[proc_macro] +pub fn make_nested_edition_macro(_input: TokenStream) -> TokenStream { + "macro_rules! make_inner { + () => { + macro_rules! edition_inner { + ($_:expr) => { + 2024 + }; + (const {}) => { + 2021 + }; + } + }; + } + " + .parse() + .unwrap() +} diff --git a/tests/ui/proc-macro/auxiliary/meta-macro.rs b/tests/ui/proc-macro/auxiliary/meta-macro.rs index cbe882c173f66..3436b1944d001 100644 --- a/tests/ui/proc-macro/auxiliary/meta-macro.rs +++ b/tests/ui/proc-macro/auxiliary/meta-macro.rs @@ -1,9 +1,6 @@ -//@ force-host -//@ no-prefer-dynamic //@ edition:2018 #![feature(proc_macro_def_site)] -#![crate_type = "proc-macro"] extern crate proc_macro; extern crate make_macro; diff --git a/tests/ui/proc-macro/auxiliary/mixed-site-span.rs b/tests/ui/proc-macro/auxiliary/mixed-site-span.rs index c143e2d40f3c8..d837c88c9556a 100644 --- a/tests/ui/proc-macro/auxiliary/mixed-site-span.rs +++ b/tests/ui/proc-macro/auxiliary/mixed-site-span.rs @@ -1,10 +1,5 @@ -//@ force-host -//@ no-prefer-dynamic - #![feature(proc_macro_quote)] -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/modify-ast.rs b/tests/ui/proc-macro/auxiliary/modify-ast.rs index 174c588e8bf23..389b096881476 100644 --- a/tests/ui/proc-macro/auxiliary/modify-ast.rs +++ b/tests/ui/proc-macro/auxiliary/modify-ast.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/multiple-derives.rs b/tests/ui/proc-macro/auxiliary/multiple-derives.rs index 84a826cf1f6ac..6f03f0a08f0bd 100644 --- a/tests/ui/proc-macro/auxiliary/multiple-derives.rs +++ b/tests/ui/proc-macro/auxiliary/multiple-derives.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/multispan.rs b/tests/ui/proc-macro/auxiliary/multispan.rs index b5f1ed9b56a9e..1eb379d3877d2 100644 --- a/tests/ui/proc-macro/auxiliary/multispan.rs +++ b/tests/ui/proc-macro/auxiliary/multispan.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_diagnostic, proc_macro_span, proc_macro_def_site)] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/negative-token.rs b/tests/ui/proc-macro/auxiliary/negative-token.rs index 43355bfd20bbe..d3731c1c8cc4d 100644 --- a/tests/ui/proc-macro/auxiliary/negative-token.rs +++ b/tests/ui/proc-macro/auxiliary/negative-token.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/nonterminal-recollect-attr.rs b/tests/ui/proc-macro/auxiliary/nonterminal-recollect-attr.rs index 48ae360019238..96aed8625aa5a 100644 --- a/tests/ui/proc-macro/auxiliary/nonterminal-recollect-attr.rs +++ b/tests/ui/proc-macro/auxiliary/nonterminal-recollect-attr.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_quote)] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/not-joint.rs b/tests/ui/proc-macro/auxiliary/not-joint.rs index 5f94805361a67..bc15ced05665b 100644 --- a/tests/ui/proc-macro/auxiliary/not-joint.rs +++ b/tests/ui/proc-macro/auxiliary/not-joint.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/parent-source-spans.rs b/tests/ui/proc-macro/auxiliary/parent-source-spans.rs index 3ec92d7133253..257d1489ce2ae 100644 --- a/tests/ui/proc-macro/auxiliary/parent-source-spans.rs +++ b/tests/ui/proc-macro/auxiliary/parent-source-spans.rs @@ -1,8 +1,4 @@ -//@ force-host -//@ no-prefer-dynamic - #![feature(proc_macro_diagnostic, proc_macro_span)] -#![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/parse-invis-delim-issue-128895.rs b/tests/ui/proc-macro/auxiliary/parse-invis-delim-issue-128895.rs index 07e135ee8ebef..2b77b45565a83 100644 --- a/tests/ui/proc-macro/auxiliary/parse-invis-delim-issue-128895.rs +++ b/tests/ui/proc-macro/auxiliary/parse-invis-delim-issue-128895.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/print-tokens.rs b/tests/ui/proc-macro/auxiliary/print-tokens.rs index 6d25f1f8471a9..171ff6e61fbd9 100644 --- a/tests/ui/proc-macro/auxiliary/print-tokens.rs +++ b/tests/ui/proc-macro/auxiliary/print-tokens.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{TokenStream, TokenTree}; diff --git a/tests/ui/proc-macro/auxiliary/proc-macro-panic.rs b/tests/ui/proc-macro/auxiliary/proc-macro-panic.rs index cfd6464661efa..8506c9f0de0bf 100644 --- a/tests/ui/proc-macro/auxiliary/proc-macro-panic.rs +++ b/tests/ui/proc-macro/auxiliary/proc-macro-panic.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{TokenStream, Ident, Span}; diff --git a/tests/ui/proc-macro/auxiliary/raw-ident.rs b/tests/ui/proc-macro/auxiliary/raw-ident.rs index 1fec617975687..7fd73dd97ba50 100644 --- a/tests/ui/proc-macro/auxiliary/raw-ident.rs +++ b/tests/ui/proc-macro/auxiliary/raw-ident.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{TokenStream, TokenTree, Ident, Punct, Spacing, Span}; diff --git a/tests/ui/proc-macro/auxiliary/re-export.rs b/tests/ui/proc-macro/auxiliary/re-export.rs index a886015a031da..ae88e2f3e1149 100644 --- a/tests/ui/proc-macro/auxiliary/re-export.rs +++ b/tests/ui/proc-macro/auxiliary/re-export.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/recollect.rs b/tests/ui/proc-macro/auxiliary/recollect.rs index 7db29035f7144..439f37c883270 100644 --- a/tests/ui/proc-macro/auxiliary/recollect.rs +++ b/tests/ui/proc-macro/auxiliary/recollect.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/proc-macro/auxiliary/resolved-located-at.rs b/tests/ui/proc-macro/auxiliary/resolved-located-at.rs index 032d41688affa..493956c00e987 100644 --- a/tests/ui/proc-macro/auxiliary/resolved-located-at.rs +++ b/tests/ui/proc-macro/auxiliary/resolved-located-at.rs @@ -1,10 +1,6 @@ -//@ force-host -//@ no-prefer-dynamic - #![feature(proc_macro_def_site)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_quote)] -#![crate_type = "proc-macro"] extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/proc-macro/auxiliary/span-api-tests.rs b/tests/ui/proc-macro/auxiliary/span-api-tests.rs index 16640a32098a7..99db66ed6a94c 100644 --- a/tests/ui/proc-macro/auxiliary/span-api-tests.rs +++ b/tests/ui/proc-macro/auxiliary/span-api-tests.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_span)] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/span-from-proc-macro.rs b/tests/ui/proc-macro/auxiliary/span-from-proc-macro.rs index fdcca29e177bc..16ca5e3f9e2d1 100644 --- a/tests/ui/proc-macro/auxiliary/span-from-proc-macro.rs +++ b/tests/ui/proc-macro/auxiliary/span-from-proc-macro.rs @@ -1,9 +1,5 @@ -//@ force-host -//@ no-prefer-dynamic - #![feature(proc_macro_quote)] #![feature(proc_macro_internals)] // FIXME - this shouldn't be necessary -#![crate_type = "proc-macro"] extern crate proc_macro; extern crate custom_quote; diff --git a/tests/ui/proc-macro/auxiliary/subspan.rs b/tests/ui/proc-macro/auxiliary/subspan.rs index 69a9c8a9fa84e..edfb053d6f102 100644 --- a/tests/ui/proc-macro/auxiliary/subspan.rs +++ b/tests/ui/proc-macro/auxiliary/subspan.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_diagnostic, proc_macro_span)] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/test-macros.rs b/tests/ui/proc-macro/auxiliary/test-macros.rs index 69a89e94cd6f9..8375767d6fb68 100644 --- a/tests/ui/proc-macro/auxiliary/test-macros.rs +++ b/tests/ui/proc-macro/auxiliary/test-macros.rs @@ -1,11 +1,6 @@ -//@ force-host -//@ no-prefer-dynamic - // Proc macros commonly used by tests. // `panic`/`print` -> `panic_bang`/`print_bang` to avoid conflicts with standard macros. -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{TokenStream, TokenTree}; diff --git a/tests/ui/proc-macro/auxiliary/three-equals.rs b/tests/ui/proc-macro/auxiliary/three-equals.rs index f0ff0437a8b46..56cfd4a2828ce 100644 --- a/tests/ui/proc-macro/auxiliary/three-equals.rs +++ b/tests/ui/proc-macro/auxiliary/three-equals.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![feature(proc_macro_diagnostic, proc_macro_span, proc_macro_def_site)] extern crate proc_macro; diff --git a/tests/ui/proc-macro/auxiliary/weird-hygiene.rs b/tests/ui/proc-macro/auxiliary/weird-hygiene.rs index f401f7d55baa8..c37eed360f066 100644 --- a/tests/ui/proc-macro/auxiliary/weird-hygiene.rs +++ b/tests/ui/proc-macro/auxiliary/weird-hygiene.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{TokenStream, TokenTree, Group}; diff --git a/tests/ui/proc-macro/bang-macro.rs b/tests/ui/proc-macro/bang-macro.rs index 03d4174d652b0..2287e34c5dda9 100644 --- a/tests/ui/proc-macro/bang-macro.rs +++ b/tests/ui/proc-macro/bang-macro.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:bang-macro.rs +//@ proc-macro: bang-macro.rs extern crate bang_macro; use bang_macro::rewrite; diff --git a/tests/ui/proc-macro/break-token-spans.rs b/tests/ui/proc-macro/break-token-spans.rs index ae90e04e08120..efbd0c0d7e234 100644 --- a/tests/ui/proc-macro/break-token-spans.rs +++ b/tests/ui/proc-macro/break-token-spans.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs // Regression test for issues #68489 and #70987 // Tests that we properly break tokens in `probably_equal_for_proc_macro` // See #72306 diff --git a/tests/ui/proc-macro/call-deprecated.rs b/tests/ui/proc-macro/call-deprecated.rs index 1779e33f3b1b9..fc9354331cce3 100644 --- a/tests/ui/proc-macro/call-deprecated.rs +++ b/tests/ui/proc-macro/call-deprecated.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:call-deprecated.rs +//@ proc-macro: call-deprecated.rs extern crate call_deprecated; diff --git a/tests/ui/proc-macro/call-site.rs b/tests/ui/proc-macro/call-site.rs index 31fa78902d5d6..9c285e1ed117a 100644 --- a/tests/ui/proc-macro/call-site.rs +++ b/tests/ui/proc-macro/call-site.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:call-site.rs +//@ proc-macro: call-site.rs extern crate call_site; diff --git a/tests/ui/proc-macro/capture-macro-rules-invoke.rs b/tests/ui/proc-macro/capture-macro-rules-invoke.rs index 71a290c1fc06d..101461854c4ae 100644 --- a/tests/ui/proc-macro/capture-macro-rules-invoke.rs +++ b/tests/ui/proc-macro/capture-macro-rules-invoke.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ check-pass //@ compile-flags: -Z span-debug diff --git a/tests/ui/proc-macro/capture-unglued-token.rs b/tests/ui/proc-macro/capture-unglued-token.rs index 32286ed084c2a..586fb934931d9 100644 --- a/tests/ui/proc-macro/capture-unglued-token.rs +++ b/tests/ui/proc-macro/capture-unglued-token.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug //@ check-pass diff --git a/tests/ui/proc-macro/cfg-eval-inner.rs b/tests/ui/proc-macro/cfg-eval-inner.rs index d0a6c1afa2307..7493f3ea52366 100644 --- a/tests/ui/proc-macro/cfg-eval-inner.rs +++ b/tests/ui/proc-macro/cfg-eval-inner.rs @@ -1,5 +1,5 @@ //@ compile-flags: -Z span-debug -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ check-pass #![feature(cfg_eval)] diff --git a/tests/ui/proc-macro/cfg-eval.rs b/tests/ui/proc-macro/cfg-eval.rs index bbf11949e7e34..1d9b4f23ea5c4 100644 --- a/tests/ui/proc-macro/cfg-eval.rs +++ b/tests/ui/proc-macro/cfg-eval.rs @@ -1,6 +1,6 @@ //@ check-pass //@ compile-flags: -Z span-debug -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![feature(cfg_eval)] #![feature(proc_macro_hygiene)] diff --git a/tests/ui/proc-macro/count_compound_ops.rs b/tests/ui/proc-macro/count_compound_ops.rs index e58c36e047db6..20b0b87817e2f 100644 --- a/tests/ui/proc-macro/count_compound_ops.rs +++ b/tests/ui/proc-macro/count_compound_ops.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:count_compound_ops.rs +//@ proc-macro: count_compound_ops.rs extern crate count_compound_ops; use count_compound_ops::count_compound_ops; diff --git a/tests/ui/proc-macro/crate-attrs-multiple.rs b/tests/ui/proc-macro/crate-attrs-multiple.rs index 24f46b0a2fab4..ebd14590a2152 100644 --- a/tests/ui/proc-macro/crate-attrs-multiple.rs +++ b/tests/ui/proc-macro/crate-attrs-multiple.rs @@ -1,7 +1,7 @@ // Multiple custom crate-level attributes, both inert and active. //@ check-pass -//@ aux-crate:test_macros=test-macros.rs +//@ proc-macro: test-macros.rs #![feature(custom_inner_attributes)] #![feature(prelude_import)] diff --git a/tests/ui/proc-macro/crate-var.rs b/tests/ui/proc-macro/crate-var.rs index 7388ca683580e..cea5d48e0806b 100644 --- a/tests/ui/proc-macro/crate-var.rs +++ b/tests/ui/proc-macro/crate-var.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:double.rs +//@ proc-macro: double.rs //@ aux-build:external-crate-var.rs #![allow(unused)] diff --git a/tests/ui/proc-macro/custom-attr-only-one-derive.rs b/tests/ui/proc-macro/custom-attr-only-one-derive.rs index 2616c122a6597..f0e82f367579b 100644 --- a/tests/ui/proc-macro/custom-attr-only-one-derive.rs +++ b/tests/ui/proc-macro/custom-attr-only-one-derive.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:custom-attr-only-one-derive.rs +//@ proc-macro: custom-attr-only-one-derive.rs #[macro_use] extern crate custom_attr_only_one_derive; diff --git a/tests/ui/proc-macro/custom-attr-panic.rs b/tests/ui/proc-macro/custom-attr-panic.rs index 23bcb66319d28..560af228c2aef 100644 --- a/tests/ui/proc-macro/custom-attr-panic.rs +++ b/tests/ui/proc-macro/custom-attr-panic.rs @@ -1,4 +1,4 @@ -//@ aux-build: test-macros.rs +//@ proc-macro: test-macros.rs extern crate test_macros; diff --git a/tests/ui/proc-macro/debug/auxiliary/macro-dump-debug.rs b/tests/ui/proc-macro/debug/auxiliary/macro-dump-debug.rs index 2d7bff836815e..1e261ea32130f 100644 --- a/tests/ui/proc-macro/debug/auxiliary/macro-dump-debug.rs +++ b/tests/ui/proc-macro/debug/auxiliary/macro-dump-debug.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] #![crate_name = "macro_dump_debug"] extern crate proc_macro; diff --git a/tests/ui/proc-macro/debug/dump-debug-span-debug.rs b/tests/ui/proc-macro/debug/dump-debug-span-debug.rs index d4d9199bf3b0a..618e13c0f15e2 100644 --- a/tests/ui/proc-macro/debug/dump-debug-span-debug.rs +++ b/tests/ui/proc-macro/debug/dump-debug-span-debug.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:macro-dump-debug.rs +//@ proc-macro: macro-dump-debug.rs //@ compile-flags: -Z span-debug diff --git a/tests/ui/proc-macro/debug/dump-debug.rs b/tests/ui/proc-macro/debug/dump-debug.rs index 7a5cc979df9b1..b20cd2dc948a2 100644 --- a/tests/ui/proc-macro/debug/dump-debug.rs +++ b/tests/ui/proc-macro/debug/dump-debug.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:macro-dump-debug.rs +//@ proc-macro: macro-dump-debug.rs extern crate macro_dump_debug; use macro_dump_debug::dump_debug; diff --git a/tests/ui/proc-macro/debug/dump-debug.stderr b/tests/ui/proc-macro/debug/dump-debug.stderr index 6aefacacd0025..abcbfbfd5ec06 100644 --- a/tests/ui/proc-macro/debug/dump-debug.stderr +++ b/tests/ui/proc-macro/debug/dump-debug.stderr @@ -1,166 +1,166 @@ -TokenStream [Ident { ident: "ident", span: #0 bytes(132..137) }, Ident { ident: "r#ident", span: #0 bytes(153..160) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(178..179) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(205..206) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(206..207) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(207..208) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(232..234) }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: #0 bytes(260..261) }], span: #0 bytes(259..262) }, Literal { kind: Integer, symbol: "0", suffix: None, span: #0 bytes(317..318) }, Literal { kind: Float, symbol: "1.0", suffix: None, span: #0 bytes(323..326) }, Literal { kind: Str, symbol: "S", suffix: None, span: #0 bytes(331..334) }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: #0 bytes(339..343) }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: #0 bytes(348..352) }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: #0 bytes(357..365) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: #0 bytes(370..376) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: #0 bytes(381..391) }, Literal { kind: Char, symbol: "C", suffix: None, span: #0 bytes(396..399) }, Literal { kind: Byte, symbol: "B", suffix: None, span: #0 bytes(404..408) }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: #0 bytes(439..441) }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: #0 bytes(446..450) }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: #0 bytes(455..459) }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: #0 bytes(464..469) }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: #0 bytes(474..479) }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: #0 bytes(484..493) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: #0 bytes(498..505) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: #0 bytes(510..521) }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: #0 bytes(526..530) }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: #0 bytes(535..540) }] +TokenStream [Ident { ident: "ident", span: #0 bytes(134..139) }, Ident { ident: "r#ident", span: #0 bytes(155..162) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(180..181) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(207..208) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(208..209) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(209..210) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(234..236) }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: #0 bytes(262..263) }], span: #0 bytes(261..264) }, Literal { kind: Integer, symbol: "0", suffix: None, span: #0 bytes(319..320) }, Literal { kind: Float, symbol: "1.0", suffix: None, span: #0 bytes(325..328) }, Literal { kind: Str, symbol: "S", suffix: None, span: #0 bytes(333..336) }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: #0 bytes(341..345) }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: #0 bytes(350..354) }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: #0 bytes(359..367) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: #0 bytes(372..378) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: #0 bytes(383..393) }, Literal { kind: Char, symbol: "C", suffix: None, span: #0 bytes(398..401) }, Literal { kind: Byte, symbol: "B", suffix: None, span: #0 bytes(406..410) }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: #0 bytes(441..443) }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: #0 bytes(448..452) }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: #0 bytes(457..461) }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: #0 bytes(466..471) }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: #0 bytes(476..481) }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: #0 bytes(486..495) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: #0 bytes(500..507) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: #0 bytes(512..523) }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: #0 bytes(528..532) }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: #0 bytes(537..542) }] TokenStream [ Ident { ident: "ident", - span: #0 bytes(132..137), + span: #0 bytes(134..139), }, Ident { ident: "r#ident", - span: #0 bytes(153..160), + span: #0 bytes(155..162), }, Punct { ch: ',', spacing: Alone, - span: #0 bytes(178..179), + span: #0 bytes(180..181), }, Punct { ch: '=', spacing: Joint, - span: #0 bytes(205..206), + span: #0 bytes(207..208), }, Punct { ch: '=', spacing: Joint, - span: #0 bytes(206..207), + span: #0 bytes(208..209), }, Punct { ch: '>', spacing: Alone, - span: #0 bytes(207..208), + span: #0 bytes(209..210), }, Group { delimiter: Parenthesis, stream: TokenStream [], - span: #0 bytes(232..234), + span: #0 bytes(234..236), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "_", - span: #0 bytes(260..261), + span: #0 bytes(262..263), }, ], - span: #0 bytes(259..262), + span: #0 bytes(261..264), }, Literal { kind: Integer, symbol: "0", suffix: None, - span: #0 bytes(317..318), + span: #0 bytes(319..320), }, Literal { kind: Float, symbol: "1.0", suffix: None, - span: #0 bytes(323..326), + span: #0 bytes(325..328), }, Literal { kind: Str, symbol: "S", suffix: None, - span: #0 bytes(331..334), + span: #0 bytes(333..336), }, Literal { kind: ByteStr, symbol: "B", suffix: None, - span: #0 bytes(339..343), + span: #0 bytes(341..345), }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, - span: #0 bytes(348..352), + span: #0 bytes(350..354), }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, - span: #0 bytes(357..365), + span: #0 bytes(359..367), }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, - span: #0 bytes(370..376), + span: #0 bytes(372..378), }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, - span: #0 bytes(381..391), + span: #0 bytes(383..393), }, Literal { kind: Char, symbol: "C", suffix: None, - span: #0 bytes(396..399), + span: #0 bytes(398..401), }, Literal { kind: Byte, symbol: "B", suffix: None, - span: #0 bytes(404..408), + span: #0 bytes(406..410), }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), - span: #0 bytes(439..441), + span: #0 bytes(441..443), }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), - span: #0 bytes(446..450), + span: #0 bytes(448..452), }, Literal { kind: Str, symbol: "S", suffix: Some("q"), - span: #0 bytes(455..459), + span: #0 bytes(457..461), }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), - span: #0 bytes(464..469), + span: #0 bytes(466..471), }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), - span: #0 bytes(474..479), + span: #0 bytes(476..481), }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), - span: #0 bytes(484..493), + span: #0 bytes(486..495), }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), - span: #0 bytes(498..505), + span: #0 bytes(500..507), }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), - span: #0 bytes(510..521), + span: #0 bytes(512..523), }, Literal { kind: Char, symbol: "C", suffix: Some("q"), - span: #0 bytes(526..530), + span: #0 bytes(528..532), }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), - span: #0 bytes(535..540), + span: #0 bytes(537..542), }, ] diff --git a/tests/ui/proc-macro/derive-attr-cfg.rs b/tests/ui/proc-macro/derive-attr-cfg.rs index 162be0754d91d..2f3516cabae9e 100644 --- a/tests/ui/proc-macro/derive-attr-cfg.rs +++ b/tests/ui/proc-macro/derive-attr-cfg.rs @@ -1,7 +1,7 @@ //@ run-pass #![allow(dead_code)] -//@ aux-build:derive-attr-cfg.rs +//@ proc-macro: derive-attr-cfg.rs extern crate derive_attr_cfg; use derive_attr_cfg::Foo; diff --git a/tests/ui/proc-macro/derive-b.rs b/tests/ui/proc-macro/derive-b.rs index 6cbe1fd0a3f8d..68d341478f187 100644 --- a/tests/ui/proc-macro/derive-b.rs +++ b/tests/ui/proc-macro/derive-b.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:derive-b-rpass.rs +//@ proc-macro: derive-b-rpass.rs extern crate derive_b_rpass as derive_b; diff --git a/tests/ui/proc-macro/derive-bad.rs b/tests/ui/proc-macro/derive-bad.rs index c8f3a77ea4c5f..9b237c731dbe4 100644 --- a/tests/ui/proc-macro/derive-bad.rs +++ b/tests/ui/proc-macro/derive-bad.rs @@ -1,4 +1,4 @@ -//@ aux-build:derive-bad.rs +//@ proc-macro: derive-bad.rs #[macro_use] extern crate derive_bad; diff --git a/tests/ui/proc-macro/derive-expand-order.rs b/tests/ui/proc-macro/derive-expand-order.rs index 75981f16a7fd8..076590bdb4cda 100644 --- a/tests/ui/proc-macro/derive-expand-order.rs +++ b/tests/ui/proc-macro/derive-expand-order.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:multiple-derives.rs +//@ proc-macro: multiple-derives.rs extern crate multiple_derives; diff --git a/tests/ui/proc-macro/derive-helper-configured.rs b/tests/ui/proc-macro/derive-helper-configured.rs index 45e6e64d392c1..b753e29b8bf3b 100644 --- a/tests/ui/proc-macro/derive-helper-configured.rs +++ b/tests/ui/proc-macro/derive-helper-configured.rs @@ -1,7 +1,7 @@ // Derive helpers are resolved successfully inside `cfg_attr`. //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/derive-helper-legacy-limits.rs b/tests/ui/proc-macro/derive-helper-legacy-limits.rs index ff09095a60f9d..76b09f33ecc02 100644 --- a/tests/ui/proc-macro/derive-helper-legacy-limits.rs +++ b/tests/ui/proc-macro/derive-helper-legacy-limits.rs @@ -2,7 +2,7 @@ // (that's exactly the reason why they are deprecated). //@ edition:2018 -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/derive-helper-legacy-spurious.rs b/tests/ui/proc-macro/derive-helper-legacy-spurious.rs index 2b5bb905e8302..8e902f3041932 100644 --- a/tests/ui/proc-macro/derive-helper-legacy-spurious.rs +++ b/tests/ui/proc-macro/derive-helper-legacy-spurious.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![dummy] //~ ERROR cannot find attribute `dummy` in this scope diff --git a/tests/ui/proc-macro/derive-helper-shadowed.rs b/tests/ui/proc-macro/derive-helper-shadowed.rs index 9b2a4ab6bc741..ea2c56b0b73bc 100644 --- a/tests/ui/proc-macro/derive-helper-shadowed.rs +++ b/tests/ui/proc-macro/derive-helper-shadowed.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ aux-build:derive-helper-shadowed-2.rs #[macro_use] diff --git a/tests/ui/proc-macro/derive-helper-shadowing-2.rs b/tests/ui/proc-macro/derive-helper-shadowing-2.rs index dc35dd05498bd..6aba061acf357 100644 --- a/tests/ui/proc-macro/derive-helper-shadowing-2.rs +++ b/tests/ui/proc-macro/derive-helper-shadowing-2.rs @@ -2,7 +2,7 @@ // then make sure that it's usable without ambiguities. //@ check-pass -//@ aux-build:derive-helper-shadowing-2.rs +//@ proc-macro: derive-helper-shadowing-2.rs #[macro_use] extern crate derive_helper_shadowing_2; diff --git a/tests/ui/proc-macro/derive-helper-shadowing.rs b/tests/ui/proc-macro/derive-helper-shadowing.rs index 1c66a60b294b8..e774e46405381 100644 --- a/tests/ui/proc-macro/derive-helper-shadowing.rs +++ b/tests/ui/proc-macro/derive-helper-shadowing.rs @@ -1,6 +1,6 @@ //@ edition:2018 -//@ aux-build:test-macros.rs -//@ aux-build:derive-helper-shadowing.rs +//@ proc-macro: test-macros.rs +//@ proc-macro: derive-helper-shadowing.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/derive-helper-vs-legacy.rs b/tests/ui/proc-macro/derive-helper-vs-legacy.rs index feae7adda68f6..83917a2fbf709 100644 --- a/tests/ui/proc-macro/derive-helper-vs-legacy.rs +++ b/tests/ui/proc-macro/derive-helper-vs-legacy.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/derive-in-mod.rs b/tests/ui/proc-macro/derive-in-mod.rs index 3bd70f1090d03..7ec7cf62fb40a 100644 --- a/tests/ui/proc-macro/derive-in-mod.rs +++ b/tests/ui/proc-macro/derive-in-mod.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs extern crate test_macros; diff --git a/tests/ui/proc-macro/derive-same-struct.rs b/tests/ui/proc-macro/derive-same-struct.rs index 432476d1ebb1d..f7669ba1480b2 100644 --- a/tests/ui/proc-macro/derive-same-struct.rs +++ b/tests/ui/proc-macro/derive-same-struct.rs @@ -2,7 +2,7 @@ #![allow(path_statements)] #![allow(dead_code)] -//@ aux-build:derive-same-struct.rs +//@ proc-macro: derive-same-struct.rs #[macro_use] extern crate derive_same_struct; diff --git a/tests/ui/proc-macro/derive-still-gated.rs b/tests/ui/proc-macro/derive-still-gated.rs index bce7badeffe1d..518ed9d51be8a 100644 --- a/tests/ui/proc-macro/derive-still-gated.rs +++ b/tests/ui/proc-macro/derive-still-gated.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/derive-two-attrs.rs b/tests/ui/proc-macro/derive-two-attrs.rs index 911160976658e..33a8fef2ac7b9 100644 --- a/tests/ui/proc-macro/derive-two-attrs.rs +++ b/tests/ui/proc-macro/derive-two-attrs.rs @@ -1,7 +1,7 @@ //@ run-pass #![allow(dead_code)] -//@ aux-build:derive-two-attrs.rs +//@ proc-macro: derive-two-attrs.rs extern crate derive_two_attrs as foo; diff --git a/tests/ui/proc-macro/derive-union.rs b/tests/ui/proc-macro/derive-union.rs index d1e65bf45957b..e0fe9dee85cb0 100644 --- a/tests/ui/proc-macro/derive-union.rs +++ b/tests/ui/proc-macro/derive-union.rs @@ -1,7 +1,7 @@ //@ run-pass #![allow(unused_variables)] -//@ aux-build:derive-union.rs +//@ proc-macro: derive-union.rs #[macro_use] extern crate derive_union; diff --git a/tests/ui/proc-macro/disappearing-resolution.rs b/tests/ui/proc-macro/disappearing-resolution.rs index b8bc2953576a6..8e7fa85eba15b 100644 --- a/tests/ui/proc-macro/disappearing-resolution.rs +++ b/tests/ui/proc-macro/disappearing-resolution.rs @@ -1,6 +1,6 @@ // Regression test for issue #64803 (initial attribute resolution can disappear later). -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/disappearing-resolution.stderr b/tests/ui/proc-macro/disappearing-resolution.stderr index e6d0868687e27..e66f721444fc3 100644 --- a/tests/ui/proc-macro/disappearing-resolution.stderr +++ b/tests/ui/proc-macro/disappearing-resolution.stderr @@ -16,7 +16,7 @@ note: the derive macro import `Empty` is defined here... LL | use test_macros::Empty; | ^^^^^^^^^^^^^^^^^^ note: ...and refers to the derive macro `Empty` which is defined here - --> $DIR/auxiliary/test-macros.rs:25:1 + --> $DIR/auxiliary/test-macros.rs:20:1 | LL | pub fn empty_derive(_: TokenStream) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ you could import this directly diff --git a/tests/ui/proc-macro/doc-comment-preserved.rs b/tests/ui/proc-macro/doc-comment-preserved.rs index f0891e7d6a74e..a4bfd105d36e1 100644 --- a/tests/ui/proc-macro/doc-comment-preserved.rs +++ b/tests/ui/proc-macro/doc-comment-preserved.rs @@ -1,6 +1,6 @@ //@ check-pass //@ compile-flags: -Z span-debug -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/tests/ui/proc-macro/dollar-crate-issue-101211.rs b/tests/ui/proc-macro/dollar-crate-issue-101211.rs index fd5768dc7d1c2..ca871d57a6912 100644 --- a/tests/ui/proc-macro/dollar-crate-issue-101211.rs +++ b/tests/ui/proc-macro/dollar-crate-issue-101211.rs @@ -1,6 +1,6 @@ //@ check-pass //@ edition:2021 -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/tests/ui/proc-macro/dollar-crate-issue-57089.rs b/tests/ui/proc-macro/dollar-crate-issue-57089.rs index d4540643e029d..52f41b78375fa 100644 --- a/tests/ui/proc-macro/dollar-crate-issue-57089.rs +++ b/tests/ui/proc-macro/dollar-crate-issue-57089.rs @@ -1,7 +1,7 @@ //@ check-pass //@ edition:2018 //@ compile-flags: -Z span-debug -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/tests/ui/proc-macro/dollar-crate-issue-62325.rs b/tests/ui/proc-macro/dollar-crate-issue-62325.rs index ee2e0c3973dca..716bf6790fe63 100644 --- a/tests/ui/proc-macro/dollar-crate-issue-62325.rs +++ b/tests/ui/proc-macro/dollar-crate-issue-62325.rs @@ -1,7 +1,7 @@ //@ check-pass //@ edition:2018 //@ compile-flags: -Z span-debug -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ aux-build:dollar-crate-external.rs diff --git a/tests/ui/proc-macro/dollar-crate.rs b/tests/ui/proc-macro/dollar-crate.rs index a487e77a83310..0d13bbd8967bf 100644 --- a/tests/ui/proc-macro/dollar-crate.rs +++ b/tests/ui/proc-macro/dollar-crate.rs @@ -1,7 +1,7 @@ //@ check-pass //@ edition:2018 //@ compile-flags: -Z span-debug -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ aux-build:dollar-crate-external.rs #![no_std] // Don't load unnecessary hygiene information from std diff --git a/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.rs b/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.rs index 0f302708537ed..e4878a93af123 100644 --- a/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.rs +++ b/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.rs @@ -1,4 +1,4 @@ -//@ aux-build:edition-gated-async-move-syntax.rs +//@ proc-macro: edition-gated-async-move-syntax.rs //@ edition: 2015 // Non-regression test for issue #89699, where a proc-macro emitting syntax only available in diff --git a/tests/ui/proc-macro/edition-imports-2018.rs b/tests/ui/proc-macro/edition-imports-2018.rs index de05868ebf933..a3808d9dce823 100644 --- a/tests/ui/proc-macro/edition-imports-2018.rs +++ b/tests/ui/proc-macro/edition-imports-2018.rs @@ -1,6 +1,6 @@ //@ check-pass //@ edition:2018 -//@ aux-build:edition-imports-2015.rs +//@ proc-macro: edition-imports-2015.rs #[macro_use] extern crate edition_imports_2015; diff --git a/tests/ui/proc-macro/empty-crate.rs b/tests/ui/proc-macro/empty-crate.rs index ba4de590e6364..f82660ac4fd5b 100644 --- a/tests/ui/proc-macro/empty-crate.rs +++ b/tests/ui/proc-macro/empty-crate.rs @@ -1,7 +1,7 @@ //@ run-pass #![allow(unused_imports)] -//@ aux-build:empty-crate.rs +//@ proc-macro: empty-crate.rs #[macro_use] extern crate empty_crate; diff --git a/tests/ui/proc-macro/empty-where-clause.rs b/tests/ui/proc-macro/empty-where-clause.rs index 4e432934e3cde..770b44515f91e 100644 --- a/tests/ui/proc-macro/empty-where-clause.rs +++ b/tests/ui/proc-macro/empty-where-clause.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs extern crate test_macros; use test_macros::recollect_attr; diff --git a/tests/ui/proc-macro/env.rs b/tests/ui/proc-macro/env.rs index 85bcf4521fe60..94e3b09e5269b 100644 --- a/tests/ui/proc-macro/env.rs +++ b/tests/ui/proc-macro/env.rs @@ -1,4 +1,4 @@ -//@ aux-build:env.rs +//@ proc-macro: env.rs //@ run-pass //@ rustc-env: THE_CONST=1 //@ compile-flags: -Zunstable-options --env-set THE_CONST=12 --env-set ANOTHER=4 diff --git a/tests/ui/proc-macro/expand-expr.rs b/tests/ui/proc-macro/expand-expr.rs index e06ddc51a297e..8a4ed9768d53a 100644 --- a/tests/ui/proc-macro/expand-expr.rs +++ b/tests/ui/proc-macro/expand-expr.rs @@ -1,4 +1,4 @@ -//@ aux-build:expand-expr.rs +//@ proc-macro: expand-expr.rs // no-remap-src-base: check_expand_expr_file!() fails when enabled. #![feature(concat_bytes)] diff --git a/tests/ui/proc-macro/expand-to-derive.rs b/tests/ui/proc-macro/expand-to-derive.rs index 0b603cd4bccb0..0e38e471980bc 100644 --- a/tests/ui/proc-macro/expand-to-derive.rs +++ b/tests/ui/proc-macro/expand-to-derive.rs @@ -1,6 +1,6 @@ //@ check-pass //@ compile-flags: -Z span-debug --error-format human -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![feature(rustc_attrs)] diff --git a/tests/ui/proc-macro/expand-to-unstable.rs b/tests/ui/proc-macro/expand-to-unstable.rs index c4eaba6bba235..8968471ebd872 100644 --- a/tests/ui/proc-macro/expand-to-unstable.rs +++ b/tests/ui/proc-macro/expand-to-unstable.rs @@ -1,4 +1,4 @@ -//@ aux-build:derive-unstable.rs +//@ proc-macro: derive-unstable.rs #![allow(warnings)] diff --git a/tests/ui/proc-macro/expand-with-a-macro.rs b/tests/ui/proc-macro/expand-with-a-macro.rs index fcaafbbc1490e..e5baf3601db0a 100644 --- a/tests/ui/proc-macro/expand-with-a-macro.rs +++ b/tests/ui/proc-macro/expand-with-a-macro.rs @@ -1,6 +1,6 @@ //@ run-pass //@ needs-unwind -//@ aux-build:expand-with-a-macro.rs +//@ proc-macro: expand-with-a-macro.rs #![deny(warnings)] diff --git a/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.rs b/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.rs index 0b34b07edbee4..6f31c07ff89be 100644 --- a/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.rs +++ b/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![feature(decl_macro)] #![feature(stmt_expr_attributes)] diff --git a/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout b/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout index 0168689b605ff..7555ef8f63297 100644 --- a/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout +++ b/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout @@ -2,39 +2,39 @@ PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = #[allow(warnings)] 0; 0 }, PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "enum", - span: #3 bytes(301..305), + span: #3 bytes(303..307), }, Ident { ident: "E", - span: #3 bytes(306..307), + span: #3 bytes(308..309), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "V", - span: #3 bytes(322..323), + span: #3 bytes(324..325), }, Punct { ch: '=', spacing: Alone, - span: #3 bytes(324..325), + span: #3 bytes(326..327), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "let", - span: #3 bytes(328..331), + span: #3 bytes(330..333), }, Ident { ident: "_", - span: #3 bytes(332..333), + span: #3 bytes(334..335), }, Punct { ch: '=', spacing: Alone, - span: #3 bytes(334..335), + span: #3 bytes(336..337), }, Group { delimiter: None, @@ -42,97 +42,97 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: #0 bytes(543..544), + span: #0 bytes(545..546), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "allow", - span: #0 bytes(545..550), + span: #0 bytes(547..552), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "warnings", - span: #0 bytes(551..559), + span: #0 bytes(553..561), }, ], - span: #0 bytes(550..560), + span: #0 bytes(552..562), }, ], - span: #0 bytes(544..561), + span: #0 bytes(546..563), }, Literal { kind: Integer, symbol: "0", suffix: None, - span: #0 bytes(562..563), + span: #0 bytes(564..565), }, ], - span: #3 bytes(336..341), + span: #3 bytes(338..343), }, Punct { ch: ';', spacing: Alone, - span: #3 bytes(341..342), + span: #3 bytes(343..344), }, Literal { kind: Integer, symbol: "0", suffix: None, - span: #3 bytes(343..344), + span: #3 bytes(345..346), }, ], - span: #3 bytes(326..346), + span: #3 bytes(328..348), }, Punct { ch: ',', spacing: Alone, - span: #3 bytes(346..347), + span: #3 bytes(348..349), }, ], - span: #3 bytes(308..357), + span: #3 bytes(310..359), }, ] PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { 0 }; 0 }, } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "enum", - span: #7 bytes(425..429), + span: #7 bytes(427..431), }, Ident { ident: "E", - span: #7 bytes(430..431), + span: #7 bytes(432..433), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "V", - span: #7 bytes(446..447), + span: #7 bytes(448..449), }, Punct { ch: '=', spacing: Alone, - span: #7 bytes(448..449), + span: #7 bytes(450..451), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "let", - span: #7 bytes(452..455), + span: #7 bytes(454..457), }, Ident { ident: "_", - span: #7 bytes(456..457), + span: #7 bytes(458..459), }, Punct { ch: '=', spacing: Alone, - span: #7 bytes(458..459), + span: #7 bytes(460..461), }, Group { delimiter: Brace, @@ -144,74 +144,74 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ kind: Integer, symbol: "0", suffix: None, - span: #0 bytes(580..581), + span: #0 bytes(582..583), }, ], - span: #7 bytes(462..467), + span: #7 bytes(464..469), }, ], - span: #7 bytes(460..469), + span: #7 bytes(462..471), }, Punct { ch: ';', spacing: Alone, - span: #7 bytes(469..470), + span: #7 bytes(471..472), }, Literal { kind: Integer, symbol: "0", suffix: None, - span: #7 bytes(471..472), + span: #7 bytes(473..474), }, ], - span: #7 bytes(450..474), + span: #7 bytes(452..476), }, Punct { ch: ',', spacing: Alone, - span: #7 bytes(474..475), + span: #7 bytes(476..477), }, ], - span: #7 bytes(432..485), + span: #7 bytes(434..487), }, ] PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { {} }; 0 }, } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "enum", - span: #11 bytes(425..429), + span: #11 bytes(427..431), }, Ident { ident: "E", - span: #11 bytes(430..431), + span: #11 bytes(432..433), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "V", - span: #11 bytes(446..447), + span: #11 bytes(448..449), }, Punct { ch: '=', spacing: Alone, - span: #11 bytes(448..449), + span: #11 bytes(450..451), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "let", - span: #11 bytes(452..455), + span: #11 bytes(454..457), }, Ident { ident: "_", - span: #11 bytes(456..457), + span: #11 bytes(458..459), }, Punct { ch: '=', spacing: Alone, - span: #11 bytes(458..459), + span: #11 bytes(460..461), }, Group { delimiter: Brace, @@ -222,74 +222,74 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Group { delimiter: Brace, stream: TokenStream [], - span: #0 bytes(598..600), + span: #0 bytes(600..602), }, ], - span: #11 bytes(462..467), + span: #11 bytes(464..469), }, ], - span: #11 bytes(460..469), + span: #11 bytes(462..471), }, Punct { ch: ';', spacing: Alone, - span: #11 bytes(469..470), + span: #11 bytes(471..472), }, Literal { kind: Integer, symbol: "0", suffix: None, - span: #11 bytes(471..472), + span: #11 bytes(473..474), }, ], - span: #11 bytes(450..474), + span: #11 bytes(452..476), }, Punct { ch: ',', spacing: Alone, - span: #11 bytes(474..475), + span: #11 bytes(476..477), }, ], - span: #11 bytes(432..485), + span: #11 bytes(434..487), }, ] PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { PATH }; 0 }, } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "enum", - span: #15 bytes(425..429), + span: #15 bytes(427..431), }, Ident { ident: "E", - span: #15 bytes(430..431), + span: #15 bytes(432..433), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "V", - span: #15 bytes(446..447), + span: #15 bytes(448..449), }, Punct { ch: '=', spacing: Alone, - span: #15 bytes(448..449), + span: #15 bytes(450..451), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "let", - span: #15 bytes(452..455), + span: #15 bytes(454..457), }, Ident { ident: "_", - span: #15 bytes(456..457), + span: #15 bytes(458..459), }, Punct { ch: '=', spacing: Alone, - span: #15 bytes(458..459), + span: #15 bytes(460..461), }, Group { delimiter: Brace, @@ -299,74 +299,74 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "PATH", - span: #0 bytes(617..621), + span: #0 bytes(619..623), }, ], - span: #15 bytes(462..467), + span: #15 bytes(464..469), }, ], - span: #15 bytes(460..469), + span: #15 bytes(462..471), }, Punct { ch: ';', spacing: Alone, - span: #15 bytes(469..470), + span: #15 bytes(471..472), }, Literal { kind: Integer, symbol: "0", suffix: None, - span: #15 bytes(471..472), + span: #15 bytes(473..474), }, ], - span: #15 bytes(450..474), + span: #15 bytes(452..476), }, Punct { ch: ',', spacing: Alone, - span: #15 bytes(474..475), + span: #15 bytes(476..477), }, ], - span: #15 bytes(432..485), + span: #15 bytes(434..487), }, ] PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { 0 + 1 }; 0 }, } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "enum", - span: #19 bytes(425..429), + span: #19 bytes(427..431), }, Ident { ident: "E", - span: #19 bytes(430..431), + span: #19 bytes(432..433), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "V", - span: #19 bytes(446..447), + span: #19 bytes(448..449), }, Punct { ch: '=', spacing: Alone, - span: #19 bytes(448..449), + span: #19 bytes(450..451), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "let", - span: #19 bytes(452..455), + span: #19 bytes(454..457), }, Ident { ident: "_", - span: #19 bytes(456..457), + span: #19 bytes(458..459), }, Punct { ch: '=', spacing: Alone, - span: #19 bytes(458..459), + span: #19 bytes(460..461), }, Group { delimiter: Brace, @@ -378,85 +378,85 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ kind: Integer, symbol: "0", suffix: None, - span: #0 bytes(638..639), + span: #0 bytes(640..641), }, Punct { ch: '+', spacing: Alone, - span: #0 bytes(640..641), + span: #0 bytes(642..643), }, Literal { kind: Integer, symbol: "1", suffix: None, - span: #0 bytes(642..643), + span: #0 bytes(644..645), }, ], - span: #19 bytes(462..467), + span: #19 bytes(464..469), }, ], - span: #19 bytes(460..469), + span: #19 bytes(462..471), }, Punct { ch: ';', spacing: Alone, - span: #19 bytes(469..470), + span: #19 bytes(471..472), }, Literal { kind: Integer, symbol: "0", suffix: None, - span: #19 bytes(471..472), + span: #19 bytes(473..474), }, ], - span: #19 bytes(450..474), + span: #19 bytes(452..476), }, Punct { ch: ',', spacing: Alone, - span: #19 bytes(474..475), + span: #19 bytes(476..477), }, ], - span: #19 bytes(432..485), + span: #19 bytes(434..487), }, ] PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { PATH + 1 }; 0 }, } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "enum", - span: #23 bytes(425..429), + span: #23 bytes(427..431), }, Ident { ident: "E", - span: #23 bytes(430..431), + span: #23 bytes(432..433), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "V", - span: #23 bytes(446..447), + span: #23 bytes(448..449), }, Punct { ch: '=', spacing: Alone, - span: #23 bytes(448..449), + span: #23 bytes(450..451), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "let", - span: #23 bytes(452..455), + span: #23 bytes(454..457), }, Ident { ident: "_", - span: #23 bytes(456..457), + span: #23 bytes(458..459), }, Punct { ch: '=', spacing: Alone, - span: #23 bytes(458..459), + span: #23 bytes(460..461), }, Group { delimiter: Brace, @@ -466,45 +466,45 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "PATH", - span: #0 bytes(660..664), + span: #0 bytes(662..666), }, Punct { ch: '+', spacing: Alone, - span: #0 bytes(665..666), + span: #0 bytes(667..668), }, Literal { kind: Integer, symbol: "1", suffix: None, - span: #0 bytes(667..668), + span: #0 bytes(669..670), }, ], - span: #23 bytes(462..467), + span: #23 bytes(464..469), }, ], - span: #23 bytes(460..469), + span: #23 bytes(462..471), }, Punct { ch: ';', spacing: Alone, - span: #23 bytes(469..470), + span: #23 bytes(471..472), }, Literal { kind: Integer, symbol: "0", suffix: None, - span: #23 bytes(471..472), + span: #23 bytes(473..474), }, ], - span: #23 bytes(450..474), + span: #23 bytes(452..476), }, Punct { ch: ',', spacing: Alone, - span: #23 bytes(474..475), + span: #23 bytes(476..477), }, ], - span: #23 bytes(432..485), + span: #23 bytes(434..487), }, ] diff --git a/tests/ui/proc-macro/gen-lifetime-token.rs b/tests/ui/proc-macro/gen-lifetime-token.rs index d65efb5c46475..4296d58df0d51 100644 --- a/tests/ui/proc-macro/gen-lifetime-token.rs +++ b/tests/ui/proc-macro/gen-lifetime-token.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:gen-lifetime-token.rs +//@ proc-macro: gen-lifetime-token.rs extern crate gen_lifetime_token as bar; diff --git a/tests/ui/proc-macro/gen-macro-rules-hygiene.rs b/tests/ui/proc-macro/gen-macro-rules-hygiene.rs index 2bfbf9dcccaaf..3deec94fa3411 100644 --- a/tests/ui/proc-macro/gen-macro-rules-hygiene.rs +++ b/tests/ui/proc-macro/gen-macro-rules-hygiene.rs @@ -2,7 +2,7 @@ // Local variables and labels are hygienic, items are not hygienic. // `$crate` refers to the crate that defines `macro_rules` and not the outer transparent macro. -//@ aux-build:gen-macro-rules-hygiene.rs +//@ proc-macro: gen-macro-rules-hygiene.rs #[macro_use] extern crate gen_macro_rules_hygiene; diff --git a/tests/ui/proc-macro/gen-macro-rules.rs b/tests/ui/proc-macro/gen-macro-rules.rs index 5f2cfc70d8ecc..121d029e2e346 100644 --- a/tests/ui/proc-macro/gen-macro-rules.rs +++ b/tests/ui/proc-macro/gen-macro-rules.rs @@ -1,7 +1,7 @@ // Derive macros can generate `macro_rules` items, regression test for issue #63651. //@ check-pass -//@ aux-build:gen-macro-rules.rs +//@ proc-macro: gen-macro-rules.rs extern crate gen_macro_rules as repro; diff --git a/tests/ui/proc-macro/generate-dollar-ident.rs b/tests/ui/proc-macro/generate-dollar-ident.rs index c087a206566f4..54e872fefb62e 100644 --- a/tests/ui/proc-macro/generate-dollar-ident.rs +++ b/tests/ui/proc-macro/generate-dollar-ident.rs @@ -2,7 +2,7 @@ // without it being recognized as an unknown macro variable. //@ check-pass -//@ aux-build:generate-dollar-ident.rs +//@ proc-macro: generate-dollar-ident.rs extern crate generate_dollar_ident; use generate_dollar_ident::*; diff --git a/tests/ui/proc-macro/generate-mod.rs b/tests/ui/proc-macro/generate-mod.rs index ab93666f28af1..729bfc1db6674 100644 --- a/tests/ui/proc-macro/generate-mod.rs +++ b/tests/ui/proc-macro/generate-mod.rs @@ -1,6 +1,6 @@ // Modules generated by transparent proc macros still acts as barriers for names (issue #50504). -//@ aux-build:generate-mod.rs +//@ proc-macro: generate-mod.rs extern crate generate_mod; diff --git a/tests/ui/proc-macro/helper-attr-blocked-by-import-ambig.rs b/tests/ui/proc-macro/helper-attr-blocked-by-import-ambig.rs index 03bb04b77860c..1197dd7f3bfd0 100644 --- a/tests/ui/proc-macro/helper-attr-blocked-by-import-ambig.rs +++ b/tests/ui/proc-macro/helper-attr-blocked-by-import-ambig.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use(Empty)] extern crate test_macros; diff --git a/tests/ui/proc-macro/helper-attr-blocked-by-import.rs b/tests/ui/proc-macro/helper-attr-blocked-by-import.rs index 03c307834114a..53c079fd19cf6 100644 --- a/tests/ui/proc-macro/helper-attr-blocked-by-import.rs +++ b/tests/ui/proc-macro/helper-attr-blocked-by-import.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use(Empty)] extern crate test_macros; diff --git a/tests/ui/proc-macro/helper-attr-builtin-derive.rs b/tests/ui/proc-macro/helper-attr-builtin-derive.rs index eb7292e093c3a..7d36e055c1435 100644 --- a/tests/ui/proc-macro/helper-attr-builtin-derive.rs +++ b/tests/ui/proc-macro/helper-attr-builtin-derive.rs @@ -2,7 +2,7 @@ // other built-in derive macros. // issue: rust-lang/rust#132561 //@ check-pass -//@ aux-build:helper-attr.rs +//@ proc-macro: helper-attr.rs //@ edition:2021 #[macro_use] diff --git a/tests/ui/proc-macro/hygiene_example.rs b/tests/ui/proc-macro/hygiene_example.rs index 6c3e1067436d0..84b5e345608aa 100644 --- a/tests/ui/proc-macro/hygiene_example.rs +++ b/tests/ui/proc-macro/hygiene_example.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ aux-build:hygiene_example_codegen.rs //@ aux-build:hygiene_example.rs extern crate hygiene_example; diff --git a/tests/ui/proc-macro/import.rs b/tests/ui/proc-macro/import.rs index 53dc0f4cbedcb..44a37dad5c536 100644 --- a/tests/ui/proc-macro/import.rs +++ b/tests/ui/proc-macro/import.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs extern crate test_macros; diff --git a/tests/ui/proc-macro/inert-attribute-order.rs b/tests/ui/proc-macro/inert-attribute-order.rs index bca4df9604060..5a4eae03594bc 100644 --- a/tests/ui/proc-macro/inert-attribute-order.rs +++ b/tests/ui/proc-macro/inert-attribute-order.rs @@ -2,7 +2,7 @@ //@ check-pass //@ compile-flags: -Z span-debug -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/tests/ui/proc-macro/inner-attr-non-inline-mod.rs b/tests/ui/proc-macro/inner-attr-non-inline-mod.rs index df006a4d7a93d..714463b622508 100644 --- a/tests/ui/proc-macro/inner-attr-non-inline-mod.rs +++ b/tests/ui/proc-macro/inner-attr-non-inline-mod.rs @@ -2,7 +2,7 @@ //@ error-pattern:custom inner attributes are unstable //@ error-pattern:inner macro attributes are unstable //@ error-pattern:this was previously accepted -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/tests/ui/proc-macro/inner-attrs.rs b/tests/ui/proc-macro/inner-attrs.rs index 45bb4d3c5bfee..34c37ddfac35d 100644 --- a/tests/ui/proc-macro/inner-attrs.rs +++ b/tests/ui/proc-macro/inner-attrs.rs @@ -1,7 +1,7 @@ // gate-test-custom_inner_attributes //@ compile-flags: -Z span-debug --error-format human //@ error-pattern:expected non-macro inner attribute -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ edition:2018 #![feature(custom_inner_attributes)] diff --git a/tests/ui/proc-macro/input-interpolated.rs b/tests/ui/proc-macro/input-interpolated.rs index d84572a6afe7a..a20fe72c6d5d4 100644 --- a/tests/ui/proc-macro/input-interpolated.rs +++ b/tests/ui/proc-macro/input-interpolated.rs @@ -2,7 +2,7 @@ //@ check-pass //@ edition:2018 -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/tests/ui/proc-macro/input-interpolated.stdout b/tests/ui/proc-macro/input-interpolated.stdout index 1bccd8806be91..b567292ea9a96 100644 --- a/tests/ui/proc-macro/input-interpolated.stdout +++ b/tests/ui/proc-macro/input-interpolated.stdout @@ -2,58 +2,58 @@ PRINT-BANG INPUT (DISPLAY): A PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "A", - span: #0 bytes(506..507), + span: #0 bytes(508..509), }, ] PRINT-ATTR INPUT (DISPLAY): const A : u8 = 0; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "const", - span: #3 bytes(419..424), + span: #3 bytes(421..426), }, Ident { ident: "A", - span: #0 bytes(506..507), + span: #0 bytes(508..509), }, Punct { ch: ':', spacing: Alone, - span: #3 bytes(427..428), + span: #3 bytes(429..430), }, Ident { ident: "u8", - span: #3 bytes(429..431), + span: #3 bytes(431..433), }, Punct { ch: '=', spacing: Alone, - span: #3 bytes(432..433), + span: #3 bytes(434..435), }, Literal { kind: Integer, symbol: "0", suffix: None, - span: #3 bytes(434..435), + span: #3 bytes(436..437), }, Punct { ch: ';', spacing: Alone, - span: #3 bytes(435..436), + span: #3 bytes(437..438), }, ] PRINT-DERIVE INPUT (DISPLAY): struct A {} PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: #3 bytes(471..477), + span: #3 bytes(473..479), }, Ident { ident: "A", - span: #0 bytes(506..507), + span: #0 bytes(508..509), }, Group { delimiter: Brace, stream: TokenStream [], - span: #3 bytes(481..483), + span: #3 bytes(483..485), }, ] diff --git a/tests/ui/proc-macro/invalid-punct-ident-1.rs b/tests/ui/proc-macro/invalid-punct-ident-1.rs index b0f163adc02e8..e7306a7e8ba8c 100644 --- a/tests/ui/proc-macro/invalid-punct-ident-1.rs +++ b/tests/ui/proc-macro/invalid-punct-ident-1.rs @@ -1,4 +1,4 @@ -//@ aux-build:invalid-punct-ident.rs +//@ proc-macro: invalid-punct-ident.rs //@ needs-unwind proc macro panics to report errors #[macro_use] diff --git a/tests/ui/proc-macro/invalid-punct-ident-2.rs b/tests/ui/proc-macro/invalid-punct-ident-2.rs index b1f7f570d3f16..14656652e1d3f 100644 --- a/tests/ui/proc-macro/invalid-punct-ident-2.rs +++ b/tests/ui/proc-macro/invalid-punct-ident-2.rs @@ -1,4 +1,4 @@ -//@ aux-build:invalid-punct-ident.rs +//@ proc-macro: invalid-punct-ident.rs //@ needs-unwind proc macro panics to report errors #[macro_use] diff --git a/tests/ui/proc-macro/invalid-punct-ident-3.rs b/tests/ui/proc-macro/invalid-punct-ident-3.rs index 7698d2c4b394c..266e8d3d92583 100644 --- a/tests/ui/proc-macro/invalid-punct-ident-3.rs +++ b/tests/ui/proc-macro/invalid-punct-ident-3.rs @@ -1,4 +1,4 @@ -//@ aux-build:invalid-punct-ident.rs +//@ proc-macro: invalid-punct-ident.rs //@ needs-unwind proc macro panics to report errors #[macro_use] diff --git a/tests/ui/proc-macro/invalid-punct-ident-4.rs b/tests/ui/proc-macro/invalid-punct-ident-4.rs index 042fe6c600daa..dbffddd158579 100644 --- a/tests/ui/proc-macro/invalid-punct-ident-4.rs +++ b/tests/ui/proc-macro/invalid-punct-ident-4.rs @@ -1,4 +1,4 @@ -//@ aux-build:invalid-punct-ident.rs +//@ proc-macro: invalid-punct-ident.rs //@ needs-unwind proc macro panics to report errors #[macro_use] diff --git a/tests/ui/proc-macro/is-available.rs b/tests/ui/proc-macro/is-available.rs index 36fd44b266f72..faee560d7a975 100644 --- a/tests/ui/proc-macro/is-available.rs +++ b/tests/ui/proc-macro/is-available.rs @@ -2,7 +2,7 @@ extern crate proc_macro; -//@ aux-build:is-available.rs +//@ proc-macro: is-available.rs extern crate is_available; fn main() { diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs index 29793e9f7347d..abdd6bf136dcf 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs @@ -1,4 +1,4 @@ -//@ aux-build:issue-104884.rs +//@ proc-macro: issue-104884.rs use std::collections::BinaryHeap; diff --git a/tests/ui/proc-macro/issue-107113-wrap.rs b/tests/ui/proc-macro/issue-107113-wrap.rs index 01bf3615acfe3..2799e79bb1cb4 100644 --- a/tests/ui/proc-macro/issue-107113-wrap.rs +++ b/tests/ui/proc-macro/issue-107113-wrap.rs @@ -1,5 +1,5 @@ //@ edition:2021 -//@ aux-build:issue-107113.rs +//@ proc-macro: issue-107113.rs #[macro_use] extern crate issue_107113; diff --git a/tests/ui/proc-macro/issue-118809.rs b/tests/ui/proc-macro/issue-118809.rs index 770b19e817219..a6a3956981a78 100644 --- a/tests/ui/proc-macro/issue-118809.rs +++ b/tests/ui/proc-macro/issue-118809.rs @@ -1,4 +1,4 @@ -//@ aux-build: issue-118809.rs +//@ proc-macro: issue-118809.rs #[macro_use] extern crate issue_118809; diff --git a/tests/ui/proc-macro/issue-36935.rs b/tests/ui/proc-macro/issue-36935.rs index eb019d1e1740c..51d85c7dfa94f 100644 --- a/tests/ui/proc-macro/issue-36935.rs +++ b/tests/ui/proc-macro/issue-36935.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ needs-unwind proc macro panics to report errors #[macro_use] diff --git a/tests/ui/proc-macro/issue-37788.rs b/tests/ui/proc-macro/issue-37788.rs index c32ab6b8116e4..b44525b3b20e7 100644 --- a/tests/ui/proc-macro/issue-37788.rs +++ b/tests/ui/proc-macro/issue-37788.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/issue-38586.rs b/tests/ui/proc-macro/issue-38586.rs index 54d5d1038a621..88dbb8037bebd 100644 --- a/tests/ui/proc-macro/issue-38586.rs +++ b/tests/ui/proc-macro/issue-38586.rs @@ -1,4 +1,4 @@ -//@ aux-build:issue-38586.rs +//@ proc-macro: issue-38586.rs #[macro_use] extern crate issue_38586; diff --git a/tests/ui/proc-macro/issue-39889.rs b/tests/ui/proc-macro/issue-39889.rs index 687aefbc068ae..a10fa02e14a8a 100644 --- a/tests/ui/proc-macro/issue-39889.rs +++ b/tests/ui/proc-macro/issue-39889.rs @@ -1,7 +1,7 @@ //@ run-pass #![allow(dead_code, unused_macros)] -//@ aux-build:issue-39889.rs +//@ proc-macro: issue-39889.rs extern crate issue_39889; use issue_39889::Issue39889; diff --git a/tests/ui/proc-macro/issue-42708.rs b/tests/ui/proc-macro/issue-42708.rs index 27cb2f73d562c..9eb616008de5c 100644 --- a/tests/ui/proc-macro/issue-42708.rs +++ b/tests/ui/proc-macro/issue-42708.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:issue-42708.rs +//@ proc-macro: issue-42708.rs #![feature(decl_macro)] #![allow(unused)] diff --git a/tests/ui/proc-macro/issue-50061.rs b/tests/ui/proc-macro/issue-50061.rs index 34999bb507024..8a660c2f3506a 100644 --- a/tests/ui/proc-macro/issue-50061.rs +++ b/tests/ui/proc-macro/issue-50061.rs @@ -1,7 +1,7 @@ //@ run-pass #![allow(path_statements)] -//@ aux-build:issue-50061.rs +//@ proc-macro: issue-50061.rs #![feature(decl_macro)] diff --git a/tests/ui/proc-macro/issue-50493.rs b/tests/ui/proc-macro/issue-50493.rs index 5456eddb78d0b..e23f1f7c7d872 100644 --- a/tests/ui/proc-macro/issue-50493.rs +++ b/tests/ui/proc-macro/issue-50493.rs @@ -1,4 +1,4 @@ -//@ aux-build:issue-50493.rs +//@ proc-macro: issue-50493.rs #[macro_use] extern crate issue_50493; diff --git a/tests/ui/proc-macro/issue-53481.rs b/tests/ui/proc-macro/issue-53481.rs index 636b8e0c0ae5c..11e11e2e6b6d4 100644 --- a/tests/ui/proc-macro/issue-53481.rs +++ b/tests/ui/proc-macro/issue-53481.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs index 24e3be0ed2e40..c1b55fd99dfad 100644 --- a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs +++ b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs @@ -2,7 +2,7 @@ // `issue_59191::no_main` replaces whatever's passed in with `fn main() {}`. //@ edition:2018 -//@ aux-crate:issue_59191=issue-59191.rs +//@ proc-macro: issue-59191.rs //@ error-pattern: requires `sized` lang_item #![feature(custom_inner_attributes)] diff --git a/tests/ui/proc-macro/issue-66286.rs b/tests/ui/proc-macro/issue-66286.rs index 3ca064768b2d6..57d1af26e934d 100644 --- a/tests/ui/proc-macro/issue-66286.rs +++ b/tests/ui/proc-macro/issue-66286.rs @@ -1,4 +1,4 @@ -//@ aux-build:issue-66286.rs +//@ proc-macro: issue-66286.rs // Regression test for #66286. diff --git a/tests/ui/proc-macro/issue-73933-procedural-masquerade.rs b/tests/ui/proc-macro/issue-73933-procedural-masquerade.rs index 8f07cd34cc9eb..3421d13f4d9d6 100644 --- a/tests/ui/proc-macro/issue-73933-procedural-masquerade.rs +++ b/tests/ui/proc-macro/issue-73933-procedural-masquerade.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ check-pass #[macro_use] diff --git a/tests/ui/proc-macro/issue-73933-procedural-masquerade.stdout b/tests/ui/proc-macro/issue-73933-procedural-masquerade.stdout index 5e39c01ab5e2b..83a3f58095836 100644 --- a/tests/ui/proc-macro/issue-73933-procedural-masquerade.stdout +++ b/tests/ui/proc-macro/issue-73933-procedural-masquerade.stdout @@ -2,20 +2,20 @@ PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "enum", - span: #0 bytes(102..106), + span: #0 bytes(104..108), }, Ident { ident: "ProceduralMasqueradeDummyType", - span: #0 bytes(107..136), + span: #0 bytes(109..138), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "Input", - span: #0 bytes(143..148), + span: #0 bytes(145..150), }, ], - span: #0 bytes(137..150), + span: #0 bytes(139..152), }, ] diff --git a/tests/ui/proc-macro/issue-75734-pp-paren.rs b/tests/ui/proc-macro/issue-75734-pp-paren.rs index ab0f4f72e62d0..d084c4a2873bc 100644 --- a/tests/ui/proc-macro/issue-75734-pp-paren.rs +++ b/tests/ui/proc-macro/issue-75734-pp-paren.rs @@ -3,7 +3,7 @@ // normally insert extra parentheses. //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug #![no_std] // Don't load unnecessary hygiene information from std diff --git a/tests/ui/proc-macro/issue-75801.rs b/tests/ui/proc-macro/issue-75801.rs index f0a1940cb5c12..feda5e60b0d42 100644 --- a/tests/ui/proc-macro/issue-75801.rs +++ b/tests/ui/proc-macro/issue-75801.rs @@ -1,4 +1,4 @@ -//@ aux-build: issue-75801.rs +//@ proc-macro: issue-75801.rs // Regression test for #75801. diff --git a/tests/ui/proc-macro/issue-75930-derive-cfg.rs b/tests/ui/proc-macro/issue-75930-derive-cfg.rs index f480de24e3e40..376a8ea42783a 100644 --- a/tests/ui/proc-macro/issue-75930-derive-cfg.rs +++ b/tests/ui/proc-macro/issue-75930-derive-cfg.rs @@ -1,6 +1,6 @@ //@ check-pass //@ compile-flags: -Z span-debug -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs // Regression test for issue #75930 // Tests that we cfg-strip all targets before invoking diff --git a/tests/ui/proc-macro/issue-76182-leading-vert-pat.rs b/tests/ui/proc-macro/issue-76182-leading-vert-pat.rs index dc40a1715a685..218debf3e7cea 100644 --- a/tests/ui/proc-macro/issue-76182-leading-vert-pat.rs +++ b/tests/ui/proc-macro/issue-76182-leading-vert-pat.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug // // Regression test for issue #76182 diff --git a/tests/ui/proc-macro/issue-76270-panic-in-libproc-macro.rs b/tests/ui/proc-macro/issue-76270-panic-in-libproc-macro.rs index 001a09fc5523e..2a003c30bf9f3 100644 --- a/tests/ui/proc-macro/issue-76270-panic-in-libproc-macro.rs +++ b/tests/ui/proc-macro/issue-76270-panic-in-libproc-macro.rs @@ -1,4 +1,4 @@ -//@ aux-build:proc-macro-panic.rs +//@ proc-macro: proc-macro-panic.rs //@ edition:2018 //@ needs-unwind proc macro panics to report errors diff --git a/tests/ui/proc-macro/issue-78675-captured-inner-attrs.rs b/tests/ui/proc-macro/issue-78675-captured-inner-attrs.rs index d3716b22729fe..63e8af3102725 100644 --- a/tests/ui/proc-macro/issue-78675-captured-inner-attrs.rs +++ b/tests/ui/proc-macro/issue-78675-captured-inner-attrs.rs @@ -1,7 +1,7 @@ //@ check-pass //@ edition:2018 //@ compile-flags: -Z span-debug -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/tests/ui/proc-macro/issue-79148.rs b/tests/ui/proc-macro/issue-79148.rs index 96ee5e033e16a..b2248759b5f8e 100644 --- a/tests/ui/proc-macro/issue-79148.rs +++ b/tests/ui/proc-macro/issue-79148.rs @@ -1,4 +1,4 @@ -//@ aux-build:re-export.rs +//@ proc-macro: re-export.rs //@ edition:2018 extern crate re_export; diff --git a/tests/ui/proc-macro/issue-79242-slow-retokenize-check.rs b/tests/ui/proc-macro/issue-79242-slow-retokenize-check.rs index d0c14d8b5d09f..3306bc21e3a9b 100644 --- a/tests/ui/proc-macro/issue-79242-slow-retokenize-check.rs +++ b/tests/ui/proc-macro/issue-79242-slow-retokenize-check.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:issue-79242.rs +//@ proc-macro: issue-79242.rs // Regression test for issue #79242 // Tests that compilation time doesn't blow up for a proc-macro diff --git a/tests/ui/proc-macro/issue-79825.rs b/tests/ui/proc-macro/issue-79825.rs index f846bb404864c..67b79172bb3b3 100644 --- a/tests/ui/proc-macro/issue-79825.rs +++ b/tests/ui/proc-macro/issue-79825.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:issue-79825.rs +//@ proc-macro: issue-79825.rs #![feature(trait_alias)] extern crate issue_79825; diff --git a/tests/ui/proc-macro/issue-80760-empty-stmt.rs b/tests/ui/proc-macro/issue-80760-empty-stmt.rs index 59244e12eb8d2..b940da6778a07 100644 --- a/tests/ui/proc-macro/issue-80760-empty-stmt.rs +++ b/tests/ui/proc-macro/issue-80760-empty-stmt.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug #![no_std] // Don't load unnecessary hygiene information from std diff --git a/tests/ui/proc-macro/issue-81007-item-attrs.rs b/tests/ui/proc-macro/issue-81007-item-attrs.rs index ab47c9df08179..f3b8aa8c7c5a5 100644 --- a/tests/ui/proc-macro/issue-81007-item-attrs.rs +++ b/tests/ui/proc-macro/issue-81007-item-attrs.rs @@ -1,7 +1,7 @@ //@ check-pass //@ edition:2018 //@ compile-flags: -Z span-debug -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![feature(rustc_attrs)] diff --git a/tests/ui/proc-macro/issue-81543-item-parse-err.rs b/tests/ui/proc-macro/issue-81543-item-parse-err.rs index f3c307318a0b4..6cd8c0d6c40ab 100644 --- a/tests/ui/proc-macro/issue-81543-item-parse-err.rs +++ b/tests/ui/proc-macro/issue-81543-item-parse-err.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs // Regression test for issue #81543 // Tests that we emit a properly spanned error diff --git a/tests/ui/proc-macro/issue-81555.rs b/tests/ui/proc-macro/issue-81555.rs index 7a61a31952f41..bbc7542cb24a7 100644 --- a/tests/ui/proc-macro/issue-81555.rs +++ b/tests/ui/proc-macro/issue-81555.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![feature(stmt_expr_attributes, proc_macro_hygiene)] extern crate test_macros; diff --git a/tests/ui/proc-macro/issue-83510.rs b/tests/ui/proc-macro/issue-83510.rs index ea8a334f57c55..67469511fc367 100644 --- a/tests/ui/proc-macro/issue-83510.rs +++ b/tests/ui/proc-macro/issue-83510.rs @@ -1,4 +1,4 @@ -//@ aux-build: issue-83510.rs +//@ proc-macro: issue-83510.rs extern crate issue_83510; diff --git a/tests/ui/proc-macro/issue-86781-bad-inner-doc.fixed b/tests/ui/proc-macro/issue-86781-bad-inner-doc.fixed index 367ad66a1a62b..b8b3e6f3f7e3b 100644 --- a/tests/ui/proc-macro/issue-86781-bad-inner-doc.fixed +++ b/tests/ui/proc-macro/issue-86781-bad-inner-doc.fixed @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ run-rustfix #[macro_use] diff --git a/tests/ui/proc-macro/issue-86781-bad-inner-doc.rs b/tests/ui/proc-macro/issue-86781-bad-inner-doc.rs index c49619ef2ac7d..ce1a0da6cad70 100644 --- a/tests/ui/proc-macro/issue-86781-bad-inner-doc.rs +++ b/tests/ui/proc-macro/issue-86781-bad-inner-doc.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ run-rustfix #[macro_use] diff --git a/tests/ui/proc-macro/issue-91800.rs b/tests/ui/proc-macro/issue-91800.rs index b69fce4cf7731..bc78bcacfd0f7 100644 --- a/tests/ui/proc-macro/issue-91800.rs +++ b/tests/ui/proc-macro/issue-91800.rs @@ -1,4 +1,4 @@ -//@ aux-build: issue-91800-macro.rs +//@ proc-macro: issue-91800-macro.rs #[macro_use] extern crate issue_91800_macro; diff --git a/tests/ui/proc-macro/item-error.rs b/tests/ui/proc-macro/item-error.rs index f3e3eafcd8d17..5f798faf436a5 100644 --- a/tests/ui/proc-macro/item-error.rs +++ b/tests/ui/proc-macro/item-error.rs @@ -1,4 +1,4 @@ -//@ aux-build:derive-b.rs +//@ proc-macro: derive-b.rs #![allow(warnings)] diff --git a/tests/ui/proc-macro/keep-expr-tokens.rs b/tests/ui/proc-macro/keep-expr-tokens.rs index ced7fad47b924..2bd66da90e27d 100644 --- a/tests/ui/proc-macro/keep-expr-tokens.rs +++ b/tests/ui/proc-macro/keep-expr-tokens.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug #![feature(stmt_expr_attributes)] diff --git a/tests/ui/proc-macro/lifetimes-rpass.rs b/tests/ui/proc-macro/lifetimes-rpass.rs index a6b1f46a5d1a7..c462b27722f7e 100644 --- a/tests/ui/proc-macro/lifetimes-rpass.rs +++ b/tests/ui/proc-macro/lifetimes-rpass.rs @@ -1,7 +1,7 @@ //@ run-pass #![allow(unused_variables)] -//@ aux-build:lifetimes-rpass.rs +//@ proc-macro: lifetimes-rpass.rs extern crate lifetimes_rpass as lifetimes; use lifetimes::*; diff --git a/tests/ui/proc-macro/lifetimes.rs b/tests/ui/proc-macro/lifetimes.rs index 0c5d3e2f72fa5..cfff3cb1785d6 100644 --- a/tests/ui/proc-macro/lifetimes.rs +++ b/tests/ui/proc-macro/lifetimes.rs @@ -1,4 +1,4 @@ -//@ aux-build:lifetimes.rs +//@ proc-macro: lifetimes.rs extern crate lifetimes; diff --git a/tests/ui/proc-macro/lints_in_proc_macros.rs b/tests/ui/proc-macro/lints_in_proc_macros.rs index 13ae7239a143d..6714b8b6e1d5f 100644 --- a/tests/ui/proc-macro/lints_in_proc_macros.rs +++ b/tests/ui/proc-macro/lints_in_proc_macros.rs @@ -1,4 +1,4 @@ -//@ aux-build:bang_proc_macro2.rs +//@ proc-macro: bang_proc_macro2.rs extern crate bang_proc_macro2; diff --git a/tests/ui/proc-macro/literal-to-string.rs b/tests/ui/proc-macro/literal-to-string.rs index e87315fe14492..7a56e08109c58 100644 --- a/tests/ui/proc-macro/literal-to-string.rs +++ b/tests/ui/proc-macro/literal-to-string.rs @@ -1,7 +1,7 @@ //@ check-pass //@ edition: 2021 -//@ aux-build: print-tokens.rs +//@ proc-macro: print-tokens.rs extern crate print_tokens; fn main() { diff --git a/tests/ui/proc-macro/literal-to-string.stdout b/tests/ui/proc-macro/literal-to-string.stdout index c3114265e0a86..18c0c20dde4e9 100644 --- a/tests/ui/proc-macro/literal-to-string.stdout +++ b/tests/ui/proc-macro/literal-to-string.stdout @@ -3,91 +3,91 @@ TokenStream [ kind: Integer, symbol: "1", suffix: None, - span: #0 bytes(147..148), + span: #0 bytes(148..149), }, Literal { kind: Integer, symbol: "17", suffix: Some("u8"), - span: #0 bytes(157..161), + span: #0 bytes(158..162), }, Literal { kind: Float, symbol: "42.", suffix: None, - span: #0 bytes(170..173), + span: #0 bytes(171..174), }, Literal { kind: Float, symbol: "3.14", suffix: Some("f32"), - span: #0 bytes(182..189), + span: #0 bytes(183..190), }, Literal { kind: Byte, symbol: "a", suffix: None, - span: #0 bytes(198..202), + span: #0 bytes(199..203), }, Literal { kind: Byte, symbol: "\xFF", suffix: None, - span: #0 bytes(211..218), + span: #0 bytes(212..219), }, Literal { kind: Char, symbol: "c", suffix: None, - span: #0 bytes(227..230), + span: #0 bytes(228..231), }, Literal { kind: Char, symbol: "\x32", suffix: None, - span: #0 bytes(239..245), + span: #0 bytes(240..246), }, Literal { kind: Str, symbol: "\\"str\\"", suffix: None, - span: #0 bytes(254..263), + span: #0 bytes(255..264), }, Literal { kind: StrRaw(1), symbol: "\"raw\" str", suffix: None, - span: #0 bytes(272..286), + span: #0 bytes(273..287), }, Literal { kind: StrRaw(3), symbol: "very ##\"raw\"## str", suffix: None, - span: #0 bytes(295..322), + span: #0 bytes(296..323), }, Literal { kind: ByteStr, symbol: "\\"byte\\" str", suffix: None, - span: #0 bytes(331..346), + span: #0 bytes(332..347), }, Literal { kind: ByteStrRaw(1), symbol: "\"raw\" \"byte\" str", suffix: None, - span: #0 bytes(355..377), + span: #0 bytes(356..378), }, Literal { kind: CStr, symbol: "\\"c\\" str", suffix: None, - span: #0 bytes(386..398), + span: #0 bytes(387..399), }, Literal { kind: CStrRaw(1), symbol: "\"raw\" \"c\" str", suffix: None, - span: #0 bytes(407..426), + span: #0 bytes(408..427), }, ] 1 diff --git a/tests/ui/proc-macro/load-panic-backtrace.rs b/tests/ui/proc-macro/load-panic-backtrace.rs index 15badedef973d..302bcaea75e68 100644 --- a/tests/ui/proc-macro/load-panic-backtrace.rs +++ b/tests/ui/proc-macro/load-panic-backtrace.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z proc-macro-backtrace //@ rustc-env:RUST_BACKTRACE=0 //@ normalize-stderr-test: "thread '.*' panicked " -> "" diff --git a/tests/ui/proc-macro/load-panic-backtrace.stderr b/tests/ui/proc-macro/load-panic-backtrace.stderr index 18f5135867262..0f3db6c831e19 100644 --- a/tests/ui/proc-macro/load-panic-backtrace.stderr +++ b/tests/ui/proc-macro/load-panic-backtrace.stderr @@ -1,4 +1,4 @@ -at $DIR/auxiliary/test-macros.rs:43:5: +at $DIR/auxiliary/test-macros.rs:38:5: panic-derive error: proc-macro derive panicked --> $DIR/load-panic-backtrace.rs:11:10 diff --git a/tests/ui/proc-macro/load-panic.rs b/tests/ui/proc-macro/load-panic.rs index 50475a34226b4..18bfb71050b3d 100644 --- a/tests/ui/proc-macro/load-panic.rs +++ b/tests/ui/proc-macro/load-panic.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ needs-unwind proc macro panics to report errors #[macro_use] diff --git a/tests/ui/proc-macro/load-two.rs b/tests/ui/proc-macro/load-two.rs index 44fcdb056dd61..608379949e665 100644 --- a/tests/ui/proc-macro/load-two.rs +++ b/tests/ui/proc-macro/load-two.rs @@ -2,8 +2,8 @@ #![allow(path_statements)] #![allow(dead_code)] -//@ aux-build:derive-atob.rs -//@ aux-build:derive-ctod.rs +//@ proc-macro: derive-atob.rs +//@ proc-macro: derive-ctod.rs #[macro_use] extern crate derive_atob; diff --git a/tests/ui/proc-macro/macro-brackets.rs b/tests/ui/proc-macro/macro-brackets.rs index 91bd652d37b88..70686eed0bd64 100644 --- a/tests/ui/proc-macro/macro-brackets.rs +++ b/tests/ui/proc-macro/macro-brackets.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/macro-crate-multi-decorator.rs b/tests/ui/proc-macro/macro-crate-multi-decorator.rs index 26a2d1592aba3..c4f02e7adfcbc 100644 --- a/tests/ui/proc-macro/macro-crate-multi-decorator.rs +++ b/tests/ui/proc-macro/macro-crate-multi-decorator.rs @@ -1,7 +1,7 @@ // The duplicate macro will create a copy of the item with the given identifier. //@ check-pass -//@ aux-build:duplicate.rs +//@ proc-macro: duplicate.rs #[macro_use] extern crate duplicate; diff --git a/tests/ui/proc-macro/macro-quote-cond.rs b/tests/ui/proc-macro/macro-quote-cond.rs index 3658e2a28f2a7..062511eec9bc2 100644 --- a/tests/ui/proc-macro/macro-quote-cond.rs +++ b/tests/ui/proc-macro/macro-quote-cond.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:cond_plugin.rs +//@ proc-macro: cond_plugin.rs #![allow(unused_parens)] diff --git a/tests/ui/proc-macro/macro-rules-derive-cfg.rs b/tests/ui/proc-macro/macro-rules-derive-cfg.rs index c34f1695761cf..ab504bc63a29d 100644 --- a/tests/ui/proc-macro/macro-rules-derive-cfg.rs +++ b/tests/ui/proc-macro/macro-rules-derive-cfg.rs @@ -1,6 +1,6 @@ //@ check-pass //@ compile-flags: -Z span-debug --error-format human -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] diff --git a/tests/ui/proc-macro/macro-rules-derive.rs b/tests/ui/proc-macro/macro-rules-derive.rs index 4023a9a044aa8..c4e906fb5edec 100644 --- a/tests/ui/proc-macro/macro-rules-derive.rs +++ b/tests/ui/proc-macro/macro-rules-derive.rs @@ -1,4 +1,4 @@ -//@ aux-build:first-second.rs +//@ proc-macro: first-second.rs extern crate first_second; use first_second::*; diff --git a/tests/ui/proc-macro/macro-use-attr.rs b/tests/ui/proc-macro/macro-use-attr.rs index fe071b263838a..b2d4b9e6ffa63 100644 --- a/tests/ui/proc-macro/macro-use-attr.rs +++ b/tests/ui/proc-macro/macro-use-attr.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/macro-use-bang.rs b/tests/ui/proc-macro/macro-use-bang.rs index f8ccba6b0941a..9397baff1d674 100644 --- a/tests/ui/proc-macro/macro-use-bang.rs +++ b/tests/ui/proc-macro/macro-use-bang.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/macro_rules_edition_from_pm.rs b/tests/ui/proc-macro/macro_rules_edition_from_pm.rs new file mode 100644 index 0000000000000..8fc7d9097493d --- /dev/null +++ b/tests/ui/proc-macro/macro_rules_edition_from_pm.rs @@ -0,0 +1,26 @@ +// Tests how edition hygiene works for macro_rules macros generated from a +// proc-macro. +// See https://github.com/rust-lang/rust/issues/132906 + +//@ proc-macro: macro_rules_edition_pm.rs +//@ revisions: edition2021 edition2024 +//@[edition2021] edition:2021 +//@[edition2024] edition:2024 +//@ check-pass + +// This checks how the expr fragment specifier works. +macro_rules_edition_pm::make_edition_macro!{} + +const _: () = { + assert!(edition!(const {}) == 2021); +}; + +// This checks how the expr fragment specifier from a nested macro. +macro_rules_edition_pm::make_nested_edition_macro!{} +make_inner!{} + +const _: () = { + assert!(edition_inner!(const {}) == 2021); +}; + +fn main() {} diff --git a/tests/ui/proc-macro/macros-in-extern.rs b/tests/ui/proc-macro/macros-in-extern.rs index da384d1b141e4..f39322d126e04 100644 --- a/tests/ui/proc-macro/macros-in-extern.rs +++ b/tests/ui/proc-macro/macros-in-extern.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/macros-in-type.rs b/tests/ui/proc-macro/macros-in-type.rs index 4db7cf273f702..1874bb80db35f 100644 --- a/tests/ui/proc-macro/macros-in-type.rs +++ b/tests/ui/proc-macro/macros-in-type.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/meta-macro-hygiene.rs b/tests/ui/proc-macro/meta-macro-hygiene.rs index 98496d5a4c609..9fbe9763b44dc 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.rs +++ b/tests/ui/proc-macro/meta-macro-hygiene.rs @@ -1,5 +1,5 @@ //@ aux-build:make-macro.rs -//@ aux-build:meta-macro.rs +//@ proc-macro: meta-macro.rs //@ edition:2018 //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no //@ check-pass diff --git a/tests/ui/proc-macro/meta-macro-hygiene.stdout b/tests/ui/proc-macro/meta-macro-hygiene.stdout index 3c6ec6fbdd4ba..ae02b24e1d0e9 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.stdout +++ b/tests/ui/proc-macro/meta-macro-hygiene.stdout @@ -3,7 +3,7 @@ Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:26 Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: ':', spacing: Joint, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: ':', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Ident { ident: "dummy", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: '!', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }] #![feature /* 0#0 */(prelude_import)] //@ aux-build:make-macro.rs -//@ aux-build:meta-macro.rs +//@ proc-macro: meta-macro.rs //@ edition:2018 //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no //@ check-pass diff --git a/tests/ui/proc-macro/meta-macro.rs b/tests/ui/proc-macro/meta-macro.rs index abe63c60fb8de..02ef45c0c21f5 100644 --- a/tests/ui/proc-macro/meta-macro.rs +++ b/tests/ui/proc-macro/meta-macro.rs @@ -1,5 +1,5 @@ //@ aux-build:make-macro.rs -//@ aux-build:meta-macro.rs +//@ proc-macro: meta-macro.rs //@ edition:2018 //@ compile-flags: -Z span-debug //@ run-pass diff --git a/tests/ui/proc-macro/mixed-site-span.rs b/tests/ui/proc-macro/mixed-site-span.rs index bab76a8c43319..2b5d97570438a 100644 --- a/tests/ui/proc-macro/mixed-site-span.rs +++ b/tests/ui/proc-macro/mixed-site-span.rs @@ -1,6 +1,6 @@ // Proc macros using `mixed_site` spans exhibit usual properties of `macro_rules` hygiene. -//@ aux-build:mixed-site-span.rs +//@ proc-macro: mixed-site-span.rs #[macro_use] extern crate mixed_site_span; diff --git a/tests/ui/proc-macro/modify-ast.rs b/tests/ui/proc-macro/modify-ast.rs index 4c125c1c6e8f5..9e890f3ebaad9 100644 --- a/tests/ui/proc-macro/modify-ast.rs +++ b/tests/ui/proc-macro/modify-ast.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:modify-ast.rs +//@ proc-macro: modify-ast.rs extern crate modify_ast; diff --git a/tests/ui/proc-macro/multispan.rs b/tests/ui/proc-macro/multispan.rs index 60f67c8c67c06..e06aa9f7c5adb 100644 --- a/tests/ui/proc-macro/multispan.rs +++ b/tests/ui/proc-macro/multispan.rs @@ -1,4 +1,4 @@ -//@ aux-build:multispan.rs +//@ proc-macro: multispan.rs extern crate multispan; diff --git a/tests/ui/proc-macro/negative-token.rs b/tests/ui/proc-macro/negative-token.rs index 32408e0d9367f..8c6fa9ca6893c 100644 --- a/tests/ui/proc-macro/negative-token.rs +++ b/tests/ui/proc-macro/negative-token.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:negative-token.rs +//@ proc-macro: negative-token.rs extern crate negative_token; diff --git a/tests/ui/proc-macro/nested-derive-cfg.rs b/tests/ui/proc-macro/nested-derive-cfg.rs index 696a5024ec2ae..bd8f231ac2c2a 100644 --- a/tests/ui/proc-macro/nested-derive-cfg.rs +++ b/tests/ui/proc-macro/nested-derive-cfg.rs @@ -1,5 +1,5 @@ //@ compile-flags: -Z span-debug --error-format human -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ check-pass #![no_std] // Don't load unnecessary hygiene information from std diff --git a/tests/ui/proc-macro/nested-item-spans.rs b/tests/ui/proc-macro/nested-item-spans.rs index c19af0f9796a4..f7e2365586d54 100644 --- a/tests/ui/proc-macro/nested-item-spans.rs +++ b/tests/ui/proc-macro/nested-item-spans.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/nested-macro-rules.rs b/tests/ui/proc-macro/nested-macro-rules.rs index 2f0d85c4bbf88..95a38e4c1b6a2 100644 --- a/tests/ui/proc-macro/nested-macro-rules.rs +++ b/tests/ui/proc-macro/nested-macro-rules.rs @@ -1,6 +1,6 @@ //@ run-pass //@ aux-build:nested-macro-rules.rs -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug -Z macro-backtrace //@ edition:2018 diff --git a/tests/ui/proc-macro/nested-nonterminal-tokens.rs b/tests/ui/proc-macro/nested-nonterminal-tokens.rs index 6e28cabd2fe60..630e33dbd83cb 100644 --- a/tests/ui/proc-macro/nested-nonterminal-tokens.rs +++ b/tests/ui/proc-macro/nested-nonterminal-tokens.rs @@ -1,7 +1,7 @@ //@ check-pass //@ edition:2018 //@ compile-flags: -Z span-debug -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs // Tests that we properly pass tokens to proc-macro when nested // nonterminals are involved. diff --git a/tests/ui/proc-macro/no-macro-use-attr.rs b/tests/ui/proc-macro/no-macro-use-attr.rs index ae507a31ba783..d44f51bfd8d47 100644 --- a/tests/ui/proc-macro/no-macro-use-attr.rs +++ b/tests/ui/proc-macro/no-macro-use-attr.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![feature(rustc_attrs)] #![warn(unused_extern_crates)] diff --git a/tests/ui/proc-macro/nodelim-groups.rs b/tests/ui/proc-macro/nodelim-groups.rs index f13d97aaff57b..9acdc7023c083 100644 --- a/tests/ui/proc-macro/nodelim-groups.rs +++ b/tests/ui/proc-macro/nodelim-groups.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug //@ edition:2018 // diff --git a/tests/ui/proc-macro/nonterminal-expansion.rs b/tests/ui/proc-macro/nonterminal-expansion.rs index 96ea4aef85b4d..99a68996c309f 100644 --- a/tests/ui/proc-macro/nonterminal-expansion.rs +++ b/tests/ui/proc-macro/nonterminal-expansion.rs @@ -1,6 +1,6 @@ //@ check-pass //@ compile-flags: -Z span-debug -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/tests/ui/proc-macro/nonterminal-recollect-attr.rs b/tests/ui/proc-macro/nonterminal-recollect-attr.rs index 7d922bafdcdb6..3f3348b18c1f3 100644 --- a/tests/ui/proc-macro/nonterminal-recollect-attr.rs +++ b/tests/ui/proc-macro/nonterminal-recollect-attr.rs @@ -1,6 +1,6 @@ //@ check-pass //@ compile-flags: -Z span-debug -//@ aux-build:nonterminal-recollect-attr.rs +//@ proc-macro: nonterminal-recollect-attr.rs #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.rs b/tests/ui/proc-macro/nonterminal-token-hygiene.rs index 6a4406b053d5e..76c71441c8083 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.rs +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.rs @@ -7,7 +7,7 @@ //@ normalize-stdout-test: "\d+#" -> "0#" //@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" //@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![feature(decl_macro)] #![no_std] // Don't load unnecessary hygiene information from std diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout index de3265e928141..1ad1405902815 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout @@ -31,7 +31,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ //@ normalize-stdout-test: "\d+#" -> "0#" //@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" //@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![feature /* 0#0 */(decl_macro)] #![no_std /* 0#0 */] diff --git a/tests/ui/proc-macro/not-joint.rs b/tests/ui/proc-macro/not-joint.rs index 16b89bc6e8193..c585e7e33dc3c 100644 --- a/tests/ui/proc-macro/not-joint.rs +++ b/tests/ui/proc-macro/not-joint.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:not-joint.rs +//@ proc-macro: not-joint.rs extern crate not_joint as bar; use bar::{tokens, nothing}; diff --git a/tests/ui/proc-macro/out-of-line-mod.rs b/tests/ui/proc-macro/out-of-line-mod.rs index 2a4fb16a09ad4..efe9588bef667 100644 --- a/tests/ui/proc-macro/out-of-line-mod.rs +++ b/tests/ui/proc-macro/out-of-line-mod.rs @@ -1,7 +1,7 @@ // Out-of-line module is found on the filesystem if passed through a proc macro (issue #58818). //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/parent-source-spans.rs b/tests/ui/proc-macro/parent-source-spans.rs index 12a1ab1a43d57..cc3ac795f7f17 100644 --- a/tests/ui/proc-macro/parent-source-spans.rs +++ b/tests/ui/proc-macro/parent-source-spans.rs @@ -1,4 +1,4 @@ -//@ aux-build:parent-source-spans.rs +//@ proc-macro: parent-source-spans.rs #![feature(decl_macro)] diff --git a/tests/ui/proc-macro/parse-invis-delim-issue-128895.rs b/tests/ui/proc-macro/parse-invis-delim-issue-128895.rs index 3d5af5fee217d..2dc3220246538 100644 --- a/tests/ui/proc-macro/parse-invis-delim-issue-128895.rs +++ b/tests/ui/proc-macro/parse-invis-delim-issue-128895.rs @@ -1,4 +1,4 @@ -//@ aux-build:parse-invis-delim-issue-128895.rs +//@ proc-macro: parse-invis-delim-issue-128895.rs //@ check-pass #![no_std] // Don't load unnecessary hygiene information from std diff --git a/tests/ui/proc-macro/pretty-print-hack-hide.rs b/tests/ui/proc-macro/pretty-print-hack-hide.rs index 26db43341ab7a..fd98f16a780ea 100644 --- a/tests/ui/proc-macro/pretty-print-hack-hide.rs +++ b/tests/ui/proc-macro/pretty-print-hack-hide.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug //@ check-pass diff --git a/tests/ui/proc-macro/pretty-print-hack-show.rs b/tests/ui/proc-macro/pretty-print-hack-show.rs index 1b6794ae69862..de6453c6a821d 100644 --- a/tests/ui/proc-macro/pretty-print-hack-show.rs +++ b/tests/ui/proc-macro/pretty-print-hack-show.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug //@ revisions: local remapped // [local] no-remap-src-base: The hack should work regardless of remapping. diff --git a/tests/ui/proc-macro/pretty-print-tts.rs b/tests/ui/proc-macro/pretty-print-tts.rs index e3240e27c2a04..b1b4f278e2a3a 100644 --- a/tests/ui/proc-macro/pretty-print-tts.rs +++ b/tests/ui/proc-macro/pretty-print-tts.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug #![feature(rustc_attrs)] diff --git a/tests/ui/proc-macro/proc-macro-attributes.rs b/tests/ui/proc-macro/proc-macro-attributes.rs index 6d5e7b67c782e..455fcc56e58b0 100644 --- a/tests/ui/proc-macro/proc-macro-attributes.rs +++ b/tests/ui/proc-macro/proc-macro-attributes.rs @@ -1,4 +1,4 @@ -//@ aux-build:derive-b.rs +//@ proc-macro: derive-b.rs #[macro_use] extern crate derive_b; diff --git a/tests/ui/proc-macro/proc-macro-gates.rs b/tests/ui/proc-macro/proc-macro-gates.rs index 585d9a3c9be34..bf384bc479b51 100644 --- a/tests/ui/proc-macro/proc-macro-gates.rs +++ b/tests/ui/proc-macro/proc-macro-gates.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs // gate-test-proc_macro_hygiene #![feature(stmt_expr_attributes)] diff --git a/tests/ui/proc-macro/proc-macro-gates2.rs b/tests/ui/proc-macro/proc-macro-gates2.rs index 76d8036d8a447..450f64982b01f 100644 --- a/tests/ui/proc-macro/proc-macro-gates2.rs +++ b/tests/ui/proc-macro/proc-macro-gates2.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![feature(stmt_expr_attributes)] diff --git a/tests/ui/proc-macro/raw-ident.rs b/tests/ui/proc-macro/raw-ident.rs index 2ea2d3079dc00..95ada295f5c0e 100644 --- a/tests/ui/proc-macro/raw-ident.rs +++ b/tests/ui/proc-macro/raw-ident.rs @@ -1,4 +1,4 @@ -//@ aux-build:raw-ident.rs +//@ proc-macro: raw-ident.rs #[macro_use] extern crate raw_ident; diff --git a/tests/ui/proc-macro/resolve-error.rs b/tests/ui/proc-macro/resolve-error.rs index 2670d8884ae72..0ca250194f01a 100644 --- a/tests/ui/proc-macro/resolve-error.rs +++ b/tests/ui/proc-macro/resolve-error.rs @@ -1,6 +1,6 @@ -//@ aux-build:derive-foo.rs -//@ aux-build:derive-clona.rs -//@ aux-build:test-macros.rs +//@ proc-macro: derive-foo.rs +//@ proc-macro: derive-clona.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate derive_foo; diff --git a/tests/ui/proc-macro/resolve-error.stderr b/tests/ui/proc-macro/resolve-error.stderr index e7639f474c75e..963298311ef5b 100644 --- a/tests/ui/proc-macro/resolve-error.stderr +++ b/tests/ui/proc-macro/resolve-error.stderr @@ -4,7 +4,7 @@ error: cannot find macro `bang_proc_macrp` in this scope LL | bang_proc_macrp!(); | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro` | - ::: $DIR/auxiliary/test-macros.rs:15:1 + ::: $DIR/auxiliary/test-macros.rs:10:1 | LL | pub fn empty(_: TokenStream) -> TokenStream { | ------------------------------------------- similarly named macro `bang_proc_macro` defined here @@ -53,7 +53,7 @@ error: cannot find derive macro `Dlona` in this scope LL | #[derive(Dlona)] | ^^^^^ help: a derive macro with a similar name exists: `Clona` | - ::: $DIR/auxiliary/derive-clona.rs:11:1 + ::: $DIR/auxiliary/derive-clona.rs:6:1 | LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | ------------------------------------------------------- similarly named derive macro `Clona` defined here @@ -64,7 +64,7 @@ error: cannot find derive macro `Dlona` in this scope LL | #[derive(Dlona)] | ^^^^^ help: a derive macro with a similar name exists: `Clona` | - ::: $DIR/auxiliary/derive-clona.rs:11:1 + ::: $DIR/auxiliary/derive-clona.rs:6:1 | LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | ------------------------------------------------------- similarly named derive macro `Clona` defined here @@ -103,7 +103,7 @@ error: cannot find attribute `attr_proc_macra` in this scope LL | #[attr_proc_macra] | ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro` | - ::: $DIR/auxiliary/test-macros.rs:20:1 + ::: $DIR/auxiliary/test-macros.rs:15:1 | LL | pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream { | ---------------------------------------------------------------- similarly named attribute macro `attr_proc_macro` defined here @@ -114,7 +114,7 @@ error: cannot find derive macro `FooWithLongNan` in this scope LL | #[derive(FooWithLongNan)] | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` | - ::: $DIR/auxiliary/derive-foo.rs:11:1 + ::: $DIR/auxiliary/derive-foo.rs:6:1 | LL | pub fn derive_foo(input: TokenStream) -> TokenStream { | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here @@ -125,7 +125,7 @@ error: cannot find derive macro `FooWithLongNan` in this scope LL | #[derive(FooWithLongNan)] | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` | - ::: $DIR/auxiliary/derive-foo.rs:11:1 + ::: $DIR/auxiliary/derive-foo.rs:6:1 | LL | pub fn derive_foo(input: TokenStream) -> TokenStream { | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here diff --git a/tests/ui/proc-macro/resolved-located-at.rs b/tests/ui/proc-macro/resolved-located-at.rs index 2f906d91e6b2b..c932c40189681 100644 --- a/tests/ui/proc-macro/resolved-located-at.rs +++ b/tests/ui/proc-macro/resolved-located-at.rs @@ -1,4 +1,4 @@ -//@ aux-build:resolved-located-at.rs +//@ proc-macro: resolved-located-at.rs #[macro_use] extern crate resolved_located_at; diff --git a/tests/ui/proc-macro/shadow.rs b/tests/ui/proc-macro/shadow.rs index 22aecb7c05fc8..bcb38f97dbfa7 100644 --- a/tests/ui/proc-macro/shadow.rs +++ b/tests/ui/proc-macro/shadow.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/smoke.rs b/tests/ui/proc-macro/smoke.rs index dc32adb2e27ab..667112837c191 100644 --- a/tests/ui/proc-macro/smoke.rs +++ b/tests/ui/proc-macro/smoke.rs @@ -2,7 +2,7 @@ #![allow(unused_must_use)] #![allow(path_statements)] -//@ aux-build:derive-a.rs +//@ proc-macro: derive-a.rs #[macro_use] extern crate derive_a; diff --git a/tests/ui/proc-macro/span-absolute-posititions.rs b/tests/ui/proc-macro/span-absolute-posititions.rs index ddbc5902d6b00..fc9f06a9e9fc0 100644 --- a/tests/ui/proc-macro/span-absolute-posititions.rs +++ b/tests/ui/proc-macro/span-absolute-posititions.rs @@ -1,4 +1,4 @@ -//@ aux-build:assert-span-pos.rs +//@ proc-macro: assert-span-pos.rs // ignore-tidy-tab extern crate assert_span_pos; diff --git a/tests/ui/proc-macro/span-api-tests.rs b/tests/ui/proc-macro/span-api-tests.rs index 1e00f3ad7ac60..ac42a7ea611ab 100644 --- a/tests/ui/proc-macro/span-api-tests.rs +++ b/tests/ui/proc-macro/span-api-tests.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:span-api-tests.rs +//@ proc-macro: span-api-tests.rs //@ aux-build:span-test-macros.rs //@ compile-flags: -Ztranslate-remapped-path-to-local-path=yes diff --git a/tests/ui/proc-macro/span-from-proc-macro.rs b/tests/ui/proc-macro/span-from-proc-macro.rs index 9d851d62d1269..4e12a695a5c09 100644 --- a/tests/ui/proc-macro/span-from-proc-macro.rs +++ b/tests/ui/proc-macro/span-from-proc-macro.rs @@ -1,5 +1,5 @@ -//@ aux-build:custom-quote.rs -//@ aux-build:span-from-proc-macro.rs +//@ proc-macro: custom-quote.rs +//@ proc-macro: span-from-proc-macro.rs //@ compile-flags: -Z macro-backtrace #[macro_use] diff --git a/tests/ui/proc-macro/span-from-proc-macro.stderr b/tests/ui/proc-macro/span-from-proc-macro.stderr index 7beed505a7efa..452c04df8779e 100644 --- a/tests/ui/proc-macro/span-from-proc-macro.stderr +++ b/tests/ui/proc-macro/span-from-proc-macro.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `MissingType` in this scope - --> $DIR/auxiliary/span-from-proc-macro.rs:37:20 + --> $DIR/auxiliary/span-from-proc-macro.rs:33:20 | LL | pub fn error_from_attribute(_args: TokenStream, _input: TokenStream) -> TokenStream { | ----------------------------------------------------------------------------------- in this expansion of `#[error_from_attribute]` @@ -13,7 +13,7 @@ LL | #[error_from_attribute] | ----------------------- in this procedural macro expansion error[E0412]: cannot find type `OtherMissingType` in this scope - --> $DIR/auxiliary/span-from-proc-macro.rs:46:21 + --> $DIR/auxiliary/span-from-proc-macro.rs:42:21 | LL | pub fn error_from_derive(_input: TokenStream) -> TokenStream { | ------------------------------------------------------------ in this expansion of `#[derive(ErrorFromDerive)]` @@ -27,7 +27,7 @@ LL | #[derive(ErrorFromDerive)] | --------------- in this derive macro expansion error[E0425]: cannot find value `my_ident` in this scope - --> $DIR/auxiliary/span-from-proc-macro.rs:29:9 + --> $DIR/auxiliary/span-from-proc-macro.rs:25:9 | LL | pub fn other_error_from_bang(_input: TokenStream) -> TokenStream { | ---------------------------------------------------------------- in this expansion of `other_error_from_bang!` @@ -41,7 +41,7 @@ LL | other_error_from_bang!(); | ------------------------ in this macro invocation error[E0308]: mismatched types - --> $DIR/auxiliary/span-from-proc-macro.rs:16:36 + --> $DIR/auxiliary/span-from-proc-macro.rs:12:36 | LL | let bang_error: bool = 25; | ---- ^^ expected `bool`, found integer diff --git a/tests/ui/proc-macro/span-preservation.rs b/tests/ui/proc-macro/span-preservation.rs index 25a44505c772e..fc91486567867 100644 --- a/tests/ui/proc-macro/span-preservation.rs +++ b/tests/ui/proc-macro/span-preservation.rs @@ -1,7 +1,7 @@ // For each of these, we should get the appropriate type mismatch error message, // and the function should be echoed. -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/struct-field-macro.rs b/tests/ui/proc-macro/struct-field-macro.rs index b2c3dd49de942..9b1ddcaf27458 100644 --- a/tests/ui/proc-macro/struct-field-macro.rs +++ b/tests/ui/proc-macro/struct-field-macro.rs @@ -1,7 +1,7 @@ //@ run-pass #![allow(dead_code)] -//@ aux-build:derive-nothing.rs +//@ proc-macro: derive-nothing.rs #[macro_use] extern crate derive_nothing; diff --git a/tests/ui/proc-macro/subspan.rs b/tests/ui/proc-macro/subspan.rs index 78804cba342d0..a87b11f3288af 100644 --- a/tests/ui/proc-macro/subspan.rs +++ b/tests/ui/proc-macro/subspan.rs @@ -1,4 +1,4 @@ -//@ aux-build:subspan.rs +//@ proc-macro: subspan.rs extern crate subspan; diff --git a/tests/ui/proc-macro/test.rs b/tests/ui/proc-macro/test.rs index 9e76deab9ce4b..b36910a414b10 100644 --- a/tests/ui/proc-macro/test.rs +++ b/tests/ui/proc-macro/test.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:api/mod.rs +//@ proc-macro: api/proc_macro_api_tests.rs //@ edition: 2021 //! This is for everything that *would* be a #[test] inside of libproc_macro, diff --git a/tests/ui/proc-macro/three-equals.rs b/tests/ui/proc-macro/three-equals.rs index d16fc55656ce3..ad528e144b035 100644 --- a/tests/ui/proc-macro/three-equals.rs +++ b/tests/ui/proc-macro/three-equals.rs @@ -1,4 +1,4 @@ -//@ aux-build:three-equals.rs +//@ proc-macro: three-equals.rs extern crate three_equals; diff --git a/tests/ui/proc-macro/trailing-plus.rs b/tests/ui/proc-macro/trailing-plus.rs index 875225c15cae4..a69ec510bed65 100644 --- a/tests/ui/proc-macro/trailing-plus.rs +++ b/tests/ui/proc-macro/trailing-plus.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug #![no_std] // Don't load unnecessary hygiene information from std diff --git a/tests/ui/proc-macro/trait-fn-args-2015.rs b/tests/ui/proc-macro/trait-fn-args-2015.rs index 389bb5b6a92f5..c25bd768efe76 100644 --- a/tests/ui/proc-macro/trait-fn-args-2015.rs +++ b/tests/ui/proc-macro/trait-fn-args-2015.rs @@ -1,7 +1,7 @@ // Unnamed arguments in trait functions can be passed through proc macros on 2015 edition. //@ check-pass -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs #![allow(anonymous_parameters)] diff --git a/tests/ui/proc-macro/unsafe-foreign-mod.rs b/tests/ui/proc-macro/unsafe-foreign-mod.rs index b863b0fc11403..e1e4ce96f1ff2 100644 --- a/tests/ui/proc-macro/unsafe-foreign-mod.rs +++ b/tests/ui/proc-macro/unsafe-foreign-mod.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:macro-only-syntax.rs +//@ proc-macro: macro-only-syntax.rs extern crate macro_only_syntax; diff --git a/tests/ui/proc-macro/unsafe-mod.rs b/tests/ui/proc-macro/unsafe-mod.rs index 00ea388af932a..f8453c2f62cd4 100644 --- a/tests/ui/proc-macro/unsafe-mod.rs +++ b/tests/ui/proc-macro/unsafe-mod.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:macro-only-syntax.rs +//@ proc-macro: macro-only-syntax.rs #![feature(proc_macro_hygiene)] diff --git a/tests/ui/proc-macro/weird-braces.rs b/tests/ui/proc-macro/weird-braces.rs index b17b90742b502..1197156f6b03d 100644 --- a/tests/ui/proc-macro/weird-braces.rs +++ b/tests/ui/proc-macro/weird-braces.rs @@ -1,4 +1,4 @@ -//@ aux-build:test-macros.rs +//@ proc-macro: test-macros.rs //@ check-pass //@ compile-flags: -Z span-debug diff --git a/tests/ui/proc-macro/weird-hygiene.rs b/tests/ui/proc-macro/weird-hygiene.rs index 8b35898a4d20c..de55484109ae3 100644 --- a/tests/ui/proc-macro/weird-hygiene.rs +++ b/tests/ui/proc-macro/weird-hygiene.rs @@ -1,4 +1,4 @@ -//@ aux-build:weird-hygiene.rs +//@ proc-macro: weird-hygiene.rs #![feature(stmt_expr_attributes)] #![feature(proc_macro_hygiene)] diff --git a/tests/ui/ptr-coercion-rpass.rs b/tests/ui/ptr-coercion-rpass.rs index 5d9b907f0e4a9..8cc4120328e45 100644 --- a/tests/ui/ptr-coercion-rpass.rs +++ b/tests/ui/ptr-coercion-rpass.rs @@ -3,7 +3,6 @@ #![allow(unused_variables)] // Test coercions between pointers which don't do anything fancy like unsizing. -//@ pretty-expanded FIXME #23616 pub fn main() { // &mut -> & diff --git a/tests/ui/reachable/issue-11225-1.rs b/tests/ui/reachable/issue-11225-1.rs index 6af270555c3dc..c87dd0d819bd0 100644 --- a/tests/ui/reachable/issue-11225-1.rs +++ b/tests/ui/reachable/issue-11225-1.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-11225-1.rs -//@ pretty-expanded FIXME #23616 extern crate issue_11225_1 as foo; diff --git a/tests/ui/reachable/issue-11225-2.rs b/tests/ui/reachable/issue-11225-2.rs index d9449564e7fd8..2f2ca47aa0417 100644 --- a/tests/ui/reachable/issue-11225-2.rs +++ b/tests/ui/reachable/issue-11225-2.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-11225-2.rs -//@ pretty-expanded FIXME #23616 extern crate issue_11225_2 as foo; diff --git a/tests/ui/reachable/issue-11225-3.rs b/tests/ui/reachable/issue-11225-3.rs index 6f2d7dafdf614..0d2911bde8bde 100644 --- a/tests/ui/reachable/issue-11225-3.rs +++ b/tests/ui/reachable/issue-11225-3.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:issue-11225-3.rs -//@ pretty-expanded FIXME #23616 extern crate issue_11225_3; diff --git a/tests/ui/recursion/instantiable.rs b/tests/ui/recursion/instantiable.rs index 9bbae7dfca076..3fe50e8d011e9 100644 --- a/tests/ui/recursion/instantiable.rs +++ b/tests/ui/recursion/instantiable.rs @@ -2,7 +2,6 @@ #![allow(non_camel_case_types)] #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 use std::ptr; diff --git a/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr b/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr index 5abec88eeff00..35d436a1413ed 100644 --- a/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr +++ b/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr @@ -5,7 +5,7 @@ LL | let Ok(x) = res; | ^^^^^ pattern `Err(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `Result>` help: you might want to use `let else` to handle the variant that isn't matched | diff --git a/tests/ui/regions/issue-11612.rs b/tests/ui/regions/issue-11612.rs index b95229ffa4a00..af0071e10889f 100644 --- a/tests/ui/regions/issue-11612.rs +++ b/tests/ui/regions/issue-11612.rs @@ -4,7 +4,6 @@ // We weren't updating the auto adjustments with all the resolved // type information after type check. -//@ pretty-expanded FIXME #23616 trait A { fn dummy(&self) { } } diff --git a/tests/ui/regions/issue-21520.rs b/tests/ui/regions/issue-21520.rs index 4f92109ab90a6..825d6f2ee5624 100644 --- a/tests/ui/regions/issue-21520.rs +++ b/tests/ui/regions/issue-21520.rs @@ -3,7 +3,6 @@ // Test that the requirement (in `Bar`) that `T::Bar : 'static` does // not wind up propagating to `T`. -//@ pretty-expanded FIXME #23616 pub trait Foo { type Bar; diff --git a/tests/ui/regions/issue-5243.rs b/tests/ui/regions/issue-5243.rs index a346903d6525e..d3c77403a375f 100644 --- a/tests/ui/regions/issue-5243.rs +++ b/tests/ui/regions/issue-5243.rs @@ -4,7 +4,6 @@ // enough for codegen to consider this as non-monomorphic, // which led to various assertions and failures in turn. -//@ pretty-expanded FIXME #23616 struct S<'a> { v: &'a isize diff --git a/tests/ui/regions/issue-6157.rs b/tests/ui/regions/issue-6157.rs index 03a8c14e1a625..8d3002e52c858 100644 --- a/tests/ui/regions/issue-6157.rs +++ b/tests/ui/regions/issue-6157.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub trait OpInt { fn call(&mut self, _: isize, _: isize) -> isize; } diff --git a/tests/ui/regions/owned-implies-static.rs b/tests/ui/regions/owned-implies-static.rs index d97e2f2d239b8..ffbee5a4bb789 100644 --- a/tests/ui/regions/owned-implies-static.rs +++ b/tests/ui/regions/owned-implies-static.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn f(_x: T) {} diff --git a/tests/ui/regions/regions-addr-of-interior-of-unique-box.rs b/tests/ui/regions/regions-addr-of-interior-of-unique-box.rs index bd3d4a1acdc4e..9dd49d35d44a4 100644 --- a/tests/ui/regions/regions-addr-of-interior-of-unique-box.rs +++ b/tests/ui/regions/regions-addr-of-interior-of-unique-box.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct Point { x: isize, diff --git a/tests/ui/regions/regions-assoc-type-region-bound.rs b/tests/ui/regions/regions-assoc-type-region-bound.rs index 1b7fdf112515e..86c8359b61a0d 100644 --- a/tests/ui/regions/regions-assoc-type-region-bound.rs +++ b/tests/ui/regions/regions-assoc-type-region-bound.rs @@ -3,7 +3,6 @@ // Test that the compiler considers the 'a bound declared in the // trait. Issue #20890. -//@ pretty-expanded FIXME #23616 trait Foo<'a> { type Value: 'a; diff --git a/tests/ui/regions/regions-assoc-type-static-bound.rs b/tests/ui/regions/regions-assoc-type-static-bound.rs index 9ffc66d284d2e..111cffcaf27e3 100644 --- a/tests/ui/regions/regions-assoc-type-static-bound.rs +++ b/tests/ui/regions/regions-assoc-type-static-bound.rs @@ -3,7 +3,6 @@ // Test that the compiler considers the 'static bound declared in the // trait. Issue #20890. -//@ pretty-expanded FIXME #23616 trait Foo { type Value: 'static; diff --git a/tests/ui/regions/regions-creating-enums2.rs b/tests/ui/regions/regions-creating-enums2.rs index b81344cceecbf..de6e51b1fbd64 100644 --- a/tests/ui/regions/regions-creating-enums2.rs +++ b/tests/ui/regions/regions-creating-enums2.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 enum ast<'a> { num(usize), diff --git a/tests/ui/regions/regions-creating-enums5.rs b/tests/ui/regions/regions-creating-enums5.rs index 55793fb620299..14221a9d75f6c 100644 --- a/tests/ui/regions/regions-creating-enums5.rs +++ b/tests/ui/regions/regions-creating-enums5.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 enum ast<'a> { num(usize), diff --git a/tests/ui/regions/regions-debruijn-of-object.rs b/tests/ui/regions/regions-debruijn-of-object.rs index 04bedf18ef08b..a2de66aef3709 100644 --- a/tests/ui/regions/regions-debruijn-of-object.rs +++ b/tests/ui/regions/regions-debruijn-of-object.rs @@ -3,7 +3,6 @@ #![allow(unused_variables)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 struct ctxt<'tcx> { x: &'tcx i32 diff --git a/tests/ui/regions/regions-dependent-autofn.rs b/tests/ui/regions/regions-dependent-autofn.rs index ccbb1219ce271..c58ae5e24ee3e 100644 --- a/tests/ui/regions/regions-dependent-autofn.rs +++ b/tests/ui/regions/regions-dependent-autofn.rs @@ -2,7 +2,6 @@ // Test lifetimes are linked properly when we autoslice a vector. // Issue #3148. -//@ pretty-expanded FIXME #23616 fn subslice(v: F) -> F where F: FnOnce() { v } diff --git a/tests/ui/regions/regions-dependent-let-ref.rs b/tests/ui/regions/regions-dependent-let-ref.rs index f3127abafb7a9..23b46abc91d25 100644 --- a/tests/ui/regions/regions-dependent-let-ref.rs +++ b/tests/ui/regions/regions-dependent-let-ref.rs @@ -2,7 +2,6 @@ // Test lifetimes are linked properly when we take reference // to interior. -//@ pretty-expanded FIXME #23616 struct Foo(isize); pub fn main() { diff --git a/tests/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs b/tests/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs index 1b6c3c933771a..c08142154edbd 100644 --- a/tests/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs +++ b/tests/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs @@ -6,7 +6,6 @@ // lifetime parameters must be early bound in the type of the // associated item. -//@ pretty-expanded FIXME #23616 use std::marker; diff --git a/tests/ui/regions/regions-expl-self.rs b/tests/ui/regions/regions-expl-self.rs index 812201d7e52a6..552204867f630 100644 --- a/tests/ui/regions/regions-expl-self.rs +++ b/tests/ui/regions/regions-expl-self.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] // Test that you can insert an explicit lifetime in explicit self. -//@ pretty-expanded FIXME #23616 struct Foo { f: usize diff --git a/tests/ui/regions/regions-fn-subtyping-2.rs b/tests/ui/regions/regions-fn-subtyping-2.rs index f5332ac12809f..98be8de8671b7 100644 --- a/tests/ui/regions/regions-fn-subtyping-2.rs +++ b/tests/ui/regions/regions-fn-subtyping-2.rs @@ -5,7 +5,6 @@ // Here, `f` is a function that takes a pointer `x` and a function // `g`, where `g` requires its argument `y` to be in the same region // that `x` is in. -//@ pretty-expanded FIXME #23616 fn has_same_region(f: Box FnMut(&'a isize, Box)>) { // `f` should be the type that `wants_same_region` wants, but diff --git a/tests/ui/regions/regions-fn-subtyping.rs b/tests/ui/regions/regions-fn-subtyping.rs index 7e264eb03d836..dacd2f007c107 100644 --- a/tests/ui/regions/regions-fn-subtyping.rs +++ b/tests/ui/regions/regions-fn-subtyping.rs @@ -3,7 +3,6 @@ #![allow(unused_assignments)] // Issue #2263. -//@ pretty-expanded FIXME #23616 #![allow(unused_variables)] diff --git a/tests/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs b/tests/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs index f5d28a281541b..f4e5c3a93a653 100644 --- a/tests/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs +++ b/tests/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs @@ -3,7 +3,6 @@ // Test an edge case in region inference: the lifetime of the borrow // of `*x` must be extended to at least 'a. -//@ pretty-expanded FIXME #23616 fn foo<'a,'b>(x: &'a &'b mut isize) -> &'a isize { let y = &*x; // should be inferred to have type &'a &'b mut isize... diff --git a/tests/ui/regions/regions-infer-region-in-fn-but-not-type.rs b/tests/ui/regions/regions-infer-region-in-fn-but-not-type.rs index 165a246935f97..402cee201bee0 100644 --- a/tests/ui/regions/regions-infer-region-in-fn-but-not-type.rs +++ b/tests/ui/regions/regions-infer-region-in-fn-but-not-type.rs @@ -6,7 +6,6 @@ // check that the &isize here does not cause us to think that `foo` // contains region pointers -//@ pretty-expanded FIXME #23616 struct foo(Box); diff --git a/tests/ui/regions/regions-infer-static-from-proc.rs b/tests/ui/regions/regions-infer-static-from-proc.rs index 9a130808ae8df..09e1c8f635b98 100644 --- a/tests/ui/regions/regions-infer-static-from-proc.rs +++ b/tests/ui/regions/regions-infer-static-from-proc.rs @@ -5,7 +5,6 @@ // region variables contained within (otherwise, region inference will // give `x` a very short lifetime). -//@ pretty-expanded FIXME #23616 static i: usize = 3; fn foo(_: F) {} diff --git a/tests/ui/regions/regions-issue-21422.rs b/tests/ui/regions/regions-issue-21422.rs index 54beed9b3ac2b..25f5d0f50139f 100644 --- a/tests/ui/regions/regions-issue-21422.rs +++ b/tests/ui/regions/regions-issue-21422.rs @@ -3,7 +3,6 @@ // add inference constraints that the operands of a binary operator // should outlive the binary operation itself. -//@ pretty-expanded FIXME #23616 pub struct P<'a> { _ptr: *const &'a u8, diff --git a/tests/ui/regions/regions-issue-22246.rs b/tests/ui/regions/regions-issue-22246.rs index e3bf7b31205cb..c943f33150eab 100644 --- a/tests/ui/regions/regions-issue-22246.rs +++ b/tests/ui/regions/regions-issue-22246.rs @@ -3,7 +3,6 @@ // Regression test for issue #22246 -- we should be able to deduce // that `&'a B::Owned` implies that `B::Owned : 'a`. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/regions/regions-lifetime-nonfree-late-bound.rs b/tests/ui/regions/regions-lifetime-nonfree-late-bound.rs index ee29f44ecc99e..57ad6cbbaf73f 100644 --- a/tests/ui/regions/regions-lifetime-nonfree-late-bound.rs +++ b/tests/ui/regions/regions-lifetime-nonfree-late-bound.rs @@ -13,7 +13,6 @@ // doing region-folding, when really all clients of the region-folding // case only want to see FREE lifetime variables, not bound ones. -//@ pretty-expanded FIXME #23616 pub fn main() { fn explicit() { diff --git a/tests/ui/regions/regions-link-fn-args.rs b/tests/ui/regions/regions-link-fn-args.rs index 5fed86d504870..9172ebf9664fe 100644 --- a/tests/ui/regions/regions-link-fn-args.rs +++ b/tests/ui/regions/regions-link-fn-args.rs @@ -2,7 +2,6 @@ // Test that region inference correctly links up the regions when a // `ref` borrow occurs inside a fn argument. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/regions/regions-mock-codegen.rs b/tests/ui/regions/regions-mock-codegen.rs index 4cdbc680e6fc9..99c863640669e 100644 --- a/tests/ui/regions/regions-mock-codegen.rs +++ b/tests/ui/regions/regions-mock-codegen.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 #![feature(allocator_api)] use std::alloc::{handle_alloc_error, Allocator, Global, Layout}; diff --git a/tests/ui/regions/regions-no-bound-in-argument-cleanup.rs b/tests/ui/regions/regions-no-bound-in-argument-cleanup.rs index 2c02ce670b944..3836c661df8ef 100644 --- a/tests/ui/regions/regions-no-bound-in-argument-cleanup.rs +++ b/tests/ui/regions/regions-no-bound-in-argument-cleanup.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use std::marker; diff --git a/tests/ui/regions/regions-nullary-variant.rs b/tests/ui/regions/regions-nullary-variant.rs index 8fe0a97c61c8f..8624f9961f667 100644 --- a/tests/ui/regions/regions-nullary-variant.rs +++ b/tests/ui/regions/regions-nullary-variant.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 enum roption<'a> { a, b(&'a usize) diff --git a/tests/ui/regions/regions-reassign-let-bound-pointer.rs b/tests/ui/regions/regions-reassign-let-bound-pointer.rs index d2f35973511a8..7ecfd95851271 100644 --- a/tests/ui/regions/regions-reassign-let-bound-pointer.rs +++ b/tests/ui/regions/regions-reassign-let-bound-pointer.rs @@ -5,7 +5,6 @@ // started out with a longer lifetime and was reassigned to a shorter // one (it should infer to be the intersection). -//@ pretty-expanded FIXME #23616 fn foo(x: &isize) { let a = 1; diff --git a/tests/ui/regions/regions-reassign-match-bound-pointer.rs b/tests/ui/regions/regions-reassign-match-bound-pointer.rs index 5e69396aa37f6..e549804db4363 100644 --- a/tests/ui/regions/regions-reassign-match-bound-pointer.rs +++ b/tests/ui/regions/regions-reassign-match-bound-pointer.rs @@ -5,7 +5,6 @@ // started out with a longer lifetime and was reassigned to a shorter // one (it should infer to be the intersection). -//@ pretty-expanded FIXME #23616 fn foo(x: &isize) { let a = 1; diff --git a/tests/ui/regions/regions-scope-chain-example.rs b/tests/ui/regions/regions-scope-chain-example.rs index 01ce04b63d065..184ce01589233 100644 --- a/tests/ui/regions/regions-scope-chain-example.rs +++ b/tests/ui/regions/regions-scope-chain-example.rs @@ -9,7 +9,6 @@ // wrong path. The new algorithm avoids this problem and hence this // example typechecks correctly. -//@ pretty-expanded FIXME #23616 enum ScopeChain<'a> { Link(Scope<'a>), diff --git a/tests/ui/regions/regions-variance-contravariant-use-contravariant.rs b/tests/ui/regions/regions-variance-contravariant-use-contravariant.rs index b177f3a011042..db7cf869450b4 100644 --- a/tests/ui/regions/regions-variance-contravariant-use-contravariant.rs +++ b/tests/ui/regions/regions-variance-contravariant-use-contravariant.rs @@ -7,7 +7,6 @@ // Note: see ui/variance/variance-regions-*.rs for the tests that check that the // variance inference works in the first place. -//@ pretty-expanded FIXME #23616 struct Contravariant<'a> { f: &'a isize diff --git a/tests/ui/regions/regions-variance-covariant-use-covariant.rs b/tests/ui/regions/regions-variance-covariant-use-covariant.rs index bd5959df2e1e2..4258268c3e0de 100644 --- a/tests/ui/regions/regions-variance-covariant-use-covariant.rs +++ b/tests/ui/regions/regions-variance-covariant-use-covariant.rs @@ -9,7 +9,6 @@ // This is covariant with respect to 'a, meaning that // Covariant<'foo> <: Covariant<'static> because // 'foo <= 'static -//@ pretty-expanded FIXME #23616 struct Covariant<'a> { f: extern "Rust" fn(&'a isize) diff --git a/tests/ui/regions/wf-bound-region-in-object-type.rs b/tests/ui/regions/wf-bound-region-in-object-type.rs index caa265b4ea281..c77845ab3060b 100644 --- a/tests/ui/regions/wf-bound-region-in-object-type.rs +++ b/tests/ui/regions/wf-bound-region-in-object-type.rs @@ -5,7 +5,6 @@ // Test that the `wf` checker properly handles bound regions in object // types. Compiling this code used to trigger an ICE. -//@ pretty-expanded FIXME #23616 pub struct Context<'tcx> { vec: &'tcx Vec diff --git a/tests/ui/resolve/auxiliary/issue-112831-aux.rs b/tests/ui/resolve/auxiliary/issue-112831-aux.rs index e5c1486d8ae7a..7d258299c186d 100644 --- a/tests/ui/resolve/auxiliary/issue-112831-aux.rs +++ b/tests/ui/resolve/auxiliary/issue-112831-aux.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; struct Zeroable; diff --git a/tests/ui/resolve/auxiliary/proc_macro_generate_packed.rs b/tests/ui/resolve/auxiliary/proc_macro_generate_packed.rs index c0b24706dcba6..9a9e0eb3ff758 100644 --- a/tests/ui/resolve/auxiliary/proc_macro_generate_packed.rs +++ b/tests/ui/resolve/auxiliary/proc_macro_generate_packed.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic -//@ compile-flags: --crate-type proc-macro - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/resolve/blind-item-mixed-crate-use-item.rs b/tests/ui/resolve/blind-item-mixed-crate-use-item.rs index 9869881db9a48..6c1ae737cc207 100644 --- a/tests/ui/resolve/blind-item-mixed-crate-use-item.rs +++ b/tests/ui/resolve/blind-item-mixed-crate-use-item.rs @@ -2,7 +2,6 @@ //@ aux-build:blind-item-mixed-crate-use-item-foo.rs //@ aux-build:blind-item-mixed-crate-use-item-foo2.rs -//@ pretty-expanded FIXME #23616 mod m { pub fn f(_: T, _: (), _: ()) { } diff --git a/tests/ui/resolve/blind-item-mixed-use-item.rs b/tests/ui/resolve/blind-item-mixed-use-item.rs index 416496f3219ee..7796233c41991 100644 --- a/tests/ui/resolve/blind-item-mixed-use-item.rs +++ b/tests/ui/resolve/blind-item-mixed-use-item.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 mod m { pub fn f(_: T, _: ()) { } diff --git a/tests/ui/resolve/const-with-typo-in-pattern-binding.rs b/tests/ui/resolve/const-with-typo-in-pattern-binding.rs new file mode 100644 index 0000000000000..fe45cee91dbcb --- /dev/null +++ b/tests/ui/resolve/const-with-typo-in-pattern-binding.rs @@ -0,0 +1,45 @@ +#![deny(unreachable_patterns)] //~ NOTE the lint level is defined here +#![allow(non_snake_case, non_upper_case_globals)] +mod x { + pub use std::env::consts::ARCH; + const X: i32 = 0; //~ NOTE there is a constant of the same name +} +fn main() { + let input: i32 = 42; + + const god: i32 = 1; + const GOOD: i32 = 1; + const BAD: i32 = 2; + + let name: i32 = 42; //~ NOTE there is a binding of the same name + + match input { + X => {} //~ NOTE matches any value + _ => {} //~ ERROR unreachable pattern + //~^ NOTE no value can reach this + } + match input { + GOD => {} //~ HELP you might have meant to pattern match against the value of similarly named constant `god` + //~^ NOTE matches any value + _ => {} //~ ERROR unreachable pattern + //~^ NOTE no value can reach this + } + match input { + GOOOD => {} //~ HELP you might have meant to pattern match against the value of similarly named constant `GOOD` + //~^ NOTE matches any value + _ => {} //~ ERROR unreachable pattern + //~^ NOTE no value can reach this + } + match input { + name => {} + //~^ NOTE matches any value + _ => {} //~ ERROR unreachable pattern + //~^ NOTE no value can reach this + } + match "" { + ARCH => {} //~ HELP you might have meant to pattern match against the value of constant `ARCH` + //~^ NOTE matches any value + _ => {} //~ ERROR unreachable pattern + //~^ NOTE no value can reach this + } +} diff --git a/tests/ui/resolve/const-with-typo-in-pattern-binding.stderr b/tests/ui/resolve/const-with-typo-in-pattern-binding.stderr new file mode 100644 index 0000000000000..a0cdac3fa2538 --- /dev/null +++ b/tests/ui/resolve/const-with-typo-in-pattern-binding.stderr @@ -0,0 +1,78 @@ +error: unreachable pattern + --> $DIR/const-with-typo-in-pattern-binding.rs:18:9 + | +LL | X => {} + | - matches any value +LL | _ => {} + | ^ no value can reach this + | +note: there is a constant of the same name, which could have been used to pattern match against its value instead of introducing a new catch-all binding, but it is not accessible from this scope + --> $DIR/const-with-typo-in-pattern-binding.rs:5:5 + | +LL | const X: i32 = 0; + | ^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/const-with-typo-in-pattern-binding.rs:1:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/const-with-typo-in-pattern-binding.rs:24:9 + | +LL | GOD => {} + | --- matches any value +LL | +LL | _ => {} + | ^ no value can reach this + | +help: you might have meant to pattern match against the value of similarly named constant `god` instead of introducing a new catch-all binding + | +LL | god => {} + | ~~~ + +error: unreachable pattern + --> $DIR/const-with-typo-in-pattern-binding.rs:30:9 + | +LL | GOOOD => {} + | ----- matches any value +LL | +LL | _ => {} + | ^ no value can reach this + | +help: you might have meant to pattern match against the value of similarly named constant `GOOD` instead of introducing a new catch-all binding + | +LL | GOOD => {} + | ~~~~ + +error: unreachable pattern + --> $DIR/const-with-typo-in-pattern-binding.rs:36:9 + | +LL | name => {} + | ---- matches any value +LL | +LL | _ => {} + | ^ no value can reach this + | +note: there is a binding of the same name; if you meant to pattern match against the value of that binding, that is a feature of constants that is not available for `let` bindings + --> $DIR/const-with-typo-in-pattern-binding.rs:14:9 + | +LL | let name: i32 = 42; + | ^^^^ + +error: unreachable pattern + --> $DIR/const-with-typo-in-pattern-binding.rs:42:9 + | +LL | ARCH => {} + | ---- matches any value +LL | +LL | _ => {} + | ^ no value can reach this + | +help: you might have meant to pattern match against the value of constant `ARCH` instead of introducing a new catch-all binding + | +LL | std::env::consts::ARCH => {} + | ~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/resolve/derive-macro-1.rs b/tests/ui/resolve/derive-macro-1.rs index f4fbb1d2c7c1d..d39eeba2e6c85 100644 --- a/tests/ui/resolve/derive-macro-1.rs +++ b/tests/ui/resolve/derive-macro-1.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:issue-112831-aux.rs +//@ proc-macro: issue-112831-aux.rs mod z { pub trait Zeroable {} diff --git a/tests/ui/resolve/derive-macro-2.rs b/tests/ui/resolve/derive-macro-2.rs index 126f5ae107ff2..71d791eaef8de 100644 --- a/tests/ui/resolve/derive-macro-2.rs +++ b/tests/ui/resolve/derive-macro-2.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:issue-112831-aux.rs +//@ proc-macro: issue-112831-aux.rs extern crate issue_112831_aux; use issue_112831_aux::Zeroable; diff --git a/tests/ui/resolve/issue-10200.stderr b/tests/ui/resolve/issue-10200.stderr index 172d016c6e6c4..4b6d9b6f1dfa6 100644 --- a/tests/ui/resolve/issue-10200.stderr +++ b/tests/ui/resolve/issue-10200.stderr @@ -7,7 +7,7 @@ LL | struct Foo(bool); LL | foo(x) | ^^^ help: a tuple struct with a similar name exists (notice the capitalization): `Foo` | - = note: function calls are not allowed in patterns: + = note: function calls are not allowed in patterns: error: aborting due to 1 previous error diff --git a/tests/ui/resolve/proc_macro_generated_packed.rs b/tests/ui/resolve/proc_macro_generated_packed.rs index e8d04f808d03b..8459fb79f1ed2 100644 --- a/tests/ui/resolve/proc_macro_generated_packed.rs +++ b/tests/ui/resolve/proc_macro_generated_packed.rs @@ -1,7 +1,7 @@ //! This test ICEs because the `repr(packed)` attribute //! was generated by a proc macro, so `#[derive]` didn't see it. -//@aux-build: proc_macro_generate_packed.rs +//@proc-macro: proc_macro_generate_packed.rs //@known-bug: #120873 //@ failure-status: 101 //@ normalize-stderr-test: "note: .*\n\n" -> "" diff --git a/tests/ui/return/return-nil.rs b/tests/ui/return/return-nil.rs index 403eae260dc1a..c2591a77b3015 100644 --- a/tests/ui/return/return-nil.rs +++ b/tests/ui/return/return-nil.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn f() { let x = (); return x; } diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr index 1037033c4b74b..f89ae241f44bc 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr @@ -136,7 +136,7 @@ LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit | ^^^^^^^^^^^^^^^ pattern `_` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `NonExhaustiveEnum` help: you might want to use `let else` to handle the variant that isn't matched | diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs index 389c76337f097..2c7fe2eea3308 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs @@ -1,5 +1,5 @@ // issue-103476 -//@ compile-flags: -Zlint-mir -Zunstable-options +//@ compile-flags: -Zlint-mir //@ edition: 2024 //@ check-pass diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/auxiliary/ident-mac.rs b/tests/ui/rfcs/rfc-2565-param-attrs/auxiliary/ident-mac.rs index 93c2901fe66ca..176ba837043b2 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/auxiliary/ident-mac.rs +++ b/tests/ui/rfcs/rfc-2565-param-attrs/auxiliary/ident-mac.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/auxiliary/param-attrs.rs b/tests/ui/rfcs/rfc-2565-param-attrs/auxiliary/param-attrs.rs index c427cf7af6d65..9a813666c331e 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/auxiliary/param-attrs.rs +++ b/tests/ui/rfcs/rfc-2565-param-attrs/auxiliary/param-attrs.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs b/tests/ui/rfcs/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs index 17b59009bb84f..cd97587bf033c 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs +++ b/tests/ui/rfcs/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs @@ -1,4 +1,4 @@ -//@ aux-build:param-attrs.rs +//@ proc-macro: param-attrs.rs //@ check-pass diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-pretty.rs b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-pretty.rs index 6ed2d4fad0eee..89864348eda0b 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-pretty.rs +++ b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-pretty.rs @@ -1,4 +1,4 @@ -//@ aux-build:param-attrs.rs +//@ proc-macro: param-attrs.rs //@ check-pass diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs b/tests/ui/rfcs/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs index c1e6a92e3174e..049c5b32cb36c 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs +++ b/tests/ui/rfcs/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs @@ -1,4 +1,4 @@ -//@ aux-build:ident-mac.rs +//@ proc-macro: ident-mac.rs #![feature(c_variadic)] #![allow(anonymous_parameters)] diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/auxiliary/count.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/auxiliary/count.rs index e7c560a2c3514..aebf8d1e0fca7 100644 --- a/tests/ui/rfcs/rfc-3348-c-string-literals/auxiliary/count.rs +++ b/tests/ui/rfcs/rfc-3348-c-string-literals/auxiliary/count.rs @@ -1,7 +1,4 @@ -//@ force-host //@ edition: 2018 -//@ no-prefer-dynamic -#![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/edition-spans.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/edition-spans.rs index 57c1ba055608c..414d5518e1fb0 100644 --- a/tests/ui/rfcs/rfc-3348-c-string-literals/edition-spans.rs +++ b/tests/ui/rfcs/rfc-3348-c-string-literals/edition-spans.rs @@ -6,7 +6,7 @@ //@ edition: 2021 //@ check-pass -//@ aux-build: count.rs +//@ proc-macro: count.rs extern crate count; const _: () = { diff --git a/tests/ui/rust-2018/auxiliary/suggestions-not-always-applicable.rs b/tests/ui/rust-2018/auxiliary/suggestions-not-always-applicable.rs index d8e5eb884cfcc..bccde8e8de7ff 100644 --- a/tests/ui/rust-2018/auxiliary/suggestions-not-always-applicable.rs +++ b/tests/ui/rust-2018/auxiliary/suggestions-not-always-applicable.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/rust-2018/suggestions-not-always-applicable.fixed b/tests/ui/rust-2018/suggestions-not-always-applicable.fixed index f94bf2d66d38f..e3070ba150b6d 100644 --- a/tests/ui/rust-2018/suggestions-not-always-applicable.fixed +++ b/tests/ui/rust-2018/suggestions-not-always-applicable.fixed @@ -1,4 +1,4 @@ -//@ aux-build:suggestions-not-always-applicable.rs +//@ proc-macro: suggestions-not-always-applicable.rs //@ edition:2015 //@ run-rustfix //@ rustfix-only-machine-applicable diff --git a/tests/ui/rust-2018/suggestions-not-always-applicable.rs b/tests/ui/rust-2018/suggestions-not-always-applicable.rs index f94bf2d66d38f..e3070ba150b6d 100644 --- a/tests/ui/rust-2018/suggestions-not-always-applicable.rs +++ b/tests/ui/rust-2018/suggestions-not-always-applicable.rs @@ -1,4 +1,4 @@ -//@ aux-build:suggestions-not-always-applicable.rs +//@ proc-macro: suggestions-not-always-applicable.rs //@ edition:2015 //@ run-rustfix //@ rustfix-only-machine-applicable diff --git a/tests/ui/rust-2021/auxiliary/reserved-prefixes-macro-2018.rs b/tests/ui/rust-2021/auxiliary/reserved-prefixes-macro-2018.rs index 1273969c4af3b..469c2e7f8d9ea 100644 --- a/tests/ui/rust-2021/auxiliary/reserved-prefixes-macro-2018.rs +++ b/tests/ui/rust-2021/auxiliary/reserved-prefixes-macro-2018.rs @@ -1,8 +1,4 @@ -//@ force-host //@ edition:2018 -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/rust-2021/auxiliary/reserved-prefixes-macro-2021.rs b/tests/ui/rust-2021/auxiliary/reserved-prefixes-macro-2021.rs index b68701a516525..cfc39d5208ba9 100644 --- a/tests/ui/rust-2021/auxiliary/reserved-prefixes-macro-2021.rs +++ b/tests/ui/rust-2021/auxiliary/reserved-prefixes-macro-2021.rs @@ -1,8 +1,4 @@ -//@ force-host //@ edition:2021 -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/rust-2021/reserved-prefixes-via-macro-2.rs b/tests/ui/rust-2021/reserved-prefixes-via-macro-2.rs index b64761b55e98b..6c0c7b38c0142 100644 --- a/tests/ui/rust-2021/reserved-prefixes-via-macro-2.rs +++ b/tests/ui/rust-2021/reserved-prefixes-via-macro-2.rs @@ -1,6 +1,6 @@ //@ edition:2018 -//@ aux-build:reserved-prefixes-macro-2018.rs -//@ aux-build:reserved-prefixes-macro-2021.rs +//@ proc-macro: reserved-prefixes-macro-2018.rs +//@ proc-macro: reserved-prefixes-macro-2021.rs extern crate reserved_prefixes_macro_2018 as m2018; extern crate reserved_prefixes_macro_2021 as m2021; diff --git a/tests/ui/rust-2021/reserved-prefixes-via-macro.rs b/tests/ui/rust-2021/reserved-prefixes-via-macro.rs index 85f894d7f7970..eec1b859c2033 100644 --- a/tests/ui/rust-2021/reserved-prefixes-via-macro.rs +++ b/tests/ui/rust-2021/reserved-prefixes-via-macro.rs @@ -1,6 +1,6 @@ //@ run-pass //@ edition:2021 -//@ aux-build:reserved-prefixes-macro-2018.rs +//@ proc-macro: reserved-prefixes-macro-2018.rs extern crate reserved_prefixes_macro_2018 as m2018; diff --git a/tests/ui/rust-2024/auxiliary/reserved-guarded-strings-macro-2021.rs b/tests/ui/rust-2024/auxiliary/reserved-guarded-strings-macro-2021.rs index 81080fcdce307..ab23e63c0da9a 100644 --- a/tests/ui/rust-2024/auxiliary/reserved-guarded-strings-macro-2021.rs +++ b/tests/ui/rust-2024/auxiliary/reserved-guarded-strings-macro-2021.rs @@ -1,8 +1,4 @@ -//@ force-host //@ edition:2021 -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/rust-2024/auxiliary/reserved-guarded-strings-macro-2024.rs b/tests/ui/rust-2024/auxiliary/reserved-guarded-strings-macro-2024.rs index 2c3dc30f0ae9b..0fa908411f5f0 100644 --- a/tests/ui/rust-2024/auxiliary/reserved-guarded-strings-macro-2024.rs +++ b/tests/ui/rust-2024/auxiliary/reserved-guarded-strings-macro-2024.rs @@ -1,9 +1,4 @@ -//@ force-host -//@ compile-flags: -Zunstable-options //@ edition:2024 -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-already-future.rs b/tests/ui/rust-2024/prelude-migration/future-poll-already-future.rs index 7bf5118c3402e..0f0120b721ff6 100644 --- a/tests/ui/rust-2024/prelude-migration/future-poll-already-future.rs +++ b/tests/ui/rust-2024/prelude-migration/future-poll-already-future.rs @@ -1,7 +1,6 @@ //@ revisions: e2021 e2024 //@[e2021] edition: 2021 //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options //@ check-pass #![deny(rust_2024_prelude_collisions)] diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.fixed b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.fixed index 44850c8c45bbc..ff8c4beca6b2d 100644 --- a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.fixed +++ b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.fixed @@ -2,7 +2,6 @@ //@[e2021] edition: 2021 //@[e2021] run-rustfix //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options //@[e2024] check-pass #![deny(rust_2024_prelude_collisions)] diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr index 496b3197c3405..15a3fa114147e 100644 --- a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr +++ b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr @@ -1,5 +1,5 @@ error: trait method `poll` will become ambiguous in Rust 2024 - --> $DIR/future-poll-async-block.rs:14:5 + --> $DIR/future-poll-async-block.rs:13:5 | LL | core::pin::pin!(async {}).poll(&mut context()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(async {}), &mut context())` @@ -7,7 +7,7 @@ LL | core::pin::pin!(async {}).poll(&mut context()); = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see note: the lint level is defined here - --> $DIR/future-poll-async-block.rs:8:9 + --> $DIR/future-poll-async-block.rs:7:9 | LL | #![deny(rust_2024_prelude_collisions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.rs b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.rs index 614e4c786c533..60b0b2689c2a4 100644 --- a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.rs +++ b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.rs @@ -2,7 +2,6 @@ //@[e2021] edition: 2021 //@[e2021] run-rustfix //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options //@[e2024] check-pass #![deny(rust_2024_prelude_collisions)] diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.fixed b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.fixed index c96d1dcecc219..f68729e483a5c 100644 --- a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.fixed +++ b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.fixed @@ -2,7 +2,6 @@ //@[e2021] edition: 2021 //@[e2021] run-rustfix //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options //@[e2024] check-pass #![deny(rust_2024_prelude_collisions)] diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr index 020a00ccdec02..633731c2a5a52 100644 --- a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr +++ b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr @@ -1,5 +1,5 @@ error: trait method `poll` will become ambiguous in Rust 2024 - --> $DIR/future-poll-not-future-pinned.rs:18:5 + --> $DIR/future-poll-not-future-pinned.rs:17:5 | LL | core::pin::pin!(()).poll(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(()))` @@ -7,7 +7,7 @@ LL | core::pin::pin!(()).poll(); = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see note: the lint level is defined here - --> $DIR/future-poll-not-future-pinned.rs:8:9 + --> $DIR/future-poll-not-future-pinned.rs:7:9 | LL | #![deny(rust_2024_prelude_collisions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.rs b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.rs index 21b170a5f1db0..4845ef779e01a 100644 --- a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.rs +++ b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.rs @@ -2,7 +2,6 @@ //@[e2021] edition: 2021 //@[e2021] run-rustfix //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options //@[e2024] check-pass #![deny(rust_2024_prelude_collisions)] diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-not-future.rs b/tests/ui/rust-2024/prelude-migration/future-poll-not-future.rs index 899b69ebfc246..36578e28b8070 100644 --- a/tests/ui/rust-2024/prelude-migration/future-poll-not-future.rs +++ b/tests/ui/rust-2024/prelude-migration/future-poll-not-future.rs @@ -1,7 +1,6 @@ //@ revisions: e2021 e2024 //@[e2021] edition: 2021 //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options //@ check-pass #![deny(rust_2024_prelude_collisions)] diff --git a/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.fixed b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.fixed index 0b0873eb23842..03bf4ab19c1b2 100644 --- a/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.fixed +++ b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.fixed @@ -2,7 +2,6 @@ //@[e2021] edition: 2021 //@[e2021] run-rustfix //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options //@[e2024] check-pass #![deny(rust_2024_prelude_collisions)] diff --git a/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr index b74e80e2a4a08..e67f07b4e4651 100644 --- a/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr +++ b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr @@ -1,5 +1,5 @@ error: trait method `into_future` will become ambiguous in Rust 2024 - --> $DIR/into-future-adt.rs:26:5 + --> $DIR/into-future-adt.rs:25:5 | LL | Cat.into_future(); | ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::into_future(&Cat)` @@ -7,7 +7,7 @@ LL | Cat.into_future(); = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see note: the lint level is defined here - --> $DIR/into-future-adt.rs:8:9 + --> $DIR/into-future-adt.rs:7:9 | LL | #![deny(rust_2024_prelude_collisions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rust-2024/prelude-migration/into-future-adt.rs b/tests/ui/rust-2024/prelude-migration/into-future-adt.rs index 0db70930bc75b..65edc88baabc7 100644 --- a/tests/ui/rust-2024/prelude-migration/into-future-adt.rs +++ b/tests/ui/rust-2024/prelude-migration/into-future-adt.rs @@ -2,7 +2,6 @@ //@[e2021] edition: 2021 //@[e2021] run-rustfix //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options //@[e2024] check-pass #![deny(rust_2024_prelude_collisions)] diff --git a/tests/ui/rust-2024/prelude-migration/into-future-already-into-future.rs b/tests/ui/rust-2024/prelude-migration/into-future-already-into-future.rs index 6bc2ea317059e..16ac89759f381 100644 --- a/tests/ui/rust-2024/prelude-migration/into-future-already-into-future.rs +++ b/tests/ui/rust-2024/prelude-migration/into-future-already-into-future.rs @@ -1,7 +1,6 @@ //@ revisions: e2021 e2024 //@[e2021] edition: 2021 //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options //@ check-pass #![deny(rust_2024_prelude_collisions)] diff --git a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.fixed b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.fixed index a798014d93d3b..4e0828833950c 100644 --- a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.fixed +++ b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.fixed @@ -2,7 +2,6 @@ //@[e2021] edition: 2021 //@[e2021] run-rustfix //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options //@[e2024] check-pass #![deny(rust_2024_prelude_collisions)] diff --git a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr index 6ea4580ca72ed..0588f5bf3f558 100644 --- a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr +++ b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr @@ -1,5 +1,5 @@ error: trait method `into_future` will become ambiguous in Rust 2024 - --> $DIR/into-future-not-into-future.rs:20:5 + --> $DIR/into-future-not-into-future.rs:19:5 | LL | Cat.into_future(); | ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::into_future(&Cat)` @@ -7,7 +7,7 @@ LL | Cat.into_future(); = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see note: the lint level is defined here - --> $DIR/into-future-not-into-future.rs:8:9 + --> $DIR/into-future-not-into-future.rs:7:9 | LL | #![deny(rust_2024_prelude_collisions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.rs b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.rs index 23e81cfe6b48d..f640d9b50bbb9 100644 --- a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.rs +++ b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.rs @@ -2,7 +2,6 @@ //@[e2021] edition: 2021 //@[e2021] run-rustfix //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options //@[e2024] check-pass #![deny(rust_2024_prelude_collisions)] diff --git a/tests/ui/rust-2024/prelude2024.rs b/tests/ui/rust-2024/prelude2024.rs index e58ebe74188f3..b7573948d9a17 100644 --- a/tests/ui/rust-2024/prelude2024.rs +++ b/tests/ui/rust-2024/prelude2024.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ compile-flags: -Zunstable-options //@ edition:2024 fn main() { diff --git a/tests/ui/rust-2024/reserved-guarded-strings-lexing.rs b/tests/ui/rust-2024/reserved-guarded-strings-lexing.rs index 83e0dcbb4bebc..43413f7470e89 100644 --- a/tests/ui/rust-2024/reserved-guarded-strings-lexing.rs +++ b/tests/ui/rust-2024/reserved-guarded-strings-lexing.rs @@ -26,24 +26,24 @@ macro_rules! demo7 { fn main() { demo3!(## "foo"); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo4!(### "foo"); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo4!(## "foo"#); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo7!(### "foo"###); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo5!(###"foo"#); @@ -56,14 +56,14 @@ fn main() { demo5!(#"foo"###); //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo4!("foo"###); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 // Non-ascii identifiers diff --git a/tests/ui/rust-2024/reserved-guarded-strings-lexing.stderr b/tests/ui/rust-2024/reserved-guarded-strings-lexing.stderr index e2e1ac42f05c2..4d54a08617b55 100644 --- a/tests/ui/rust-2024/reserved-guarded-strings-lexing.stderr +++ b/tests/ui/rust-2024/reserved-guarded-strings-lexing.stderr @@ -28,7 +28,7 @@ error: identifiers cannot contain emoji: `🙃` LL | demo3!(🙃#""); | ^^ -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-lexing.rs:28:12 | LL | demo3!(## "foo"); @@ -41,12 +41,12 @@ note: the lint level is defined here | LL | #![warn(rust_2024_guarded_string_incompatible_syntax)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo3!(# # "foo"); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-lexing.rs:31:12 | LL | demo4!(### "foo"); @@ -54,12 +54,12 @@ LL | demo4!(### "foo"); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo4!(# ## "foo"); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-lexing.rs:31:13 | LL | demo4!(### "foo"); @@ -67,12 +67,12 @@ LL | demo4!(### "foo"); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo4!(## # "foo"); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-lexing.rs:36:12 | LL | demo4!(## "foo"#); @@ -80,12 +80,12 @@ LL | demo4!(## "foo"#); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo4!(# # "foo"#); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-lexing.rs:39:12 | LL | demo7!(### "foo"###); @@ -93,12 +93,12 @@ LL | demo7!(### "foo"###); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo7!(# ## "foo"###); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-lexing.rs:39:13 | LL | demo7!(### "foo"###); @@ -106,12 +106,12 @@ LL | demo7!(### "foo"###); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo7!(## # "foo"###); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-lexing.rs:39:21 | LL | demo7!(### "foo"###); @@ -119,12 +119,12 @@ LL | demo7!(### "foo"###); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo7!(### "foo"# ##); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-lexing.rs:39:22 | LL | demo7!(### "foo"###); @@ -132,7 +132,7 @@ LL | demo7!(### "foo"###); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo7!(### "foo"## #); | + @@ -189,7 +189,7 @@ help: insert whitespace here to avoid this being parsed as a guarded string in R LL | demo5!(# "foo"###); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-lexing.rs:56:18 | LL | demo5!(#"foo"###); @@ -197,12 +197,12 @@ LL | demo5!(#"foo"###); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo5!(#"foo"# ##); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-lexing.rs:56:19 | LL | demo5!(#"foo"###); @@ -210,12 +210,12 @@ LL | demo5!(#"foo"###); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo5!(#"foo"## #); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-lexing.rs:63:17 | LL | demo4!("foo"###); @@ -223,12 +223,12 @@ LL | demo4!("foo"###); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo4!("foo"# ##); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-lexing.rs:63:18 | LL | demo4!("foo"###); @@ -236,7 +236,7 @@ LL | demo4!("foo"###); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo4!("foo"## #); | + diff --git a/tests/ui/rust-2024/reserved-guarded-strings-migration.fixed b/tests/ui/rust-2024/reserved-guarded-strings-migration.fixed index d92df7b5375a7..ef00ed3f61070 100644 --- a/tests/ui/rust-2024/reserved-guarded-strings-migration.fixed +++ b/tests/ui/rust-2024/reserved-guarded-strings-migration.fixed @@ -38,28 +38,28 @@ fn main() { demo2!("foo"#); demo3!(# # "foo"); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo4!(# # # "foo"); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo4!(# # "foo"#); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo6!(# # # "foo"# #); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo4!("foo"# # #); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo2!(# ""); @@ -94,6 +94,6 @@ fn main() { //~| WARNING hard error in Rust 2024 //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 } diff --git a/tests/ui/rust-2024/reserved-guarded-strings-migration.rs b/tests/ui/rust-2024/reserved-guarded-strings-migration.rs index 5905f2abe3232..cf2d8716ad2e5 100644 --- a/tests/ui/rust-2024/reserved-guarded-strings-migration.rs +++ b/tests/ui/rust-2024/reserved-guarded-strings-migration.rs @@ -38,28 +38,28 @@ fn main() { demo2!("foo"#); demo3!(## "foo"); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo4!(### "foo"); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo4!(## "foo"#); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo6!(### "foo"##); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo4!("foo"###); - //~^ WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~^ WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 demo2!(#""); @@ -94,6 +94,6 @@ fn main() { //~| WARNING hard error in Rust 2024 //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 - //~| WARNING parsed as a guarded string in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] + //~| WARNING reserved token in Rust 2024 [rust_2024_guarded_string_incompatible_syntax] //~| WARNING hard error in Rust 2024 } diff --git a/tests/ui/rust-2024/reserved-guarded-strings-migration.stderr b/tests/ui/rust-2024/reserved-guarded-strings-migration.stderr index d7f8e5c9b4b24..b17ae941ef41b 100644 --- a/tests/ui/rust-2024/reserved-guarded-strings-migration.stderr +++ b/tests/ui/rust-2024/reserved-guarded-strings-migration.stderr @@ -1,4 +1,4 @@ -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-migration.rs:40:12 | LL | demo3!(## "foo"); @@ -11,12 +11,12 @@ note: the lint level is defined here | LL | #![warn(rust_2024_guarded_string_incompatible_syntax)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo3!(# # "foo"); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-migration.rs:43:12 | LL | demo4!(### "foo"); @@ -24,12 +24,12 @@ LL | demo4!(### "foo"); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo4!(# ## "foo"); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-migration.rs:43:13 | LL | demo4!(### "foo"); @@ -37,12 +37,12 @@ LL | demo4!(### "foo"); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo4!(## # "foo"); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-migration.rs:48:12 | LL | demo4!(## "foo"#); @@ -50,12 +50,12 @@ LL | demo4!(## "foo"#); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo4!(# # "foo"#); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-migration.rs:51:12 | LL | demo6!(### "foo"##); @@ -63,12 +63,12 @@ LL | demo6!(### "foo"##); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo6!(# ## "foo"##); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-migration.rs:51:13 | LL | demo6!(### "foo"##); @@ -76,12 +76,12 @@ LL | demo6!(### "foo"##); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo6!(## # "foo"##); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-migration.rs:51:21 | LL | demo6!(### "foo"##); @@ -89,12 +89,12 @@ LL | demo6!(### "foo"##); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo6!(### "foo"# #); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-migration.rs:59:17 | LL | demo4!("foo"###); @@ -102,12 +102,12 @@ LL | demo4!("foo"###); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo4!("foo"# ##); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-migration.rs:59:18 | LL | demo4!("foo"###); @@ -115,7 +115,7 @@ LL | demo4!("foo"###); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo4!("foo"## #); | + @@ -276,7 +276,7 @@ help: insert whitespace here to avoid this being parsed as a guarded string in R LL | demo5!(## "foo"##); | + -warning: will be parsed as a guarded string in Rust 2024 +warning: reserved token in Rust 2024 --> $DIR/reserved-guarded-strings-migration.rs:92:19 | LL | demo5!(##"foo"##); @@ -284,7 +284,7 @@ LL | demo5!(##"foo"##); | = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! = note: for more information, see issue #123735 -help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 +help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 | LL | demo5!(##"foo"# #); | + diff --git a/tests/ui/rust-2024/reserved-guarded-strings-via-macro-2.rs b/tests/ui/rust-2024/reserved-guarded-strings-via-macro-2.rs index 3f9f373ba227b..6b0103d4a5002 100644 --- a/tests/ui/rust-2024/reserved-guarded-strings-via-macro-2.rs +++ b/tests/ui/rust-2024/reserved-guarded-strings-via-macro-2.rs @@ -1,6 +1,6 @@ //@ edition:2021 -//@ aux-build:reserved-guarded-strings-macro-2021.rs -//@ aux-build:reserved-guarded-strings-macro-2024.rs +//@ proc-macro: reserved-guarded-strings-macro-2021.rs +//@ proc-macro: reserved-guarded-strings-macro-2024.rs extern crate reserved_guarded_strings_macro_2021 as m2021; extern crate reserved_guarded_strings_macro_2024 as m2024; diff --git a/tests/ui/rust-2024/reserved-guarded-strings-via-macro.rs b/tests/ui/rust-2024/reserved-guarded-strings-via-macro.rs index f9e3c1e3c51b4..ead2ab40b77ac 100644 --- a/tests/ui/rust-2024/reserved-guarded-strings-via-macro.rs +++ b/tests/ui/rust-2024/reserved-guarded-strings-via-macro.rs @@ -1,7 +1,6 @@ //@ run-pass -//@ compile-flags: -Zunstable-options //@ edition:2024 -//@ aux-build:reserved-guarded-strings-macro-2021.rs +//@ proc-macro: reserved-guarded-strings-macro-2021.rs extern crate reserved_guarded_strings_macro_2021 as m2021; diff --git a/tests/ui/rust-2024/reserved-guarded-strings.rs b/tests/ui/rust-2024/reserved-guarded-strings.rs index dab97039be03f..ae68d34cb86e5 100644 --- a/tests/ui/rust-2024/reserved-guarded-strings.rs +++ b/tests/ui/rust-2024/reserved-guarded-strings.rs @@ -1,4 +1,3 @@ -//@ compile-flags: -Zunstable-options //@ edition:2024 // ignore-tidy-linelength @@ -47,13 +46,13 @@ fn main() { //~^ ERROR prefix `blah` is unknown //~| ERROR invalid string literal - demo2!(## "foo"); //~ ERROR invalid string literal - demo3!("foo"###); //~ ERROR invalid string literal - demo3!(### "foo"); //~ ERROR invalid string literal - demo3!(## "foo"#); //~ ERROR invalid string literal + demo2!(## "foo"); //~ reserved multi-hash token is forbidden + demo3!("foo"###); //~ reserved multi-hash token is forbidden + demo3!(### "foo"); //~ reserved multi-hash token is forbidden + demo3!(## "foo"#); //~ reserved multi-hash token is forbidden demo5!(### "foo"###); - //~^ ERROR invalid string literal - //~| ERROR invalid string literal + //~^ reserved multi-hash token is forbidden + //~| reserved multi-hash token is forbidden demo1!(#""); //~ ERROR invalid string literal demo1!(#""#); //~ ERROR invalid string literal @@ -66,7 +65,7 @@ fn main() { demo1!(###"foo"###); //~ ERROR invalid string literal demo2!(#"foo"###); //~^ ERROR invalid string literal - //~| ERROR invalid string literal + //~| ERROR reserved multi-hash token is forbidden // More than 255 hashes demon!(####################################################################################################################################################################################################################################################################"foo"); diff --git a/tests/ui/rust-2024/reserved-guarded-strings.stderr b/tests/ui/rust-2024/reserved-guarded-strings.stderr index f465ba7944a08..0f3b06147c4fd 100644 --- a/tests/ui/rust-2024/reserved-guarded-strings.stderr +++ b/tests/ui/rust-2024/reserved-guarded-strings.stderr @@ -1,5 +1,5 @@ error: prefix `blah` is unknown - --> $DIR/reserved-guarded-strings.rs:45:12 + --> $DIR/reserved-guarded-strings.rs:44:12 | LL | demo2!(blah"xx"); | ^^^^ unknown prefix @@ -11,7 +11,7 @@ LL | demo2!(blah "xx"); | + error: prefix `blah` is unknown - --> $DIR/reserved-guarded-strings.rs:46:12 + --> $DIR/reserved-guarded-strings.rs:45:12 | LL | demo2!(blah#"xx"#); | ^^^^ unknown prefix @@ -23,7 +23,7 @@ LL | demo2!(blah #"xx"#); | + error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:46:16 + --> $DIR/reserved-guarded-strings.rs:45:16 | LL | demo2!(blah#"xx"#); | ^^^^^^ @@ -34,80 +34,80 @@ help: consider inserting whitespace here LL | demo2!(blah# "xx"#); | + -error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:50:12 +error: reserved multi-hash token is forbidden + --> $DIR/reserved-guarded-strings.rs:49:12 | LL | demo2!(## "foo"); | ^^ | - = note: unprefixed guarded string literals are reserved for future use since Rust 2024 + = note: sequences of two or more # are reserved for future use since Rust 2024 help: consider inserting whitespace here | LL | demo2!(# # "foo"); | + -error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:51:17 +error: reserved multi-hash token is forbidden + --> $DIR/reserved-guarded-strings.rs:50:17 | LL | demo3!("foo"###); | ^^ | - = note: unprefixed guarded string literals are reserved for future use since Rust 2024 + = note: sequences of two or more # are reserved for future use since Rust 2024 help: consider inserting whitespace here | LL | demo3!("foo"# ##); | + -error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:52:12 +error: reserved multi-hash token is forbidden + --> $DIR/reserved-guarded-strings.rs:51:12 | LL | demo3!(### "foo"); | ^^ | - = note: unprefixed guarded string literals are reserved for future use since Rust 2024 + = note: sequences of two or more # are reserved for future use since Rust 2024 help: consider inserting whitespace here | LL | demo3!(# ## "foo"); | + -error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:53:12 +error: reserved multi-hash token is forbidden + --> $DIR/reserved-guarded-strings.rs:52:12 | LL | demo3!(## "foo"#); | ^^ | - = note: unprefixed guarded string literals are reserved for future use since Rust 2024 + = note: sequences of two or more # are reserved for future use since Rust 2024 help: consider inserting whitespace here | LL | demo3!(# # "foo"#); | + -error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:54:12 +error: reserved multi-hash token is forbidden + --> $DIR/reserved-guarded-strings.rs:53:12 | LL | demo5!(### "foo"###); | ^^ | - = note: unprefixed guarded string literals are reserved for future use since Rust 2024 + = note: sequences of two or more # are reserved for future use since Rust 2024 help: consider inserting whitespace here | LL | demo5!(# ## "foo"###); | + -error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:54:21 +error: reserved multi-hash token is forbidden + --> $DIR/reserved-guarded-strings.rs:53:21 | LL | demo5!(### "foo"###); | ^^ | - = note: unprefixed guarded string literals are reserved for future use since Rust 2024 + = note: sequences of two or more # are reserved for future use since Rust 2024 help: consider inserting whitespace here | LL | demo5!(### "foo"# ##); | + error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:58:12 + --> $DIR/reserved-guarded-strings.rs:57:12 | LL | demo1!(#""); | ^^^ @@ -119,7 +119,7 @@ LL | demo1!(# ""); | + error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:59:12 + --> $DIR/reserved-guarded-strings.rs:58:12 | LL | demo1!(#""#); | ^^^^ @@ -131,7 +131,7 @@ LL | demo1!(# ""#); | + error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:60:12 + --> $DIR/reserved-guarded-strings.rs:59:12 | LL | demo1!(####""); | ^^^^^^ @@ -143,7 +143,7 @@ LL | demo1!(# ###""); | + error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:61:12 + --> $DIR/reserved-guarded-strings.rs:60:12 | LL | demo1!(#"foo"); | ^^^^^^ @@ -155,7 +155,7 @@ LL | demo1!(# "foo"); | + error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:62:12 + --> $DIR/reserved-guarded-strings.rs:61:12 | LL | demo1!(###"foo"); | ^^^^^^^^ @@ -167,7 +167,7 @@ LL | demo1!(# ##"foo"); | + error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:63:12 + --> $DIR/reserved-guarded-strings.rs:62:12 | LL | demo1!(#"foo"#); | ^^^^^^^ @@ -179,7 +179,7 @@ LL | demo1!(# "foo"#); | + error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:64:12 + --> $DIR/reserved-guarded-strings.rs:63:12 | LL | demo1!(###"foo"#); | ^^^^^^^^^ @@ -191,7 +191,7 @@ LL | demo1!(# ##"foo"#); | + error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:65:12 + --> $DIR/reserved-guarded-strings.rs:64:12 | LL | demo1!(###"foo"##); | ^^^^^^^^^^ @@ -203,7 +203,7 @@ LL | demo1!(# ##"foo"##); | + error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:66:12 + --> $DIR/reserved-guarded-strings.rs:65:12 | LL | demo1!(###"foo"###); | ^^^^^^^^^^^ @@ -215,7 +215,7 @@ LL | demo1!(# ##"foo"###); | + error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:67:12 + --> $DIR/reserved-guarded-strings.rs:66:12 | LL | demo2!(#"foo"###); | ^^^^^^^ @@ -226,20 +226,20 @@ help: consider inserting whitespace here LL | demo2!(# "foo"###); | + -error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:67:19 +error: reserved multi-hash token is forbidden + --> $DIR/reserved-guarded-strings.rs:66:19 | LL | demo2!(#"foo"###); | ^^ | - = note: unprefixed guarded string literals are reserved for future use since Rust 2024 + = note: sequences of two or more # are reserved for future use since Rust 2024 help: consider inserting whitespace here | LL | demo2!(#"foo"## #); | + error: invalid string literal - --> $DIR/reserved-guarded-strings.rs:72:12 + --> $DIR/reserved-guarded-strings.rs:71:12 | LL | ...n!(####################################################################################################################################################################################################################################################################"foo... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm.rs b/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm.rs new file mode 100644 index 0000000000000..cab6af57cb1fd --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm.rs @@ -0,0 +1,19 @@ +//@ edition: 2018 + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn missing_unsafe(_input: TokenStream) -> TokenStream { + "#[no_mangle] pub fn abc() {}".parse().unwrap() +} + +#[proc_macro] +pub fn macro_rules_missing_unsafe(_input: TokenStream) -> TokenStream { + "macro_rules! make_fn { + () => { #[no_mangle] pub fn foo() { } }; + }" + .parse() + .unwrap() +} diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs index 7c919fed976f5..79fba46c77f81 100644 --- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs @@ -1,7 +1,6 @@ //@ revisions: edition2021 edition2024 //@[edition2021] edition:2021 //@[edition2024] edition:2024 -//@[edition2024] compile-flags: -Zunstable-options //@ check-pass diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs new file mode 100644 index 0000000000000..e2c504e708c55 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs @@ -0,0 +1,16 @@ +// Test for unsafe attributes generated by a proc-macro. +// See https://github.com/rust-lang/rust/issues/132906 + +//@ revisions: edition2021 edition2024 +//@ check-pass +//@[edition2021] edition:2021 +//@[edition2024] edition:2024 +//@ proc-macro: unsafe-attributes-pm.rs + +unsafe_attributes_pm::missing_unsafe!(); + +unsafe_attributes_pm::macro_rules_missing_unsafe!(); + +make_fn!(); + +fn main() {} diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr index fb697e14ef1c7..5c3927a09280d 100644 --- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr @@ -1,5 +1,5 @@ error: unsafe attribute used without unsafe - --> $DIR/unsafe-attributes.rs:8:3 + --> $DIR/unsafe-attributes.rs:7:3 | LL | #[no_mangle] | ^^^^^^^^^ usage of unsafe attribute diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs index f6f2994bb6def..4b161bc34ea06 100644 --- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs @@ -2,7 +2,6 @@ //@[edition2021] edition:2021 //@[edition2021] check-pass //@[edition2024] edition:2024 -//@[edition2024] compile-flags: -Zunstable-options #[no_mangle] //[edition2024]~ ERROR: unsafe attribute used without unsafe diff --git a/tests/ui/rust-2024/unsafe-before_exec.e2024.stderr b/tests/ui/rust-2024/unsafe-before_exec.e2024.stderr index 2798ccdefd0c6..10d0e8b830c9b 100644 --- a/tests/ui/rust-2024/unsafe-before_exec.e2024.stderr +++ b/tests/ui/rust-2024/unsafe-before_exec.e2024.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function `before_exec` is unsafe and requires unsafe block - --> $DIR/unsafe-before_exec.rs:14:5 + --> $DIR/unsafe-before_exec.rs:13:5 | LL | cmd.before_exec(|| Ok(())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function diff --git a/tests/ui/rust-2024/unsafe-before_exec.rs b/tests/ui/rust-2024/unsafe-before_exec.rs index 540394da80ef8..44a955e229d8f 100644 --- a/tests/ui/rust-2024/unsafe-before_exec.rs +++ b/tests/ui/rust-2024/unsafe-before_exec.rs @@ -3,7 +3,6 @@ //@[e2021] edition: 2021 //@[e2021] check-pass //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options use std::process::Command; use std::os::unix::process::CommandExt; diff --git a/tests/ui/rust-2024/unsafe-env.e2021.stderr b/tests/ui/rust-2024/unsafe-env.e2021.stderr index 90c1df192aa05..6f9618eb14bfb 100644 --- a/tests/ui/rust-2024/unsafe-env.e2021.stderr +++ b/tests/ui/rust-2024/unsafe-env.e2021.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block - --> $DIR/unsafe-env.rs:15:9 + --> $DIR/unsafe-env.rs:14:9 | LL | unsafe_fn(); | ^^^^^^^^^^^ call to unsafe function @@ -7,18 +7,18 @@ LL | unsafe_fn(); = note: for more information, see issue #71668 = note: consult the function's documentation for information on how to avoid undefined behavior note: an unsafe function restricts its caller, but its body is safe by default - --> $DIR/unsafe-env.rs:9:1 + --> $DIR/unsafe-env.rs:8:1 | LL | unsafe fn unsafe_fn() { | ^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here - --> $DIR/unsafe-env.rs:8:8 + --> $DIR/unsafe-env.rs:7:8 | LL | #[deny(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe function or block - --> $DIR/unsafe-env.rs:33:5 + --> $DIR/unsafe-env.rs:32:5 | LL | unsafe_fn(); | ^^^^^^^^^^^ call to unsafe function @@ -26,13 +26,13 @@ LL | unsafe_fn(); = note: consult the function's documentation for information on how to avoid undefined behavior error: unnecessary `unsafe` block - --> $DIR/unsafe-env.rs:36:5 + --> $DIR/unsafe-env.rs:35:5 | LL | unsafe { | ^^^^^^ unnecessary `unsafe` block | note: the lint level is defined here - --> $DIR/unsafe-env.rs:21:8 + --> $DIR/unsafe-env.rs:20:8 | LL | #[deny(unused_unsafe)] | ^^^^^^^^^^^^^ diff --git a/tests/ui/rust-2024/unsafe-env.e2024.stderr b/tests/ui/rust-2024/unsafe-env.e2024.stderr index 5ecdf3cd7a74c..04a35933c79b2 100644 --- a/tests/ui/rust-2024/unsafe-env.e2024.stderr +++ b/tests/ui/rust-2024/unsafe-env.e2024.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function `std::env::set_var` is unsafe and requires unsafe block - --> $DIR/unsafe-env.rs:10:5 + --> $DIR/unsafe-env.rs:9:5 | LL | env::set_var("FOO", "BAR"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function @@ -7,18 +7,18 @@ LL | env::set_var("FOO", "BAR"); = note: for more information, see issue #71668 = note: consult the function's documentation for information on how to avoid undefined behavior note: an unsafe function restricts its caller, but its body is safe by default - --> $DIR/unsafe-env.rs:9:1 + --> $DIR/unsafe-env.rs:8:1 | LL | unsafe fn unsafe_fn() { | ^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here - --> $DIR/unsafe-env.rs:8:8 + --> $DIR/unsafe-env.rs:7:8 | LL | #[deny(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ error[E0133]: call to unsafe function `std::env::remove_var` is unsafe and requires unsafe block - --> $DIR/unsafe-env.rs:12:5 + --> $DIR/unsafe-env.rs:11:5 | LL | env::remove_var("FOO"); | ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function @@ -27,7 +27,7 @@ LL | env::remove_var("FOO"); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block - --> $DIR/unsafe-env.rs:15:9 + --> $DIR/unsafe-env.rs:14:9 | LL | unsafe_fn(); | ^^^^^^^^^^^ call to unsafe function @@ -36,7 +36,7 @@ LL | unsafe_fn(); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function `set_var` is unsafe and requires unsafe block - --> $DIR/unsafe-env.rs:23:5 + --> $DIR/unsafe-env.rs:22:5 | LL | env::set_var("FOO", "BAR"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function @@ -44,7 +44,7 @@ LL | env::set_var("FOO", "BAR"); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function `remove_var` is unsafe and requires unsafe block - --> $DIR/unsafe-env.rs:25:5 + --> $DIR/unsafe-env.rs:24:5 | LL | env::remove_var("FOO"); | ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function @@ -52,7 +52,7 @@ LL | env::remove_var("FOO"); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block - --> $DIR/unsafe-env.rs:33:5 + --> $DIR/unsafe-env.rs:32:5 | LL | unsafe_fn(); | ^^^^^^^^^^^ call to unsafe function @@ -60,13 +60,13 @@ LL | unsafe_fn(); = note: consult the function's documentation for information on how to avoid undefined behavior error: unnecessary `unsafe` block - --> $DIR/unsafe-env.rs:36:5 + --> $DIR/unsafe-env.rs:35:5 | LL | unsafe { | ^^^^^^ unnecessary `unsafe` block | note: the lint level is defined here - --> $DIR/unsafe-env.rs:21:8 + --> $DIR/unsafe-env.rs:20:8 | LL | #[deny(unused_unsafe)] | ^^^^^^^^^^^^^ diff --git a/tests/ui/rust-2024/unsafe-env.rs b/tests/ui/rust-2024/unsafe-env.rs index 601f44e1d3ec5..4a7c646323a64 100644 --- a/tests/ui/rust-2024/unsafe-env.rs +++ b/tests/ui/rust-2024/unsafe-env.rs @@ -1,7 +1,6 @@ //@ revisions: e2021 e2024 //@[e2021] edition: 2021 //@[e2024] edition: 2024 -//@[e2024] compile-flags: -Zunstable-options use std::env; diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr index 77554da10e60b..50201140cdaf6 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block - --> $DIR/extern-items-unsafe.rs:12:5 + --> $DIR/extern-items-unsafe.rs:11:5 | LL | test1(TEST1); | ^^^^^^^^^^^^ call to unsafe function @@ -7,7 +7,7 @@ LL | test1(TEST1); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: use of extern static is unsafe and requires unsafe function or block - --> $DIR/extern-items-unsafe.rs:12:11 + --> $DIR/extern-items-unsafe.rs:11:11 | LL | test1(TEST1); | ^^^^^ use of extern static diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr index 33b752782d599..fa79d76546a15 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block - --> $DIR/extern-items-unsafe.rs:12:5 + --> $DIR/extern-items-unsafe.rs:11:5 | LL | test1(TEST1); | ^^^^^^^^^^^^ call to unsafe function @@ -7,7 +7,7 @@ LL | test1(TEST1); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: use of extern static is unsafe and requires unsafe block - --> $DIR/extern-items-unsafe.rs:12:11 + --> $DIR/extern-items-unsafe.rs:11:11 | LL | test1(TEST1); | ^^^^^ use of extern static diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs index 721e07acca588..7bb4f666924d7 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs +++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs @@ -1,7 +1,6 @@ //@ revisions: edition2021 edition2024 //@[edition2021] edition:2021 //@[edition2024] edition:2024 -//@[edition2024] compile-flags: -Zunstable-options unsafe extern "C" { static TEST1: i32; diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr index 8ef7c2caf21ee..17b49d8ed5c36 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr @@ -1,5 +1,5 @@ error: extern blocks must be unsafe - --> $DIR/extern-items.rs:7:1 + --> $DIR/extern-items.rs:6:1 | LL | / extern "C" { LL | | diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs index 08805c3634765..8c0b8bc889903 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs +++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs @@ -2,7 +2,6 @@ //@[edition2021] edition:2021 //@[edition2021] check-pass //@[edition2024] edition:2024 -//@[edition2024] compile-flags: -Zunstable-options extern "C" { //[edition2024]~^ ERROR extern blocks must be unsafe diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs b/tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs index b0b8a8b012a6a..2b2d58c3eb3d6 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs @@ -1,7 +1,6 @@ //@ revisions: edition2021 edition2024 //@[edition2021] edition:2021 //@[edition2024] edition:2024 -//@[edition2024] compile-flags: -Zunstable-options //@ check-pass unsafe extern "C" { diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr index ddc5477116f76..07d934da24b10 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr @@ -1,5 +1,5 @@ error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers - --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:8:5 + --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:7:5 | LL | safe static TEST1: i32; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | unsafe extern "C" { | ++++++ error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers - --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:10:5 + --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:9:5 | LL | safe fn test1(i: i32); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr index ae7b4cd47c076..cceb3bddef439 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr @@ -1,5 +1,5 @@ error: extern blocks must be unsafe - --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:6:1 + --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:5:1 | LL | / extern "C" { LL | | @@ -11,7 +11,7 @@ LL | | } | |_^ error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers - --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:8:5 + --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:7:5 | LL | safe static TEST1: i32; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | unsafe extern "C" { | ++++++ error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers - --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:10:5 + --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:9:5 | LL | safe fn test1(i: i32); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs index 89415a69f08f3..a5a6ccdffa0c9 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs @@ -1,7 +1,6 @@ //@ revisions: edition2021 edition2024 //@[edition2021] edition:2021 //@[edition2024] edition:2024 -//@[edition2024] compile-flags: -Zunstable-options extern "C" { //[edition2024]~^ ERROR extern blocks must be unsafe diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr index e3626bb497e4f..9433dd1f2e591 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block - --> $DIR/unsafe-items.rs:18:5 + --> $DIR/unsafe-items.rs:17:5 | LL | test1(TEST1); | ^^^^^^^^^^^^ call to unsafe function @@ -7,7 +7,7 @@ LL | test1(TEST1); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: use of extern static is unsafe and requires unsafe function or block - --> $DIR/unsafe-items.rs:18:11 + --> $DIR/unsafe-items.rs:17:11 | LL | test1(TEST1); | ^^^^^ use of extern static diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr index 89bc501b7b5a5..af86b4c580520 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block - --> $DIR/unsafe-items.rs:18:5 + --> $DIR/unsafe-items.rs:17:5 | LL | test1(TEST1); | ^^^^^^^^^^^^ call to unsafe function @@ -7,7 +7,7 @@ LL | test1(TEST1); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: use of extern static is unsafe and requires unsafe block - --> $DIR/unsafe-items.rs:18:11 + --> $DIR/unsafe-items.rs:17:11 | LL | test1(TEST1); | ^^^^^ use of extern static diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs index dc2bae892a988..50c97b51768ee 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs +++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs @@ -1,7 +1,6 @@ //@ revisions: edition2021 edition2024 //@[edition2021] edition:2021 //@[edition2024] edition:2024 -//@[edition2024] compile-flags: -Zunstable-options unsafe extern "C" { unsafe static TEST1: i32; diff --git a/tests/ui/sanitizer/cfi/can-reveal-opaques.rs b/tests/ui/sanitizer/cfi/can-reveal-opaques.rs index 55988a62a8cdf..99c12d72eb524 100644 --- a/tests/ui/sanitizer/cfi/can-reveal-opaques.rs +++ b/tests/ui/sanitizer/cfi/can-reveal-opaques.rs @@ -39,6 +39,6 @@ fn main() { // So why is the second generic of `test` "`()`", and not the // `impl Sized` since we inferred it from the return type of `rpit_fn` // during typeck? Well, that's because we're using the generics from the - // terminator of the MIR, which has had the RevealAll pass performed on it. + // terminator of the MIR, which has had the PostAnalysisNormalize pass performed on it. let _ = test(rpit_fn); } diff --git a/tests/ui/sanitizer/cfi/coroutine.rs b/tests/ui/sanitizer/cfi/coroutine.rs index ad994fcf73700..ec7c58889688a 100644 --- a/tests/ui/sanitizer/cfi/coroutine.rs +++ b/tests/ui/sanitizer/cfi/coroutine.rs @@ -11,7 +11,7 @@ //@ [cfi] compile-flags: -Z sanitizer=cfi //@ [kcfi] compile-flags: -Z sanitizer=kcfi //@ [kcfi] compile-flags: -C panic=abort -Z panic-abort-tests -C prefer-dynamic=off -//@ compile-flags: --test -Z unstable-options +//@ compile-flags: --test //@ run-pass #![feature(coroutines, stmt_expr_attributes)] diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs index d121a194be6bb..2c0f25fc6ff93 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs @@ -11,7 +11,7 @@ impl Foo { //~^ ERROR invalid generic `self` parameter type //~| ERROR destructor of `R` cannot be evaluated at compile-time self.0 - //~^ ERROR cannot call non-const fn `::deref` in constant function + //~^ ERROR cannot call conditionally-const method `::deref` in constant function } } diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr index 7252b5890fdbf..cf4c219215e08 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr @@ -1,10 +1,12 @@ -error[E0015]: cannot call non-const fn `::deref` in constant functions +error[E0658]: cannot call conditionally-const method `::deref` in constant functions --> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9 | LL | self.0 | ^^^^^^ | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: see issue #67792 for more information + = help: add `#![feature(const_trait_impl)]` 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[E0493]: destructor of `R` cannot be evaluated at compile-time --> $DIR/arbitrary-self-from-method-substs-ice.rs:10:43 @@ -26,5 +28,5 @@ LL | const fn get>(self: R) -> u32 { error: aborting due to 3 previous errors -Some errors have detailed explanations: E0015, E0493, E0801. -For more information about an error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0493, E0658, E0801. +For more information about an error, try `rustc --explain E0493`. diff --git a/tests/ui/self/explicit-self-closures.rs b/tests/ui/self/explicit-self-closures.rs index ea85caa22cea4..cb8b89e90ce8c 100644 --- a/tests/ui/self/explicit-self-closures.rs +++ b/tests/ui/self/explicit-self-closures.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] // Test to make sure that explicit self params work inside closures -//@ pretty-expanded FIXME #23616 struct Box { x: usize diff --git a/tests/ui/self/explicit_self_xcrate_exe.rs b/tests/ui/self/explicit_self_xcrate_exe.rs index f9daf91bdfa56..3bd64d6a4abc9 100644 --- a/tests/ui/self/explicit_self_xcrate_exe.rs +++ b/tests/ui/self/explicit_self_xcrate_exe.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:explicit_self_xcrate.rs -//@ pretty-expanded FIXME #23616 extern crate explicit_self_xcrate; use explicit_self_xcrate::{Foo, Bar}; diff --git a/tests/ui/self/self-impl-2.rs b/tests/ui/self/self-impl-2.rs index 8c09f1ef75691..7316adfde1a62 100644 --- a/tests/ui/self/self-impl-2.rs +++ b/tests/ui/self/self-impl-2.rs @@ -3,7 +3,6 @@ #![allow(unused_variables)] // Test that we can use `Self` types in impls in the expected way. -//@ pretty-expanded FIXME #23616 struct Foo; diff --git a/tests/ui/self/self-type-param.rs b/tests/ui/self/self-type-param.rs index 0b123de2531a8..3b107f465ea16 100644 --- a/tests/ui/self/self-type-param.rs +++ b/tests/ui/self/self-type-param.rs @@ -1,6 +1,5 @@ //@ build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 trait MyTrait { fn f(&self) -> Self; diff --git a/tests/ui/simd-abi-checks-empty-list.stderr b/tests/ui/simd-abi-checks-empty-list.stderr index d7ce52eab80fd..c49fe1a01de5e 100644 --- a/tests/ui/simd-abi-checks-empty-list.stderr +++ b/tests/ui/simd-abi-checks-empty-list.stderr @@ -10,3 +10,14 @@ LL | pub extern "C" fn pass_by_vec(_: SimdVec) {} warning: 1 warning emitted +Future incompatibility report: Future breakage diagnostic: +warning: this function definition uses a SIMD vector type that is not currently supported with the chosen ABI + --> $DIR/simd-abi-checks-empty-list.rs:17:1 + | +LL | pub extern "C" fn pass_by_vec(_: SimdVec) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = note: `#[warn(abi_unsupported_vector_types)]` on by default + diff --git a/tests/ui/simd-abi-checks-s390x.z10.stderr b/tests/ui/simd-abi-checks-s390x.z10.stderr index a91322ec05839..cf135afb428f4 100644 --- a/tests/ui/simd-abi-checks-s390x.z10.stderr +++ b/tests/ui/simd-abi-checks-s390x.z10.stderr @@ -109,3 +109,167 @@ LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) error: aborting due to 10 previous errors +Future incompatibility report: Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:46:1 + | +LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:52:1 + | +LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:99:1 + | +LL | / extern "C" fn vector_transparent_wrapper_ret_small( +LL | | x: &TransparentWrapper, +LL | | ) -> TransparentWrapper { + | |_____________________________^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:107:1 + | +LL | / extern "C" fn vector_transparent_wrapper_ret( +LL | | x: &TransparentWrapper, +LL | | ) -> TransparentWrapper { + | |______________________________^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:123:1 + | +LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:129:1 + | +LL | extern "C" fn vector_arg(x: i8x16) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:141:1 + | +LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:147:1 + | +LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:159:1 + | +LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:165:1 + | +LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr b/tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr index a91322ec05839..cf135afb428f4 100644 --- a/tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr +++ b/tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr @@ -109,3 +109,167 @@ LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) error: aborting due to 10 previous errors +Future incompatibility report: Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:46:1 + | +LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:52:1 + | +LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:99:1 + | +LL | / extern "C" fn vector_transparent_wrapper_ret_small( +LL | | x: &TransparentWrapper, +LL | | ) -> TransparentWrapper { + | |_____________________________^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:107:1 + | +LL | / extern "C" fn vector_transparent_wrapper_ret( +LL | | x: &TransparentWrapper, +LL | | ) -> TransparentWrapper { + | |______________________________^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:123:1 + | +LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:129:1 + | +LL | extern "C" fn vector_arg(x: i8x16) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:141:1 + | +LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:147:1 + | +LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:159:1 + | +LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:165:1 + | +LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr b/tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr index a91322ec05839..cf135afb428f4 100644 --- a/tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr +++ b/tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr @@ -109,3 +109,167 @@ LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) error: aborting due to 10 previous errors +Future incompatibility report: Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:46:1 + | +LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:52:1 + | +LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:99:1 + | +LL | / extern "C" fn vector_transparent_wrapper_ret_small( +LL | | x: &TransparentWrapper, +LL | | ) -> TransparentWrapper { + | |_____________________________^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:107:1 + | +LL | / extern "C" fn vector_transparent_wrapper_ret( +LL | | x: &TransparentWrapper, +LL | | ) -> TransparentWrapper { + | |______________________________^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:123:1 + | +LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:129:1 + | +LL | extern "C" fn vector_arg(x: i8x16) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:141:1 + | +LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:147:1 + | +LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:159:1 + | +LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:165:1 + | +LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) +note: the lint level is defined here + --> $DIR/simd-abi-checks-s390x.rs:15:9 + | +LL | #![deny(abi_unsupported_vector_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/simd-abi-checks.rs b/tests/ui/simd-abi-checks.rs index 9e3af26e9c469..c97767b27941e 100644 --- a/tests/ui/simd-abi-checks.rs +++ b/tests/ui/simd-abi-checks.rs @@ -4,6 +4,7 @@ #![feature(avx512_target_feature)] #![feature(portable_simd)] +#![feature(target_feature_11, simd_ffi)] #![allow(improper_ctypes_definitions)] use std::arch::x86_64::*; @@ -50,6 +51,14 @@ unsafe fn test() { as_f64x8(arg); } +#[target_feature(enable = "avx")] +unsafe fn in_closure() -> impl FnOnce() -> __m256 { + #[inline(always)] // this disables target-feature inheritance + || g() + //~^ WARNING this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller + //~| WARNING this was previously accepted by the compiler +} + fn main() { unsafe { f(g()); @@ -78,4 +87,24 @@ fn main() { //~| WARNING this was previously accepted by the compiler //~| WARNING this was previously accepted by the compiler } + + unsafe { + in_closure()(); + } + + unsafe { + #[expect(improper_ctypes)] + extern "C" { + fn some_extern() -> __m256; + } + some_extern(); + //~^ WARNING this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller + //~| WARNING this was previously accepted by the compiler + } +} + +#[no_mangle] +#[target_feature(enable = "avx")] +fn some_extern() -> __m256 { + todo!() } diff --git a/tests/ui/simd-abi-checks.stderr b/tests/ui/simd-abi-checks.stderr index 7d2915f7dea64..eb7d9e8102978 100644 --- a/tests/ui/simd-abi-checks.stderr +++ b/tests/ui/simd-abi-checks.stderr @@ -1,5 +1,5 @@ warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:55:11 + --> $DIR/simd-abi-checks.rs:64:11 | LL | f(g()); | ^^^ function called here @@ -10,7 +10,7 @@ LL | f(g()); = note: `#[warn(abi_unsupported_vector_types)]` on by default warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:55:9 + --> $DIR/simd-abi-checks.rs:64:9 | LL | f(g()); | ^^^^^^ function called here @@ -20,7 +20,7 @@ LL | f(g()); = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:63:14 + --> $DIR/simd-abi-checks.rs:72:14 | LL | gavx(favx()); | ^^^^^^ function called here @@ -30,7 +30,7 @@ LL | gavx(favx()); = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:63:9 + --> $DIR/simd-abi-checks.rs:72:9 | LL | gavx(favx()); | ^^^^^^^^^^^^ function called here @@ -40,7 +40,7 @@ LL | gavx(favx()); = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:75:19 + --> $DIR/simd-abi-checks.rs:84:19 | LL | w(Wrapper(g())); | ^^^ function called here @@ -50,7 +50,7 @@ LL | w(Wrapper(g())); = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:75:9 + --> $DIR/simd-abi-checks.rs:84:9 | LL | w(Wrapper(g())); | ^^^^^^^^^^^^^^^ function called here @@ -59,8 +59,145 @@ LL | w(Wrapper(g())); = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) +warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller + --> $DIR/simd-abi-checks.rs:100:9 + | +LL | some_extern(); + | ^^^^^^^^^^^^^ function called here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + +warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled + --> $DIR/simd-abi-checks.rs:27:1 + | +LL | unsafe extern "C" fn g() -> __m256 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + +warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled + --> $DIR/simd-abi-checks.rs:21:1 + | +LL | unsafe extern "C" fn f(_: __m256) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + +warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled + --> $DIR/simd-abi-checks.rs:15:1 + | +LL | unsafe extern "C" fn w(_: Wrapper) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + +warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller + --> $DIR/simd-abi-checks.rs:57:8 + | +LL | || g() + | ^^^ function called here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + +warning: 11 warnings emitted + +Future incompatibility report: Future breakage diagnostic: +warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller + --> $DIR/simd-abi-checks.rs:64:11 + | +LL | f(g()); + | ^^^ function called here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + = note: `#[warn(abi_unsupported_vector_types)]` on by default + +Future breakage diagnostic: +warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller + --> $DIR/simd-abi-checks.rs:64:9 + | +LL | f(g()); + | ^^^^^^ function called here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + = note: `#[warn(abi_unsupported_vector_types)]` on by default + +Future breakage diagnostic: +warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller + --> $DIR/simd-abi-checks.rs:72:14 + | +LL | gavx(favx()); + | ^^^^^^ function called here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + = note: `#[warn(abi_unsupported_vector_types)]` on by default + +Future breakage diagnostic: +warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller + --> $DIR/simd-abi-checks.rs:72:9 + | +LL | gavx(favx()); + | ^^^^^^^^^^^^ function called here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + = note: `#[warn(abi_unsupported_vector_types)]` on by default + +Future breakage diagnostic: +warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller + --> $DIR/simd-abi-checks.rs:84:19 + | +LL | w(Wrapper(g())); + | ^^^ function called here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + = note: `#[warn(abi_unsupported_vector_types)]` on by default + +Future breakage diagnostic: +warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller + --> $DIR/simd-abi-checks.rs:84:9 + | +LL | w(Wrapper(g())); + | ^^^^^^^^^^^^^^^ function called here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + = note: `#[warn(abi_unsupported_vector_types)]` on by default + +Future breakage diagnostic: +warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller + --> $DIR/simd-abi-checks.rs:100:9 + | +LL | some_extern(); + | ^^^^^^^^^^^^^ function called here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + = note: `#[warn(abi_unsupported_vector_types)]` on by default + +Future breakage diagnostic: warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled - --> $DIR/simd-abi-checks.rs:26:1 + --> $DIR/simd-abi-checks.rs:27:1 | LL | unsafe extern "C" fn g() -> __m256 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -68,9 +205,11 @@ LL | unsafe extern "C" fn g() -> __m256 { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + = note: `#[warn(abi_unsupported_vector_types)]` on by default +Future breakage diagnostic: warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled - --> $DIR/simd-abi-checks.rs:20:1 + --> $DIR/simd-abi-checks.rs:21:1 | LL | unsafe extern "C" fn f(_: __m256) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -78,9 +217,11 @@ LL | unsafe extern "C" fn f(_: __m256) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + = note: `#[warn(abi_unsupported_vector_types)]` on by default +Future breakage diagnostic: warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled - --> $DIR/simd-abi-checks.rs:14:1 + --> $DIR/simd-abi-checks.rs:15:1 | LL | unsafe extern "C" fn w(_: Wrapper) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -88,6 +229,17 @@ LL | unsafe extern "C" fn w(_: Wrapper) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + = note: `#[warn(abi_unsupported_vector_types)]` on by default -warning: 9 warnings emitted +Future breakage diagnostic: +warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller + --> $DIR/simd-abi-checks.rs:57:8 + | +LL | || g() + | ^^^ function called here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) + = note: `#[warn(abi_unsupported_vector_types)]` on by default diff --git a/tests/ui/simd/array-trait.rs b/tests/ui/simd/array-trait.rs index d2f246a2146ca..67583bf82087d 100644 --- a/tests/ui/simd/array-trait.rs +++ b/tests/ui/simd/array-trait.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #![feature(repr_simd, intrinsics, generic_const_exprs)] #![allow(non_camel_case_types, incomplete_features)] diff --git a/tests/ui/simd/array-trait.stderr b/tests/ui/simd/array-trait.stderr index a63dbf37959f8..2d2a11f25ade0 100644 --- a/tests/ui/simd/array-trait.stderr +++ b/tests/ui/simd/array-trait.stderr @@ -1,5 +1,5 @@ error: unconstrained generic constant - --> $DIR/array-trait.rs:23:23 + --> $DIR/array-trait.rs:22:23 | LL | pub struct T([S::Lane; S::SIZE]); | ^^^^^^^^^^^^^^^^^^ @@ -10,13 +10,13 @@ LL | pub struct T([S::Lane; S::SIZE]) where [(); S::SIZE]:; | ++++++++++++++++++++ error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type - --> $DIR/array-trait.rs:23:1 + --> $DIR/array-trait.rs:22:1 | LL | pub struct T([S::Lane; S::SIZE]); | ^^^^^^^^^^^^^^^^^^^^^ error: unconstrained generic constant - --> $DIR/array-trait.rs:23:23 + --> $DIR/array-trait.rs:22:23 | LL | #[derive(Copy, Clone)] | ----- in this derive macro expansion diff --git a/tests/ui/simd/array-type.rs b/tests/ui/simd/array-type.rs index 4063dcd703cd7..8ca53b1a453fc 100644 --- a/tests/ui/simd/array-type.rs +++ b/tests/ui/simd/array-type.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #![feature(repr_simd, intrinsics)] diff --git a/tests/ui/sized-borrowed-pointer.rs b/tests/ui/sized-borrowed-pointer.rs index f1635531e4ece..bd213c067db5d 100644 --- a/tests/ui/sized-borrowed-pointer.rs +++ b/tests/ui/sized-borrowed-pointer.rs @@ -3,7 +3,6 @@ #![allow(dead_code)] // Possibly-dynamic size of typaram should be cleared at pointer boundary. -//@ pretty-expanded FIXME #23616 fn bar() { } fn foo() { bar::<&T>() } diff --git a/tests/ui/sized-owned-pointer.rs b/tests/ui/sized-owned-pointer.rs index 48f870de9ae7e..b35c0f91abd2c 100644 --- a/tests/ui/sized-owned-pointer.rs +++ b/tests/ui/sized-owned-pointer.rs @@ -4,7 +4,6 @@ // Possibly-dynamic size of typaram should be cleared at pointer boundary. -//@ pretty-expanded FIXME #23616 fn bar() { } fn foo() { bar::>() } diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr index d40e98224355b..eec2f5b42fda9 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr @@ -4,7 +4,7 @@ error: expected a pattern, found an expression LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; | ^^^^^^^^^^^^^^^^^^ not a pattern | - = note: arbitrary expressions are not allowed in patterns: + = note: arbitrary expressions are not allowed in patterns: error[E0412]: cannot find type `T` in this scope --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:55 diff --git a/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr b/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr index 60433e1c28467..5ecbedf186785 100644 --- a/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr +++ b/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr @@ -4,7 +4,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015 LL | pub(crate) async fn new( | ^^^^^ to use `async fn`, switch to Rust 2018 or later | - = help: pass `--edition 2021` to `rustc` + = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0412]: cannot find type `Duration` in this scope diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs index a7487b8aecb9c..d11ec79833217 100644 --- a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs +++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs @@ -17,7 +17,6 @@ impl MyTrait for D { } impl MyTrait for BadStruct { -//~^ ERROR: conflicting implementations of trait `MyTrait<_>` for type `BadStruct` fn foo() {} } diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr index 13f6ae0805dad..0ecec03a023eb 100644 --- a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr +++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr @@ -4,16 +4,6 @@ error[E0412]: cannot find type `MissingType` in this scope LL | err: MissingType | ^^^^^^^^^^^ not found in this scope -error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `BadStruct` - --> $DIR/issue-68830-spurious-diagnostics.rs:19:1 - | -LL | impl MyTrait for D { - | --------------------------- first implementation here -... -LL | impl MyTrait for BadStruct { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `BadStruct` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0119, E0412. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr index 2af75876d5b0a..04a41f0d9dd81 100644 --- a/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr +++ b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr @@ -4,11 +4,7 @@ error[E0477]: the type `&'a i32` does not fulfill the required lifetime LL | impl<'a> Tr for &'a i32 { | ^^^^^^^^^^^^^^^^^^^^^^^ | -note: type must satisfy the static lifetime as required by this binding - --> $DIR/specialize_with_generalize_lifetimes.rs:12:15 - | -LL | impl Tr for T { - | ^^^^^^^ + = note: type must satisfy the static lifetime error[E0477]: the type `Wrapper<'a>` does not fulfill the required lifetime --> $DIR/specialize_with_generalize_lifetimes.rs:31:1 @@ -16,11 +12,7 @@ error[E0477]: the type `Wrapper<'a>` does not fulfill the required lifetime LL | impl<'a> Tr for Wrapper<'a> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: type must satisfy the static lifetime as required by this binding - --> $DIR/specialize_with_generalize_lifetimes.rs:12:15 - | -LL | impl Tr for T { - | ^^^^^^^ + = note: type must satisfy the static lifetime error: aborting due to 2 previous errors diff --git a/tests/ui/sse-abi-checks.stderr b/tests/ui/sse-abi-checks.stderr index 7dd13af5091ac..e08b2d4e19179 100644 --- a/tests/ui/sse-abi-checks.stderr +++ b/tests/ui/sse-abi-checks.stderr @@ -11,3 +11,15 @@ LL | pub unsafe extern "C" fn f(_: SseVector) { warning: 1 warning emitted +Future incompatibility report: Future breakage diagnostic: +warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `sse` target feature, which is not enabled + --> $DIR/sse-abi-checks.rs:21:1 + | +LL | pub unsafe extern "C" fn f(_: SseVector) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = help: consider enabling it globally (`-C target-feature=+sse`) or locally (`#[target_feature(enable="sse")]`) + = note: `#[warn(abi_unsupported_vector_types)]` on by default + diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs index 10c31d7943866..1982073073621 100644 --- a/tests/ui/stability-attribute/missing-const-stability.rs +++ b/tests/ui/stability-attribute/missing-const-stability.rs @@ -27,7 +27,7 @@ pub trait Bar { } #[stable(feature = "stable", since = "1.0.0")] impl const Bar for Foo { - //~^ ERROR implementation has missing const stability attribute + // ok because all users must enable `const_trait_impl` fn fun() {} } diff --git a/tests/ui/stability-attribute/missing-const-stability.stderr b/tests/ui/stability-attribute/missing-const-stability.stderr index ad8a1fa9d36e1..baa4c34af0600 100644 --- a/tests/ui/stability-attribute/missing-const-stability.stderr +++ b/tests/ui/stability-attribute/missing-const-stability.stderr @@ -4,15 +4,6 @@ error: function has missing const stability attribute LL | pub const fn foo() {} | ^^^^^^^^^^^^^^^^^^^^^ -error: implementation has missing const stability attribute - --> $DIR/missing-const-stability.rs:29:1 - | -LL | / impl const Bar for Foo { -LL | | -LL | | fn fun() {} -LL | | } - | |_^ - error: function has missing const stability attribute --> $DIR/missing-const-stability.rs:36:1 | @@ -25,5 +16,5 @@ error: associated function has missing const stability attribute LL | pub const fn foo() {} | ^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/static/issue-1660.rs b/tests/ui/static/issue-1660.rs index a114a9083134e..02a408d9a561f 100644 --- a/tests/ui/static/issue-1660.rs +++ b/tests/ui/static/issue-1660.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(non_upper_case_globals)] -//@ pretty-expanded FIXME #23616 pub fn main() { static _x: isize = 1<<2; diff --git a/tests/ui/statics/check-recursion-foreign.rs b/tests/ui/statics/check-recursion-foreign.rs index 5a0ff7b59627e..6804910f4ccf9 100644 --- a/tests/ui/statics/check-recursion-foreign.rs +++ b/tests/ui/statics/check-recursion-foreign.rs @@ -4,7 +4,6 @@ //@ aux-build:check_static_recursion_foreign_helper.rs -//@ pretty-expanded FIXME #23616 extern crate check_static_recursion_foreign_helper; diff --git a/tests/ui/statics/issue-15261.rs b/tests/ui/statics/issue-15261.rs index e168abce07849..ed79a201488f3 100644 --- a/tests/ui/statics/issue-15261.rs +++ b/tests/ui/statics/issue-15261.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_upper_case_globals)] -//@ pretty-expanded FIXME #23616 static mut n_mut: usize = 0; diff --git a/tests/ui/statics/issue-15261.stderr b/tests/ui/statics/issue-15261.stderr index 417dbae9db18f..4067d151de3d4 100644 --- a/tests/ui/statics/issue-15261.stderr +++ b/tests/ui/statics/issue-15261.stderr @@ -1,5 +1,5 @@ warning: creating a shared reference to mutable static is discouraged - --> $DIR/issue-15261.rs:9:37 + --> $DIR/issue-15261.rs:8:37 | LL | static n: &'static usize = unsafe { &n_mut }; | ^^^^^^ shared reference to mutable static diff --git a/tests/ui/statics/issue-17718-static-unsafe-interior.rs b/tests/ui/statics/issue-17718-static-unsafe-interior.rs index 82d5ec8db46ce..daff7ba873c0f 100644 --- a/tests/ui/statics/issue-17718-static-unsafe-interior.rs +++ b/tests/ui/statics/issue-17718-static-unsafe-interior.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_imports)] -//@ pretty-expanded FIXME #23616 use std::marker; use std::cell::UnsafeCell; diff --git a/tests/ui/statics/static-fn-inline-xc.rs b/tests/ui/statics/static-fn-inline-xc.rs index fe230f04d3d96..e75083b218830 100644 --- a/tests/ui/statics/static-fn-inline-xc.rs +++ b/tests/ui/statics/static-fn-inline-xc.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:static_fn_inline_xc_aux.rs -//@ pretty-expanded FIXME #23616 extern crate static_fn_inline_xc_aux as mycore; diff --git a/tests/ui/statics/static-fn-trait-xc.rs b/tests/ui/statics/static-fn-trait-xc.rs index 78810eb5645c8..73747416c604d 100644 --- a/tests/ui/statics/static-fn-trait-xc.rs +++ b/tests/ui/statics/static-fn-trait-xc.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:static_fn_trait_xc_aux.rs -//@ pretty-expanded FIXME #23616 extern crate static_fn_trait_xc_aux as mycore; diff --git a/tests/ui/statics/static-methods-in-traits2.rs b/tests/ui/statics/static-methods-in-traits2.rs index dbb7120d543d5..dbd5e77c1ba9f 100644 --- a/tests/ui/statics/static-methods-in-traits2.rs +++ b/tests/ui/statics/static-methods-in-traits2.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub trait Number: NumConv { fn from(n: T) -> Self; diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr index 2cc2c8019fa1b..2adbcfab612c6 100644 --- a/tests/ui/stats/input-stats.stderr +++ b/tests/ui/stats/input-stats.stderr @@ -5,27 +5,27 @@ ast-stats-1 Crate 40 ( 0.6%) 1 40 ast-stats-1 GenericArgs 40 ( 0.6%) 1 40 ast-stats-1 - AngleBracketed 40 ( 0.6%) 1 ast-stats-1 ExprField 48 ( 0.7%) 1 48 -ast-stats-1 WherePredicate 56 ( 0.8%) 1 56 -ast-stats-1 - BoundPredicate 56 ( 0.8%) 1 ast-stats-1 Attribute 64 ( 1.0%) 2 32 ast-stats-1 - DocComment 32 ( 0.5%) 1 ast-stats-1 - Normal 32 ( 0.5%) 1 +ast-stats-1 WherePredicate 64 ( 1.0%) 1 64 +ast-stats-1 - BoundPredicate 64 ( 1.0%) 1 ast-stats-1 Local 80 ( 1.2%) 1 80 ast-stats-1 ForeignItem 88 ( 1.3%) 1 88 ast-stats-1 - Fn 88 ( 1.3%) 1 ast-stats-1 Arm 96 ( 1.4%) 2 48 ast-stats-1 FnDecl 120 ( 1.8%) 5 24 -ast-stats-1 FieldDef 160 ( 2.4%) 2 80 ast-stats-1 Param 160 ( 2.4%) 4 40 ast-stats-1 Stmt 160 ( 2.4%) 5 32 ast-stats-1 - Let 32 ( 0.5%) 1 ast-stats-1 - MacCall 32 ( 0.5%) 1 ast-stats-1 - Expr 96 ( 1.4%) 3 +ast-stats-1 FieldDef 176 ( 2.6%) 2 88 ast-stats-1 Block 192 ( 2.9%) 6 32 ast-stats-1 Variant 208 ( 3.1%) 2 104 ast-stats-1 AssocItem 352 ( 5.3%) 4 88 -ast-stats-1 - Type 176 ( 2.7%) 2 -ast-stats-1 - Fn 176 ( 2.7%) 2 +ast-stats-1 - Type 176 ( 2.6%) 2 +ast-stats-1 - Fn 176 ( 2.6%) 2 ast-stats-1 GenericBound 352 ( 5.3%) 4 88 ast-stats-1 - Trait 352 ( 5.3%) 4 ast-stats-1 GenericParam 480 ( 7.2%) 5 96 @@ -33,14 +33,14 @@ ast-stats-1 Pat 504 ( 7.6%) 7 72 ast-stats-1 - Struct 72 ( 1.1%) 1 ast-stats-1 - Wild 72 ( 1.1%) 1 ast-stats-1 - Ident 360 ( 5.4%) 5 -ast-stats-1 Expr 576 ( 8.7%) 8 72 +ast-stats-1 Expr 576 ( 8.6%) 8 72 ast-stats-1 - Path 72 ( 1.1%) 1 ast-stats-1 - Match 72 ( 1.1%) 1 ast-stats-1 - Struct 72 ( 1.1%) 1 ast-stats-1 - Lit 144 ( 2.2%) 2 -ast-stats-1 - Block 216 ( 3.3%) 3 +ast-stats-1 - Block 216 ( 3.2%) 3 ast-stats-1 PathSegment 744 (11.2%) 31 24 -ast-stats-1 Ty 896 (13.5%) 14 64 +ast-stats-1 Ty 896 (13.4%) 14 64 ast-stats-1 - Ref 64 ( 1.0%) 1 ast-stats-1 - Ptr 64 ( 1.0%) 1 ast-stats-1 - ImplicitSelf 128 ( 1.9%) 2 @@ -53,7 +53,7 @@ ast-stats-1 - Enum 136 ( 2.0%) 1 ast-stats-1 - Fn 272 ( 4.1%) 2 ast-stats-1 - Use 408 ( 6.1%) 3 ast-stats-1 ---------------------------------------------------------------- -ast-stats-1 Total 6_640 116 +ast-stats-1 Total 6_664 116 ast-stats-1 ast-stats-2 POST EXPANSION AST STATS ast-stats-2 Name Accumulated Size Count Item Size @@ -62,8 +62,8 @@ ast-stats-2 Crate 40 ( 0.5%) 1 40 ast-stats-2 GenericArgs 40 ( 0.5%) 1 40 ast-stats-2 - AngleBracketed 40 ( 0.5%) 1 ast-stats-2 ExprField 48 ( 0.7%) 1 48 -ast-stats-2 WherePredicate 56 ( 0.8%) 1 56 -ast-stats-2 - BoundPredicate 56 ( 0.8%) 1 +ast-stats-2 WherePredicate 64 ( 0.9%) 1 64 +ast-stats-2 - BoundPredicate 64 ( 0.9%) 1 ast-stats-2 Local 80 ( 1.1%) 1 80 ast-stats-2 ForeignItem 88 ( 1.2%) 1 88 ast-stats-2 - Fn 88 ( 1.2%) 1 @@ -73,14 +73,14 @@ ast-stats-2 InlineAsm 120 ( 1.6%) 1 120 ast-stats-2 Attribute 128 ( 1.8%) 4 32 ast-stats-2 - DocComment 32 ( 0.4%) 1 ast-stats-2 - Normal 96 ( 1.3%) 3 -ast-stats-2 FieldDef 160 ( 2.2%) 2 80 ast-stats-2 Param 160 ( 2.2%) 4 40 ast-stats-2 Stmt 160 ( 2.2%) 5 32 ast-stats-2 - Let 32 ( 0.4%) 1 ast-stats-2 - Semi 32 ( 0.4%) 1 ast-stats-2 - Expr 96 ( 1.3%) 3 +ast-stats-2 FieldDef 176 ( 2.4%) 2 88 ast-stats-2 Block 192 ( 2.6%) 6 32 -ast-stats-2 Variant 208 ( 2.9%) 2 104 +ast-stats-2 Variant 208 ( 2.8%) 2 104 ast-stats-2 AssocItem 352 ( 4.8%) 4 88 ast-stats-2 - Type 176 ( 2.4%) 2 ast-stats-2 - Fn 176 ( 2.4%) 2 @@ -98,7 +98,7 @@ ast-stats-2 - Struct 72 ( 1.0%) 1 ast-stats-2 - InlineAsm 72 ( 1.0%) 1 ast-stats-2 - Lit 144 ( 2.0%) 2 ast-stats-2 - Block 216 ( 3.0%) 3 -ast-stats-2 PathSegment 864 (11.9%) 36 24 +ast-stats-2 PathSegment 864 (11.8%) 36 24 ast-stats-2 Ty 896 (12.3%) 14 64 ast-stats-2 - Ref 64 ( 0.9%) 1 ast-stats-2 - Ptr 64 ( 0.9%) 1 @@ -111,9 +111,9 @@ ast-stats-2 - Impl 136 ( 1.9%) 1 ast-stats-2 - ExternCrate 136 ( 1.9%) 1 ast-stats-2 - ForeignMod 136 ( 1.9%) 1 ast-stats-2 - Fn 272 ( 3.7%) 2 -ast-stats-2 - Use 544 ( 7.5%) 4 +ast-stats-2 - Use 544 ( 7.4%) 4 ast-stats-2 ---------------------------------------------------------------- -ast-stats-2 Total 7_288 127 +ast-stats-2 Total 7_312 127 ast-stats-2 hir-stats HIR STATS hir-stats Name Accumulated Size Count Item Size @@ -131,39 +131,39 @@ hir-stats Param 64 ( 0.7%) 2 32 hir-stats Body 72 ( 0.8%) 3 24 hir-stats ImplItemRef 72 ( 0.8%) 2 36 hir-stats InlineAsm 72 ( 0.8%) 1 72 +hir-stats WherePredicate 72 ( 0.8%) 3 24 +hir-stats - BoundPredicate 72 ( 0.8%) 3 hir-stats Arm 80 ( 0.9%) 2 40 -hir-stats FieldDef 96 ( 1.1%) 2 48 hir-stats Stmt 96 ( 1.1%) 3 32 hir-stats - Let 32 ( 0.4%) 1 hir-stats - Semi 32 ( 0.4%) 1 hir-stats - Expr 32 ( 0.4%) 1 +hir-stats FieldDef 112 ( 1.3%) 2 56 hir-stats FnDecl 120 ( 1.3%) 3 40 hir-stats Attribute 128 ( 1.4%) 4 32 hir-stats GenericArgs 144 ( 1.6%) 3 48 hir-stats Variant 144 ( 1.6%) 2 72 -hir-stats WherePredicate 192 ( 2.1%) 3 64 -hir-stats - BoundPredicate 192 ( 2.1%) 3 -hir-stats GenericBound 256 ( 2.8%) 4 64 -hir-stats - Trait 256 ( 2.8%) 4 +hir-stats GenericBound 256 ( 2.9%) 4 64 +hir-stats - Trait 256 ( 2.9%) 4 hir-stats Block 288 ( 3.2%) 6 48 hir-stats GenericParam 360 ( 4.0%) 5 72 hir-stats Pat 360 ( 4.0%) 5 72 hir-stats - Struct 72 ( 0.8%) 1 hir-stats - Wild 72 ( 0.8%) 1 hir-stats - Binding 216 ( 2.4%) 3 -hir-stats Generics 560 ( 6.2%) 10 56 -hir-stats Ty 720 ( 8.0%) 15 48 +hir-stats Generics 560 ( 6.3%) 10 56 +hir-stats Ty 720 ( 8.1%) 15 48 hir-stats - Ref 48 ( 0.5%) 1 hir-stats - Ptr 48 ( 0.5%) 1 -hir-stats - Path 624 ( 6.9%) 13 -hir-stats Expr 768 ( 8.5%) 12 64 +hir-stats - Path 624 ( 7.0%) 13 +hir-stats Expr 768 ( 8.6%) 12 64 hir-stats - Path 64 ( 0.7%) 1 hir-stats - Match 64 ( 0.7%) 1 hir-stats - Struct 64 ( 0.7%) 1 hir-stats - InlineAsm 64 ( 0.7%) 1 hir-stats - Lit 128 ( 1.4%) 2 hir-stats - Block 384 ( 4.3%) 6 -hir-stats Item 968 (10.7%) 11 88 +hir-stats Item 968 (10.9%) 11 88 hir-stats - Enum 88 ( 1.0%) 1 hir-stats - Trait 88 ( 1.0%) 1 hir-stats - Impl 88 ( 1.0%) 1 @@ -171,8 +171,8 @@ hir-stats - ExternCrate 88 ( 1.0%) 1 hir-stats - ForeignMod 88 ( 1.0%) 1 hir-stats - Fn 176 ( 2.0%) 2 hir-stats - Use 352 ( 3.9%) 4 -hir-stats Path 1_240 (13.7%) 31 40 -hir-stats PathSegment 1_920 (21.3%) 40 48 +hir-stats Path 1_240 (13.9%) 31 40 +hir-stats PathSegment 1_920 (21.5%) 40 48 hir-stats ---------------------------------------------------------------- -hir-stats Total 9_024 180 +hir-stats Total 8_920 180 hir-stats diff --git a/tests/ui/structs-enums/class-dtor.rs b/tests/ui/structs-enums/class-dtor.rs index ee6220b6fa451..a08f0f0b0a47f 100644 --- a/tests/ui/structs-enums/class-dtor.rs +++ b/tests/ui/structs-enums/class-dtor.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 struct cat { done : extern "C" fn(usize), diff --git a/tests/ui/structs-enums/class-str-field.rs b/tests/ui/structs-enums/class-str-field.rs index a33a635344ead..24f648afc90b1 100644 --- a/tests/ui/structs-enums/class-str-field.rs +++ b/tests/ui/structs-enums/class-str-field.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 struct cat { diff --git a/tests/ui/structs-enums/class-typarams.rs b/tests/ui/structs-enums/class-typarams.rs index 01cfa47024f10..b5a3923983f36 100644 --- a/tests/ui/structs-enums/class-typarams.rs +++ b/tests/ui/structs-enums/class-typarams.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 use std::marker::PhantomData; diff --git a/tests/ui/structs-enums/classes-self-referential.rs b/tests/ui/structs-enums/classes-self-referential.rs index 35696a9cff9e6..f819e558aa2ee 100644 --- a/tests/ui/structs-enums/classes-self-referential.rs +++ b/tests/ui/structs-enums/classes-self-referential.rs @@ -3,7 +3,6 @@ #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 struct kitten { cat: Option, diff --git a/tests/ui/structs-enums/enum-discrim-range-overflow.rs b/tests/ui/structs-enums/enum-discrim-range-overflow.rs index 51cabd10e3089..91be8014ebdaa 100644 --- a/tests/ui/structs-enums/enum-discrim-range-overflow.rs +++ b/tests/ui/structs-enums/enum-discrim-range-overflow.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(overflowing_literals)] -//@ pretty-expanded FIXME #23616 pub enum E64 { H64 = 0x7FFF_FFFF_FFFF_FFFF, diff --git a/tests/ui/structs-enums/enum-export-inheritance.rs b/tests/ui/structs-enums/enum-export-inheritance.rs index 5bb689260c2c4..1fd697830db51 100644 --- a/tests/ui/structs-enums/enum-export-inheritance.rs +++ b/tests/ui/structs-enums/enum-export-inheritance.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 mod a { pub enum Foo { diff --git a/tests/ui/structs-enums/enum-variants.rs b/tests/ui/structs-enums/enum-variants.rs index 1f5206b8de5dd..d9639b329419a 100644 --- a/tests/ui/structs-enums/enum-variants.rs +++ b/tests/ui/structs-enums/enum-variants.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(unused_assignments)] -//@ pretty-expanded FIXME #23616 #![allow(unused_variables)] diff --git a/tests/ui/structs-enums/enum-vec-initializer.rs b/tests/ui/structs-enums/enum-vec-initializer.rs index 2fa77ec6ecda5..8c610456c227f 100644 --- a/tests/ui/structs-enums/enum-vec-initializer.rs +++ b/tests/ui/structs-enums/enum-vec-initializer.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 enum Flopsy { Bunny = 2 diff --git a/tests/ui/structs-enums/export-abstract-tag.rs b/tests/ui/structs-enums/export-abstract-tag.rs index ff36fa9590330..e6d359803856d 100644 --- a/tests/ui/structs-enums/export-abstract-tag.rs +++ b/tests/ui/structs-enums/export-abstract-tag.rs @@ -4,7 +4,6 @@ // We can export tags without exporting the variants to create a simple // sort of ADT. -//@ pretty-expanded FIXME #23616 mod foo { pub enum t { t1, } diff --git a/tests/ui/structs-enums/export-tag-variant.rs b/tests/ui/structs-enums/export-tag-variant.rs index bd762a0166e47..c6216d1b567b3 100644 --- a/tests/ui/structs-enums/export-tag-variant.rs +++ b/tests/ui/structs-enums/export-tag-variant.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 mod foo { pub enum t { t1, } diff --git a/tests/ui/structs-enums/foreign-struct.rs b/tests/ui/structs-enums/foreign-struct.rs index 4f2e413ab40cd..f339c191ae806 100644 --- a/tests/ui/structs-enums/foreign-struct.rs +++ b/tests/ui/structs-enums/foreign-struct.rs @@ -4,7 +4,6 @@ // Passing enums by value -//@ pretty-expanded FIXME #23616 pub enum void {} diff --git a/tests/ui/structs-enums/module-qualified-struct-destructure.rs b/tests/ui/structs-enums/module-qualified-struct-destructure.rs index b90acb1b98c0d..9d06980fca97d 100644 --- a/tests/ui/structs-enums/module-qualified-struct-destructure.rs +++ b/tests/ui/structs-enums/module-qualified-struct-destructure.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 mod m { pub struct S { diff --git a/tests/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs b/tests/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs index ea56faef09cd4..fca89728f2106 100644 --- a/tests/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs +++ b/tests/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs @@ -3,7 +3,6 @@ //@ aux-build:namespaced_enum_emulate_flat.rs -//@ pretty-expanded FIXME #23616 extern crate namespaced_enum_emulate_flat; diff --git a/tests/ui/structs-enums/namespaced-enum-emulate-flat.rs b/tests/ui/structs-enums/namespaced-enum-emulate-flat.rs index 4a6352b328a1a..774cfa1a38089 100644 --- a/tests/ui/structs-enums/namespaced-enum-emulate-flat.rs +++ b/tests/ui/structs-enums/namespaced-enum-emulate-flat.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub use Foo::*; use nest::{Bar, D, E, F}; diff --git a/tests/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs b/tests/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs index 4e58c1f717ff2..80d5231fc85ab 100644 --- a/tests/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs +++ b/tests/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:namespaced_enums.rs -//@ pretty-expanded FIXME #23616 extern crate namespaced_enums; diff --git a/tests/ui/structs-enums/namespaced-enum-glob-import.rs b/tests/ui/structs-enums/namespaced-enum-glob-import.rs index d02ee5a122daa..e8a709d5bd0c0 100644 --- a/tests/ui/structs-enums/namespaced-enum-glob-import.rs +++ b/tests/ui/structs-enums/namespaced-enum-glob-import.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 mod m2 { pub enum Foo { diff --git a/tests/ui/structs-enums/namespaced-enums-xcrate.rs b/tests/ui/structs-enums/namespaced-enums-xcrate.rs index b5655e68a47e3..36bc973749c33 100644 --- a/tests/ui/structs-enums/namespaced-enums-xcrate.rs +++ b/tests/ui/structs-enums/namespaced-enums-xcrate.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:namespaced_enums.rs -//@ pretty-expanded FIXME #23616 extern crate namespaced_enums; diff --git a/tests/ui/structs-enums/namespaced-enums.rs b/tests/ui/structs-enums/namespaced-enums.rs index 1ce9319b8ec85..3e2e0b5ffa8fd 100644 --- a/tests/ui/structs-enums/namespaced-enums.rs +++ b/tests/ui/structs-enums/namespaced-enums.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 enum Foo { A, diff --git a/tests/ui/structs-enums/nested-enum-same-names.rs b/tests/ui/structs-enums/nested-enum-same-names.rs index e24073c38e9a4..5ff730aff4415 100644 --- a/tests/ui/structs-enums/nested-enum-same-names.rs +++ b/tests/ui/structs-enums/nested-enum-same-names.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 /* diff --git a/tests/ui/structs-enums/newtype-struct-with-dtor.rs b/tests/ui/structs-enums/newtype-struct-with-dtor.rs index 19672e41c9a30..35476c5ed2d6b 100644 --- a/tests/ui/structs-enums/newtype-struct-with-dtor.rs +++ b/tests/ui/structs-enums/newtype-struct-with-dtor.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_unsafe)] #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 pub struct Fd(u32); diff --git a/tests/ui/structs-enums/newtype-struct-xc-2.rs b/tests/ui/structs-enums/newtype-struct-xc-2.rs index e83025346d75a..a52c41dde2774 100644 --- a/tests/ui/structs-enums/newtype-struct-xc-2.rs +++ b/tests/ui/structs-enums/newtype-struct-xc-2.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:newtype_struct_xc.rs -//@ pretty-expanded FIXME #23616 extern crate newtype_struct_xc; use newtype_struct_xc::Au; diff --git a/tests/ui/structs-enums/newtype-struct-xc.rs b/tests/ui/structs-enums/newtype-struct-xc.rs index 6f90cfe8e4af4..138bf4878f001 100644 --- a/tests/ui/structs-enums/newtype-struct-xc.rs +++ b/tests/ui/structs-enums/newtype-struct-xc.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:newtype_struct_xc.rs -//@ pretty-expanded FIXME #23616 extern crate newtype_struct_xc; diff --git a/tests/ui/structs-enums/simple-generic-tag.rs b/tests/ui/structs-enums/simple-generic-tag.rs index 59521a446f4f9..b78505edd1f2b 100644 --- a/tests/ui/structs-enums/simple-generic-tag.rs +++ b/tests/ui/structs-enums/simple-generic-tag.rs @@ -4,7 +4,6 @@ -//@ pretty-expanded FIXME #23616 enum clam { a(T), } diff --git a/tests/ui/structs-enums/struct-like-variant-construct.rs b/tests/ui/structs-enums/struct-like-variant-construct.rs index 5a49d715b21f4..ec60fef9d3f74 100644 --- a/tests/ui/structs-enums/struct-like-variant-construct.rs +++ b/tests/ui/structs-enums/struct-like-variant-construct.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 enum Foo { Bar { diff --git a/tests/ui/structs-enums/struct-variant-field-visibility.rs b/tests/ui/structs-enums/struct-variant-field-visibility.rs index 02d1ceb051324..a6528f9a2b17e 100644 --- a/tests/ui/structs-enums/struct-variant-field-visibility.rs +++ b/tests/ui/structs-enums/struct-variant-field-visibility.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 mod foo { pub enum Foo { diff --git a/tests/ui/structs-enums/struct_variant_xc.rs b/tests/ui/structs-enums/struct_variant_xc.rs index 4723f2291856d..bf69a2aead93d 100644 --- a/tests/ui/structs-enums/struct_variant_xc.rs +++ b/tests/ui/structs-enums/struct_variant_xc.rs @@ -1,6 +1,5 @@ //@ run-pass //@ aux-build:struct_variant_xc_aux.rs -//@ pretty-expanded FIXME #23616 extern crate struct_variant_xc_aux; diff --git a/tests/ui/structs-enums/tag-exports.rs b/tests/ui/structs-enums/tag-exports.rs index a01b951e675ab..bac428e67233c 100644 --- a/tests/ui/structs-enums/tag-exports.rs +++ b/tests/ui/structs-enums/tag-exports.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 use alder::*; diff --git a/tests/ui/structs-enums/tag-in-block.rs b/tests/ui/structs-enums/tag-in-block.rs index 944a611c71a17..27b48aae51f60 100644 --- a/tests/ui/structs-enums/tag-in-block.rs +++ b/tests/ui/structs-enums/tag-in-block.rs @@ -4,7 +4,6 @@ -//@ pretty-expanded FIXME #23616 fn foo() { fn zed(_z: bar) { } diff --git a/tests/ui/structs-enums/tag-variant-disr-type-mismatch.rs b/tests/ui/structs-enums/tag-variant-disr-type-mismatch.rs index 9205ac81650ec..f4c202d91a7c1 100644 --- a/tests/ui/structs-enums/tag-variant-disr-type-mismatch.rs +++ b/tests/ui/structs-enums/tag-variant-disr-type-mismatch.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 enum color { red = 1, diff --git a/tests/ui/structs-enums/tuple-struct-trivial.rs b/tests/ui/structs-enums/tuple-struct-trivial.rs index 329f80a462ed0..e2395036551e4 100644 --- a/tests/ui/structs-enums/tuple-struct-trivial.rs +++ b/tests/ui/structs-enums/tuple-struct-trivial.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 struct Foo(isize, isize, isize); diff --git a/tests/ui/structs-enums/variant-structs-trivial.rs b/tests/ui/structs-enums/variant-structs-trivial.rs index 8ca86fa35ee86..a7b0575118437 100644 --- a/tests/ui/structs-enums/variant-structs-trivial.rs +++ b/tests/ui/structs-enums/variant-structs-trivial.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 enum Foo { Bar { x: isize }, diff --git a/tests/ui/structs/large-records.rs b/tests/ui/structs/large-records.rs index c78b62596678d..d02a9f488c61b 100644 --- a/tests/ui/structs/large-records.rs +++ b/tests/ui/structs/large-records.rs @@ -5,7 +5,6 @@ -//@ pretty-expanded FIXME #23616 struct Large {a: isize, b: isize, diff --git a/tests/ui/suggestions/auxiliary/issue-61963-1.rs b/tests/ui/suggestions/auxiliary/issue-61963-1.rs index 33e5f9db2c38e..2e7b0dbef1982 100644 --- a/tests/ui/suggestions/auxiliary/issue-61963-1.rs +++ b/tests/ui/suggestions/auxiliary/issue-61963-1.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{Group, TokenStream, TokenTree}; diff --git a/tests/ui/suggestions/auxiliary/issue-61963.rs b/tests/ui/suggestions/auxiliary/issue-61963.rs index bfea8061c4b38..07e6f319585ba 100644 --- a/tests/ui/suggestions/auxiliary/issue-61963.rs +++ b/tests/ui/suggestions/auxiliary/issue-61963.rs @@ -1,7 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::{Group, Spacing, Punct, TokenTree, TokenStream}; diff --git a/tests/ui/suggestions/auxiliary/proc-macro-type-error.rs b/tests/ui/suggestions/auxiliary/proc-macro-type-error.rs index aebc5a6aaa9bf..2930b87d1bbec 100644 --- a/tests/ui/suggestions/auxiliary/proc-macro-type-error.rs +++ b/tests/ui/suggestions/auxiliary/proc-macro-type-error.rs @@ -1,6 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic -#![crate_type = "proc-macro"] #![feature(proc_macro_quote)] extern crate proc_macro; diff --git a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr index a275d8e4e8397..4f92d3aceefe0 100644 --- a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr +++ b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr @@ -8,7 +8,7 @@ LL | const A: i32 = 2; | ------------ missing patterns are not covered because `A` is interpreted as a constant pattern, not a new variable | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html = note: the matched value is of type `i32` help: introduce a variable instead | diff --git a/tests/ui/suggestions/issue-61963.rs b/tests/ui/suggestions/issue-61963.rs index de82700d7e4bc..2fafe629db97e 100644 --- a/tests/ui/suggestions/issue-61963.rs +++ b/tests/ui/suggestions/issue-61963.rs @@ -1,5 +1,5 @@ -//@ aux-build:issue-61963.rs -//@ aux-build:issue-61963-1.rs +//@ proc-macro: issue-61963.rs +//@ proc-macro: issue-61963-1.rs #![deny(bare_trait_objects)] #[macro_use] diff --git a/tests/ui/suggestions/suggest-ref-macro.rs b/tests/ui/suggestions/suggest-ref-macro.rs index e5084e5411529..2f31af33782cb 100644 --- a/tests/ui/suggestions/suggest-ref-macro.rs +++ b/tests/ui/suggestions/suggest-ref-macro.rs @@ -1,5 +1,5 @@ // run-check -//@ aux-build:proc-macro-type-error.rs +//@ proc-macro: proc-macro-type-error.rs extern crate proc_macro_type_error; diff --git a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs index ed262fd39a5a9..c2387bf5411d1 100644 --- a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs +++ b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs @@ -5,8 +5,7 @@ pub trait T { } pub struct Foo { i: Box>, - //~^ ERROR must be specified - //~| ERROR trait takes 2 generic arguments but 4 generic arguments were supplied + //~^ ERROR trait takes 2 generic arguments but 4 generic arguments were supplied } diff --git a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr index 7c84dd4b8ff33..18cf0674f0231 100644 --- a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr +++ b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr @@ -14,19 +14,6 @@ help: replace the generic bounds with the associated types LL | i: Box>, | +++ +++ -error[E0191]: the value of the associated types `C` and `A` in `T` must be specified - --> $DIR/use-type-argument-instead-of-assoc-type.rs:7:16 - | -LL | type A; - | ------ `A` defined here -LL | type B; -LL | type C; - | ------ `C` defined here -... -LL | i: Box>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated types `A`, `C` must be specified - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0107, E0191. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/super.rs b/tests/ui/super.rs index 5d2ea92e921c5..69aff4f98e004 100644 --- a/tests/ui/super.rs +++ b/tests/ui/super.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub mod a { pub fn f() {} diff --git a/tests/ui/svh-add-nothing.rs b/tests/ui/svh-add-nothing.rs index 75ef82d0fa3ee..6e4b9fa7f4c9f 100644 --- a/tests/ui/svh-add-nothing.rs +++ b/tests/ui/svh-add-nothing.rs @@ -4,7 +4,6 @@ //@ aux-build:svh-b.rs //@ aux-build:svh-a-base.rs -//@ pretty-expanded FIXME #23616 extern crate a; extern crate b; diff --git a/tests/ui/swap-overlapping.rs b/tests/ui/swap-overlapping.rs index f7720e0470d74..38d5a8109d1cd 100644 --- a/tests/ui/swap-overlapping.rs +++ b/tests/ui/swap-overlapping.rs @@ -3,7 +3,6 @@ #![allow(dead_code)] // Issue #5041 - avoid overlapping memcpy when src and dest of a swap are the same -//@ pretty-expanded FIXME #23616 use std::ptr; diff --git a/tests/ui/tail-call-arg-leak.rs b/tests/ui/tail-call-arg-leak.rs index 003fb212fcb7a..234924307c3f6 100644 --- a/tests/ui/tail-call-arg-leak.rs +++ b/tests/ui/tail-call-arg-leak.rs @@ -1,6 +1,5 @@ //@ run-pass // use of tail calls causes arg slot leaks, issue #160. -//@ pretty-expanded FIXME #23616 fn inner(dummy: String, b: bool) { if b { return inner(dummy, false); } } diff --git a/tests/ui/thir-print/thir-tree-match.stdout b/tests/ui/thir-print/thir-tree-match.stdout index a9d6985928aad..d56f15fb221c8 100644 --- a/tests/ui/thir-print/thir-tree-match.stdout +++ b/tests/ui/thir-print/thir-tree-match.stdout @@ -92,7 +92,7 @@ body: adt_def: AdtDef { did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) - variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] + variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } args: [] @@ -154,7 +154,7 @@ body: adt_def: AdtDef { did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) - variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] + variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } args: [] @@ -206,7 +206,7 @@ body: adt_def: AdtDef { did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) - variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] + variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } args: [] diff --git a/tests/ui/threads-sendsync/child-outlives-parent.rs b/tests/ui/threads-sendsync/child-outlives-parent.rs index e965bac5713ce..fd6e0c4630d6f 100644 --- a/tests/ui/threads-sendsync/child-outlives-parent.rs +++ b/tests/ui/threads-sendsync/child-outlives-parent.rs @@ -1,7 +1,6 @@ //@ run-pass // Reported as issue #126, child leaks the string. -//@ pretty-expanded FIXME #23616 //@ needs-threads use std::thread; diff --git a/tests/ui/threads-sendsync/send-resource.rs b/tests/ui/threads-sendsync/send-resource.rs index c02a3717d3d75..e4c08dd598f4b 100644 --- a/tests/ui/threads-sendsync/send-resource.rs +++ b/tests/ui/threads-sendsync/send-resource.rs @@ -3,7 +3,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 //@ needs-threads use std::sync::mpsc::channel; diff --git a/tests/ui/threads-sendsync/send-type-inference.rs b/tests/ui/threads-sendsync/send-type-inference.rs index 7608c19b5758e..c6150026c0a26 100644 --- a/tests/ui/threads-sendsync/send-type-inference.rs +++ b/tests/ui/threads-sendsync/send-type-inference.rs @@ -2,7 +2,6 @@ #![allow(unused_must_use)] #![allow(dead_code)] #![allow(unused_mut)] -//@ pretty-expanded FIXME #23616 use std::sync::mpsc::{channel, Sender}; diff --git a/tests/ui/threads-sendsync/sendable-class.rs b/tests/ui/threads-sendsync/sendable-class.rs index 8e5e76d826a06..da61ea6be2cee 100644 --- a/tests/ui/threads-sendsync/sendable-class.rs +++ b/tests/ui/threads-sendsync/sendable-class.rs @@ -6,7 +6,6 @@ // Test that a class with only sendable fields can be sent -//@ pretty-expanded FIXME #23616 use std::sync::mpsc::channel; diff --git a/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs b/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs index a443785a678c7..b2d22631c1a5e 100644 --- a/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs +++ b/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use std::sync; diff --git a/tests/ui/threads-sendsync/sync-send-atomics.rs b/tests/ui/threads-sendsync/sync-send-atomics.rs index f64506af0a3f7..fc7f3971e7600 100644 --- a/tests/ui/threads-sendsync/sync-send-atomics.rs +++ b/tests/ui/threads-sendsync/sync-send-atomics.rs @@ -1,6 +1,5 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 use std::sync::atomic::*; diff --git a/tests/ui/threads-sendsync/sync-send-iterators-in-libcore.rs b/tests/ui/threads-sendsync/sync-send-iterators-in-libcore.rs index 512c81a85fcaf..4baf123295ec6 100644 --- a/tests/ui/threads-sendsync/sync-send-iterators-in-libcore.rs +++ b/tests/ui/threads-sendsync/sync-send-iterators-in-libcore.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(warnings)] diff --git a/tests/ui/threads-sendsync/task-comm-11.rs b/tests/ui/threads-sendsync/task-comm-11.rs index 7c349c716fa35..1585ec3b4f680 100644 --- a/tests/ui/threads-sendsync/task-comm-11.rs +++ b/tests/ui/threads-sendsync/task-comm-11.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_must_use)] -//@ pretty-expanded FIXME #23616 //@ needs-threads use std::sync::mpsc::{channel, Sender}; diff --git a/tests/ui/threads-sendsync/task-comm-15.rs b/tests/ui/threads-sendsync/task-comm-15.rs index 1308446893b86..54e7b08b6a699 100644 --- a/tests/ui/threads-sendsync/task-comm-15.rs +++ b/tests/ui/threads-sendsync/task-comm-15.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_must_use)] //@ needs-threads -//@ pretty-expanded FIXME #23616 use std::sync::mpsc::{channel, Sender}; use std::thread; diff --git a/tests/ui/threads-sendsync/task-comm-17.rs b/tests/ui/threads-sendsync/task-comm-17.rs index a545beee59913..3720826526697 100644 --- a/tests/ui/threads-sendsync/task-comm-17.rs +++ b/tests/ui/threads-sendsync/task-comm-17.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_must_use)] //@ needs-threads -//@ pretty-expanded FIXME #23616 // Issue #922 diff --git a/tests/ui/threads-sendsync/task-life-0.rs b/tests/ui/threads-sendsync/task-life-0.rs index f08a281e76c6d..c2440bc44bc3d 100644 --- a/tests/ui/threads-sendsync/task-life-0.rs +++ b/tests/ui/threads-sendsync/task-life-0.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_must_use)] //@ needs-threads -//@ pretty-expanded FIXME #23616 use std::thread; diff --git a/tests/ui/trailing-comma.rs b/tests/ui/trailing-comma.rs index 95a8b366ad9d2..53b76fb60374a 100644 --- a/tests/ui/trailing-comma.rs +++ b/tests/ui/trailing-comma.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn f(_: T,) {} diff --git a/tests/ui/traits/astconv-cycle-between-and-type.rs b/tests/ui/traits/astconv-cycle-between-and-type.rs index 1d45028657e08..cb2e172f02ec5 100644 --- a/tests/ui/traits/astconv-cycle-between-and-type.rs +++ b/tests/ui/traits/astconv-cycle-between-and-type.rs @@ -4,7 +4,6 @@ // carries a predicate that references the trait (`u32 : Trait1`, // substituted). -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/traits/bad-sized.rs b/tests/ui/traits/bad-sized.rs index a15219679788d..7e4f37e4ae26c 100644 --- a/tests/ui/traits/bad-sized.rs +++ b/tests/ui/traits/bad-sized.rs @@ -3,7 +3,4 @@ trait Trait {} pub fn main() { let x: Vec = Vec::new(); //~^ ERROR only auto traits can be used as additional traits in a trait object - //~| ERROR the size for values of type - //~| ERROR the size for values of type - //~| ERROR the size for values of type } diff --git a/tests/ui/traits/bad-sized.stderr b/tests/ui/traits/bad-sized.stderr index 4c1835dfed085..0e82867ef03b0 100644 --- a/tests/ui/traits/bad-sized.stderr +++ b/tests/ui/traits/bad-sized.stderr @@ -9,37 +9,6 @@ LL | let x: Vec = Vec::new(); = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Trait + Sized {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit -error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/bad-sized.rs:4:12 - | -LL | let x: Vec = Vec::new(); - | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `dyn Trait` -note: required by an implicit `Sized` bound in `Vec` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - -error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/bad-sized.rs:4:37 - | -LL | let x: Vec = Vec::new(); - | ^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `dyn Trait` -note: required by a bound in `Vec::::new` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - -error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/bad-sized.rs:4:37 - | -LL | let x: Vec = Vec::new(); - | ^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `dyn Trait` -note: required by an implicit `Sized` bound in `Vec` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - -error: aborting due to 4 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0225, E0277. -For more information about an error, try `rustc --explain E0225`. +For more information about this error, try `rustc --explain E0225`. diff --git a/tests/ui/traits/bound/basic.rs b/tests/ui/traits/bound/basic.rs index 85157fdbf62f6..acd8056bee083 100644 --- a/tests/ui/traits/bound/basic.rs +++ b/tests/ui/traits/bound/basic.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(unconditional_recursion)] -//@ pretty-expanded FIXME #23616 trait Foo { } diff --git a/tests/ui/traits/bound/impl-comparison-duplicates.rs b/tests/ui/traits/bound/impl-comparison-duplicates.rs index 68b64de3e96d5..14553ed27b7a4 100644 --- a/tests/ui/traits/bound/impl-comparison-duplicates.rs +++ b/tests/ui/traits/bound/impl-comparison-duplicates.rs @@ -3,7 +3,6 @@ // trait exactly, as long as the implementation doesn't demand *more* bounds // than the trait. -//@ pretty-expanded FIXME #23616 trait A { fn foo(&self); diff --git a/tests/ui/traits/bound/multiple.rs b/tests/ui/traits/bound/multiple.rs index 385fa8851c124..30f229b285aaa 100644 --- a/tests/ui/traits/bound/multiple.rs +++ b/tests/ui/traits/bound/multiple.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn f(_: T) { } diff --git a/tests/ui/traits/bound/on-structs-and-enums-rpass.rs b/tests/ui/traits/bound/on-structs-and-enums-rpass.rs index 25e1b6b4bc35b..8dd243015057e 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-rpass.rs +++ b/tests/ui/traits/bound/on-structs-and-enums-rpass.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 trait U {} trait T { fn get(self) -> X; } diff --git a/tests/ui/traits/bound/recursion.rs b/tests/ui/traits/bound/recursion.rs index 1d9832ac917d9..90cdfed0c9915 100644 --- a/tests/ui/traits/bound/recursion.rs +++ b/tests/ui/traits/bound/recursion.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait I { fn i(&self) -> Self; } diff --git a/tests/ui/traits/bug-7295.rs b/tests/ui/traits/bug-7295.rs index bd4e126c22004..a1cbcf1601e95 100644 --- a/tests/ui/traits/bug-7295.rs +++ b/tests/ui/traits/bug-7295.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub trait Foo { fn func1(&self, t: U, w: T); diff --git a/tests/ui/traits/cache-issue-18209.rs b/tests/ui/traits/cache-issue-18209.rs index e0c309ed97d24..6a027d6b3f3dd 100644 --- a/tests/ui/traits/cache-issue-18209.rs +++ b/tests/ui/traits/cache-issue-18209.rs @@ -4,7 +4,6 @@ // // See issue #18209. -//@ pretty-expanded FIXME #23616 pub trait Foo { fn load_from() -> Box; diff --git a/tests/ui/traits/composition-trivial.rs b/tests/ui/traits/composition-trivial.rs index 26f7673e61650..8a5a36f4cfde2 100644 --- a/tests/ui/traits/composition-trivial.rs +++ b/tests/ui/traits/composition-trivial.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait Foo { fn foo(&self); diff --git a/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr index 9ae1ed18e3511..1e48a0331cca2 100644 --- a/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr +++ b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr @@ -1,12 +1,3 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/call-const-trait-method-pass.rs:7:12 - | -LL | impl const std::ops::Add for Int { - | ^^^^^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` --> $DIR/call-const-trait-method-pass.rs:15:12 | @@ -16,14 +7,6 @@ LL | impl const PartialEq for Int { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0015]: cannot call non-const operator in constants - --> $DIR/call-const-trait-method-pass.rs:39:22 - | -LL | const ADD_INT: Int = Int(1i32) + Int(2i32); - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants - error[E0015]: cannot call non-const fn `::eq` in constant functions --> $DIR/call-const-trait-method-pass.rs:20:15 | @@ -32,6 +15,6 @@ LL | !self.eq(other) | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/const-and-non-const-impl.stderr b/tests/ui/traits/const-traits/const-and-non-const-impl.stderr index cf7af41cd4e47..4eb1517734700 100644 --- a/tests/ui/traits/const-traits/const-and-non-const-impl.stderr +++ b/tests/ui/traits/const-traits/const-and-non-const-impl.stderr @@ -1,21 +1,3 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/const-and-non-const-impl.rs:7:12 - | -LL | impl const std::ops::Add for i32 { - | ^^^^^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/const-and-non-const-impl.rs:23:12 - | -LL | impl const std::ops::Add for Int { - | ^^^^^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - error[E0119]: conflicting implementations of trait `Add` for type `Int` --> $DIR/const-and-non-const-impl.rs:23:1 | @@ -38,7 +20,7 @@ LL | impl const std::ops::Add for i32 { = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules = note: define and implement a trait or new type instead -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0117, E0119. For more information about an error, try `rustc --explain E0117`. diff --git a/tests/ui/traits/const-traits/const-drop-bound.rs b/tests/ui/traits/const-traits/const-drop-bound.rs index b0790f86ef54f..398fb39064055 100644 --- a/tests/ui/traits/const-traits/const-drop-bound.rs +++ b/tests/ui/traits/const-traits/const-drop-bound.rs @@ -2,7 +2,7 @@ // FIXME check-pass #![feature(const_trait_impl)] -#![feature(const_precise_live_drops)] +#![feature(const_precise_live_drops, const_destruct)] use std::marker::Destruct; diff --git a/tests/ui/traits/const-traits/const-drop-bound.stderr b/tests/ui/traits/const-traits/const-drop-bound.stderr index 3f71864543337..60718cc84c101 100644 --- a/tests/ui/traits/const-traits/const-drop-bound.stderr +++ b/tests/ui/traits/const-traits/const-drop-bound.stderr @@ -1,51 +1,9 @@ -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-bound.rs:9:61 +error[E0277]: the trait bound `Foo: ~const Destruct` is not satisfied + --> $DIR/const-drop-bound.rs:23:5 | -LL | const fn foo(res: Result) -> Option where E: ~const Destruct { - | ^^^^^^ +LL | foo(res) + | ^^^^^^^^ -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-bound.rs:9:61 - | -LL | const fn foo(res: Result) -> Option where E: ~const Destruct { - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-bound.rs:20:8 - | -LL | T: ~const Destruct, - | ^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-bound.rs:21:8 - | -LL | E: ~const Destruct, - | ^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-bound.rs:20:8 - | -LL | T: ~const Destruct, - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-bound.rs:21:8 - | -LL | E: ~const Destruct, - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `E` cannot be evaluated at compile-time - --> $DIR/const-drop-bound.rs:12:13 - | -LL | Err(_e) => None, - | ^^ the destructor for this type cannot be evaluated in constant functions - -error: aborting due to 7 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0493`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr index 7529af9293d44..bb9966c7ec393 100644 --- a/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr @@ -1,26 +1,13 @@ -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop-fail-2.rs:23:25 +error[E0277]: the trait bound `ConstDropImplWithBounds: const Destruct` is not satisfied + --> $DIR/const-drop-fail-2.rs:31:15 | -LL | impl const Drop for ConstDropImplWithBounds { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-fail-2.rs:29:26 - | -LL | const fn check(_: T) {} - | ^^^^^^^^ - -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop-fail-2.rs:39:25 - | -LL | impl const Drop for ConstDropImplWithNonConstBounds { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change +LL | const _: () = check::>( + | _______________^ +LL | | +LL | | ConstDropImplWithBounds(PhantomData) +LL | | ); + | |_^ -error: aborting due to 3 previous errors +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.rs b/tests/ui/traits/const-traits/const-drop-fail-2.rs index 5d7bafa38871f..1bcc87e907037 100644 --- a/tests/ui/traits/const-traits/const-drop-fail-2.rs +++ b/tests/ui/traits/const-traits/const-drop-fail-2.rs @@ -1,6 +1,7 @@ -//@ known-bug: #110395 -#![feature(const_trait_impl)] -// #![cfg_attr(precise, feature(const_precise_live_drops))] +//@ revisions: stock precise + +#![feature(const_trait_impl, const_destruct)] +#![cfg_attr(precise, feature(const_precise_live_drops))] use std::marker::{Destruct, PhantomData}; @@ -19,9 +20,7 @@ impl A for NonTrivialDrop {} const fn check(_: T) {} - -/* FIXME(const_trait_impl) -struct ConstDropImplWithBounds(PhantomData); +struct ConstDropImplWithBounds(PhantomData); impl const Drop for ConstDropImplWithBounds { fn drop(&mut self) { @@ -30,9 +29,9 @@ impl const Drop for ConstDropImplWithBounds { } const _: () = check::>( + //~^ ERROR the trait bound ConstDropImplWithBounds(PhantomData) ); -*/ struct ConstDropImplWithNonConstBounds(PhantomData); diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stderr deleted file mode 100644 index fde106599c236..0000000000000 --- a/tests/ui/traits/const-traits/const-drop-fail-2.stderr +++ /dev/null @@ -1,41 +0,0 @@ -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop-fail-2.rs:39:25 - | -LL | impl const Drop for ConstDropImplWithNonConstBounds { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-fail-2.rs:20:19 - | -LL | const fn check(_: T) {} - | ^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-fail-2.rs:20:19 - | -LL | const fn check(_: T) {} - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0277]: the trait bound `T: ~const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:41:9 - | -LL | T::a(); - | ^^^^^^ - -error[E0493]: destructor of `T` cannot be evaluated at compile-time - --> $DIR/const-drop-fail-2.rs:20:36 - | -LL | const fn check(_: T) {} - | ^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constant functions - -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0277, E0493. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr index 7529af9293d44..bb9966c7ec393 100644 --- a/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr @@ -1,26 +1,13 @@ -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop-fail-2.rs:23:25 +error[E0277]: the trait bound `ConstDropImplWithBounds: const Destruct` is not satisfied + --> $DIR/const-drop-fail-2.rs:31:15 | -LL | impl const Drop for ConstDropImplWithBounds { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-fail-2.rs:29:26 - | -LL | const fn check(_: T) {} - | ^^^^^^^^ - -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop-fail-2.rs:39:25 - | -LL | impl const Drop for ConstDropImplWithNonConstBounds { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change +LL | const _: () = check::>( + | _______________^ +LL | | +LL | | ConstDropImplWithBounds(PhantomData) +LL | | ); + | |_^ -error: aborting due to 3 previous errors +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const-drop-fail.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr index 859fdfae81aef..67e774fbd0597 100644 --- a/tests/ui/traits/const-traits/const-drop-fail.precise.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr @@ -1,45 +1,4 @@ -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop-fail.rs:19:12 - | -LL | impl const Drop for ConstImplWithDropGlue { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-fail.rs:23:19 - | -LL | const fn check(_: T) {} - | ^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-fail.rs:23:19 - | -LL | const fn check(_: T) {} - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `T` cannot be evaluated at compile-time - --> $DIR/const-drop-fail.rs:23:36 - | -LL | const fn check(_: T) {} - | ^ the destructor for this type cannot be evaluated in constant functions - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: calling non-const function `::drop` - | -note: inside `std::ptr::drop_in_place:: - shim(Some(NonTrivialDrop))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `check::` - --> $DIR/const-drop-fail.rs:23:43 - | -LL | const fn check(_: T) {} - | ^ -note: inside `_` +error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied --> $DIR/const-drop-fail.rs:27:23 | LL | const _: () = check($exp); @@ -50,23 +9,10 @@ LL | | NonTrivialDrop, LL | | ConstImplWithDropGlue(NonTrivialDrop), LL | | } | |_- in this macro invocation + | = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: calling non-const function `::drop` - | -note: inside `std::ptr::drop_in_place:: - shim(Some(NonTrivialDrop))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `std::ptr::drop_in_place:: - shim(Some(ConstImplWithDropGlue))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `check::` - --> $DIR/const-drop-fail.rs:23:43 - | -LL | const fn check(_: T) {} - | ^ -note: inside `_` +error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied --> $DIR/const-drop-fail.rs:27:23 | LL | const _: () = check($exp); @@ -77,9 +23,10 @@ LL | | NonTrivialDrop, LL | | ConstImplWithDropGlue(NonTrivialDrop), LL | | } | |_- in this macro invocation + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 6 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0080, E0493. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const-drop-fail.rs b/tests/ui/traits/const-traits/const-drop-fail.rs index 5a98c32e83887..08435266e1f80 100644 --- a/tests/ui/traits/const-traits/const-drop-fail.rs +++ b/tests/ui/traits/const-traits/const-drop-fail.rs @@ -1,7 +1,7 @@ -//@ known-bug: #110395 - +//@ compile-flags: -Znext-solver //@ revisions: stock precise -#![feature(const_trait_impl)] + +#![feature(const_trait_impl, const_destruct)] #![cfg_attr(precise, feature(const_precise_live_drops))] use std::marker::{Destruct, PhantomData}; @@ -25,6 +25,8 @@ const fn check(_: T) {} macro_rules! check_all { ($($exp:expr),*$(,)?) => {$( const _: () = check($exp); + //~^ ERROR the trait bound `NonTrivialDrop: const Destruct` is not satisfied + //~| ERROR the trait bound `NonTrivialDrop: const Destruct` is not satisfied )*}; } diff --git a/tests/ui/traits/const-traits/const-drop-fail.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail.stock.stderr index 20dea28922b6a..67e774fbd0597 100644 --- a/tests/ui/traits/const-traits/const-drop-fail.stock.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail.stock.stderr @@ -1,34 +1,32 @@ -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop-fail.rs:19:12 +error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied + --> $DIR/const-drop-fail.rs:27:23 | -LL | impl const Drop for ConstImplWithDropGlue { - | ^^^^ +LL | const _: () = check($exp); + | ^^^^^^^^^^^ +... +LL | / check_all! { +LL | | NonTrivialDrop, +LL | | ConstImplWithDropGlue(NonTrivialDrop), +LL | | } + | |_- in this macro invocation | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change + = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-fail.rs:23:19 +error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied + --> $DIR/const-drop-fail.rs:27:23 | -LL | const fn check(_: T) {} - | ^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop-fail.rs:23:19 - | -LL | const fn check(_: T) {} - | ^^^^^^ +LL | const _: () = check($exp); + | ^^^^^^^^^^^ +... +LL | / check_all! { +LL | | NonTrivialDrop, +LL | | ConstImplWithDropGlue(NonTrivialDrop), +LL | | } + | |_- in this macro invocation | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0493]: destructor of `T` cannot be evaluated at compile-time - --> $DIR/const-drop-fail.rs:23:36 - | -LL | const fn check(_: T) {} - | ^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constant functions - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0493`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const-drop.precise.stderr b/tests/ui/traits/const-traits/const-drop.precise.stderr deleted file mode 100644 index ed90b234761ad..0000000000000 --- a/tests/ui/traits/const-traits/const-drop.precise.stderr +++ /dev/null @@ -1,90 +0,0 @@ -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop.rs:12:16 - | -LL | impl<'a> const Drop for S<'a> { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop.rs:46:16 - | -LL | impl const Drop for ConstDrop { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop.rs:67:37 - | -LL | impl const Drop for ConstDropWithBound { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop.rs:75:30 - | -LL | impl const Drop for ConstDropWithNonconstBound { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop.rs:18:15 - | -LL | const fn a(_: T) {} - | ^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop.rs:18:15 - | -LL | const fn a(_: T) {} - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0277]: the trait bound `T: const SomeTrait` is not satisfied - --> $DIR/const-drop.rs:67:46 - | -LL | impl const Drop for ConstDropWithBound { - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: required by a bound in `t::ConstDropWithBound` - --> $DIR/const-drop.rs:65:38 - | -LL | pub struct ConstDropWithBound(pub core::marker::PhantomData); - | ^^^^^ required by this bound in `ConstDropWithBound` - -error[E0277]: the trait bound `T: const SomeTrait` is not satisfied - --> $DIR/const-drop.rs:68:22 - | -LL | fn drop(&mut self) { - | ^^^^ - | -note: required by a bound in `t::ConstDropWithBound` - --> $DIR/const-drop.rs:65:38 - | -LL | pub struct ConstDropWithBound(pub core::marker::PhantomData); - | ^^^^^ required by this bound in `ConstDropWithBound` - -error[E0493]: destructor of `T` cannot be evaluated at compile-time - --> $DIR/const-drop.rs:18:32 - | -LL | const fn a(_: T) {} - | ^ the destructor for this type cannot be evaluated in constant functions - -error[E0277]: the trait bound `T: ~const SomeTrait` is not satisfied - --> $DIR/const-drop.rs:69:13 - | -LL | T::foo(); - | ^^^^^^^^ - -error: aborting due to 10 previous errors - -Some errors have detailed explanations: E0277, E0493. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const-drop.rs b/tests/ui/traits/const-traits/const-drop.rs index 5bd81fb3ab631..e2d87aeff47fb 100644 --- a/tests/ui/traits/const-traits/const-drop.rs +++ b/tests/ui/traits/const-traits/const-drop.rs @@ -1,7 +1,8 @@ -// FIXME run-pass -//@ known-bug: #110395 +//@ run-pass +//@ compile-flags: -Znext-solver //@ revisions: stock precise -#![feature(const_trait_impl)] + +#![feature(const_trait_impl, const_destruct)] #![feature(never_type)] #![cfg_attr(precise, feature(const_precise_live_drops))] @@ -64,7 +65,7 @@ mod t { pub struct ConstDropWithBound(pub core::marker::PhantomData); - impl const Drop for ConstDropWithBound { + impl const Drop for ConstDropWithBound { fn drop(&mut self) { T::foo(); } diff --git a/tests/ui/traits/const-traits/const-drop.stock.stderr b/tests/ui/traits/const-traits/const-drop.stock.stderr deleted file mode 100644 index 2b46b048e9095..0000000000000 --- a/tests/ui/traits/const-traits/const-drop.stock.stderr +++ /dev/null @@ -1,92 +0,0 @@ -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop.rs:12:16 - | -LL | impl<'a> const Drop for S<'a> { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop.rs:46:16 - | -LL | impl const Drop for ConstDrop { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop.rs:67:37 - | -LL | impl const Drop for ConstDropWithBound { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` - --> $DIR/const-drop.rs:75:30 - | -LL | impl const Drop for ConstDropWithNonconstBound { - | ^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop.rs:18:15 - | -LL | const fn a(_: T) {} - | ^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-drop.rs:18:15 - | -LL | const fn a(_: T) {} - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0277]: the trait bound `T: const SomeTrait` is not satisfied - --> $DIR/const-drop.rs:67:46 - | -LL | impl const Drop for ConstDropWithBound { - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: required by a bound in `t::ConstDropWithBound` - --> $DIR/const-drop.rs:65:38 - | -LL | pub struct ConstDropWithBound(pub core::marker::PhantomData); - | ^^^^^ required by this bound in `ConstDropWithBound` - -error[E0277]: the trait bound `T: const SomeTrait` is not satisfied - --> $DIR/const-drop.rs:68:22 - | -LL | fn drop(&mut self) { - | ^^^^ - | -note: required by a bound in `t::ConstDropWithBound` - --> $DIR/const-drop.rs:65:38 - | -LL | pub struct ConstDropWithBound(pub core::marker::PhantomData); - | ^^^^^ required by this bound in `ConstDropWithBound` - -error[E0493]: destructor of `T` cannot be evaluated at compile-time - --> $DIR/const-drop.rs:18:32 - | -LL | const fn a(_: T) {} - | ^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constant functions - -error[E0277]: the trait bound `T: ~const SomeTrait` is not satisfied - --> $DIR/const-drop.rs:69:13 - | -LL | T::foo(); - | ^^^^^^^^ - -error: aborting due to 10 previous errors - -Some errors have detailed explanations: E0277, E0493. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs b/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs index 209a111c24366..aaa61e21155f4 100644 --- a/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs +++ b/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs @@ -11,7 +11,8 @@ rustc_attrs, fundamental, marker_trait_attr, - const_trait_impl + const_trait_impl, + const_destruct )] #![allow(internal_features, incomplete_features)] #![no_std] @@ -444,12 +445,12 @@ impl Deref for Ref<'_, T> { #[lang = "clone"] #[rustc_trivial_field_reads] -// FIXME: #[const_trait] +#[const_trait] pub trait Clone: Sized { fn clone(&self) -> Self; fn clone_from(&mut self, source: &Self) where - // FIXME: Self: ~const Destruct, + Self: ~const Destruct, { *self = source.clone() } @@ -458,7 +459,7 @@ pub trait Clone: Sized { #[lang = "structural_peq"] pub trait StructuralPartialEq {} -// FIXME: const fn drop(_: T) {} +pub const fn drop(_: T) {} #[rustc_intrinsic_must_be_overridden] #[rustc_intrinsic] diff --git a/tests/ui/traits/const-traits/effects/dont-prefer-param-env-for-infer-self-ty.rs b/tests/ui/traits/const-traits/effects/dont-prefer-param-env-for-infer-self-ty.rs new file mode 100644 index 0000000000000..08dcd7d80b344 --- /dev/null +++ b/tests/ui/traits/const-traits/effects/dont-prefer-param-env-for-infer-self-ty.rs @@ -0,0 +1,16 @@ +//@ check-pass + +#![feature(const_trait_impl)] + +#[const_trait] +trait Foo {} + +impl const Foo for (T,) where T: ~const Foo {} + +const fn needs_const_foo(_: impl ~const Foo + Copy) {} + +const fn test(t: T) { + needs_const_foo((t,)); +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/effects/minicore-drop-fail.rs b/tests/ui/traits/const-traits/effects/minicore-drop-fail.rs new file mode 100644 index 0000000000000..274e5db21c4f6 --- /dev/null +++ b/tests/ui/traits/const-traits/effects/minicore-drop-fail.rs @@ -0,0 +1,37 @@ +//@ aux-build:minicore.rs +//@ compile-flags: --crate-type=lib -Znext-solver + +#![feature(no_core, const_trait_impl, const_destruct)] +#![no_std] +#![no_core] + +extern crate minicore; +use minicore::*; + +struct Contains(T); + +struct NotDropImpl; +impl Drop for NotDropImpl { + fn drop(&mut self) {} +} + +#[const_trait] trait Foo {} +impl Foo for () {} + +struct Conditional(T); +impl const Drop for Conditional where T: ~const Foo { + fn drop(&mut self) {} +} + +const fn test() { + let _ = NotDropImpl; + //~^ ERROR destructor of `NotDropImpl` cannot be evaluated at compile-time + let _ = Contains(NotDropImpl); + //~^ ERROR destructor of `Contains` cannot be evaluated at compile-time + let _ = Conditional(()); + //~^ ERROR destructor of `Conditional<()>` cannot be evaluated at compile-time +} + +const fn drop_arbitrary(_: T) { + //~^ ERROR destructor of `T` cannot be evaluated at compile-time +} diff --git a/tests/ui/traits/const-traits/effects/minicore-drop-fail.stderr b/tests/ui/traits/const-traits/effects/minicore-drop-fail.stderr new file mode 100644 index 0000000000000..12d1877a18aba --- /dev/null +++ b/tests/ui/traits/const-traits/effects/minicore-drop-fail.stderr @@ -0,0 +1,36 @@ +error[E0493]: destructor of `NotDropImpl` cannot be evaluated at compile-time + --> $DIR/minicore-drop-fail.rs:27:13 + | +LL | let _ = NotDropImpl; + | ^^^^^^^^^^^- value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions + +error[E0493]: destructor of `Contains` cannot be evaluated at compile-time + --> $DIR/minicore-drop-fail.rs:29:13 + | +LL | let _ = Contains(NotDropImpl); + | ^^^^^^^^^^^^^^^^^^^^^- value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions + +error[E0493]: destructor of `Conditional<()>` cannot be evaluated at compile-time + --> $DIR/minicore-drop-fail.rs:31:13 + | +LL | let _ = Conditional(()); + | ^^^^^^^^^^^^^^^- value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions + +error[E0493]: destructor of `T` cannot be evaluated at compile-time + --> $DIR/minicore-drop-fail.rs:35:28 + | +LL | const fn drop_arbitrary(_: T) { + | ^ the destructor for this type cannot be evaluated in constant functions +LL | +LL | } + | - value is dropped here + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.no.stderr b/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.no.stderr new file mode 100644 index 0000000000000..218f3661e39d4 --- /dev/null +++ b/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.no.stderr @@ -0,0 +1,15 @@ +error[E0493]: destructor of `ConstDrop` cannot be evaluated at compile-time + --> $DIR/minicore-drop-without-feature-gate.rs:24:13 + | +LL | let _ = ConstDrop; + | ^^^^^^^^^- value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions + | + = note: see issue #133214 for more information + = help: add `#![feature(const_destruct)]` 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 E0493`. diff --git a/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.rs b/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.rs new file mode 100644 index 0000000000000..e75bf3db007f0 --- /dev/null +++ b/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.rs @@ -0,0 +1,26 @@ +//@ aux-build:minicore.rs +//@ compile-flags: --crate-type=lib -Znext-solver +//@ revisions: yes no +//@[yes] check-pass +// gate-test-const_destruct + +#![feature(no_core, const_trait_impl)] +#![cfg_attr(yes, feature(const_destruct))] +#![no_std] +#![no_core] + +extern crate minicore; +use minicore::*; + +struct ConstDrop; +impl const Drop for ConstDrop { + fn drop(&mut self) {} +} + +// Make sure that `ConstDrop` can only be dropped when the `const_drop` +// feature gate is enabled. Otherwise, we should error if there is a drop +// impl at all. +const fn test() { + let _ = ConstDrop; + //[no]~^ ERROR destructor of `ConstDrop` cannot be evaluated at compile-time +} diff --git a/tests/ui/traits/const-traits/generic-bound.rs b/tests/ui/traits/const-traits/generic-bound.rs index 620e3259917eb..5eb236acde22c 100644 --- a/tests/ui/traits/const-traits/generic-bound.rs +++ b/tests/ui/traits/const-traits/generic-bound.rs @@ -1,4 +1,4 @@ -//@ known-bug: #110395 +//@ check-pass #![feature(const_trait_impl)] @@ -26,5 +26,6 @@ const fn twice(arg: S) -> S { } fn main() { + const _: S = twice(S(PhantomData)); let _ = twice(S(PhantomData::)); } diff --git a/tests/ui/traits/const-traits/generic-bound.stderr b/tests/ui/traits/const-traits/generic-bound.stderr deleted file mode 100644 index 0444c3195773e..0000000000000 --- a/tests/ui/traits/const-traits/generic-bound.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/generic-bound.rs:16:15 - | -LL | impl const std::ops::Add for S { - | ^^^^^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error[E0015]: cannot call non-const operator in constant functions - --> $DIR/generic-bound.rs:25:5 - | -LL | arg + arg - | ^^^^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/issue-92111.rs b/tests/ui/traits/const-traits/issue-92111.rs index 64fa32156c39a..c8db5cc9e7ad8 100644 --- a/tests/ui/traits/const-traits/issue-92111.rs +++ b/tests/ui/traits/const-traits/issue-92111.rs @@ -1,9 +1,6 @@ -// Regression test for #92111. -// -//@ known-bug: #110395 -// FIXME check-pass +//@ check-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_destruct)] use std::marker::Destruct; diff --git a/tests/ui/traits/const-traits/issue-92111.stderr b/tests/ui/traits/const-traits/issue-92111.stderr deleted file mode 100644 index 51c6a22b43b3d..0000000000000 --- a/tests/ui/traits/const-traits/issue-92111.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/issue-92111.rs:20:15 - | -LL | const fn a(t: T) {} - | ^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/issue-92111.rs:20:15 - | -LL | const fn a(t: T) {} - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `T` cannot be evaluated at compile-time - --> $DIR/issue-92111.rs:20:32 - | -LL | const fn a(t: T) {} - | ^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constant functions - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/traits/const-traits/syntax.rs b/tests/ui/traits/const-traits/syntax.rs index 1064713ac592c..cfac6e0a93e38 100644 --- a/tests/ui/traits/const-traits/syntax.rs +++ b/tests/ui/traits/const-traits/syntax.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Z parse-only +//@ compile-flags: -Z parse-crate-root-only //@ check-pass #![feature(const_trait_bound_opt_out)] diff --git a/tests/ui/traits/const-traits/tilde-const-syntax.rs b/tests/ui/traits/const-traits/tilde-const-syntax.rs index d65ecae3d067c..f9944c426ccee 100644 --- a/tests/ui/traits/const-traits/tilde-const-syntax.rs +++ b/tests/ui/traits/const-traits/tilde-const-syntax.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Z parse-only +//@ compile-flags: -Z parse-crate-root-only //@ check-pass #![feature(const_trait_impl)] diff --git a/tests/ui/traits/const-traits/tilde-twice.rs b/tests/ui/traits/const-traits/tilde-twice.rs index c3f9f8e676480..d341513b8a819 100644 --- a/tests/ui/traits/const-traits/tilde-twice.rs +++ b/tests/ui/traits/const-traits/tilde-twice.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Z parse-only +//@ compile-flags: -Z parse-crate-root-only #![feature(const_trait_impl)] diff --git a/tests/ui/traits/cycle-generic-bound.rs b/tests/ui/traits/cycle-generic-bound.rs index dec51ef35bc04..0fb0f74a6eac5 100644 --- a/tests/ui/traits/cycle-generic-bound.rs +++ b/tests/ui/traits/cycle-generic-bound.rs @@ -1,7 +1,6 @@ //@ check-pass // Regression test for #15477. This test just needs to compile. -//@ pretty-expanded FIXME #23616 trait Chromosome> { } diff --git a/tests/ui/traits/cycle-type-trait.rs b/tests/ui/traits/cycle-type-trait.rs index f1125c9274aaf..3a6cd2eccc250 100644 --- a/tests/ui/traits/cycle-type-trait.rs +++ b/tests/ui/traits/cycle-type-trait.rs @@ -3,7 +3,6 @@ // Test a case where a supertrait references a type that references // the original trait. This poses no problem at the moment. -//@ pretty-expanded FIXME #23616 trait Chromosome: Get> { } diff --git a/tests/ui/traits/default-method/mut.rs b/tests/ui/traits/default-method/mut.rs index fd8b788035f87..1130ca0b4be25 100644 --- a/tests/ui/traits/default-method/mut.rs +++ b/tests/ui/traits/default-method/mut.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(unused_assignments)] -//@ pretty-expanded FIXME #23616 #![allow(unused_variables)] diff --git a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs index a08407683d8fe..85c70a21f6839 100644 --- a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs +++ b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs @@ -1,5 +1,6 @@ fn function() { foo == 2; //~ ERROR cannot find value `foo` in this scope [E0425] + //~^ ERROR mismatched types } fn main() {} diff --git a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr index 2da731dcc4b14..8010c0842ba97 100644 --- a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr +++ b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr @@ -4,6 +4,18 @@ error[E0425]: cannot find value `foo` in this scope LL | foo == 2; | ^^^ not found in this scope -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs:2:12 + | +LL | fn function() { + | - expected this type parameter +LL | foo == 2; + | ^ expected type parameter `T`, found integer + | + = note: expected type parameter `T` + found type `{integer}` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0308, E0425. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/early-vtbl-resolution.rs b/tests/ui/traits/early-vtbl-resolution.rs index f2dd2b8a6609a..bf3cc04cdc227 100644 --- a/tests/ui/traits/early-vtbl-resolution.rs +++ b/tests/ui/traits/early-vtbl-resolution.rs @@ -2,7 +2,6 @@ #![allow(non_camel_case_types)] #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 trait thing { fn foo(&self) -> Option; diff --git a/tests/ui/traits/false-ambiguity-where-clause-builtin-bound.rs b/tests/ui/traits/false-ambiguity-where-clause-builtin-bound.rs index b41d719d0ec4f..ab9d10d14fdd0 100644 --- a/tests/ui/traits/false-ambiguity-where-clause-builtin-bound.rs +++ b/tests/ui/traits/false-ambiguity-where-clause-builtin-bound.rs @@ -3,7 +3,6 @@ // between the builtin rules for Sized and the where clause. Issue // #20959. -//@ pretty-expanded FIXME #23616 fn foo(x: Option) where Option : Sized diff --git a/tests/ui/traits/impl-2.rs b/tests/ui/traits/impl-2.rs index 6cc702800e392..c6f60a9081cc4 100644 --- a/tests/ui/traits/impl-2.rs +++ b/tests/ui/traits/impl-2.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_snake_case)] -//@ pretty-expanded FIXME #23616 pub mod Foo { pub trait Trait { diff --git a/tests/ui/traits/impl-implicit-trait.rs b/tests/ui/traits/impl-implicit-trait.rs index 03c1ec8a53b2e..ff62858dcc2ff 100644 --- a/tests/ui/traits/impl-implicit-trait.rs +++ b/tests/ui/traits/impl-implicit-trait.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -//@ pretty-expanded FIXME #23616 enum option_ { none_, diff --git a/tests/ui/traits/inheritance/num.rs b/tests/ui/traits/inheritance/num.rs index 339ff04ff530d..58564147a2929 100644 --- a/tests/ui/traits/inheritance/num.rs +++ b/tests/ui/traits/inheritance/num.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 pub trait NumExt: PartialEq + PartialOrd {} diff --git a/tests/ui/traits/inheritance/num0.rs b/tests/ui/traits/inheritance/num0.rs index a2ebc5c62d787..a170388b49453 100644 --- a/tests/ui/traits/inheritance/num0.rs +++ b/tests/ui/traits/inheritance/num0.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] // Extending Num and using inherited static methods -//@ pretty-expanded FIXME #23616 pub trait NumCast: Sized { fn from(i: i32) -> Option; diff --git a/tests/ui/traits/inheritance/num1.rs b/tests/ui/traits/inheritance/num1.rs index 9fa2cde6d2222..d02cff70842a6 100644 --- a/tests/ui/traits/inheritance/num1.rs +++ b/tests/ui/traits/inheritance/num1.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub trait NumCast: Sized { fn from(i: i32) -> Option; diff --git a/tests/ui/traits/inheritance/num5.rs b/tests/ui/traits/inheritance/num5.rs index b38fb441cff4e..8ac4c86c39215 100644 --- a/tests/ui/traits/inheritance/num5.rs +++ b/tests/ui/traits/inheritance/num5.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub trait NumCast: Sized { fn from(i: i32) -> Option; diff --git a/tests/ui/traits/issue-22019.rs b/tests/ui/traits/issue-22019.rs index 120f611ccb69c..191c345e2d17f 100644 --- a/tests/ui/traits/issue-22019.rs +++ b/tests/ui/traits/issue-22019.rs @@ -3,7 +3,6 @@ // distinct scopes to be compared (`'g` and `'h`). The only important // thing is that compilation succeeds here. -//@ pretty-expanded FIXME #23616 #![allow(missing_copy_implementations)] #![allow(unused_variables)] diff --git a/tests/ui/traits/issue-22110.rs b/tests/ui/traits/issue-22110.rs index b0b584bd49daf..f16f5328ad368 100644 --- a/tests/ui/traits/issue-22110.rs +++ b/tests/ui/traits/issue-22110.rs @@ -3,7 +3,6 @@ // and the blanket impl. The only important thing is that compilation // succeeds here. Issue #22110. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/traits/issue-22655.rs b/tests/ui/traits/issue-22655.rs index aaf1b05b6e563..dfba8011a1e27 100644 --- a/tests/ui/traits/issue-22655.rs +++ b/tests/ui/traits/issue-22655.rs @@ -3,7 +3,6 @@ // Regression test for issue #22655: This test should not lead to // infinite recursion. -//@ pretty-expanded FIXME #23616 unsafe impl Send for Unique { } diff --git a/tests/ui/traits/issue-23003.rs b/tests/ui/traits/issue-23003.rs index cb05a5dfb6b80..93c5bfe32ce9e 100644 --- a/tests/ui/traits/issue-23003.rs +++ b/tests/ui/traits/issue-23003.rs @@ -4,7 +4,6 @@ // Async>::Cancel` be WF. This normalizes to `Receipt` // again, leading to an infinite cycle. Issue #23003. -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] #![allow(unused_variables)] diff --git a/tests/ui/traits/issue-32963.rs b/tests/ui/traits/issue-32963.rs index 56a68f3a2312c..4c4cd91d72e3e 100644 --- a/tests/ui/traits/issue-32963.rs +++ b/tests/ui/traits/issue-32963.rs @@ -7,5 +7,4 @@ fn size_of_copy() -> usize { mem::size_of::() } fn main() { size_of_copy::(); //~^ ERROR only auto traits can be used as additional traits in a trait object - //~| ERROR the trait bound `dyn Misc: Copy` is not satisfied } diff --git a/tests/ui/traits/issue-32963.stderr b/tests/ui/traits/issue-32963.stderr index bad45e54d6428..1c70d0aaa0ac5 100644 --- a/tests/ui/traits/issue-32963.stderr +++ b/tests/ui/traits/issue-32963.stderr @@ -9,19 +9,6 @@ LL | size_of_copy::(); = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Misc + Copy {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit -error[E0277]: the trait bound `dyn Misc: Copy` is not satisfied - --> $DIR/issue-32963.rs:8:20 - | -LL | size_of_copy::(); - | ^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `dyn Misc` - | -note: required by a bound in `size_of_copy` - --> $DIR/issue-32963.rs:5:20 - | -LL | fn size_of_copy() -> usize { mem::size_of::() } - | ^^^^ required by this bound in `size_of_copy` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0225, E0277. -For more information about an error, try `rustc --explain E0225`. +For more information about this error, try `rustc --explain E0225`. diff --git a/tests/ui/traits/issue-78372.rs b/tests/ui/traits/issue-78372.rs index 82b13cc0b6238..f03baf2ceca36 100644 --- a/tests/ui/traits/issue-78372.rs +++ b/tests/ui/traits/issue-78372.rs @@ -10,5 +10,4 @@ trait X { } trait Marker {} impl Marker for dyn Foo {} -//~^ ERROR cannot be made into an object fn main() {} diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr index 4cc2c59fd8dc5..86234d15a5d4b 100644 --- a/tests/ui/traits/issue-78372.stderr +++ b/tests/ui/traits/issue-78372.stderr @@ -55,24 +55,6 @@ LL | impl DispatchFromDyn> for T {} = help: add `#![feature(dispatch_from_dyn)]` 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[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/issue-78372.rs:12:17 - | -LL | fn foo(self: Smaht); - | -------------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` -... -LL | impl Marker for dyn Foo {} - | ^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/issue-78372.rs:9:18 - | -LL | trait Foo: X {} - | --- this trait cannot be made into an object... -LL | trait X { -LL | fn foo(self: Smaht); - | ^^^^^^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on - error[E0307]: invalid `self` parameter type: `Smaht` --> $DIR/issue-78372.rs:9:18 | @@ -88,7 +70,7 @@ error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion LL | impl DispatchFromDyn> for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0038, E0307, E0378, E0412, E0658. -For more information about an error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0307, E0378, E0412, E0658. +For more information about an error, try `rustc --explain E0307`. diff --git a/tests/ui/traits/monomorphized-callees-with-ty-params-3314.rs b/tests/ui/traits/monomorphized-callees-with-ty-params-3314.rs index 35d6dddfa30d6..9d33ec8c1728e 100644 --- a/tests/ui/traits/monomorphized-callees-with-ty-params-3314.rs +++ b/tests/ui/traits/monomorphized-callees-with-ty-params-3314.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 trait Serializer { } diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs index 1260cca510680..cbd591eec96c0 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs @@ -14,13 +14,7 @@ fn main() { fn weird0() -> impl Sized + !Sized {} //~^ ERROR the trait bound `(): !Sized` is not satisfied -//~| ERROR the trait bound `(): !Sized` is not satisfied -//~| ERROR the trait bound `(): !Sized` is not satisfied fn weird1() -> impl !Sized + Sized {} //~^ ERROR the trait bound `(): !Sized` is not satisfied -//~| ERROR the trait bound `(): !Sized` is not satisfied -//~| ERROR the trait bound `(): !Sized` is not satisfied fn weird2() -> impl !Sized {} //~^ ERROR the trait bound `(): !Sized` is not satisfied -//~| ERROR the trait bound `(): !Sized` is not satisfied -//~| ERROR the trait bound `(): !Sized` is not satisfied diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr index 4ec578a3b7bc2..3dad6d534fd83 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr @@ -5,53 +5,17 @@ LL | fn weird0() -> impl Sized + !Sized {} | ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied error[E0277]: the trait bound `(): !Sized` is not satisfied - --> $DIR/opaque-type-unsatisfied-bound.rs:15:36 - | -LL | fn weird0() -> impl Sized + !Sized {} - | ^^ the trait bound `(): !Sized` is not satisfied - -error[E0277]: the trait bound `(): !Sized` is not satisfied - --> $DIR/opaque-type-unsatisfied-bound.rs:15:1 - | -LL | fn weird0() -> impl Sized + !Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied - -error[E0277]: the trait bound `(): !Sized` is not satisfied - --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 + --> $DIR/opaque-type-unsatisfied-bound.rs:17:16 | LL | fn weird1() -> impl !Sized + Sized {} | ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied error[E0277]: the trait bound `(): !Sized` is not satisfied - --> $DIR/opaque-type-unsatisfied-bound.rs:19:36 - | -LL | fn weird1() -> impl !Sized + Sized {} - | ^^ the trait bound `(): !Sized` is not satisfied - -error[E0277]: the trait bound `(): !Sized` is not satisfied - --> $DIR/opaque-type-unsatisfied-bound.rs:19:1 - | -LL | fn weird1() -> impl !Sized + Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied - -error[E0277]: the trait bound `(): !Sized` is not satisfied - --> $DIR/opaque-type-unsatisfied-bound.rs:23:16 + --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 | LL | fn weird2() -> impl !Sized {} | ^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the trait bound `(): !Sized` is not satisfied - --> $DIR/opaque-type-unsatisfied-bound.rs:23:28 - | -LL | fn weird2() -> impl !Sized {} - | ^^ the trait bound `(): !Sized` is not satisfied - -error[E0277]: the trait bound `(): !Sized` is not satisfied - --> $DIR/opaque-type-unsatisfied-bound.rs:23:1 - | -LL | fn weird2() -> impl !Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied - error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:12:13 | @@ -66,6 +30,6 @@ note: required by a bound in `consume` LL | fn consume(_: impl Trait) {} | ^^^^^ required by this bound in `consume` -error: aborting due to 10 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs index c6826578658fd..39422914afcdd 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs @@ -4,7 +4,5 @@ fn produce() -> impl !Fn<(u32,)> {} //~^ ERROR the trait bound `(): !Fn(u32)` is not satisfied -//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied -//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied fn main() {} diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr index f81f0a23ac315..760e5aa62f2c1 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr @@ -4,18 +4,6 @@ error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied LL | fn produce() -> impl !Fn<(u32,)> {} | ^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied -error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied - --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34 - | -LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^ the trait bound `(): !Fn(u32)` is not satisfied - -error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied - --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1 - | -LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.rs b/tests/ui/traits/next-solver/alias-bound-unsound.rs index 272e5db3b7ad2..0236826c3ed29 100644 --- a/tests/ui/traits/next-solver/alias-bound-unsound.rs +++ b/tests/ui/traits/next-solver/alias-bound-unsound.rs @@ -28,5 +28,6 @@ fn main() { //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _` //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _` //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _` + //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _` println!("{x}"); } diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.stderr b/tests/ui/traits/next-solver/alias-bound-unsound.stderr index e5cf5b6bc3d30..7e3737d120bf4 100644 --- a/tests/ui/traits/next-solver/alias-bound-unsound.stderr +++ b/tests/ui/traits/next-solver/alias-bound-unsound.stderr @@ -24,6 +24,14 @@ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _` LL | drop(<() as Foo>::copy_me(&x)); | ^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _` + --> $DIR/alias-bound-unsound.rs:24:10 + | +LL | drop(<() as Foo>::copy_me(&x)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0275]: overflow evaluating the requirement `&<() as Foo>::Item well-formed` --> $DIR/alias-bound-unsound.rs:24:31 | @@ -50,6 +58,6 @@ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _` LL | drop(<() as Foo>::copy_me(&x)); | ^^ -error: aborting due to 7 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/destruct.rs b/tests/ui/traits/next-solver/destruct.rs index f595cb30db846..fd14132124c4b 100644 --- a/tests/ui/traits/next-solver/destruct.rs +++ b/tests/ui/traits/next-solver/destruct.rs @@ -1,7 +1,7 @@ //@ compile-flags: -Znext-solver //@ check-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_destruct)] fn foo(_: impl std::marker::Destruct) {} diff --git a/tests/ui/traits/next-solver/non-wf-ret.rs b/tests/ui/traits/next-solver/non-wf-ret.rs new file mode 100644 index 0000000000000..c54d61c895d23 --- /dev/null +++ b/tests/ui/traits/next-solver/non-wf-ret.rs @@ -0,0 +1,47 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +use std::ops::Deref; + +pub struct List { + skel: [T], +} + +impl<'a, T: Copy> IntoIterator for &'a List { + type Item = T; + type IntoIter = std::iter::Copied<<&'a [T] as IntoIterator>::IntoIter>; + + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} + +impl Deref for List { + type Target = [T]; + + fn deref(&self) -> &[T] { + todo!() + } +} + +impl List { + fn iter(&self) -> <&Self as IntoIterator>::IntoIter + where + T: Copy, + { + todo!() + } +} + +fn test(t: &List) { + // Checking that `<&List as IntoIterator>::IntoIter` is WF + // will disqualify the inherent method, since normalizing it + // requires `Q: Copy` which does not hold. and allow us to fall + // through to the deref'd `<[Q]>::iter` method which works. + // + // In the old solver, the same behavior is achieved by just + // eagerly normalizing the return type. + t.iter(); +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/normalization-shadowing/alias-bound-shadowed-by-env.rs b/tests/ui/traits/next-solver/normalization-shadowing/alias-bound-shadowed-by-env.rs new file mode 100644 index 0000000000000..c0b169abcd576 --- /dev/null +++ b/tests/ui/traits/next-solver/normalization-shadowing/alias-bound-shadowed-by-env.rs @@ -0,0 +1,19 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +trait Super { + type Assoc; +} +trait Bound { + type Assoc: Super; +} +trait Trait: Super {} + +// Elaborating the environment results in a `T::Assoc: Super` where-bound. +// This where-bound must not prevent normalization via the `Super` +// item bound. +fn heck>(x: ::Assoc) -> u32 { + x +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs b/tests/ui/traits/next-solver/normalization-shadowing/ambig-env-no-shadow.rs similarity index 100% rename from tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs rename to tests/ui/traits/next-solver/normalization-shadowing/ambig-env-no-shadow.rs diff --git a/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-1.rs b/tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-1.rs similarity index 100% rename from tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-1.rs rename to tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-1.rs diff --git a/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-2.rs b/tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-2.rs similarity index 100% rename from tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-2.rs rename to tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-2.rs diff --git a/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-3.rs b/tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-3.rs similarity index 100% rename from tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-3.rs rename to tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-3.rs diff --git a/tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.rs b/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.rs similarity index 100% rename from tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.rs rename to tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.rs diff --git a/tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.stderr b/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.stderr similarity index 100% rename from tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.stderr rename to tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.stderr diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs b/tests/ui/traits/next-solver/normalization-shadowing/param-candidate-shadows-project.rs similarity index 100% rename from tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs rename to tests/ui/traits/next-solver/normalization-shadowing/param-candidate-shadows-project.rs diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr b/tests/ui/traits/next-solver/normalization-shadowing/param-candidate-shadows-project.stderr similarity index 100% rename from tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr rename to tests/ui/traits/next-solver/normalization-shadowing/param-candidate-shadows-project.stderr diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-env-impl-conflict.rs b/tests/ui/traits/next-solver/normalization-shadowing/param-env-impl-conflict.rs similarity index 100% rename from tests/ui/traits/next-solver/env-shadows-impls/param-env-impl-conflict.rs rename to tests/ui/traits/next-solver/normalization-shadowing/param-env-impl-conflict.rs diff --git a/tests/ui/traits/next-solver/dont-remap-tait-substs.rs b/tests/ui/traits/next-solver/opaques/dont-remap-tait-substs.rs similarity index 100% rename from tests/ui/traits/next-solver/dont-remap-tait-substs.rs rename to tests/ui/traits/next-solver/opaques/dont-remap-tait-substs.rs diff --git a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.is_send.stderr b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.is_send.stderr similarity index 100% rename from tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.is_send.stderr rename to tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.is_send.stderr diff --git a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.not_send.stderr similarity index 100% rename from tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr rename to tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.not_send.stderr diff --git a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.rs similarity index 100% rename from tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs rename to tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.rs diff --git a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr new file mode 100644 index 0000000000000..9a28dc093c1be --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr @@ -0,0 +1,34 @@ +error: unconstrained opaque type + --> $DIR/no-define-in-wf-check.rs:19:18 + | +LL | type Tait1 = impl Sized; + | ^^^^^^^^^^ + | + = note: `Tait1` must be used in combination with a concrete type within the same module + +error: unconstrained opaque type + --> $DIR/no-define-in-wf-check.rs:27:18 + | +LL | type Tait1 = impl Sized; + | ^^^^^^^^^^ + | + = note: `Tait1` must be used in combination with a concrete type within the same module + +error: unconstrained opaque type + --> $DIR/no-define-in-wf-check.rs:36:18 + | +LL | type Tait1 = impl Sized; + | ^^^^^^^^^^ + | + = note: `Tait1` must be used in combination with a concrete type within the same module + +error: unconstrained opaque type + --> $DIR/no-define-in-wf-check.rs:47:18 + | +LL | type Tait1 = impl Sized; + | ^^^^^^^^^^ + | + = note: `Tait1` must be used in combination with a concrete type within the same module + +error: aborting due to 4 previous errors + diff --git a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs new file mode 100644 index 0000000000000..dd6df097da1bb --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs @@ -0,0 +1,66 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +// Regression test for trait-system-refactor-initiative#106. We previously +// tried to define other opaques while checking that opaques are well-formed. +// +// This resulted in undesirable ambiguity + +#![feature(type_alias_impl_trait)] + +mod ex0 { + fn foo() -> (impl Sized, impl Sized) { + ((), ()) + } +} +mod ex1 { + type Tait1 = impl Sized; + //[current]~^ ERROR unconstrained opaque type + fn foo(x: Tait1) -> impl Sized { + let () = x; + } +} + +mod ex2 { + type Tait1 = impl Sized; + //[current]~^ ERROR unconstrained opaque type + type Tait2 = impl Sized; + fn foo(x: Tait1) -> Tait2 { + let () = x; + } +} + +mod ex3 { + type Tait1 = impl Sized; + //[current]~^ ERROR unconstrained opaque type + trait Something {} + impl Something for T {} + type Tait2 = impl Something; + fn foo(x: Tait1) -> Tait2 { + let () = x; + } +} + +mod ex4 { + type Tait1 = impl Sized; + //[current]~^ ERROR unconstrained opaque type + trait Trait { + type Assoc; + } + + impl Trait for T { + type Assoc = T; + } + + // ambiguity when checking that `Tait2` is wf + // + // ambiguity proving `(): Trait`. + type Tait2 = impl Trait<(), Assoc = impl Trait>; + fn foo(x: Tait1) -> Tait2 { + let () = x; + } +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/select-alias-bound-as-param.rs b/tests/ui/traits/next-solver/opaques/select-alias-bound-as-param.rs similarity index 100% rename from tests/ui/traits/next-solver/select-alias-bound-as-param.rs rename to tests/ui/traits/next-solver/opaques/select-alias-bound-as-param.rs diff --git a/tests/ui/traits/next-solver/structurally-normalize-in-borrowck-field-projection.rs b/tests/ui/traits/next-solver/structurally-normalize-in-borrowck-field-projection.rs new file mode 100644 index 0000000000000..d2d68128fde54 --- /dev/null +++ b/tests/ui/traits/next-solver/structurally-normalize-in-borrowck-field-projection.rs @@ -0,0 +1,32 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +trait Interner: Sized { + type Value; +} + +enum Kind { + Value(I::Value), +} + +struct Intern; + +impl Interner for Intern { + type Value = Wrap; +} + +struct Wrap(T); + +type KindAlias = Kind; + +trait PrettyPrinter: Sized { + fn hello(c: KindAlias) { + match c { + KindAlias::Value(Wrap(v)) => { + println!("{v:?}"); + } + } + } +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/typeck/resolve-before-checking-builtin-ptr.rs b/tests/ui/traits/next-solver/typeck/resolve-before-checking-builtin-ptr.rs new file mode 100644 index 0000000000000..d47f705a8ab6d --- /dev/null +++ b/tests/ui/traits/next-solver/typeck/resolve-before-checking-builtin-ptr.rs @@ -0,0 +1,20 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +trait Mirror { + type Assoc; +} +impl Mirror for T { + type Assoc = T; +} + +struct Place { + field: <&'static [u8] as Mirror>::Assoc, +} + +fn main() { + let local = Place { field: &[] }; + let z = || { + let y = &local.field[0]; + }; +} diff --git a/tests/ui/traits/next-solver/typeck/resolve-before-checking-never.rs b/tests/ui/traits/next-solver/typeck/resolve-before-checking-never.rs new file mode 100644 index 0000000000000..6df1fd5d4ba16 --- /dev/null +++ b/tests/ui/traits/next-solver/typeck/resolve-before-checking-never.rs @@ -0,0 +1,20 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +#![feature(never_type)] + +trait Mirror { + type Assoc; +} +impl Mirror for T { + type Assoc = T; +} + +fn diverge() -> ::Assoc { todo!() } + +fn main() { + let close = || { + diverge(); + }; + let x: u32 = close(); +} diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs index 3af299e5b115a..4aadd45c49c1e 100644 --- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs +++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs @@ -10,6 +10,7 @@ fn w<'a, T: 'a, F: Fn(&'a T)>() { let b: &dyn FromResidual = &(); //~^ ERROR: the trait `FromResidual` cannot be made into an object //~| ERROR: the trait `FromResidual` cannot be made into an object + //~| ERROR: the trait `FromResidual` cannot be made into an object } fn main() {} diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr index 960802e2f8f82..c67a8c05379cd 100644 --- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr +++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr @@ -6,6 +6,29 @@ LL | let b: &dyn FromResidual = &(); | = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause +error[E0038]: the trait `FromResidual` cannot be made into an object + --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:32 + | +LL | let b: &dyn FromResidual = &(); + | ^^^ `FromResidual` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:2:8 + | +LL | trait FromResidual::Residual> { + | ------------ this trait cannot be made into an object... +LL | fn from_residual(residual: R) -> Self; + | ^^^^^^^^^^^^^ ...because associated function `from_residual` has no `self` parameter + = note: required for the cast from `&()` to `&dyn FromResidual<{type error}>` +help: consider turning `from_residual` into a method by giving it a `&self` argument + | +LL | fn from_residual(&self, residual: R) -> Self; + | ++++++ +help: alternatively, consider constraining `from_residual` so it does not apply to trait objects + | +LL | fn from_residual(residual: R) -> Self where Self: Sized; + | +++++++++++++++++ + error[E0038]: the trait `FromResidual` cannot be made into an object --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:12 | @@ -28,6 +51,6 @@ help: alternatively, consider constraining `from_residual` so it does not apply LL | fn from_residual(residual: R) -> Self where Self: Sized; | +++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/traits/parameterized-with-bounds.rs b/tests/ui/traits/parameterized-with-bounds.rs index 2de9bf3d04cc8..54e2d6e096d64 100644 --- a/tests/ui/traits/parameterized-with-bounds.rs +++ b/tests/ui/traits/parameterized-with-bounds.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.rs b/tests/ui/traits/resolve-impl-before-constrain-check.rs new file mode 100644 index 0000000000000..87f9c241e402b --- /dev/null +++ b/tests/ui/traits/resolve-impl-before-constrain-check.rs @@ -0,0 +1,20 @@ +// Need a different module so we try to build the mir for `test` +// before analyzing `mod foo`. + +mod foo { + pub trait Callable { + fn call(); + } + + impl Callable for () { + //~^ ERROR the type parameter `V` is not constrained by the impl trait, self type, or predicates + fn call() {} + } +} +use foo::*; + +fn test() -> impl Sized { + <() as Callable>::call() +} + +fn main() {} diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.stderr b/tests/ui/traits/resolve-impl-before-constrain-check.stderr new file mode 100644 index 0000000000000..e8e569ba625ee --- /dev/null +++ b/tests/ui/traits/resolve-impl-before-constrain-check.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates + --> $DIR/resolve-impl-before-constrain-check.rs:9:10 + | +LL | impl Callable for () { + | ^ unconstrained type parameter + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/traits/solver-cycles/100347-recursive-enum-cow-slice.rs b/tests/ui/traits/solver-cycles/100347-recursive-enum-cow-slice.rs new file mode 100644 index 0000000000000..26ae42b3e082f --- /dev/null +++ b/tests/ui/traits/solver-cycles/100347-recursive-enum-cow-slice.rs @@ -0,0 +1,11 @@ +//@ check-pass + +use std::borrow::Cow; + +#[derive(Clone)] +enum Test<'a> { + Int(u8), + Array(Cow<'a, [Test<'a>]>), +} + +fn main() {} diff --git a/tests/ui/traits/solver-cycles/107481-self-referential-struct-cow-as-last-field.rs b/tests/ui/traits/solver-cycles/107481-self-referential-struct-cow-as-last-field.rs new file mode 100644 index 0000000000000..f953eb1c0f744 --- /dev/null +++ b/tests/ui/traits/solver-cycles/107481-self-referential-struct-cow-as-last-field.rs @@ -0,0 +1,19 @@ +// Regression test for #107481 + +//@ check-pass + +use std::{borrow::Cow, collections::HashMap}; + +#[derive(Clone)] +struct Foo<'a>(Cow<'a, [Self]>); + +#[derive(Clone)] +struct Bar<'a>(Cow<'a, HashMap>); + +#[derive(Clone)] +struct Baz<'a>(Cow<'a, Vec>); + +#[derive(Clone)] +struct Qux<'a>(Cow<'a, Box>); + +fn main() {} diff --git a/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.rs b/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.rs new file mode 100644 index 0000000000000..197207dfb4be8 --- /dev/null +++ b/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.rs @@ -0,0 +1,22 @@ +// Regression test for #129541 +//~^ ERROR cycle detected when computing layout of `<[Hello] as Normalize>::Assoc` [E0391] + +trait Bound {} +trait Normalize { + type Assoc; +} + +impl Normalize for T { + type Assoc = T; +} + +impl Normalize for [T] { + type Assoc = T; +} + +impl Bound for Hello {} +enum Hello { + Variant(<[Hello] as Normalize>::Assoc), +} + +fn main() {} diff --git a/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.stderr b/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.stderr new file mode 100644 index 0000000000000..50dcea0bfac69 --- /dev/null +++ b/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.stderr @@ -0,0 +1,10 @@ +error[E0391]: cycle detected when computing layout of `<[Hello] as Normalize>::Assoc` + | + = note: ...which requires computing layout of `Hello`... + = note: ...which again requires computing layout of `<[Hello] as Normalize>::Assoc`, completing the cycle + = note: cycle used when computing layout of `Hello` + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs new file mode 100644 index 0000000000000..defb39aae06d4 --- /dev/null +++ b/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs @@ -0,0 +1,23 @@ +// Regression test for #129541 + +//@ check-pass + +trait Bound {} +trait Normalize { + type Assoc; +} + +impl Normalize for T { + type Assoc = T; +} + +impl Normalize for [T] { + type Assoc = T; +} + +impl Bound for Hello {} +struct Hello { + a: <[Hello] as Normalize>::Assoc, +} + +fn main() {} diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs new file mode 100644 index 0000000000000..d4339dd54d6c7 --- /dev/null +++ b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs @@ -0,0 +1,19 @@ +// Regression test for #129541 + +//@ check-pass + +trait Bound {} +trait Normalize { + type Assoc; +} + +impl Normalize for [T] { + type Assoc = T; +} + +impl Bound for Hello {} +struct Hello { + a: <[Hello] as Normalize>::Assoc, +} + +fn main() {} diff --git a/tests/ui/traits/span-bug-issue-121414.rs b/tests/ui/traits/span-bug-issue-121414.rs index ec38d8c2de6a6..2f4ad34f0c858 100644 --- a/tests/ui/traits/span-bug-issue-121414.rs +++ b/tests/ui/traits/span-bug-issue-121414.rs @@ -6,8 +6,7 @@ impl<'a> Bar for Foo<'f> { //~ ERROR undeclared lifetime type Type = u32; } -fn test() //~ ERROR the trait bound `for<'a> Foo<'a>: Bar` is not satisfied - //~| ERROR the trait bound `for<'a> Foo<'a>: Bar` is not satisfied +fn test() where for<'a> as Bar>::Type: Sized, { diff --git a/tests/ui/traits/span-bug-issue-121414.stderr b/tests/ui/traits/span-bug-issue-121414.stderr index e2ef6672cd57a..744806a341506 100644 --- a/tests/ui/traits/span-bug-issue-121414.stderr +++ b/tests/ui/traits/span-bug-issue-121414.stderr @@ -6,22 +6,6 @@ LL | impl<'a> Bar for Foo<'f> { | | | help: consider introducing lifetime `'f` here: `'f,` -error[E0277]: the trait bound `for<'a> Foo<'a>: Bar` is not satisfied - --> $DIR/span-bug-issue-121414.rs:9:1 - | -LL | / fn test() -LL | | -LL | | where -LL | | for<'a> as Bar>::Type: Sized, - | |__________________________________________^ the trait `for<'a> Bar` is not implemented for `Foo<'a>` - -error[E0277]: the trait bound `for<'a> Foo<'a>: Bar` is not satisfied - --> $DIR/span-bug-issue-121414.rs:9:4 - | -LL | fn test() - | ^^^^ the trait `for<'a> Bar` is not implemented for `Foo<'a>` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0261, E0277. -For more information about an error, try `rustc --explain E0261`. +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/traits/syntax-polarity.rs b/tests/ui/traits/syntax-polarity.rs index 80ad40bad8071..c6506e916ed45 100644 --- a/tests/ui/traits/syntax-polarity.rs +++ b/tests/ui/traits/syntax-polarity.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 #![feature(negative_impls)] diff --git a/tests/ui/traits/use-before-def.rs b/tests/ui/traits/use-before-def.rs index fb7e540db1875..2c7c6b19d6703 100644 --- a/tests/ui/traits/use-before-def.rs +++ b/tests/ui/traits/use-before-def.rs @@ -3,7 +3,6 @@ // Issue #1761 -//@ pretty-expanded FIXME #23616 impl foo for isize { fn foo(&self) -> isize { 10 } } trait foo { fn foo(&self) -> isize; } diff --git a/tests/ui/traits/where-clause-vs-impl.rs b/tests/ui/traits/where-clause-vs-impl.rs index 074c27036c2e1..639347b3bc36d 100644 --- a/tests/ui/traits/where-clause-vs-impl.rs +++ b/tests/ui/traits/where-clause-vs-impl.rs @@ -6,7 +6,6 @@ // // Issue #18453. -//@ pretty-expanded FIXME #23616 use std::rc::Rc; diff --git a/tests/ui/transmute-non-immediate-to-immediate.rs b/tests/ui/transmute-non-immediate-to-immediate.rs index f5ddf0cfa330b..d99bbcc600fd4 100644 --- a/tests/ui/transmute-non-immediate-to-immediate.rs +++ b/tests/ui/transmute-non-immediate-to-immediate.rs @@ -2,7 +2,6 @@ // Issue #7988 // Transmuting non-immediate type to immediate type -//@ pretty-expanded FIXME #23616 pub fn main() { unsafe { diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs new file mode 100644 index 0000000000000..18cfb1c1f93be --- /dev/null +++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs @@ -0,0 +1,21 @@ +// regression test for #127353 + +#![feature(type_alias_impl_trait)] +trait Trait {} +type Alias<'a, U> = impl Trait; +//~^ ERROR unconstrained opaque type + +pub enum UninhabitedVariants { + Tuple(Alias), + //~^ ERROR missing lifetime specifier + //~| ERROR missing generics + //~| ERROR non-defining opaque type use in defining scope +} + +fn uwu(x: UninhabitedVariants) { + //~^ ERROR item does not constrain + match x {} + //~^ ERROR non-exhaustive patterns +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr new file mode 100644 index 0000000000000..cf366c55ea816 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr @@ -0,0 +1,86 @@ +error[E0106]: missing lifetime specifier + --> $DIR/bad-tait-no-substs.rs:9:11 + | +LL | Tuple(Alias), + | ^^^^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL ~ pub enum UninhabitedVariants<'a> { +LL ~ Tuple(Alias<'a>), + | + +error[E0107]: missing generics for type alias `Alias` + --> $DIR/bad-tait-no-substs.rs:9:11 + | +LL | Tuple(Alias), + | ^^^^^ expected 1 generic argument + | +note: type alias defined here, with 1 generic parameter: `U` + --> $DIR/bad-tait-no-substs.rs:5:6 + | +LL | type Alias<'a, U> = impl Trait; + | ^^^^^ - +help: add missing generic argument + | +LL | Tuple(Alias), + | +++ + +error[E0792]: non-defining opaque type use in defining scope + --> $DIR/bad-tait-no-substs.rs:9:11 + | +LL | Tuple(Alias), + | ^^^^^ argument `'_` is not a generic parameter + | +note: for this opaque type + --> $DIR/bad-tait-no-substs.rs:5:21 + | +LL | type Alias<'a, U> = impl Trait; + | ^^^^^^^^^^^^^ + +error: item does not constrain `Alias::{opaque#0}`, but has it in its signature + --> $DIR/bad-tait-no-substs.rs:15:4 + | +LL | fn uwu(x: UninhabitedVariants) { + | ^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/bad-tait-no-substs.rs:5:21 + | +LL | type Alias<'a, U> = impl Trait; + | ^^^^^^^^^^^^^ + +error: unconstrained opaque type + --> $DIR/bad-tait-no-substs.rs:5:21 + | +LL | type Alias<'a, U> = impl Trait; + | ^^^^^^^^^^^^^ + | + = note: `Alias` must be used in combination with a concrete type within the same module + +error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` not covered + --> $DIR/bad-tait-no-substs.rs:17:11 + | +LL | match x {} + | ^ pattern `UninhabitedVariants::Tuple(_)` not covered + | +note: `UninhabitedVariants` defined here + --> $DIR/bad-tait-no-substs.rs:8:10 + | +LL | pub enum UninhabitedVariants { + | ^^^^^^^^^^^^^^^^^^^ +LL | Tuple(Alias), + | ----- not covered + = note: the matched value is of type `UninhabitedVariants` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ match x { +LL + UninhabitedVariants::Tuple(_) => todo!(), +LL + } + | + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0004, E0106, E0107, E0792. +For more information about an error, try `rustc --explain E0004`. diff --git a/tests/ui/type-alias-impl-trait/bad-transmute-itiat.rs b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.rs new file mode 100644 index 0000000000000..8314b28eeac4b --- /dev/null +++ b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.rs @@ -0,0 +1,22 @@ +// regression test for rust-lang/rust#125758 + +#![feature(impl_trait_in_assoc_type)] + +trait Trait { + type Assoc2; +} + +struct Bar; +impl Trait for Bar { + type Assoc2 = impl std::fmt::Debug; + //~^ ERROR unconstrained opaque type +} + +struct Foo { + field: ::Assoc2, +} + +static BAR: u8 = 42; +static FOO2: &Foo = unsafe { std::mem::transmute(&BAR) }; + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/bad-transmute-itiat.stderr b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.stderr new file mode 100644 index 0000000000000..6cbf6c83ff4ce --- /dev/null +++ b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.stderr @@ -0,0 +1,10 @@ +error: unconstrained opaque type + --> $DIR/bad-transmute-itiat.rs:11:19 + | +LL | type Assoc2 = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `Assoc2` must be used in combination with a concrete type within the same impl + +error: aborting due to 1 previous error + diff --git a/tests/crashes/130956.rs b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs similarity index 88% rename from tests/crashes/130956.rs rename to tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs index ebb986d123f91..4332f1264a80b 100644 --- a/tests/crashes/130956.rs +++ b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs @@ -1,8 +1,11 @@ -//@ known-bug: #130956 +// Regression test for #130956 + +#![feature(type_alias_impl_trait)] mod impl_trait_mod { use super::*; pub type OpaqueBlock = impl Trait; + //~^ ERROR unconstrained opaque type pub type OpaqueIf = impl Trait; pub struct BlockWrapper(OpaqueBlock); diff --git a/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr new file mode 100644 index 0000000000000..8e5838d5ddf55 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr @@ -0,0 +1,10 @@ +error: unconstrained opaque type + --> $DIR/drop-analysis-on-unconstrained-tait.rs:7:28 + | +LL | pub type OpaqueBlock = impl Trait; + | ^^^^^^^^^^ + | + = note: `OpaqueBlock` must be used in combination with a concrete type within the same module + +error: aborting due to 1 previous error + diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.rs b/tests/ui/type-alias-impl-trait/in-where-clause.rs index a089fdc907531..065af57a86416 100644 --- a/tests/ui/type-alias-impl-trait/in-where-clause.rs +++ b/tests/ui/type-alias-impl-trait/in-where-clause.rs @@ -1,4 +1,4 @@ -//! We evaluate `1 + 2` with `Reveal::All` during typeck, causing +//! We evaluate `1 + 2` with `TypingMode::PostAnalysis` during typeck, causing //! us to get the concrete type of `Bar` while computing it. //! This again requires type checking `foo`. #![feature(type_alias_impl_trait)] diff --git a/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs b/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs index 9901c8fe25d47..c52dbd3253905 100644 --- a/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs +++ b/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs @@ -1,7 +1,7 @@ //@ compile-flags: -Zvalidate-mir //@ check-pass -// Check that we don't cause cycle errors when validating pre-`Reveal::All` MIR +// Check that we don't cause cycle errors when validating pre-`RevealOpaques` MIR // that assigns opaques through normalized projections. #![feature(impl_trait_in_assoc_type)] diff --git a/tests/ui/type-alias/issue-14933.rs b/tests/ui/type-alias/issue-14933.rs index ddad6071017cd..198a25e896425 100644 --- a/tests/ui/type-alias/issue-14933.rs +++ b/tests/ui/type-alias/issue-14933.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 pub type BigRat = T; diff --git a/tests/ui/type-param-constraints.rs b/tests/ui/type-param-constraints.rs index a5c36af63fa78..83d81c0d833f1 100644 --- a/tests/ui/type-param-constraints.rs +++ b/tests/ui/type-param-constraints.rs @@ -2,7 +2,6 @@ #![allow(non_camel_case_types)] #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn p_foo(_pinned: T) { } fn s_foo(_shared: T) { } diff --git a/tests/ui/type-param.rs b/tests/ui/type-param.rs index fdb56feab82a9..e7cf0e5446bcf 100644 --- a/tests/ui/type-param.rs +++ b/tests/ui/type-param.rs @@ -4,7 +4,6 @@ #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 type lteq = extern "C" fn(T) -> bool; diff --git a/tests/ui/type-ptr.rs b/tests/ui/type-ptr.rs index 8f3868fc609c3..5c8ed344ab33a 100644 --- a/tests/ui/type-ptr.rs +++ b/tests/ui/type-ptr.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 fn f(a: *const isize) -> *const isize { return a; } diff --git a/tests/ui/type-use-i1-versus-i8.rs b/tests/ui/type-use-i1-versus-i8.rs index 916a77d993484..4eb25329223cf 100644 --- a/tests/ui/type-use-i1-versus-i8.rs +++ b/tests/ui/type-use-i1-versus-i8.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 use std::ptr; diff --git a/tests/ui/type/issue-7607-2.rs b/tests/ui/type/issue-7607-2.rs index 654f26bf298d7..ebc4fe1c2d301 100644 --- a/tests/ui/type/issue-7607-2.rs +++ b/tests/ui/type/issue-7607-2.rs @@ -1,6 +1,5 @@ //@ check-pass #![allow(dead_code)] -//@ pretty-expanded FIXME #23616 pub mod a { pub struct Foo { a: usize } diff --git a/tests/ui/typeck/ufcs-type-params.rs b/tests/ui/typeck/ufcs-type-params.rs index ef8b983b3e929..5a6db4620fc18 100644 --- a/tests/ui/typeck/ufcs-type-params.rs +++ b/tests/ui/typeck/ufcs-type-params.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 trait Foo { fn get(&self) -> T; diff --git a/tests/ui/typeck/unify-return-ty.rs b/tests/ui/typeck/unify-return-ty.rs index 849b72e63e5de..d33a1674e0809 100644 --- a/tests/ui/typeck/unify-return-ty.rs +++ b/tests/ui/typeck/unify-return-ty.rs @@ -3,7 +3,6 @@ // unified with the type *T, and so the type variable // in that type gets resolved. -//@ pretty-expanded FIXME #23616 use std::mem; diff --git a/tests/ui/unboxed-closures/issue-18661.rs b/tests/ui/unboxed-closures/issue-18661.rs index 44b4c49935214..dc965809ea187 100644 --- a/tests/ui/unboxed-closures/issue-18661.rs +++ b/tests/ui/unboxed-closures/issue-18661.rs @@ -2,7 +2,6 @@ // Test that param substitutions from the correct environment are // used when codegenning unboxed closure calls. -//@ pretty-expanded FIXME #23616 pub fn inside(c: F) { c(); diff --git a/tests/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs b/tests/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs index 632bffbea18df..265e8e49f0dec 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs +++ b/tests/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_mut)] -//@ pretty-expanded FIXME #23616 fn main() { let mut unboxed = || {}; diff --git a/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs b/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs index c7c50b7b50e20..8c27c4151ac7e 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs +++ b/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs @@ -2,7 +2,6 @@ // Test that we are able to infer that the type of `x` is `isize` based // on the expected type from the object. -//@ pretty-expanded FIXME #23616 pub trait ToPrimitive { fn to_int(&self) {} diff --git a/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs b/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs index a54048d25181d..10f21908902e3 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs +++ b/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs @@ -2,7 +2,6 @@ // Test that we are able to infer that the type of `x` is `isize` based // on the expected type from the object. -//@ pretty-expanded FIXME #23616 pub trait ToPrimitive { fn to_int(&self) {} diff --git a/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs b/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs index 8c7b1c7534b0a..d3a6ff91a9403 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs +++ b/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs @@ -2,7 +2,6 @@ // Test that we are able to infer that the type of `x` is `isize` based // on the expected type from the object. -//@ pretty-expanded FIXME #23616 pub trait ToPrimitive { fn to_int(&self) {} diff --git a/tests/ui/unboxed-closures/unboxed-closures-move-mutable.rs b/tests/ui/unboxed-closures/unboxed-closures-move-mutable.rs index d883053d2763e..f27461808c390 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-move-mutable.rs +++ b/tests/ui/unboxed-closures/unboxed-closures-move-mutable.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 #![deny(unused_mut)] #![allow(unused_must_use)] diff --git a/tests/ui/unboxed-closures/unboxed-closures-move-mutable.stderr b/tests/ui/unboxed-closures/unboxed-closures-move-mutable.stderr index 5c06f4e621c17..813e2eea56848 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-move-mutable.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-move-mutable.stderr @@ -1,5 +1,5 @@ warning: unused variable: `x` - --> $DIR/unboxed-closures-move-mutable.rs:17:17 + --> $DIR/unboxed-closures-move-mutable.rs:16:17 | LL | move || x += 1; | ^ @@ -8,7 +8,7 @@ LL | move || x += 1; = note: `#[warn(unused_variables)]` on by default warning: unused variable: `x` - --> $DIR/unboxed-closures-move-mutable.rs:21:17 + --> $DIR/unboxed-closures-move-mutable.rs:20:17 | LL | move || x += 1; | ^ diff --git a/tests/ui/unboxed-closures/unboxed-closures-prelude.rs b/tests/ui/unboxed-closures/unboxed-closures-prelude.rs index ca0ca66c0353d..ae90a51c48826 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-prelude.rs +++ b/tests/ui/unboxed-closures/unboxed-closures-prelude.rs @@ -1,7 +1,6 @@ //@ run-pass // Tests that the re-exports of `FnOnce` et al from the prelude work. -//@ pretty-expanded FIXME #23616 fn main() { let task: Box isize> = Box::new(|x| x); diff --git a/tests/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs b/tests/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs index 6103dbd99590a..c63594dc8787b 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs +++ b/tests/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn main() { let onetime = |x| x; diff --git a/tests/ui/unboxed-closures/unboxed-closures-zero-args.rs b/tests/ui/unboxed-closures/unboxed-closures-zero-args.rs index 81fe12afccf13..c808189b65859 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-zero-args.rs +++ b/tests/ui/unboxed-closures/unboxed-closures-zero-args.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_mut)] -//@ pretty-expanded FIXME #23616 fn main() { let mut zero = || {}; diff --git a/tests/ui/underscore-imports/auxiliary/duplicate.rs b/tests/ui/underscore-imports/auxiliary/duplicate.rs index 61613d24b9e92..b346522b72152 100644 --- a/tests/ui/underscore-imports/auxiliary/duplicate.rs +++ b/tests/ui/underscore-imports/auxiliary/duplicate.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::*; diff --git a/tests/ui/underscore-imports/duplicate.rs b/tests/ui/underscore-imports/duplicate.rs index 4afad77ee4f05..125ccdf52b012 100644 --- a/tests/ui/underscore-imports/duplicate.rs +++ b/tests/ui/underscore-imports/duplicate.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ aux-build:duplicate.rs +//@ proc-macro: duplicate.rs extern crate duplicate; diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr index 50f33607c06f5..0e87f14aa14ae 100644 --- a/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr +++ b/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr @@ -5,7 +5,7 @@ LL | let Foo::D(_y, _z) = x; | ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `Foo` defined here --> $DIR/uninhabited-irrefutable.rs:19:6 | diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr index bc1a9fa41915a..67527ce1ac452 100644 --- a/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr +++ b/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr @@ -5,7 +5,7 @@ LL | let Foo::D(_y, _z) = x; | ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `Foo` defined here --> $DIR/uninhabited-irrefutable.rs:20:6 | diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr index 50f33607c06f5..0e87f14aa14ae 100644 --- a/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr +++ b/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr @@ -5,7 +5,7 @@ LL | let Foo::D(_y, _z) = x; | ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `Foo` defined here --> $DIR/uninhabited-irrefutable.rs:19:6 | diff --git a/tests/ui/uninit-empty-types.rs b/tests/ui/uninit-empty-types.rs index a6c11c4999a2d..82474d873b788 100644 --- a/tests/ui/uninit-empty-types.rs +++ b/tests/ui/uninit-empty-types.rs @@ -1,7 +1,6 @@ //@ build-pass // Test the uninit() construct returning various empty types. -//@ pretty-expanded FIXME #23616 use std::mem::MaybeUninit; diff --git a/tests/ui/unit.rs b/tests/ui/unit.rs index 98ac164b1d415..04404fc3f5e66 100644 --- a/tests/ui/unit.rs +++ b/tests/ui/unit.rs @@ -2,7 +2,6 @@ #![allow(unused_assignments)] #![allow(unknown_lints)] -//@ pretty-expanded FIXME #23616 #![allow(unused_variables)] #![allow(dead_assignment)] diff --git a/tests/ui/unnamed_argument_mode.rs b/tests/ui/unnamed_argument_mode.rs index ba6f84c4ddea5..2014e0d23d849 100644 --- a/tests/ui/unnamed_argument_mode.rs +++ b/tests/ui/unnamed_argument_mode.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn good(_a: &isize) { } diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/expanded-exhaustive.rs index 799e8071d028a..891021e876609 100644 --- a/tests/ui/unpretty/expanded-exhaustive.rs +++ b/tests/ui/unpretty/expanded-exhaustive.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zunpretty=expanded -Zunstable-options +//@ compile-flags: -Zunpretty=expanded //@ edition:2024 //@ check-pass diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout index d8384951e12f0..007626e2c4406 100644 --- a/tests/ui/unpretty/expanded-exhaustive.stdout +++ b/tests/ui/unpretty/expanded-exhaustive.stdout @@ -1,5 +1,5 @@ #![feature(prelude_import)] -//@ compile-flags: -Zunpretty=expanded -Zunstable-options +//@ compile-flags: -Zunpretty=expanded //@ edition:2024 //@ check-pass diff --git a/tests/ui/unsafe-fields-crate.rs b/tests/ui/unsafe-fields-crate.rs new file mode 100644 index 0000000000000..cfb9ad6b544fd --- /dev/null +++ b/tests/ui/unsafe-fields-crate.rs @@ -0,0 +1,62 @@ +//@ compile-flags: --crate-type=lib +//@ aux-build: unsafe-fields-crate-dep.rs + +extern crate unsafe_fields_crate_dep; + +use unsafe_fields_crate_dep::WithUnsafeField; + +fn new_without_unsafe() -> WithUnsafeField { + WithUnsafeField { + //~^ ERROR + unsafe_field: 0, + safe_field: 0, + } +} + +fn operate_on_safe_field(s: &mut WithUnsafeField) { + s.safe_field = 2; + &s.safe_field; + s.safe_field; +} + +fn set_unsafe_field(s: &mut WithUnsafeField) { + unsafe { + s.unsafe_field = 2; + } +} + +fn read_unsafe_field(s: &WithUnsafeField) -> u32 { + unsafe { s.unsafe_field } +} + +fn ref_unsafe_field(s: &WithUnsafeField) -> &u32 { + unsafe { &s.unsafe_field } +} + +fn destructure(s: &WithUnsafeField) { + unsafe { + let WithUnsafeField { safe_field, unsafe_field } = s; + } +} + +fn set_unsafe_field_without_unsafe(s: &mut WithUnsafeField) { + s.unsafe_field = 2; + //~^ ERROR +} + +fn read_unsafe_field_without_unsafe(s: &WithUnsafeField) -> u32 { + s.unsafe_field + //~^ ERROR +} + +fn ref_unsafe_field_without_unsafe(s: &WithUnsafeField) -> &u32 { + &s.unsafe_field + //~^ ERROR +} + +fn destructure_without_unsafe(s: &WithUnsafeField) { + let WithUnsafeField { safe_field, unsafe_field } = s; + //~^ ERROR + + let WithUnsafeField { safe_field, .. } = s; +} diff --git a/tests/ui/unsafe-fields-crate.stderr b/tests/ui/unsafe-fields-crate.stderr new file mode 100644 index 0000000000000..778c26e0a4398 --- /dev/null +++ b/tests/ui/unsafe-fields-crate.stderr @@ -0,0 +1,47 @@ +error[E0133]: initializing type with an unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields-crate.rs:9:5 + | +LL | / WithUnsafeField { +LL | | +LL | | unsafe_field: 0, +LL | | safe_field: 0, +LL | | } + | |_____^ initialization of struct with unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields-crate.rs:43:5 + | +LL | s.unsafe_field = 2; + | ^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields-crate.rs:48:5 + | +LL | s.unsafe_field + | ^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields-crate.rs:53:6 + | +LL | &s.unsafe_field + | ^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields-crate.rs:58:39 + | +LL | let WithUnsafeField { safe_field, unsafe_field } = s; + | ^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/unsafe-fields-parse.rs b/tests/ui/unsafe-fields-parse.rs new file mode 100644 index 0000000000000..67277731293a7 --- /dev/null +++ b/tests/ui/unsafe-fields-parse.rs @@ -0,0 +1,10 @@ +//@ compile-flags: --crate-type=lib +#![allow(incomplete_features)] +#![feature(unsafe_fields)] + +// Parse errors even *with* unsafe_fields, which would make the compiler early-exit otherwise. +enum A { + TupleLike(unsafe u32), //~ ERROR +} + +struct B(unsafe u32); //~ ERROR diff --git a/tests/ui/unsafe-fields-parse.stderr b/tests/ui/unsafe-fields-parse.stderr new file mode 100644 index 0000000000000..5a45ab03ffe05 --- /dev/null +++ b/tests/ui/unsafe-fields-parse.stderr @@ -0,0 +1,18 @@ +error: expected type, found keyword `unsafe` + --> $DIR/unsafe-fields-parse.rs:7:15 + | +LL | enum A { + | - while parsing this enum +LL | TupleLike(unsafe u32), + | ^^^^^^ expected type + | + = help: enum variants can be `Variant`, `Variant = `, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` + +error: expected type, found keyword `unsafe` + --> $DIR/unsafe-fields-parse.rs:10:10 + | +LL | struct B(unsafe u32); + | ^^^^^^ expected type + +error: aborting due to 2 previous errors + diff --git a/tests/ui/unsafe-fields.rs b/tests/ui/unsafe-fields.rs new file mode 100644 index 0000000000000..637471582d7e4 --- /dev/null +++ b/tests/ui/unsafe-fields.rs @@ -0,0 +1,109 @@ +//@ compile-flags: --crate-type=lib +#![allow(incomplete_features)] +#![feature(unsafe_fields)] + +struct WithUnsafeField { + unsafe unsafe_field: u32, + safe_field: u32, +} + +enum A { + WithUnsafeField { unsafe unsafe_field: u32, safe_field: u32 }, +} + +fn f(a: A) { + let A::WithUnsafeField { unsafe_field, safe_field } = a; + //~^ ERROR +} + +struct WithInvalidUnsafeField { + unsafe unsafe_noncopy_field: Vec, //~ ERROR +} + +struct WithManuallyDropUnsafeField { + unsafe unsafe_noncopy_field: std::mem::ManuallyDrop>, +} + +union WithUnsafeFieldUnion { + unsafe unsafe_field: u32, + safe_field: u32, +} + +impl WithUnsafeField { + fn new() -> WithUnsafeField { + unsafe { + WithUnsafeField { + unsafe_field: 0, + safe_field: 0, + } + } + } + + fn new_without_unsafe() -> WithUnsafeField { + WithUnsafeField { //~ ERROR + unsafe_field: 0, + safe_field: 0, + } + } + + fn operate_on_safe_field(&mut self) { + self.safe_field = 2; + &self.safe_field; + self.safe_field; + } + + fn set_unsafe_field(&mut self) { + unsafe { + self.unsafe_field = 2; + } + } + + fn read_unsafe_field(&self) -> u32 { + unsafe { + self.unsafe_field + } + } + + fn ref_unsafe_field(&self) -> &u32 { + unsafe { + &self.unsafe_field + } + } + + fn destructure(&self) { + unsafe { + let Self { safe_field, unsafe_field } = self; + } + } + + fn set_unsafe_field_without_unsafe(&mut self) { + self.unsafe_field = 2; + //~^ ERROR + } + + fn read_unsafe_field_without_unsafe(&self) -> u32 { + self.unsafe_field + //~^ ERROR + } + + fn ref_unsafe_field_without_unsafe(&self) -> &u32 { + &self.unsafe_field + //~^ ERROR + } + + fn destructure_without_unsafe(&self) { + let Self { safe_field, unsafe_field } = self; + //~^ ERROR + + let WithUnsafeField { safe_field, .. } = self; + } + + fn offset_of(&self) -> usize { + std::mem::offset_of!(WithUnsafeField, unsafe_field) + } + + fn raw_const(&self) -> *const u32 { + &raw const self.unsafe_field + //~^ ERROR + } +} diff --git a/tests/ui/unsafe-fields.stderr b/tests/ui/unsafe-fields.stderr new file mode 100644 index 0000000000000..a1c5d2b44cdf1 --- /dev/null +++ b/tests/ui/unsafe-fields.stderr @@ -0,0 +1,75 @@ +error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe + --> $DIR/unsafe-fields.rs:20:5 + | +LL | unsafe unsafe_noncopy_field: Vec, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>` +help: wrap the field type in `ManuallyDrop<...>` + | +LL | unsafe unsafe_noncopy_field: std::mem::ManuallyDrop>, + | +++++++++++++++++++++++ + + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:15:30 + | +LL | let A::WithUnsafeField { unsafe_field, safe_field } = a; + | ^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: initializing type with an unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:43:9 + | +LL | / WithUnsafeField { +LL | | unsafe_field: 0, +LL | | safe_field: 0, +LL | | } + | |_________^ initialization of struct with unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:80:9 + | +LL | self.unsafe_field = 2; + | ^^^^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:85:9 + | +LL | self.unsafe_field + | ^^^^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:90:10 + | +LL | &self.unsafe_field + | ^^^^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:95:32 + | +LL | let Self { safe_field, unsafe_field } = self; + | ^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:106:20 + | +LL | &raw const self.unsafe_field + | ^^^^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0133, E0740. +For more information about an error, try `rustc --explain E0133`. diff --git a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs index f12c38939dd1e..2fb73d3a1faf0 100644 --- a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs +++ b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options //@ check-pass #![crate_type = "lib"] #![deny(unused_unsafe)] diff --git a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr index fe12dd72d9ebe..321d0ca293602 100644 --- a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr +++ b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr @@ -1,5 +1,5 @@ warning[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block - --> $DIR/edition-2024-unsafe_op_in_unsafe_fn.rs:10:5 + --> $DIR/edition-2024-unsafe_op_in_unsafe_fn.rs:9:5 | LL | unsf(); | ^^^^^^ call to unsafe function @@ -7,7 +7,7 @@ LL | unsf(); = note: for more information, see issue #71668 = note: consult the function's documentation for information on how to avoid undefined behavior note: an unsafe function restricts its caller, but its body is safe by default - --> $DIR/edition-2024-unsafe_op_in_unsafe_fn.rs:9:1 + --> $DIR/edition-2024-unsafe_op_in_unsafe_fn.rs:8:1 | LL | unsafe fn foo() { | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/unsafe/new-unsafe-pointers.rs b/tests/ui/unsafe/new-unsafe-pointers.rs index 39566cda90ac3..07c54ae96922c 100644 --- a/tests/ui/unsafe/new-unsafe-pointers.rs +++ b/tests/ui/unsafe/new-unsafe-pointers.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 fn main() { let _a: *const isize = 3 as *const isize; diff --git a/tests/ui/unsafe/unsafe-fn-called-from-unsafe-blk.rs b/tests/ui/unsafe/unsafe-fn-called-from-unsafe-blk.rs index d9f244bc4d207..d45f5c523c25a 100644 --- a/tests/ui/unsafe/unsafe-fn-called-from-unsafe-blk.rs +++ b/tests/ui/unsafe/unsafe-fn-called-from-unsafe-blk.rs @@ -4,7 +4,6 @@ // // See also: ui/unsafe/unsafe-fn-called-from-safe.rs -//@ pretty-expanded FIXME #23616 unsafe fn f() { return; } diff --git a/tests/ui/unsafe/unsafe-fn-called-from-unsafe-fn.rs b/tests/ui/unsafe/unsafe-fn-called-from-unsafe-fn.rs index bb7715b7b5cea..168c60dfc8439 100644 --- a/tests/ui/unsafe/unsafe-fn-called-from-unsafe-fn.rs +++ b/tests/ui/unsafe/unsafe-fn-called-from-unsafe-fn.rs @@ -4,7 +4,6 @@ // // See also: ui/unsafe/unsafe-fn-called-from-safe.rs -//@ pretty-expanded FIXME #23616 unsafe fn f() { return; } diff --git a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.rs b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.rs index 06a46b9812d38..261427d1eab39 100644 --- a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.rs +++ b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.rs @@ -1,5 +1,4 @@ //@ edition: 2024 -//@ compile-flags: -Zunstable-options //@ check-pass // Tests that `unsafe_op_in_unsafe_fn` is warn-by-default in edition 2024 and that the diff --git a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr index 05f36ab47cb56..d91b76e793715 100644 --- a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr +++ b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr @@ -1,5 +1,5 @@ warning[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block - --> $DIR/edition_2024_default.rs:13:5 + --> $DIR/edition_2024_default.rs:12:5 | LL | unsf(); | ^^^^^^ call to unsafe function @@ -7,7 +7,7 @@ LL | unsf(); = note: for more information, see issue #71668 = note: consult the function's documentation for information on how to avoid undefined behavior note: an unsafe function restricts its caller, but its body is safe by default - --> $DIR/edition_2024_default.rs:12:1 + --> $DIR/edition_2024_default.rs:11:1 | LL | unsafe fn foo() { | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/unused-move-capture.rs b/tests/ui/unused-move-capture.rs index c295f8d791439..5f42bcbe280e6 100644 --- a/tests/ui/unused-move-capture.rs +++ b/tests/ui/unused-move-capture.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 pub fn main() { let _x: Box<_> = Box::new(1); diff --git a/tests/ui/unused-move.rs b/tests/ui/unused-move.rs index 87398652e93c3..3d5eff2c48d50 100644 --- a/tests/ui/unused-move.rs +++ b/tests/ui/unused-move.rs @@ -3,7 +3,6 @@ // Issue Name: Unused move causes a crash // Abstract: zero-fill to block after drop -//@ pretty-expanded FIXME #23616 #![allow(path_statements)] diff --git a/tests/ui/use-import-export.rs b/tests/ui/use-import-export.rs index f784194c50590..d948ffc1520b3 100644 --- a/tests/ui/use-import-export.rs +++ b/tests/ui/use-import-export.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ pretty-expanded FIXME #23616 mod foo { pub fn x() -> isize { return 1; } diff --git a/tests/ui/use/use.rs b/tests/ui/use/use.rs index 826a049f2bbb5..db031500a4ac8 100644 --- a/tests/ui/use/use.rs +++ b/tests/ui/use/use.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(stable_features)] -//@ pretty-expanded FIXME #23616 #![allow(unused_imports)] #![feature(start, no_core, core)] diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs index 53363319ba0e6..a95e10b7265dd 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs @@ -1,11 +1,6 @@ trait Trait { //~^ ERROR cannot find value `bar` in this scope //~| ERROR cycle detected when computing type of `Trait::N` - //~| ERROR the trait `Trait` cannot be made into an object - //~| ERROR the trait `Trait` cannot be made into an object - //~| ERROR the trait `Trait` cannot be made into an object - //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects] - //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects] //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! fn fnc(&self) -> Trait { @@ -13,9 +8,6 @@ trait Trait { //~| ERROR expected value, found builtin type `u32` //~| ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions //~| ERROR associated item referring to unboxed trait object for its own trait - //~| ERROR the trait `Trait` cannot be made into an object - //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects] - //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects] //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects] diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr index fefb788fac79c..339f7b2cc8207 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr @@ -1,5 +1,5 @@ error[E0403]: the name `N` is already used for a generic parameter in this item's generic parameters - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:18 + --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:18 | LL | trait Trait { | - first use of `N` @@ -14,13 +14,13 @@ LL | trait Trait { | ^^^ not found in this scope error[E0423]: expected value, found builtin type `u32` - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:29 + --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:29 | LL | fn fnc(&self) -> Trait { | ^^^ not a value error[E0425]: cannot find value `bar` in this scope - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:23:9 + --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:15:9 | LL | bar | ^^^ not found in this scope @@ -53,27 +53,8 @@ LL | trait Trait { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:12 - | -LL | fn fnc(&self) -> Trait { - | ^^^^^^^^^^^^^^^^^^^^ - warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:21 - | -LL | fn fnc(&self) -> Trait { - | ^^^^^ - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see -help: if this is a dyn-compatible trait, use `dyn` - | -LL | fn fnc(&self) -> Trait { - | +++ - -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:44 + --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:44 | LL | fn fnc(&self) -> Trait { | ^^^^^ @@ -85,114 +66,40 @@ help: if this is a dyn-compatible trait, use `dyn` LL | fn fnc(&self) -> dyn Trait { | +++ -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:1:22 - | -LL | trait Trait { - | ^^^^^ - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: if this is a dyn-compatible trait, use `dyn` - | -LL | trait Trait { - | +++ - -error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:1:22 - | -LL | trait Trait { - | ^^^^^ `Trait` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:8 - | -LL | trait Trait { - | ----- this trait cannot be made into an object... -... -LL | fn fnc(&self) -> Trait { - | ^^^ ...because method `fnc` has generic type parameters - = help: consider moving `fnc` to another trait - -error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:1:13 - | -LL | trait Trait { - | ^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:8 - | -LL | trait Trait { - | ----- this trait cannot be made into an object... -... -LL | fn fnc(&self) -> Trait { - | ^^^ ...because method `fnc` has generic type parameters - = help: consider moving `fnc` to another trait - -error: associated item referring to unboxed trait object for its own trait - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:44 +error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:12 | -LL | trait Trait { - | ----- in this trait -... LL | fn fnc(&self) -> Trait { - | ^^^^^ - | -help: you might have meant to use `Self` to refer to the implementing type - | -LL | fn fnc(&self) -> Self { - | ~~~~ + | ^^^^^^^^^^^^^^^^^^^^ warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:21 + --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:21 | LL | fn fnc(&self) -> Trait { | ^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: if this is a dyn-compatible trait, use `dyn` | LL | fn fnc(&self) -> Trait { | +++ -error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:21 - | -LL | fn fnc(&self) -> Trait { - | ^^^^^ `Trait` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:8 +error: associated item referring to unboxed trait object for its own trait + --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:44 | LL | trait Trait { - | ----- this trait cannot be made into an object... + | ----- in this trait ... LL | fn fnc(&self) -> Trait { - | ^^^ ...because method `fnc` has generic type parameters - = help: consider moving `fnc` to another trait - -error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:1:13 - | -LL | trait Trait { - | ^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object + | ^^^^^ | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:8 +help: you might have meant to use `Self` to refer to the implementing type | -LL | trait Trait { - | ----- this trait cannot be made into an object... -... -LL | fn fnc(&self) -> Trait { - | ^^^ ...because method `fnc` has generic type parameters - = help: consider moving `fnc` to another trait - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +LL | fn fnc(&self) -> Self { + | ~~~~ -error: aborting due to 11 previous errors; 5 warnings emitted +error: aborting due to 7 previous errors; 3 warnings emitted -Some errors have detailed explanations: E0038, E0391, E0403, E0423, E0425. -For more information about an error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0391, E0403, E0423, E0425. +For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs index e6d4e2ee01a27..0be5127dcc4da 100644 --- a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs +++ b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs @@ -14,5 +14,4 @@ impl Trait for Ref {} //~ ERROR: implicit elided lifetime not allowed here extern "C" { pub fn repro(_: Wrapper); - //~^ ERROR the trait bound `Ref<'_>: Trait` is not satisfied } diff --git a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr index 59b55b2732d30..0af4ab022e1eb 100644 --- a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr +++ b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr @@ -9,19 +9,6 @@ help: indicate the anonymous lifetime LL | impl Trait for Ref<'_> {} | ++++ -error[E0277]: the trait bound `Ref<'_>: Trait` is not satisfied - --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:21 - | -LL | pub fn repro(_: Wrapper); - | ^^^^^^^^^^^^ the trait `Trait` is not implemented for `Ref<'_>` - | -note: required by a bound in `Wrapper` - --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:8:23 - | -LL | pub struct Wrapper(T); - | ^^^^^ required by this bound in `Wrapper` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0726. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0726`. diff --git a/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs b/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs index be003cbf585e0..cf9c661582e9e 100644 --- a/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs +++ b/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ pretty-expanded FIXME #23616 trait Bound { fn dummy(&self) { } diff --git a/tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs b/tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs index 67088a9818e08..153fa8a5715a1 100644 --- a/tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs +++ b/tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(non_upper_case_globals)] -//@ pretty-expanded FIXME #23616 trait TheTrait { fn dummy(&self) { } } //~ WARN method `dummy` is never used diff --git a/tests/ui/where-clauses/where-clause-early-bound-lifetimes.stderr b/tests/ui/where-clauses/where-clause-early-bound-lifetimes.stderr index a9fe11ea6b316..34ed8bd214674 100644 --- a/tests/ui/where-clauses/where-clause-early-bound-lifetimes.stderr +++ b/tests/ui/where-clauses/where-clause-early-bound-lifetimes.stderr @@ -1,5 +1,5 @@ warning: method `dummy` is never used - --> $DIR/where-clause-early-bound-lifetimes.rs:6:21 + --> $DIR/where-clause-early-bound-lifetimes.rs:5:21 | LL | trait TheTrait { fn dummy(&self) { } } | -------- ^^^^^ diff --git a/tests/ui/where-clauses/where-clause-method-substituion-rpass.rs b/tests/ui/where-clauses/where-clause-method-substituion-rpass.rs index ba409182809db..da75ed796c00f 100644 --- a/tests/ui/where-clauses/where-clause-method-substituion-rpass.rs +++ b/tests/ui/where-clauses/where-clause-method-substituion-rpass.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 trait Foo { fn dummy(&self, arg: T) { } } //~ WARN method `dummy` is never used diff --git a/tests/ui/where-clauses/where-clause-method-substituion-rpass.stderr b/tests/ui/where-clauses/where-clause-method-substituion-rpass.stderr index 0d09cb9de3f6b..9a8faf7a64e84 100644 --- a/tests/ui/where-clauses/where-clause-method-substituion-rpass.stderr +++ b/tests/ui/where-clauses/where-clause-method-substituion-rpass.stderr @@ -1,5 +1,5 @@ warning: method `dummy` is never used - --> $DIR/where-clause-method-substituion-rpass.rs:5:19 + --> $DIR/where-clause-method-substituion-rpass.rs:4:19 | LL | trait Foo { fn dummy(&self, arg: T) { } } | --- ^^^^^ diff --git a/tests/ui/where-clauses/where-clause-region-outlives.rs b/tests/ui/where-clauses/where-clause-region-outlives.rs index db61638ca2dd7..47a6d46820446 100644 --- a/tests/ui/where-clauses/where-clause-region-outlives.rs +++ b/tests/ui/where-clauses/where-clause-region-outlives.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 struct A<'a, 'b> where 'a : 'b { x: &'a isize, y: &'b isize } diff --git a/tests/ui/where-clauses/where-clauses-lifetimes.rs b/tests/ui/where-clauses/where-clauses-lifetimes.rs index 8e8c73a392511..63ab9bafa23d9 100644 --- a/tests/ui/where-clauses/where-clauses-lifetimes.rs +++ b/tests/ui/where-clauses/where-clauses-lifetimes.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(unused_mut)] #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 fn foo<'a, I>(mut it: I) where I: Iterator {} diff --git a/tests/ui/where-clauses/where-clauses-unboxed-closures.rs b/tests/ui/where-clauses/where-clauses-unboxed-closures.rs index c2ef65ab0a699..5961a51645785 100644 --- a/tests/ui/where-clauses/where-clauses-unboxed-closures.rs +++ b/tests/ui/where-clauses/where-clauses-unboxed-closures.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_variables)] -//@ pretty-expanded FIXME #23616 struct Bencher; diff --git a/triagebot.toml b/triagebot.toml index b7a9b794c8be7..47b968240984d 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -428,8 +428,14 @@ trigger_files = [ "triagebot.toml", "rustfmt.toml", "LICENSES", + "COPYRIGHT", + "LICENSE-APACHE", + "LICENSE-MIT", + "CODE_OF_CONDUCT.md", "README.md", "CONTRIBUTING.md", + "INSTALL.md", + "REUSE.toml", ".reuse", ".mailmap", ".git-blame-ignore-revs", @@ -991,7 +997,6 @@ contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" users_on_vacation = [ "jyn514", "oli-obk", - "onur-ozkan", ] [assign.adhoc_groups]