From 3ee054c32418ac7f68952678773ac3379e23e55d Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 3 May 2021 09:26:13 -0400 Subject: [PATCH 01/18] bump channel to stable --- src/ci/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index 02d868f8f2a37..a408fa83e5553 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -68,7 +68,7 @@ fi # # FIXME: need a scheme for changing this `nightly` value to `beta` and `stable` # either automatically or manually. -export RUST_RELEASE_CHANNEL=beta +export RUST_RELEASE_CHANNEL=stable # Always set the release channel for bootstrap; this is normally not important (i.e., only dist # builds would seem to matter) but in practice bootstrap wants to know whether we're targeting From 59ed9c3add7feeea0403e8d1a89ecbb52211672b Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 3 May 2021 09:28:16 -0400 Subject: [PATCH 02/18] Cherry-pick release notes --- RELEASES.md | 354 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 343 insertions(+), 11 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 5dca7abcb2629..1e94fb8e42f04 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,329 @@ +Version 1.52.0 (2021-05-06) +============================ + +Language +-------- +- [Added the `unsafe_op_in_unsafe_fn` lint, which checks whether the unsafe code + in an `unsafe fn` is wrapped in a `unsafe` block.][79208] This lint + is allowed by default, and may become a warning or hard error in a + future edition. +- [You can now cast mutable references to arrays to a pointer of the same type as + the element.][81479] + +Compiler +-------- +- [Upgraded the default LLVM to LLVM 12.][81451] + +Added tier 3\* support for the following targets. + +- [`s390x-unknown-linux-musl`][82166] +- [`riscv32gc-unknown-linux-musl` & `riscv64gc-unknown-linux-musl`][82202] +- [`powerpc-unknown-openbsd`][82733] + +\* Refer to Rust's [platform support page][platform-support-doc] for more +information on Rust's tiered platform support. + +Libraries +--------- +- [`OsString` now implements `Extend` and `FromIterator`.][82121] +- [`cmp::Reverse` now has `#[repr(transparent)]` representation.][81879] +- [`Arc` now implements `error::Error`.][80553] +- [All integer division and remainder operations are now `const`.][80962] + +Stabilised APIs +------------- +- [`Arguments::as_str`] +- [`char::MAX`] +- [`char::REPLACEMENT_CHARACTER`] +- [`char::UNICODE_VERSION`] +- [`char::decode_utf16`] +- [`char::from_digit`] +- [`char::from_u32_unchecked`] +- [`char::from_u32`] +- [`slice::partition_point`] +- [`str::rsplit_once`] +- [`str::split_once`] + +The following previously stable APIs are now `const`. + +- [`char::len_utf8`] +- [`char::len_utf16`] +- [`char::to_ascii_uppercase`] +- [`char::to_ascii_lowercase`] +- [`char::eq_ignore_ascii_case`] +- [`u8::to_ascii_uppercase`] +- [`u8::to_ascii_lowercase`] +- [`u8::eq_ignore_ascii_case`] + +Rustdoc +------- +- [Rustdoc lints are now treated as a tool lint, meaning that + lints are now prefixed with `rustdoc::` (e.g. `#[warn(rustdoc::non_autolinks)]`).][80527] + Using the old style is still allowed, and will become a warning in + a future release. +- [Rustdoc now supports argument files.][82261] +- [Rustdoc now generates smart punctuation for documentation.][79423] +- [You can now use "task lists" in Rustdoc Markdown.][81766] E.g. + ```markdown + - [x] Complete + - [ ] Todo + ``` + +Misc +---- +- [You can now pass multiple filters to tests.][81356] E.g. + `cargo test -- foo bar` will run all tests that match `foo` and `bar`. +- [Rustup now distributes PDB symbols for the `std` library on Windows, + allowing you to see `std` symbols when debugging.][82218] + +Internal Only +------------- +These changes provide no direct user facing benefits, but represent significant +improvements to the internals and overall performance of rustc and +related tools. + +- [Check the result cache before the DepGraph when ensuring queries][81855] +- [Try fast_reject::simplify_type in coherence before doing full check][81744] +- [Only store a LocalDefId in some HIR nodes][81611] +- [Store HIR attributes in a side table][79519] + +Compatibility Notes +------------------- +- [Cargo build scripts are now forbidden from setting `RUSTC_BOOTSTRAP`.][cargo/9181] +- [Removed support for the `x86_64-rumprun-netbsd` target.][82594] +- [Deprecated the `x86_64-sun-solaris` target in favor of `x86_64-pc-solaris`.][82216] +- [Rustdoc now only accepts `,`, ` `, and `\t` as delimiters for specifying + languages in code blocks.][78429] +- [Rustc now catches more cases of `pub_use_of_private_extern_crate`][80763] +- [Changes in how proc macros handle whitespace may lead to panics when used + with older `proc-macro-hack` versions. A `cargo update` should be sufficient to fix this in all cases.][84136] + +[84136]: https://github.com/rust-lang/rust/issues/84136 +[80763]: https://github.com/rust-lang/rust/pull/80763 +[82166]: https://github.com/rust-lang/rust/pull/82166 +[82121]: https://github.com/rust-lang/rust/pull/82121 +[81879]: https://github.com/rust-lang/rust/pull/81879 +[82261]: https://github.com/rust-lang/rust/pull/82261 +[82218]: https://github.com/rust-lang/rust/pull/82218 +[82216]: https://github.com/rust-lang/rust/pull/82216 +[82202]: https://github.com/rust-lang/rust/pull/82202 +[81855]: https://github.com/rust-lang/rust/pull/81855 +[81766]: https://github.com/rust-lang/rust/pull/81766 +[81744]: https://github.com/rust-lang/rust/pull/81744 +[81611]: https://github.com/rust-lang/rust/pull/81611 +[81479]: https://github.com/rust-lang/rust/pull/81479 +[81451]: https://github.com/rust-lang/rust/pull/81451 +[81356]: https://github.com/rust-lang/rust/pull/81356 +[80962]: https://github.com/rust-lang/rust/pull/80962 +[80553]: https://github.com/rust-lang/rust/pull/80553 +[80527]: https://github.com/rust-lang/rust/pull/80527 +[79519]: https://github.com/rust-lang/rust/pull/79519 +[79423]: https://github.com/rust-lang/rust/pull/79423 +[79208]: https://github.com/rust-lang/rust/pull/79208 +[78429]: https://github.com/rust-lang/rust/pull/78429 +[82733]: https://github.com/rust-lang/rust/pull/82733 +[82594]: https://github.com/rust-lang/rust/pull/82594 +[cargo/9181]: https://github.com/rust-lang/cargo/pull/9181 +[`char::MAX`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.MAX +[`char::REPLACEMENT_CHARACTER`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.REPLACEMENT_CHARACTER +[`char::UNICODE_VERSION`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.UNICODE_VERSION +[`char::decode_utf16`]: https://doc.rust-lang.org/std/primitive.char.html#method.decode_utf16 +[`char::from_u32`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_u32 +[`char::from_u32_unchecked`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_u32_unchecked +[`char::from_digit`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_digit +[`Peekable::next_if`]: https://doc.rust-lang.org/stable/std/iter/struct.Peekable.html#method.next_if +[`Peekable::next_if_eq`]: https://doc.rust-lang.org/stable/std/iter/struct.Peekable.html#method.next_if_eq +[`Arguments::as_str`]: https://doc.rust-lang.org/stable/std/fmt/struct.Arguments.html#method.as_str +[`str::split_once`]: https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_once +[`str::rsplit_once`]: https://doc.rust-lang.org/stable/std/primitive.str.html#method.rsplit_once +[`slice::partition_point`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.partition_point +[`char::len_utf8`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.len_utf8 +[`char::len_utf16`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.len_utf16 +[`char::to_ascii_uppercase`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.to_ascii_uppercase +[`char::to_ascii_lowercase`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.to_ascii_lowercase +[`char::eq_ignore_ascii_case`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.eq_ignore_ascii_case +[`u8::to_ascii_uppercase`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_ascii_uppercase +[`u8::to_ascii_lowercase`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_ascii_lowercase +[`u8::eq_ignore_ascii_case`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.eq_ignore_ascii_case + +Version 1.51.0 (2021-03-25) +============================ + +Language +-------- +- [You can now parameterize items such as functions, traits, and `struct`s by constant + values in addition to by types and lifetimes.][79135] Also known as "const generics" + E.g. you can now write the following. Note: Only values of primitive integers, + `bool`, or `char` types are currently permitted. + ```rust + struct GenericArray { + inner: [T; LENGTH] + } + + impl GenericArray { + const fn last(&self) -> Option<&T> { + if LENGTH == 0 { + None + } else { + Some(&self.inner[LENGTH - 1]) + } + } + } + ``` + + +Compiler +-------- + +- [Added the `-Csplit-debuginfo` codegen option for macOS platforms.][79570] + This option controls whether debug information is split across multiple files + or packed into a single file. **Note** This option is unstable on other platforms. +- [Added tier 3\* support for `aarch64_be-unknown-linux-gnu`, + `aarch64-unknown-linux-gnu_ilp32`, and `aarch64_be-unknown-linux-gnu_ilp32` targets.][81455] +- [Added tier 3 support for `i386-unknown-linux-gnu` and `i486-unknown-linux-gnu` targets.][80662] +- [The `target-cpu=native` option will now detect individual features of CPUs.][80749] + +\* Refer to Rust's [platform support page][platform-support-doc] for more +information on Rust's tiered platform support. + +Libraries +--------- + +- [`Box::downcast` is now also implemented for any `dyn Any + Send + Sync` object.][80945] +- [`str` now implements `AsMut`.][80279] +- [`u64` and `u128` now implement `From`.][79502] +- [`Error` is now implemented for `&T` where `T` implements `Error`.][75180] +- [`Poll::{map_ok, map_err}` are now implemented for `Poll>>`.][80968] +- [`unsigned_abs` is now implemented for all signed integer types.][80959] +- [`io::Empty` now implements `io::Seek`.][78044] +- [`rc::Weak` and `sync::Weak`'s methods such as `as_ptr` are now implemented for + `T: ?Sized` types.][80764] +- [`Div` and `Rem` by their `NonZero` variant is now implemented for all unsigned integers.][79134] + + +Stabilized APIs +--------------- + +- [`Arc::decrement_strong_count`] +- [`Arc::increment_strong_count`] +- [`Once::call_once_force`] +- [`Peekable::next_if_eq`] +- [`Peekable::next_if`] +- [`Seek::stream_position`] +- [`array::IntoIter`] +- [`panic::panic_any`] +- [`ptr::addr_of!`] +- [`ptr::addr_of_mut!`] +- [`slice::fill_with`] +- [`slice::split_inclusive_mut`] +- [`slice::split_inclusive`] +- [`slice::strip_prefix`] +- [`slice::strip_suffix`] +- [`str::split_inclusive`] +- [`sync::OnceState`] +- [`task::Wake`] +- [`VecDeque::range`] +- [`VecDeque::range_mut`] + +Cargo +----- +- [Added the `split-debuginfo` profile option to control the -Csplit-debuginfo + codegen option.][cargo/9112] +- [Added the `resolver` field to `Cargo.toml` to enable the new feature resolver + and CLI option behavior.][cargo/8997] Version 2 of the feature resolver will try + to avoid unifying features of dependencies where that unification could be unwanted. + Such as using the same dependency with a `std` feature in a build scripts and + proc-macros, while using the `no-std` feature in the final binary. See the + [Cargo book documentation][feature-resolver@2.0] for more information on the feature. + +Rustdoc +------- + +- [Rustdoc will now include documentation for methods available from _nested_ `Deref` traits.][80653] +- [You can now provide a `--default-theme` flag which sets the default theme to use for + documentation.][79642] + +Various improvements to intra-doc links: + +- [You can link to non-path primitives such as `slice`.][80181] +- [You can link to associated items.][74489] +- [You can now include generic parameters when linking to items, like `Vec`.][76934] + +Misc +---- +- [You can now pass `--include-ignored` to tests (e.g. with + `cargo test -- --include-ignored`) to include testing tests marked `#[ignore]`.][80053] + +Compatibility Notes +------------------- + +- [WASI platforms no longer use the `wasm-bindgen` ABI, and instead use the wasm32 ABI.][79998] +- [`rustc` no longer promotes division, modulo and indexing operations to `const` that + could fail.][80579] +- [The minimum version of glibc for the following platforms has been bumped to version 2.31 + for the distributed artifacts.][81521] + - `armv5te-unknown-linux-gnueabi` + - `sparc64-unknown-linux-gnu` + - `thumbv7neon-unknown-linux-gnueabihf` + - `armv7-unknown-linux-gnueabi` + - `x86_64-unknown-linux-gnux32` +- [`atomic::spin_loop_hint` has been deprecated.][80966] It's recommended to use `hint::spin_loop` instead. + +Internal Only +------------- + +- [Consistently avoid constructing optimized MIR when not doing codegen][80718] + +[79135]: https://github.com/rust-lang/rust/pull/79135 +[74489]: https://github.com/rust-lang/rust/pull/74489 +[76934]: https://github.com/rust-lang/rust/pull/76934 +[79570]: https://github.com/rust-lang/rust/pull/79570 +[80181]: https://github.com/rust-lang/rust/pull/80181 +[79642]: https://github.com/rust-lang/rust/pull/79642 +[80945]: https://github.com/rust-lang/rust/pull/80945 +[80279]: https://github.com/rust-lang/rust/pull/80279 +[80053]: https://github.com/rust-lang/rust/pull/80053 +[79502]: https://github.com/rust-lang/rust/pull/79502 +[75180]: https://github.com/rust-lang/rust/pull/75180 +[79135]: https://github.com/rust-lang/rust/pull/79135 +[81521]: https://github.com/rust-lang/rust/pull/81521 +[80968]: https://github.com/rust-lang/rust/pull/80968 +[80959]: https://github.com/rust-lang/rust/pull/80959 +[80718]: https://github.com/rust-lang/rust/pull/80718 +[80653]: https://github.com/rust-lang/rust/pull/80653 +[80579]: https://github.com/rust-lang/rust/pull/80579 +[79998]: https://github.com/rust-lang/rust/pull/79998 +[78044]: https://github.com/rust-lang/rust/pull/78044 +[81455]: https://github.com/rust-lang/rust/pull/81455 +[80764]: https://github.com/rust-lang/rust/pull/80764 +[80749]: https://github.com/rust-lang/rust/pull/80749 +[80662]: https://github.com/rust-lang/rust/pull/80662 +[79134]: https://github.com/rust-lang/rust/pull/79134 +[80966]: https://github.com/rust-lang/rust/pull/80966 +[cargo/8997]: https://github.com/rust-lang/cargo/pull/8997 +[cargo/9112]: https://github.com/rust-lang/cargo/pull/9112 +[feature-resolver@2.0]: https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-resolver-version-2 +[`Once::call_once_force`]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.call_once_force +[`sync::OnceState`]: https://doc.rust-lang.org/stable/std/sync/struct.OnceState.html +[`panic::panic_any`]: https://doc.rust-lang.org/stable/std/panic/fn.panic_any.html +[`slice::strip_prefix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix +[`slice::strip_suffix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix +[`Arc::increment_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.increment_strong_count +[`Arc::decrement_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.decrement_strong_count +[`slice::fill_with`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.fill_with +[`ptr::addr_of!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of.html +[`ptr::addr_of_mut!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of_mut.html +[`array::IntoIter`]: https://doc.rust-lang.org/nightly/std/array/struct.IntoIter.html +[`slice::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive +[`slice::split_inclusive_mut`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive_mut +[`str::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_inclusive +[`task::Wake`]: https://doc.rust-lang.org/nightly/std/task/trait.Wake.html +[`Seek::stream_position`]: https://doc.rust-lang.org/nightly/std/io/trait.Seek.html#method.stream_position +[`Peekable::next_if`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if +[`Peekable::next_if_eq`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if_eq +[`VecDeque::range`]: https://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.range +[`VecDeque::range_mut`]: https://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.range_mut + Version 1.50.0 (2021-02-11) ============================ @@ -14,7 +340,7 @@ Compiler - [The `x86_64-unknown-freebsd` is now built with the full toolset.][79484] - [Dropped support for all cloudabi targets.][78439] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -191,7 +517,7 @@ Compiler - [Output from threads spawned in tests is now captured.][78227] - [Change os and vendor values to "none" and "unknown" for some targets][78951] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -296,7 +622,7 @@ Compiler Note: If you're using cargo you must explicitly pass the `--target` flag. - [Added tier 2\* support for `aarch64-unknown-linux-musl`.][76420] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -435,7 +761,7 @@ Compiler - [Upgrade the FreeBSD toolchain to version 11.4][75204] - [`RUST_BACKTRACE`'s output is now more compact.][75048] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -720,7 +1046,7 @@ Compiler - [Added tier 3 support for the `thumbv7a-uwp-windows-msvc` target.][72133] - [Upgraded to LLVM 10.][67759] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. @@ -1229,7 +1555,7 @@ Compiler pointing to the location where they were called, rather than `core`'s internals. ][67887] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -1327,7 +1653,7 @@ Compiler - [You can now provide `--extern` flag without a path, indicating that it is available from the search path or specified with an `-L` flag.][64882] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. [argfile-docs]: https://doc.rust-lang.org/nightly/rustc/command-line-arguments.html#path-load-command-line-flags-from-a-path @@ -1451,7 +1777,7 @@ Compiler - [Added tier 3 support for the `mips64-unknown-linux-muslabi64`, and `mips64el-unknown-linux-muslabi64` targets.][65843] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -1601,7 +1927,7 @@ Compiler output of successful tests.][62600] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -1695,7 +2021,7 @@ Compiler - [Added tier 3 support for the `riscv32i-unknown-none-elf` target.][62784] - [Upgraded to LLVM 9.][62592] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -1737,6 +2063,11 @@ Cargo - [You can now pass the `--features` option multiple times to enable multiple features.][cargo/7084] +Rustdoc +------- + +- [Documentation on `pub use` statements is prepended to the documentation of the re-exported item][63048] + Misc ---- - [`rustc` will now warn about some incorrect uses of @@ -1771,6 +2102,7 @@ Compatibility Notes [63421]: https://github.com/rust-lang/rust/pull/63421/ [cargo/7084]: https://github.com/rust-lang/cargo/pull/7084/ [cargo/7143]: https://github.com/rust-lang/cargo/pull/7143/ +[63048]: https://github.com/rust-lang/rust/pull/63048 [`<*const T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast [`<*mut T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast [`Duration::as_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f32 @@ -1782,7 +2114,7 @@ Compatibility Notes [`Duration::mul_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f32 [`Duration::mul_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f64 [`any::type_name`]: https://doc.rust-lang.org/std/any/fn.type_name.html -[forge-platform-support]: https://forge.rust-lang.org/release/platform-support.html +[platform-support-doc]: https://doc.rust-lang.org/nightly/rustc/platform-support.html [pipeline-internals]: https://internals.rust-lang.org/t/evaluating-pipelined-rustc-compilation/10199 Version 1.37.0 (2019-08-15) From 1905c98e92c94478bc07e5e9c90a9d3dacead6c2 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 29 Apr 2021 15:56:12 -0400 Subject: [PATCH 03/18] Effective beta backport of 8d1083e319841624f64400e1524805a40d725439 (I recreated it by hand because the result of the cherry-pick wasn't worth trying to salvage.) --- compiler/rustc_target/src/spec/i386_apple_ios.rs | 3 ++- compiler/rustc_target/src/spec/i686_apple_darwin.rs | 3 ++- compiler/rustc_target/src/spec/i686_linux_android.rs | 3 ++- compiler/rustc_target/src/spec/i686_unknown_freebsd.rs | 3 ++- compiler/rustc_target/src/spec/i686_unknown_haiku.rs | 3 ++- compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs | 3 ++- compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs | 3 ++- compiler/rustc_target/src/spec/i686_unknown_netbsd.rs | 3 ++- compiler/rustc_target/src/spec/i686_unknown_openbsd.rs | 3 ++- compiler/rustc_target/src/spec/i686_wrs_vxworks.rs | 3 ++- compiler/rustc_target/src/spec/linux_kernel_base.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_apple_darwin.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_apple_ios.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_apple_tvos.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_fuchsia.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_linux_android.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_pc_solaris.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_sun_solaris.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs | 3 ++- .../rustc_target/src/spec/x86_64_unknown_none_hermitkernel.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_unknown_redox.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs | 3 ++- 31 files changed, 62 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_target/src/spec/i386_apple_ios.rs b/compiler/rustc_target/src/spec/i386_apple_ios.rs index cfaf020175b7f..f5d7be4537be0 100644 --- a/compiler/rustc_target/src/spec/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/i386_apple_ios.rs @@ -12,7 +12,8 @@ pub fn target() -> Target { arch: "x86".to_string(), options: TargetOptions { max_atomic_width: Some(64), - stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }, + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + stack_probes: StackProbeType::Call, ..base }, } diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs index 2d3310c7582ef..06d71db4af241 100644 --- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs @@ -6,7 +6,8 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]); base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; base.eliminate_frame_pointer = false; // Clang automatically chooses a more specific target based on diff --git a/compiler/rustc_target/src/spec/i686_linux_android.rs b/compiler/rustc_target/src/spec/i686_linux_android.rs index 18cd8847abd39..19d7b3c95cf6d 100644 --- a/compiler/rustc_target/src/spec/i686_linux_android.rs +++ b/compiler/rustc_target/src/spec/i686_linux_android.rs @@ -11,7 +11,8 @@ pub fn target() -> Target { // http://developer.android.com/ndk/guides/abis.html#x86 base.cpu = "pentiumpro".to_string(); base.features = "+mmx,+sse,+sse2,+sse3,+ssse3".to_string(); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "i686-linux-android".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs index fc425babb6948..75c3ea6a9adb1 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs @@ -7,7 +7,8 @@ pub fn target() -> Target { let pre_link_args = base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); pre_link_args.push("-m32".to_string()); pre_link_args.push("-Wl,-znotext".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "i686-unknown-freebsd".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs index 5fba4e3f14a25..e4c01db543980 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "i686-unknown-haiku".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs index fe1e6a4299dab..9daf1d37dd267 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "i686-unknown-linux-gnu".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs index 623fd1b9ae801..5fd54007edf2e 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs @@ -6,7 +6,8 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,-melf_i386".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; // The unwinder used by i686-unknown-linux-musl, the LLVM libunwind // implementation, apparently relies on frame pointers existing... somehow. diff --git a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs index c4d11bfb13ece..716bb9e246073 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "i686-unknown-netbsdelf".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs index fdaaf6c741e89..e53462c099a96 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs @@ -6,7 +6,8 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-fuse-ld=lld".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "i686-unknown-openbsd".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs index ec8a2493b4e42..2f8702d464d32 100644 --- a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "i686-unknown-linux-gnu".to_string(), diff --git a/compiler/rustc_target/src/spec/linux_kernel_base.rs b/compiler/rustc_target/src/spec/linux_kernel_base.rs index 5220156895367..738ff38b094de 100644 --- a/compiler/rustc_target/src/spec/linux_kernel_base.rs +++ b/compiler/rustc_target/src/spec/linux_kernel_base.rs @@ -13,7 +13,8 @@ pub fn opts() -> TargetOptions { env: "gnu".to_string(), disable_redzone: true, panic_strategy: PanicStrategy::Abort, - stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }, + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + stack_probes: StackProbeType::Call, eliminate_frame_pointer: false, linker_is_gnu: true, position_independent_executables: true, diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs index 8c40baccda84a..570cf7974fe28 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs @@ -10,7 +10,8 @@ pub fn target() -> Target { vec!["-m64".to_string(), "-arch".to_string(), "x86_64".to_string()], ); base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; // Clang automatically chooses a more specific target based on // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs index 6feeeac451b27..adb877185897b 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs @@ -11,7 +11,8 @@ pub fn target() -> Target { arch: "x86_64".to_string(), options: TargetOptions { max_atomic_width: Some(64), - stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }, + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + stack_probes: StackProbeType::Call, ..base }, } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs index a6e066213e7f9..c228e42ef3004 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs @@ -11,7 +11,8 @@ pub fn target() -> Target { arch: "x86_64".to_string(), options: TargetOptions { max_atomic_width: Some(64), - stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }, + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + stack_probes: StackProbeType::Call, ..base }, } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs index f8c47168da87f..e3a5de4cbd1a4 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs @@ -10,7 +10,8 @@ pub fn target() -> Target { arch: "x86_64".to_string(), options: TargetOptions { max_atomic_width: Some(64), - stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }, + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + stack_probes: StackProbeType::Call, ..base }, } diff --git a/compiler/rustc_target/src/spec/x86_64_fuchsia.rs b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs index a39e7f8c34105..7774308b4ca52 100644 --- a/compiler/rustc_target/src/spec/x86_64_fuchsia.rs +++ b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs @@ -4,7 +4,8 @@ pub fn target() -> Target { let mut base = super::fuchsia_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "x86_64-fuchsia".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_linux_android.rs b/compiler/rustc_target/src/spec/x86_64_linux_android.rs index d436242e62b30..19bf27c457e83 100644 --- a/compiler/rustc_target/src/spec/x86_64_linux_android.rs +++ b/compiler/rustc_target/src/spec/x86_64_linux_android.rs @@ -7,7 +7,8 @@ pub fn target() -> Target { base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "x86_64-linux-android".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs index 75eece74ff97d..b78e43d4fe9b6 100644 --- a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs +++ b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs @@ -6,7 +6,8 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); base.vendor = "pc".to_string(); base.max_atomic_width = Some(64); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "x86_64-pc-solaris".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs index 63e524fa8a9a2..2fa53470f74f2 100644 --- a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs @@ -6,7 +6,8 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); base.vendor = "sun".to_string(); base.max_atomic_width = Some(64); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "x86_64-pc-solaris".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs index d86b0d67acd15..d551ce6d3715f 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "x86_64-unknown-dragonfly".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs index c7d3b3feed50e..e51f6c1a75417 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "x86_64-unknown-freebsd".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs index 963d4fdb12f2d..fcd96ddd61b33 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; // This option is required to build executables on Haiku x86_64 base.position_independent_executables = true; diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs index 31164f8408dcb..1ef24b6eb365e 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.features = "+rdrnd,+rdseed".to_string(); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "x86_64-unknown-hermit".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs index 99906764dfc6e..04499bc5bbe06 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "x86_64-unknown-linux-gnu".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs index 4b2bce37470cc..5bf9a195756ba 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mx32".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; base.has_elf_tls = false; // BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI // breaks code gen. See LLVM bug 36743 diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs index fa9fdf5aa0992..658dc977c1cc7 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; base.static_position_independent_executables = true; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs index 6d19dec00b411..4718ad2be4ae9 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "x86_64-unknown-netbsd".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none_hermitkernel.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none_hermitkernel.rs index a357def190b83..28d9801b78cb5 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_none_hermitkernel.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_none_hermitkernel.rs @@ -7,7 +7,8 @@ pub fn target() -> Target { base.features = "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float" .to_string(); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "x86_64-unknown-none-elf".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs index ac5939bcb3c43..2c5ac43f24661 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "x86_64-unknown-openbsd".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs index ddabe95ab8394..b5aa37d032ee0 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; Target { llvm_target: "x86_64-unknown-redox".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs index 1b35e813fcd8f..6c59817259f8e 100644 --- a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs @@ -5,7 +5,8 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; base.disable_redzone = true; Target { From 463b3a2a74fc13eea82dc62468eadd65dfb0ca64 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 29 Apr 2021 15:12:46 -0400 Subject: [PATCH 04/18] Remove tests introduced or cahnged by PR #77885, which is reverted in this PR. --- src/test/assembly/stack-probes.rs | 42 ------------------------------- src/test/codegen/stack-probes.rs | 2 -- 2 files changed, 44 deletions(-) delete mode 100644 src/test/assembly/stack-probes.rs diff --git a/src/test/assembly/stack-probes.rs b/src/test/assembly/stack-probes.rs deleted file mode 100644 index 9597e242f1b0f..0000000000000 --- a/src/test/assembly/stack-probes.rs +++ /dev/null @@ -1,42 +0,0 @@ -// min-llvm-version: 11.0.1 -// revisions: x86_64 i686 -// assembly-output: emit-asm -//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu -//[i686] compile-flags: --target i686-unknown-linux-gnu -// compile-flags: -C llvm-args=--x86-asm-syntax=intel - -#![feature(no_core, lang_items)] -#![crate_type = "lib"] -#![no_core] - -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} - -impl Copy for u8 {} - -// Check that inline-asm stack probes are generated correctly. -// To avoid making this test fragile to slight asm changes, -// we only check that the stack pointer is decremented by a page at a time, -// instead of matching the whole probe sequence. - -// CHECK-LABEL: small_stack_probe: -#[no_mangle] -pub fn small_stack_probe(x: u8, f: fn([u8; 8192])) { - // CHECK-NOT: __rust_probestack - // x86_64: sub rsp, 4096 - // i686: sub esp, 4096 - let a = [x; 8192]; - f(a); -} - -// CHECK-LABEL: big_stack_probe: -#[no_mangle] -pub fn big_stack_probe(x: u8, f: fn([u8; 65536])) { - // CHECK-NOT: __rust_probestack - // x86_64: sub rsp, 4096 - // i686: sub esp, 4096 - let a = [x; 65536]; - f(a); -} diff --git a/src/test/codegen/stack-probes.rs b/src/test/codegen/stack-probes.rs index b05787df8e30b..9bd351df3eaa0 100644 --- a/src/test/codegen/stack-probes.rs +++ b/src/test/codegen/stack-probes.rs @@ -13,12 +13,10 @@ // ignore-emscripten // ignore-windows // compile-flags: -C no-prepopulate-passes -// min-llvm-version: 11.0.1 #![crate_type = "lib"] #[no_mangle] pub fn foo() { // CHECK: @foo() unnamed_addr #0 -// CHECK: attributes #0 = { {{.*}}"probe-stack"="inline-asm"{{.*}} } } From fa332b02450fdf5813aa82c8433f9565aff59466 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Fri, 30 Apr 2021 12:06:52 -0400 Subject: [PATCH 05/18] Revert "Add assert_matches!(expr, pat)." This reverts commit eb18746bc6c6c5c710ad674873438cbad5894f06. --- library/core/src/macros/mod.rs | 54 -------------------------- library/core/src/panicking.rs | 69 ++++++++++++---------------------- library/std/src/lib.rs | 5 +-- 3 files changed, 25 insertions(+), 103 deletions(-) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 99894b5605e6d..9a0c0a2817fe3 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -110,60 +110,6 @@ macro_rules! assert_ne { }); } -/// Asserts that an expression matches any of the given patterns. -/// -/// Like in a `match` expression, the pattern can be optionally followed by `if` -/// and a guard expression that has access to names bound by the pattern. -/// -/// On panic, this macro will print the value of the expression with its -/// debug representation. -/// -/// Like [`assert!`], this macro has a second form, where a custom -/// panic message can be provided. -/// -/// # Examples -/// -/// ``` -/// #![feature(assert_matches)] -/// -/// let a = 1u32.checked_add(2); -/// let b = 1u32.checked_sub(2); -/// assert_matches!(a, Some(_)); -/// assert_matches!(b, None); -/// -/// let c = Ok("abc".to_string()); -/// assert_matches!(c, Ok(x) | Err(x) if x.len() < 100); -/// ``` -#[macro_export] -#[unstable(feature = "assert_matches", issue = "82775")] -#[allow_internal_unstable(core_panic)] -macro_rules! assert_matches { - ($left:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => ({ - match $left { - $( $pattern )|+ $( if $guard )? => {} - ref left_val => { - $crate::panicking::assert_matches_failed( - left_val, - $crate::stringify!($($pattern)|+ $(if $guard)?), - $crate::option::Option::None - ); - } - } - }); - ($left:expr, $( $pattern:pat )|+ $( if $guard: expr )?, $($arg:tt)+) => ({ - match $left { - $( $pattern )|+ $( if $guard )? => {} - ref left_val => { - $crate::panicking::assert_matches_failed( - left_val, - $crate::stringify!($($pattern)|+ $(if $guard)?), - $crate::option::Option::Some($crate::format_args!($($arg)+)) - ); - } - } - }); -} - /// Asserts that a boolean expression is `true` at runtime. /// /// This will invoke the [`panic!`] macro if the provided expression cannot be diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 3e3e96fcd7f78..35d9b2c5d267f 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -97,7 +97,6 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { pub enum AssertKind { Eq, Ne, - Match, } /// Internal function for `assert_eq!` and `assert_ne!` macros @@ -114,54 +113,32 @@ where T: fmt::Debug + ?Sized, U: fmt::Debug + ?Sized, { - assert_failed_inner(kind, &left, &right, args) -} - -/// Internal function for `assert_match!` -#[cold] -#[track_caller] -#[doc(hidden)] -pub fn assert_matches_failed( - left: &T, - right: &str, - args: Option>, -) -> ! { - // Use the Display implementation to display the pattern. - struct Pattern<'a>(&'a str); - impl fmt::Debug for Pattern<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self.0, f) - } - } - assert_failed_inner(AssertKind::Match, &left, &Pattern(right), args); -} - -/// Non-generic version of the above functions, to avoid code bloat. -#[track_caller] -fn assert_failed_inner( - kind: AssertKind, - left: &dyn fmt::Debug, - right: &dyn fmt::Debug, - args: Option>, -) -> ! { - let op = match kind { - AssertKind::Eq => "==", - AssertKind::Ne => "!=", - AssertKind::Match => "matches", - }; - - match args { - Some(args) => panic!( - r#"assertion failed: `(left {} right)` + #[track_caller] + fn inner( + kind: AssertKind, + left: &dyn fmt::Debug, + right: &dyn fmt::Debug, + args: Option>, + ) -> ! { + let op = match kind { + AssertKind::Eq => "==", + AssertKind::Ne => "!=", + }; + + match args { + Some(args) => panic!( + r#"assertion failed: `(left {} right)` left: `{:?}`, right: `{:?}`: {}"#, - op, left, right, args - ), - None => panic!( - r#"assertion failed: `(left {} right)` + op, left, right, args + ), + None => panic!( + r#"assertion failed: `(left {} right)` left: `{:?}`, right: `{:?}`"#, - op, left, right, - ), + op, left, right, + ), + } } + inner(kind, &left, &right, args) } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 8149858e10338..51c2872e9cae7 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -228,7 +228,6 @@ #![feature(arbitrary_self_types)] #![feature(array_error_internals)] #![feature(asm)] -#![feature(assert_matches)] #![feature(associated_type_bounds)] #![feature(atomic_mut_ptr)] #![feature(box_syntax)] @@ -559,8 +558,8 @@ pub use std_detect::detect; #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated, deprecated_in_future)] pub use core::{ - assert_eq, assert_matches, assert_ne, debug_assert, debug_assert_eq, debug_assert_matches, - debug_assert_ne, matches, r#try, todo, unimplemented, unreachable, write, writeln, + assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_matches, debug_assert_ne, + matches, r#try, todo, unimplemented, unreachable, write, writeln, }; // Re-export built-in macros defined through libcore. From 1406d0610493b9090c55bb36c7cc4e8f14e4a441 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Fri, 30 Apr 2021 12:08:30 -0400 Subject: [PATCH 06/18] Revert "Add debug_assert_matches macro." This reverts commit 0a8e401188062f0c60c989978352663b1e25e70e. --- library/core/src/macros/mod.rs | 36 ---------------------------------- library/std/src/lib.rs | 4 ++-- 2 files changed, 2 insertions(+), 38 deletions(-) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 9a0c0a2817fe3..a0a8eecbc2527 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -208,42 +208,6 @@ macro_rules! debug_assert_ne { ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); }) } -/// Asserts that an expression matches any of the given patterns. -/// -/// Like in a `match` expression, the pattern can be optionally followed by `if` -/// and a guard expression that has access to names bound by the pattern. -/// -/// On panic, this macro will print the value of the expression with its -/// debug representation. -/// -/// Unlike [`assert_matches!`], `debug_assert_matches!` statements are only -/// enabled in non optimized builds by default. An optimized build will not -/// execute `debug_assert_matches!` statements unless `-C debug-assertions` is -/// passed to the compiler. This makes `debug_assert_matches!` useful for -/// checks that are too expensive to be present in a release build but may be -/// helpful during development. The result of expanding `debug_assert_matches!` -/// is always type checked. -/// -/// # Examples -/// -/// ``` -/// #![feature(assert_matches)] -/// -/// let a = 1u32.checked_add(2); -/// let b = 1u32.checked_sub(2); -/// debug_assert_matches!(a, Some(_)); -/// debug_assert_matches!(b, None); -/// -/// let c = Ok("abc".to_string()); -/// debug_assert_matches!(c, Ok(x) | Err(x) if x.len() < 100); -/// ``` -#[macro_export] -#[unstable(feature = "assert_matches", issue = "82775")] -#[allow_internal_unstable(assert_matches)] -macro_rules! debug_assert_matches { - ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_matches!($($arg)*); }) -} - /// Returns whether the given expression matches any of the given patterns. /// /// Like in a `match` expression, the pattern can be optionally followed by `if` diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 51c2872e9cae7..1f53a4c783c7a 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -558,8 +558,8 @@ pub use std_detect::detect; #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated, deprecated_in_future)] pub use core::{ - assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_matches, debug_assert_ne, - matches, r#try, todo, unimplemented, unreachable, write, writeln, + assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, matches, r#try, todo, + unimplemented, unreachable, write, writeln, }; // Re-export built-in macros defined through libcore. From aa3e8d3e7875651bda409a2a810d602ac9446142 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Fri, 30 Apr 2021 12:11:35 -0400 Subject: [PATCH 07/18] Remove assert_matches users --- compiler/rustc_middle/src/ich/impls_syntax.rs | 6 +----- .../rustc_middle/src/mir/interpret/allocation.rs | 2 +- compiler/rustc_mir/src/interpret/memory.rs | 14 +++----------- src/test/ui/macros/assert-matches-macro-msg.rs | 11 ----------- 4 files changed, 5 insertions(+), 28 deletions(-) delete mode 100644 src/test/ui/macros/assert-matches-macro-msg.rs diff --git a/compiler/rustc_middle/src/ich/impls_syntax.rs b/compiler/rustc_middle/src/ich/impls_syntax.rs index 31374429940ca..aacec86071197 100644 --- a/compiler/rustc_middle/src/ich/impls_syntax.rs +++ b/compiler/rustc_middle/src/ich/impls_syntax.rs @@ -45,11 +45,7 @@ impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> { item.hash_stable(self, hasher); style.hash_stable(self, hasher); span.hash_stable(self, hasher); - assert_matches!( - tokens.as_ref(), - None, - "Tokens should have been removed during lowering!" - ); + assert!(tokens.as_ref().is_none(), "Tokens should have been removed during lowering!"); } else { unreachable!(); } diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 766d6a06f7e59..898c375e9ae1a 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -339,7 +339,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { for dest in bytes { *dest = src.next().expect("iterator was shorter than it said it would be"); } - assert_matches!(src.next(), None, "iterator was longer than it said it would be"); + assert!(src.next().is_none(), "iterator was longer than it said it would be"); Ok(()) } diff --git a/compiler/rustc_mir/src/interpret/memory.rs b/compiler/rustc_mir/src/interpret/memory.rs index fe5ebf0b6fe97..3648748a90908 100644 --- a/compiler/rustc_mir/src/interpret/memory.rs +++ b/compiler/rustc_mir/src/interpret/memory.rs @@ -854,11 +854,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some(ptr) => ptr, None => { // zero-sized access - assert_matches!( - src.next(), - None, - "iterator said it was empty but returned an element" - ); + assert!(src.next().is_none(), "iterator said it was empty but returned an element"); return Ok(()); } }; @@ -884,11 +880,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some(ptr) => ptr, None => { // zero-sized access - assert_matches!( - src.next(), - None, - "iterator said it was empty but returned an element" - ); + assert!(src.next().is_none(), "iterator said it was empty but returned an element"); return Ok(()); } }; @@ -902,7 +894,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { let offset_ptr = ptr.offset(Size::from_bytes(idx) * 2, &tcx)?; // `Size` multiplication allocation.write_scalar(&tcx, offset_ptr, val.into(), Size::from_bytes(2))?; } - assert_matches!(src.next(), None, "iterator was longer than it said it would be"); + assert!(src.next().is_none(), "iterator was longer than it said it would be"); Ok(()) } diff --git a/src/test/ui/macros/assert-matches-macro-msg.rs b/src/test/ui/macros/assert-matches-macro-msg.rs deleted file mode 100644 index 43be9532f5d1c..0000000000000 --- a/src/test/ui/macros/assert-matches-macro-msg.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-fail -// error-pattern:panicked at 'assertion failed: `(left matches right)` -// error-pattern: left: `2` -// error-pattern:right: `3`: 1 + 1 definitely should be 3' -// ignore-emscripten no processes - -#![feature(assert_matches)] - -fn main() { - assert_matches!(1 + 1, 3, "1 + 1 definitely should be 3"); -} From cadf901b1d22c6db02005d0152dbeac52bf86854 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 30 Apr 2021 18:22:06 +0200 Subject: [PATCH 08/18] Remove assert_matches feature attributes. --- compiler/rustc_codegen_ssa/src/lib.rs | 1 - compiler/rustc_middle/src/lib.rs | 1 - compiler/rustc_mir/src/lib.rs | 1 - 3 files changed, 3 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index dd04d3e548f8c..ab9ea2f3e91da 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -1,5 +1,4 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![feature(assert_matches)] #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(drain_filter)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 6ddc38b006687..49765166c871d 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -24,7 +24,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(array_windows)] -#![feature(assert_matches)] #![feature(backtrace)] #![feature(bool_to_option)] #![feature(box_patterns)] diff --git a/compiler/rustc_mir/src/lib.rs b/compiler/rustc_mir/src/lib.rs index f73d5dc0c116d..bf4eeb408ec84 100644 --- a/compiler/rustc_mir/src/lib.rs +++ b/compiler/rustc_mir/src/lib.rs @@ -7,7 +7,6 @@ Rust MIR: a lowered representation of Rust. #![feature(nll)] #![feature(in_band_lifetimes)] #![feature(array_windows)] -#![feature(assert_matches)] #![feature(bindings_after_at)] #![feature(bool_to_option)] #![feature(box_patterns)] From 381f1318ad1884e542c82ca664adc806fde4d941 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 15 Mar 2021 16:39:41 -0400 Subject: [PATCH 09/18] Revert PR 81473 to resolve (on beta) issues 81626 and 81658. Revert "Add missing brace" This reverts commit 85ad773049536d7fed9a94ae0ac74f97135c8655. Revert "Simplify base_expr" This reverts commit 899aae465eb4ef295dc1eeb2603f744568e0768c. Revert "Warn write-only fields" This reverts commit d3c69a4c0dd98af2611b7553d1a65afef6a6ccb0. --- compiler/rustc_passes/src/dead.rs | 21 ------ .../borrowck/borrowck-assign-to-subfield.rs | 1 - .../ui/lint/dead-code/write-only-field.rs | 69 ------------------- .../ui/lint/dead-code/write-only-field.stderr | 44 ------------ 4 files changed, 135 deletions(-) delete mode 100644 src/test/ui/lint/dead-code/write-only-field.rs delete mode 100644 src/test/ui/lint/dead-code/write-only-field.stderr diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index c63edf365a1aa..9d70bc4a82d0e 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -133,22 +133,6 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } } - fn handle_assign(&mut self, expr: &'tcx hir::Expr<'tcx>) { - if self - .typeck_results() - .expr_adjustments(expr) - .iter() - .any(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(_))) - { - self.visit_expr(expr); - } else if let hir::ExprKind::Field(base, ..) = expr.kind { - // Ignore write to field - self.handle_assign(base); - } else { - self.visit_expr(expr); - } - } - fn handle_field_pattern_match( &mut self, lhs: &hir::Pat<'_>, @@ -277,11 +261,6 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { hir::ExprKind::MethodCall(..) => { self.lookup_and_handle_method(expr.hir_id); } - hir::ExprKind::Assign(ref left, ref right, ..) => { - self.handle_assign(left); - self.visit_expr(right); - return; - } hir::ExprKind::Field(ref lhs, ..) => { self.handle_field_access(&lhs, expr.hir_id); } diff --git a/src/test/ui/borrowck/borrowck-assign-to-subfield.rs b/src/test/ui/borrowck/borrowck-assign-to-subfield.rs index dfa3a561ec7ee..050d702b625ab 100644 --- a/src/test/ui/borrowck/borrowck-assign-to-subfield.rs +++ b/src/test/ui/borrowck/borrowck-assign-to-subfield.rs @@ -1,6 +1,5 @@ // run-pass // pretty-expanded FIXME #23616 -#![allow(dead_code)] pub fn main() { struct A { diff --git a/src/test/ui/lint/dead-code/write-only-field.rs b/src/test/ui/lint/dead-code/write-only-field.rs deleted file mode 100644 index 7b3f1e9f5b6cb..0000000000000 --- a/src/test/ui/lint/dead-code/write-only-field.rs +++ /dev/null @@ -1,69 +0,0 @@ -#![deny(dead_code)] - -struct S { - f: i32, //~ ERROR: field is never read - sub: Sub, //~ ERROR: field is never read -} - -struct Sub { - f: i32, //~ ERROR: field is never read -} - -fn field_write(s: &mut S) { - s.f = 1; - s.sub.f = 2; -} - -fn main() { - let mut s = S { f: 0, sub: Sub { f: 0 } }; - field_write(&mut s); - - auto_deref(); - nested_boxes(); -} - -fn auto_deref() { - struct E { - x: bool, - y: bool, //~ ERROR: field is never read - } - - struct P<'a> { - e: &'a mut E - } - - impl P<'_> { - fn f(&mut self) { - self.e.x = true; - self.e.y = true; - } - } - - let mut e = E { x: false, y: false }; - let mut p = P { e: &mut e }; - p.f(); - assert!(e.x); -} - -fn nested_boxes() { - struct A { - b: Box, - } - - struct B { - c: Box, - } - - struct C { - u: u32, //~ ERROR: field is never read - v: u32, //~ ERROR: field is never read - } - - let mut a = A { - b: Box::new(B { - c: Box::new(C { u: 0, v: 0 }), - }), - }; - a.b.c.v = 10; - a.b.c = Box::new(C { u: 1, v: 2 }); -} diff --git a/src/test/ui/lint/dead-code/write-only-field.stderr b/src/test/ui/lint/dead-code/write-only-field.stderr deleted file mode 100644 index a191d22c8b94c..0000000000000 --- a/src/test/ui/lint/dead-code/write-only-field.stderr +++ /dev/null @@ -1,44 +0,0 @@ -error: field is never read: `f` - --> $DIR/write-only-field.rs:4:5 - | -LL | f: i32, - | ^^^^^^ - | -note: the lint level is defined here - --> $DIR/write-only-field.rs:1:9 - | -LL | #![deny(dead_code)] - | ^^^^^^^^^ - -error: field is never read: `sub` - --> $DIR/write-only-field.rs:5:5 - | -LL | sub: Sub, - | ^^^^^^^^ - -error: field is never read: `f` - --> $DIR/write-only-field.rs:9:5 - | -LL | f: i32, - | ^^^^^^ - -error: field is never read: `y` - --> $DIR/write-only-field.rs:28:9 - | -LL | y: bool, - | ^^^^^^^ - -error: field is never read: `u` - --> $DIR/write-only-field.rs:58:9 - | -LL | u: u32, - | ^^^^^^ - -error: field is never read: `v` - --> $DIR/write-only-field.rs:59:9 - | -LL | v: u32, - | ^^^^^^ - -error: aborting due to 6 previous errors - From e917d2f1eae5df14e96bfb47dbfbbf27f2e52824 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 3 May 2021 11:05:24 -0400 Subject: [PATCH 10/18] beta-targetted revert of PR #80653, to address issue #82465. adapted from 513756bb55a0dbc6e74d0043afd1727bd3c73aae --- src/librustdoc/html/render/context.rs | 10 +- src/librustdoc/html/render/mod.rs | 30 ++---- src/librustdoc/passes/collect_trait_impls.rs | 101 +++++++------------ src/test/rustdoc-ui/deref-recursive-cycle.rs | 17 ---- src/test/rustdoc/deref-recursive-pathbuf.rs | 26 ----- src/test/rustdoc/deref-recursive.rs | 42 -------- src/test/rustdoc/deref-typedef.rs | 4 +- 7 files changed, 46 insertions(+), 184 deletions(-) delete mode 100644 src/test/rustdoc-ui/deref-recursive-cycle.rs delete mode 100644 src/test/rustdoc/deref-recursive-pathbuf.rs delete mode 100644 src/test/rustdoc/deref-recursive.rs diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 864fbccbcc451..1d90122af1578 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -5,8 +5,7 @@ use std::path::PathBuf; use std::rc::Rc; use std::sync::mpsc::channel; -use rustc_data_structures::fx::FxHashMap; -use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::def_id::{LOCAL_CRATE}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::edition::Edition; @@ -53,9 +52,6 @@ crate struct Context<'tcx> { pub(super) render_redirect_pages: bool, /// The map used to ensure all generated 'id=' attributes are unique. pub(super) id_map: RefCell, - /// Tracks section IDs for `Deref` targets so they match in both the main - /// body and the sidebar. - pub(super) deref_id_map: RefCell>, /// Shared mutable state. /// /// Issue for improving the situation: [#82381][] @@ -76,7 +72,7 @@ crate struct Context<'tcx> { // `Context` is cloned a lot, so we don't want the size to grow unexpectedly. #[cfg(target_arch = "x86_64")] -rustc_data_structures::static_assert_size!(Context<'_>, 152); +rustc_data_structures::static_assert_size!(Context<'_>, 112); impl<'tcx> Context<'tcx> { pub(super) fn path(&self, filename: &str) -> PathBuf { @@ -416,7 +412,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { dst, render_redirect_pages: false, id_map: RefCell::new(id_map), - deref_id_map: RefCell::new(FxHashMap::default()), shared: Rc::new(scx), cache: Rc::new(cache), }; @@ -439,7 +434,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { dst: self.dst.clone(), render_redirect_pages: self.render_redirect_pages, id_map: RefCell::new(id_map), - deref_id_map: RefCell::new(FxHashMap::default()), shared: Rc::clone(&self.shared), cache: Rc::clone(&self.cache), } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 66c47f14655ba..820a5098bb411 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1159,21 +1159,12 @@ fn render_assoc_items( RenderMode::Normal } AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => { - let id = cx.derive_id(small_url_encode(format!( - "deref-methods-{:#}", - type_.print(cx.cache()) - ))); - debug!("Adding {} to deref id map", type_.print(cx.cache())); - cx.deref_id_map - .borrow_mut() - .insert(type_.def_id_full(cx.cache()).unwrap(), id.clone()); write!( w, - "

\ + "

\ Methods from {trait_}<Target = {type_}>\ - \ + \

", - id = id, trait_ = trait_.print(cx.cache()), type_ = type_.print(cx.cache()), ); @@ -1198,6 +1189,9 @@ fn render_assoc_items( ); } } + if let AssocItemRender::DerefFor { .. } = what { + return; + } if !traits.is_empty() { let deref_impl = traits .iter() @@ -1208,13 +1202,6 @@ fn render_assoc_items( }); render_deref_methods(w, cx, impl_, containing_item, has_deref_mut); } - - // If we were already one level into rendering deref methods, we don't want to render - // anything after recursing into any further deref methods above. - if let AssocItemRender::DerefFor { .. } = what { - return; - } - let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = traits.iter().partition(|t| t.inner_impl().synthetic); let (blanket_impl, concrete): (Vec<&&Impl>, _) = @@ -2020,14 +2007,9 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V .flat_map(|i| get_methods(i.inner_impl(), true, &mut used_links, deref_mut, c)) .collect::>(); if !ret.is_empty() { - let deref_id_map = cx.deref_id_map.borrow(); - let id = deref_id_map - .get(&real_target.def_id_full(cx.cache()).unwrap()) - .expect("Deref section without derived id"); write!( out, - "Methods from {}<Target={}>", - id, + "Methods from {}<Target={}>", Escape(&format!("{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print(c))), Escape(&format!("{:#}", real_target.print(c))), ); diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 685451b87eda9..492cc9118fe60 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -3,7 +3,7 @@ use crate::clean::*; use crate::core::DocContext; use crate::fold::DocFolder; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashSet}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::ty::DefIdTree; use rustc_span::symbol::sym; @@ -53,6 +53,39 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { } } + let mut cleaner = BadImplStripper { prims, items: crate_items }; + + // scan through included items ahead of time to splice in Deref targets to the "valid" sets + for it in &new_items { + if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind { + if cleaner.keep_impl(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() { + let target = items + .iter() + .find_map(|item| match *item.kind { + TypedefItem(ref t, true) => Some(&t.type_), + _ => None, + }) + .expect("Deref impl without Target type"); + + if let Some(prim) = target.primitive_type() { + cleaner.prims.insert(prim); + } else if let Some(did) = target.def_id() { + cleaner.items.insert(did); + } + } + } + } + + new_items.retain(|it| { + if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind { + cleaner.keep_impl(for_) + || trait_.as_ref().map_or(false, |t| cleaner.keep_impl(t)) + || blanket_impl.is_some() + } else { + true + } + }); + // `tcx.crates()` doesn't include the local crate, and `tcx.all_trait_implementations` // doesn't work with it anyway, so pull them from the HIR map instead let mut extra_attrs = Vec::new(); @@ -84,53 +117,6 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { } } - let mut cleaner = BadImplStripper { prims, items: crate_items }; - - let mut type_did_to_deref_target: FxHashMap = FxHashMap::default(); - // Gather all type to `Deref` target edges. - for it in &new_items { - if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind { - if trait_.def_id() == cx.tcx.lang_items().deref_trait() { - let target = items.iter().find_map(|item| match *item.kind { - TypedefItem(ref t, true) => Some(&t.type_), - _ => None, - }); - if let (Some(for_did), Some(target)) = (for_.def_id(), target) { - type_did_to_deref_target.insert(for_did, target); - } - } - } - } - // Follow all `Deref` targets of included items and recursively add them as valid - fn add_deref_target( - map: &FxHashMap, - cleaner: &mut BadImplStripper, - type_did: &DefId, - ) { - if let Some(target) = map.get(type_did) { - debug!("add_deref_target: type {:?}, target {:?}", type_did, target); - if let Some(target_prim) = target.primitive_type() { - cleaner.prims.insert(target_prim); - } else if let Some(target_did) = target.def_id() { - // `impl Deref for S` - if target_did == *type_did { - // Avoid infinite cycles - return; - } - cleaner.items.insert(target_did); - add_deref_target(map, cleaner, &target_did); - } - } - } - for type_did in type_did_to_deref_target.keys() { - // Since only the `DefId` portion of the `Type` instances is known to be same for both the - // `Deref` target type and the impl for type positions, this map of types is keyed by - // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly. - if cleaner.keep_impl_with_def_id(type_did) { - add_deref_target(&type_did_to_deref_target, &mut cleaner, type_did); - } - } - let items = if let Some(ref mut it) = krate.module { if let ModuleItem(Module { ref mut items, .. }) = *it.kind { items @@ -142,18 +128,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { }; items.extend(synth_impls); - for it in new_items.drain(..) { - if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind { - if !(cleaner.keep_impl(for_) - || trait_.as_ref().map_or(false, |t| cleaner.keep_impl(t)) - || blanket_impl.is_some()) - { - continue; - } - } - - items.push(it); - } + items.extend(new_items); krate } @@ -208,13 +183,9 @@ impl BadImplStripper { } else if let Some(prim) = ty.primitive_type() { self.prims.contains(&prim) } else if let Some(did) = ty.def_id() { - self.keep_impl_with_def_id(&did) + self.items.contains(&did) } else { false } } - - fn keep_impl_with_def_id(&self, did: &DefId) -> bool { - self.items.contains(did) - } } diff --git a/src/test/rustdoc-ui/deref-recursive-cycle.rs b/src/test/rustdoc-ui/deref-recursive-cycle.rs deleted file mode 100644 index 4cb518cbbbd5c..0000000000000 --- a/src/test/rustdoc-ui/deref-recursive-cycle.rs +++ /dev/null @@ -1,17 +0,0 @@ -// check-pass -// #26207: Ensure `Deref` cycles are properly handled without errors. - -#[derive(Copy, Clone)] -struct S; - -impl std::ops::Deref for S { - type Target = S; - - fn deref(&self) -> &S { - self - } -} - -fn main() { - let s: S = *******S; -} diff --git a/src/test/rustdoc/deref-recursive-pathbuf.rs b/src/test/rustdoc/deref-recursive-pathbuf.rs deleted file mode 100644 index 759e881aab415..0000000000000 --- a/src/test/rustdoc/deref-recursive-pathbuf.rs +++ /dev/null @@ -1,26 +0,0 @@ -// ignore-tidy-linelength - -// #26207: Show all methods reachable via Deref impls, recursing through multiple dereferencing -// levels and across multiple crates. - -// @has 'foo/struct.Foo.html' -// @has '-' '//*[@id="deref-methods-PathBuf"]' 'Methods from Deref' -// @has '-' '//*[@class="impl-items"]//*[@id="method.as_path"]' 'pub fn as_path(&self)' -// @has '-' '//*[@id="deref-methods-Path"]' 'Methods from Deref' -// @has '-' '//*[@class="impl-items"]//*[@id="method.exists"]' 'pub fn exists(&self)' -// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-PathBuf"]' 'Methods from Deref' -// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.as_path"]' 'as_path' -// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-Path"]' 'Methods from Deref' -// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.exists"]' 'exists' - -#![crate_name = "foo"] - -use std::ops::Deref; -use std::path::PathBuf; - -pub struct Foo(PathBuf); - -impl Deref for Foo { - type Target = PathBuf; - fn deref(&self) -> &PathBuf { &self.0 } -} diff --git a/src/test/rustdoc/deref-recursive.rs b/src/test/rustdoc/deref-recursive.rs deleted file mode 100644 index 5aef87c38cd27..0000000000000 --- a/src/test/rustdoc/deref-recursive.rs +++ /dev/null @@ -1,42 +0,0 @@ -// ignore-tidy-linelength - -// #26207: Show all methods reachable via Deref impls, recursing through multiple dereferencing -// levels if needed. - -// @has 'foo/struct.Foo.html' -// @has '-' '//*[@id="deref-methods-Bar"]' 'Methods from Deref' -// @has '-' '//*[@class="impl-items"]//*[@id="method.bar"]' 'pub fn bar(&self)' -// @has '-' '//*[@id="deref-methods-Baz"]' 'Methods from Deref' -// @has '-' '//*[@class="impl-items"]//*[@id="method.baz"]' 'pub fn baz(&self)' -// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-Bar"]' 'Methods from Deref' -// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.bar"]' 'bar' -// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-Baz"]' 'Methods from Deref' -// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.baz"]' 'baz' - -#![crate_name = "foo"] - -use std::ops::Deref; - -pub struct Foo(Bar); -pub struct Bar(Baz); -pub struct Baz; - -impl Deref for Foo { - type Target = Bar; - fn deref(&self) -> &Bar { &self.0 } -} - -impl Deref for Bar { - type Target = Baz; - fn deref(&self) -> &Baz { &self.0 } -} - -impl Bar { - /// This appears under `Foo` methods - pub fn bar(&self) {} -} - -impl Baz { - /// This should also appear in `Foo` methods when recursing - pub fn baz(&self) {} -} diff --git a/src/test/rustdoc/deref-typedef.rs b/src/test/rustdoc/deref-typedef.rs index 589f133b975a5..14c7680645883 100644 --- a/src/test/rustdoc/deref-typedef.rs +++ b/src/test/rustdoc/deref-typedef.rs @@ -3,12 +3,12 @@ #![crate_name = "foo"] // @has 'foo/struct.Bar.html' -// @has '-' '//*[@id="deref-methods-FooJ"]' 'Methods from Deref' +// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref' // @has '-' '//*[@class="impl-items"]//*[@id="method.foo_a"]' 'pub fn foo_a(&self)' // @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)' // @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)' // @has '-' '//*[@class="impl-items"]//*[@id="method.foo_j"]' 'pub fn foo_j(&self)' -// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-FooJ"]' 'Methods from Deref' +// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods"]' 'Methods from Deref' // @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a' // @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b' // @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c' From 106ac7eefc9c09c06fe1262c86b51e7e114df691 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 3 May 2021 10:06:57 -0400 Subject: [PATCH 11/18] regression test for issue 82465. --- .../issue-82465-asref-for-and-of-local.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/test/rustdoc/issue-82465-asref-for-and-of-local.rs diff --git a/src/test/rustdoc/issue-82465-asref-for-and-of-local.rs b/src/test/rustdoc/issue-82465-asref-for-and-of-local.rs new file mode 100644 index 0000000000000..618ac20ac487d --- /dev/null +++ b/src/test/rustdoc/issue-82465-asref-for-and-of-local.rs @@ -0,0 +1,16 @@ +use std::convert::AsRef; +pub struct Local; + +// @has issue_82465_asref_for_and_of_local/struct.Local.html '//code' 'impl AsRef for Local' +impl AsRef for Local { + fn as_ref(&self) -> &str { + todo!() + } +} + +// @has - '//code' 'impl AsRef for str' +impl AsRef for str { + fn as_ref(&self) -> &Local { + todo!() + } +} From 9c14391f93e3a6d90b1bf35d5f8bf31fc1827949 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 3 May 2021 12:44:02 -0400 Subject: [PATCH 12/18] placate tidy. --- src/test/rustdoc/deref-typedef.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/rustdoc/deref-typedef.rs b/src/test/rustdoc/deref-typedef.rs index 14c7680645883..3fc48b46d7410 100644 --- a/src/test/rustdoc/deref-typedef.rs +++ b/src/test/rustdoc/deref-typedef.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![crate_name = "foo"] // @has 'foo/struct.Bar.html' From a3ebc6eaf499548a02601af8437704de229fb389 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 3 May 2021 14:23:55 -0400 Subject: [PATCH 13/18] Revert "directly expose copy and copy_nonoverlapping intrinsics" This reverts commit 18d12ad171384a82736a88b879540bf464161063. --- library/core/src/intrinsics.rs | 349 ++++++++++-------- library/core/src/ptr/mod.rs | 10 +- .../ui/const-ptr/out_of_bounds_read.stderr | 55 +-- 3 files changed, 234 insertions(+), 180 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index b5371d6b69dbb..84fd3124107d8 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1742,157 +1742,6 @@ extern "rust-intrinsic" { /// Allocate at compile time. Should not be called at runtime. #[rustc_const_unstable(feature = "const_heap", issue = "79597")] pub fn const_allocate(size: usize, align: usize) -> *mut u8; - - /// Copies `count * size_of::()` bytes from `src` to `dst`. The source - /// and destination must *not* overlap. - /// - /// For regions of memory which might overlap, use [`copy`] instead. - /// - /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but - /// with the argument order swapped. - /// - /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy - /// - /// # Safety - /// - /// Behavior is undefined if any of the following conditions are violated: - /// - /// * `src` must be [valid] for reads of `count * size_of::()` bytes. - /// - /// * `dst` must be [valid] for writes of `count * size_of::()` bytes. - /// - /// * Both `src` and `dst` must be properly aligned. - /// - /// * The region of memory beginning at `src` with a size of `count * - /// size_of::()` bytes must *not* overlap with the region of memory - /// beginning at `dst` with the same size. - /// - /// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of - /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values - /// in the region beginning at `*src` and the region beginning at `*dst` can - /// [violate memory safety][read-ownership]. - /// - /// Note that even if the effectively copied size (`count * size_of::()`) is - /// `0`, the pointers must be non-NULL and properly aligned. - /// - /// [`read`]: crate::ptr::read - /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value - /// [valid]: crate::ptr#safety - /// - /// # Examples - /// - /// Manually implement [`Vec::append`]: - /// - /// ``` - /// use std::ptr; - /// - /// /// Moves all the elements of `src` into `dst`, leaving `src` empty. - /// fn append(dst: &mut Vec, src: &mut Vec) { - /// let src_len = src.len(); - /// let dst_len = dst.len(); - /// - /// // Ensure that `dst` has enough capacity to hold all of `src`. - /// dst.reserve(src_len); - /// - /// unsafe { - /// // The call to offset is always safe because `Vec` will never - /// // allocate more than `isize::MAX` bytes. - /// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize); - /// let src_ptr = src.as_ptr(); - /// - /// // Truncate `src` without dropping its contents. We do this first, - /// // to avoid problems in case something further down panics. - /// src.set_len(0); - /// - /// // The two regions cannot overlap because mutable references do - /// // not alias, and two different vectors cannot own the same - /// // memory. - /// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len); - /// - /// // Notify `dst` that it now holds the contents of `src`. - /// dst.set_len(dst_len + src_len); - /// } - /// } - /// - /// let mut a = vec!['r']; - /// let mut b = vec!['u', 's', 't']; - /// - /// append(&mut a, &mut b); - /// - /// assert_eq!(a, &['r', 'u', 's', 't']); - /// assert!(b.is_empty()); - /// ``` - /// - /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append - #[doc(alias = "memcpy")] - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] - pub fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); - - /// Copies `count * size_of::()` bytes from `src` to `dst`. The source - /// and destination may overlap. - /// - /// If the source and destination will *never* overlap, - /// [`copy_nonoverlapping`] can be used instead. - /// - /// `copy` is semantically equivalent to C's [`memmove`], but with the argument - /// order swapped. Copying takes place as if the bytes were copied from `src` - /// to a temporary array and then copied from the array to `dst`. - /// - /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove - /// - /// # Safety - /// - /// Behavior is undefined if any of the following conditions are violated: - /// - /// * `src` must be [valid] for reads of `count * size_of::()` bytes. - /// - /// * `dst` must be [valid] for writes of `count * size_of::()` bytes. - /// - /// * Both `src` and `dst` must be properly aligned. - /// - /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of - /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values - /// in the region beginning at `*src` and the region beginning at `*dst` can - /// [violate memory safety][read-ownership]. - /// - /// Note that even if the effectively copied size (`count * size_of::()`) is - /// `0`, the pointers must be non-NULL and properly aligned. - /// - /// [`read`]: crate::ptr::read - /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value - /// [valid]: crate::ptr#safety - /// - /// # Examples - /// - /// Efficiently create a Rust vector from an unsafe buffer: - /// - /// ``` - /// use std::ptr; - /// - /// /// # Safety - /// /// - /// /// * `ptr` must be correctly aligned for its type and non-zero. - /// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`. - /// /// * Those elements must not be used after calling this function unless `T: Copy`. - /// # #[allow(dead_code)] - /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { - /// let mut dst = Vec::with_capacity(elts); - /// - /// // SAFETY: Our precondition ensures the source is aligned and valid, - /// // and `Vec::with_capacity` ensures that we have usable space to write them. - /// ptr::copy(ptr, dst.as_mut_ptr(), elts); - /// - /// // SAFETY: We created it with this much capacity earlier, - /// // and the previous `copy` has initialized these elements. - /// dst.set_len(elts); - /// dst - /// } - /// ``` - #[doc(alias = "memmove")] - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] - pub fn copy(src: *const T, dst: *mut T, count: usize); } // Some functions are defined here because they accidentally got made @@ -1906,6 +1755,204 @@ pub(crate) fn is_aligned_and_not_null(ptr: *const T) -> bool { !ptr.is_null() && ptr as usize % mem::align_of::() == 0 } +/// Checks whether the regions of memory starting at `src` and `dst` of size +/// `count * size_of::()` do *not* overlap. +pub(crate) fn is_nonoverlapping(src: *const T, dst: *const T, count: usize) -> bool { + let src_usize = src as usize; + let dst_usize = dst as usize; + let size = mem::size_of::().checked_mul(count).unwrap(); + let diff = if src_usize > dst_usize { src_usize - dst_usize } else { dst_usize - src_usize }; + // If the absolute distance between the ptrs is at least as big as the size of the buffer, + // they do not overlap. + diff >= size +} + +/// Copies `count * size_of::()` bytes from `src` to `dst`. The source +/// and destination must *not* overlap. +/// +/// For regions of memory which might overlap, use [`copy`] instead. +/// +/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but +/// with the argument order swapped. +/// +/// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy +/// +/// # Safety +/// +/// Behavior is undefined if any of the following conditions are violated: +/// +/// * `src` must be [valid] for reads of `count * size_of::()` bytes. +/// +/// * `dst` must be [valid] for writes of `count * size_of::()` bytes. +/// +/// * Both `src` and `dst` must be properly aligned. +/// +/// * The region of memory beginning at `src` with a size of `count * +/// size_of::()` bytes must *not* overlap with the region of memory +/// beginning at `dst` with the same size. +/// +/// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of +/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values +/// in the region beginning at `*src` and the region beginning at `*dst` can +/// [violate memory safety][read-ownership]. +/// +/// Note that even if the effectively copied size (`count * size_of::()`) is +/// `0`, the pointers must be non-NULL and properly aligned. +/// +/// [`read`]: crate::ptr::read +/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value +/// [valid]: crate::ptr#safety +/// +/// # Examples +/// +/// Manually implement [`Vec::append`]: +/// +/// ``` +/// use std::ptr; +/// +/// /// Moves all the elements of `src` into `dst`, leaving `src` empty. +/// fn append(dst: &mut Vec, src: &mut Vec) { +/// let src_len = src.len(); +/// let dst_len = dst.len(); +/// +/// // Ensure that `dst` has enough capacity to hold all of `src`. +/// dst.reserve(src_len); +/// +/// unsafe { +/// // The call to offset is always safe because `Vec` will never +/// // allocate more than `isize::MAX` bytes. +/// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize); +/// let src_ptr = src.as_ptr(); +/// +/// // Truncate `src` without dropping its contents. We do this first, +/// // to avoid problems in case something further down panics. +/// src.set_len(0); +/// +/// // The two regions cannot overlap because mutable references do +/// // not alias, and two different vectors cannot own the same +/// // memory. +/// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len); +/// +/// // Notify `dst` that it now holds the contents of `src`. +/// dst.set_len(dst_len + src_len); +/// } +/// } +/// +/// let mut a = vec!['r']; +/// let mut b = vec!['u', 's', 't']; +/// +/// append(&mut a, &mut b); +/// +/// assert_eq!(a, &['r', 'u', 's', 't']); +/// assert!(b.is_empty()); +/// ``` +/// +/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append +#[doc(alias = "memcpy")] +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] +#[inline] +pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize) { + extern "rust-intrinsic" { + #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] + fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); + } + + // FIXME: Perform these checks only at run time + /*if cfg!(debug_assertions) + && !(is_aligned_and_not_null(src) + && is_aligned_and_not_null(dst) + && is_nonoverlapping(src, dst, count)) + { + // Not panicking to keep codegen impact smaller. + abort(); + }*/ + + // SAFETY: the safety contract for `copy_nonoverlapping` must be + // upheld by the caller. + unsafe { copy_nonoverlapping(src, dst, count) } +} + +/// Copies `count * size_of::()` bytes from `src` to `dst`. The source +/// and destination may overlap. +/// +/// If the source and destination will *never* overlap, +/// [`copy_nonoverlapping`] can be used instead. +/// +/// `copy` is semantically equivalent to C's [`memmove`], but with the argument +/// order swapped. Copying takes place as if the bytes were copied from `src` +/// to a temporary array and then copied from the array to `dst`. +/// +/// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove +/// +/// # Safety +/// +/// Behavior is undefined if any of the following conditions are violated: +/// +/// * `src` must be [valid] for reads of `count * size_of::()` bytes. +/// +/// * `dst` must be [valid] for writes of `count * size_of::()` bytes. +/// +/// * Both `src` and `dst` must be properly aligned. +/// +/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of +/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values +/// in the region beginning at `*src` and the region beginning at `*dst` can +/// [violate memory safety][read-ownership]. +/// +/// Note that even if the effectively copied size (`count * size_of::()`) is +/// `0`, the pointers must be non-NULL and properly aligned. +/// +/// [`read`]: crate::ptr::read +/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value +/// [valid]: crate::ptr#safety +/// +/// # Examples +/// +/// Efficiently create a Rust vector from an unsafe buffer: +/// +/// ``` +/// use std::ptr; +/// +/// /// # Safety +/// /// +/// /// * `ptr` must be correctly aligned for its type and non-zero. +/// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`. +/// /// * Those elements must not be used after calling this function unless `T: Copy`. +/// # #[allow(dead_code)] +/// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { +/// let mut dst = Vec::with_capacity(elts); +/// +/// // SAFETY: Our precondition ensures the source is aligned and valid, +/// // and `Vec::with_capacity` ensures that we have usable space to write them. +/// ptr::copy(ptr, dst.as_mut_ptr(), elts); +/// +/// // SAFETY: We created it with this much capacity earlier, +/// // and the previous `copy` has initialized these elements. +/// dst.set_len(elts); +/// dst +/// } +/// ``` +#[doc(alias = "memmove")] +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] +#[inline] +pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { + extern "rust-intrinsic" { + #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] + fn copy(src: *const T, dst: *mut T, count: usize); + } + + // FIXME: Perform these checks only at run time + /*if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) { + // Not panicking to keep codegen impact smaller. + abort(); + }*/ + + // SAFETY: the safety contract for `copy` must be upheld by the caller. + unsafe { copy(src, dst, count) } +} + /// Sets `count * size_of::()` bytes of memory starting at `dst` to /// `val`. /// diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 3a27f01444be8..541cc754a007c 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -898,14 +898,18 @@ pub const unsafe fn read_unaligned(src: *const T) -> T { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_ptr_write", issue = "none")] -pub const unsafe fn write(dst: *mut T, src: T) { +pub unsafe fn write(dst: *mut T, src: T) { + // We are calling the intrinsics directly to avoid function calls in the generated code + // as `intrinsics::copy_nonoverlapping` is a wrapper function. + extern "rust-intrinsic" { + fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); + } + // SAFETY: the caller must guarantee that `dst` is valid for writes. // `dst` cannot overlap `src` because the caller has mutable access // to `dst` while `src` is owned by this function. unsafe { copy_nonoverlapping(&src as *const T, dst, 1); - // We are calling the intrinsic directly to avoid function calls in the generated code. intrinsics::forget(src); } } diff --git a/src/test/ui/const-ptr/out_of_bounds_read.stderr b/src/test/ui/const-ptr/out_of_bounds_read.stderr index 6c4092e3e5cc8..87b7c377b0036 100644 --- a/src/test/ui/const-ptr/out_of_bounds_read.stderr +++ b/src/test/ui/const-ptr/out_of_bounds_read.stderr @@ -1,12 +1,13 @@ error: any use of this value will cause an error - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | -LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4 - | inside `std::ptr::read::` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | inside `_READ` at $DIR/out_of_bounds_read.rs:13:33 + --> $SRC_DIR/core/src/intrinsics.rs:LL:COL + | +LL | unsafe { copy_nonoverlapping(src, dst, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4 + | inside `copy_nonoverlapping::` at $SRC_DIR/core/src/intrinsics.rs:LL:COL + | inside `std::ptr::read::` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | inside `_READ` at $DIR/out_of_bounds_read.rs:13:33 | ::: $DIR/out_of_bounds_read.rs:13:5 | @@ -18,15 +19,16 @@ LL | const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) }; = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | -LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4 - | inside `std::ptr::read::` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | inside `ptr::const_ptr::::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | inside `_CONST_READ` at $DIR/out_of_bounds_read.rs:14:39 + --> $SRC_DIR/core/src/intrinsics.rs:LL:COL + | +LL | unsafe { copy_nonoverlapping(src, dst, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4 + | inside `copy_nonoverlapping::` at $SRC_DIR/core/src/intrinsics.rs:LL:COL + | inside `std::ptr::read::` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | inside `ptr::const_ptr::::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | inside `_CONST_READ` at $DIR/out_of_bounds_read.rs:14:39 | ::: $DIR/out_of_bounds_read.rs:14:5 | @@ -37,15 +39,16 @@ LL | const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() }; = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | -LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4 - | inside `std::ptr::read::` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | inside `ptr::mut_ptr::::read` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - | inside `_MUT_READ` at $DIR/out_of_bounds_read.rs:15:37 + --> $SRC_DIR/core/src/intrinsics.rs:LL:COL + | +LL | unsafe { copy_nonoverlapping(src, dst, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4 + | inside `copy_nonoverlapping::` at $SRC_DIR/core/src/intrinsics.rs:LL:COL + | inside `std::ptr::read::` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | inside `ptr::mut_ptr::::read` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + | inside `_MUT_READ` at $DIR/out_of_bounds_read.rs:15:37 | ::: $DIR/out_of_bounds_read.rs:15:5 | From 80ec986f9f9216fcc2d005c8a938e83243dbbe72 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 3 May 2021 14:24:21 -0400 Subject: [PATCH 14/18] Revert "Fix clippy's path to the copy intrinsics." This reverts commit 1a806352e41fcba5eac91784476fc6dfa6ee05b7. --- src/tools/clippy/clippy_utils/src/paths.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs index 560614efc749e..d884659dfb4a6 100644 --- a/src/tools/clippy/clippy_utils/src/paths.rs +++ b/src/tools/clippy/clippy_utils/src/paths.rs @@ -18,8 +18,8 @@ pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeS pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"]; pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"]; pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"]; -pub const COPY: [&str; 4] = ["core", "intrinsics", "", "copy_nonoverlapping"]; -pub const COPY_NONOVERLAPPING: [&str; 4] = ["core", "intrinsics", "", "copy"]; +pub const COPY: [&str; 3] = ["core", "intrinsics", "copy_nonoverlapping"]; +pub const COPY_NONOVERLAPPING: [&str; 3] = ["core", "intrinsics", "copy"]; pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"]; pub const CSTRING_AS_C_STR: [&str; 5] = ["std", "ffi", "c_str", "CString", "as_c_str"]; pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"]; From 28e5e93fc2a350421a861801c77501382d233319 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 3 May 2021 14:29:29 -0400 Subject: [PATCH 15/18] drop some const unstables, due to revert no longer possible --- library/core/src/mem/mod.rs | 6 ++---- library/core/src/ptr/mod.rs | 3 +-- library/core/src/ptr/mut_ptr.rs | 3 +-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 37e8d65db6a38..c4f0d9176741e 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -682,8 +682,7 @@ pub unsafe fn uninitialized() -> T { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_swap", issue = "83163")] -pub const fn swap(x: &mut T, y: &mut T) { +pub fn swap(x: &mut T, y: &mut T) { // SAFETY: the raw pointers have been created from safe mutable references satisfying all the // constraints on `ptr::swap_nonoverlapping_one` unsafe { @@ -813,8 +812,7 @@ pub fn take(dest: &mut T) -> T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "if you don't need the old value, you can just assign the new value directly"] -#[rustc_const_unstable(feature = "const_replace", issue = "83164")] -pub const fn replace(dest: &mut T, src: T) -> T { +pub fn replace(dest: &mut T, src: T) -> T { // SAFETY: We read from `dest` but directly write `src` into it afterwards, // such that the old value is not duplicated. Nothing is dropped and // nothing here can panic. diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 541cc754a007c..67185217d5e40 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -463,8 +463,7 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { } #[inline] -#[rustc_const_unstable(feature = "const_swap", issue = "83163")] -pub(crate) const unsafe fn swap_nonoverlapping_one(x: *mut T, y: *mut T) { +pub(crate) unsafe fn swap_nonoverlapping_one(x: *mut T, y: *mut T) { // For types smaller than the block optimization below, // just swap directly to avoid pessimizing codegen. if mem::size_of::() < 32 { diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index fa09cf854353d..a9de2333bc0e2 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1013,9 +1013,8 @@ impl *mut T { /// /// [`ptr::write`]: crate::ptr::write() #[stable(feature = "pointer_methods", since = "1.26.0")] - #[rustc_const_unstable(feature = "const_ptr_write", issue = "none")] #[inline] - pub const unsafe fn write(self, val: T) + pub unsafe fn write(self, val: T) where T: Sized, { From ab7b1cca2dbd73a8c253c896055a04a06f1aaf17 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 23 Mar 2021 10:45:34 +0800 Subject: [PATCH 16/18] Fix ICE of for-loop mut borrowck where no suggestions are available --- .../diagnostics/mutability_errors.rs | 17 ++++++---- .../issue-83309-ice-immut-in-for-loop.rs | 32 +++++++++++++++++++ .../issue-83309-ice-immut-in-for-loop.stderr | 12 +++++++ 3 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/borrowck/issue-83309-ice-immut-in-for-loop.rs create mode 100644 src/test/ui/borrowck/issue-83309-ice-immut-in-for-loop.stderr diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs index 28f6508cab2da..d1fb999e518ca 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs @@ -642,15 +642,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { .starts_with(&original_method_ident.name.to_string()) }) .map(|ident| format!("{}()", ident)) + .peekable() }); - if let Some(suggestions) = opt_suggestions { - err.span_suggestions( - path_segment.ident.span, - &format!("use mutable method"), - suggestions, - Applicability::MaybeIncorrect, - ); + if let Some(mut suggestions) = opt_suggestions { + if suggestions.peek().is_some() { + err.span_suggestions( + path_segment.ident.span, + &format!("use mutable method"), + suggestions, + Applicability::MaybeIncorrect, + ); + } } } }; diff --git a/src/test/ui/borrowck/issue-83309-ice-immut-in-for-loop.rs b/src/test/ui/borrowck/issue-83309-ice-immut-in-for-loop.rs new file mode 100644 index 0000000000000..6da88bed2c6ba --- /dev/null +++ b/src/test/ui/borrowck/issue-83309-ice-immut-in-for-loop.rs @@ -0,0 +1,32 @@ +// rust-lang/rust#83309: The compiler tries to suggest potential +// methods that return `&mut` items. However, when it doesn't +// find such methods, it still tries to add suggestions +// which then fails an assertion later because there was +// no suggestions to make. + + +fn main() { + for v in Query.iter_mut() { + //~^ NOTE this iterator yields `&` references + *v -= 1; + //~^ ERROR cannot assign to `*v` which is behind a `&` reference + //~| NOTE `v` is a `&` reference, so the data it refers to cannot be written + } +} + +pub struct Query; +pub struct QueryIter<'a>(&'a i32); + +impl Query { + pub fn iter_mut<'a>(&'a mut self) -> QueryIter<'a> { + todo!(); + } +} + +impl<'a> Iterator for QueryIter<'a> { + type Item = &'a i32; + + fn next(&mut self) -> Option { + todo!(); + } +} diff --git a/src/test/ui/borrowck/issue-83309-ice-immut-in-for-loop.stderr b/src/test/ui/borrowck/issue-83309-ice-immut-in-for-loop.stderr new file mode 100644 index 0000000000000..143b74c39ba86 --- /dev/null +++ b/src/test/ui/borrowck/issue-83309-ice-immut-in-for-loop.stderr @@ -0,0 +1,12 @@ +error[E0594]: cannot assign to `*v` which is behind a `&` reference + --> $DIR/issue-83309-ice-immut-in-for-loop.rs:11:9 + | +LL | for v in Query.iter_mut() { + | ---------------- this iterator yields `&` references +LL | +LL | *v -= 1; + | ^^^^^^^ `v` is a `&` reference, so the data it refers to cannot be written + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0594`. From f99929f24aa5cb3962dfa8c45afe76a262376238 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 3 May 2021 14:41:52 -0400 Subject: [PATCH 17/18] Remove some more consts --- library/core/src/intrinsics.rs | 12 ---- library/core/src/ptr/mod.rs | 3 +- library/core/tests/const_ptr.rs | 98 ++++++++++++++++----------------- 3 files changed, 50 insertions(+), 63 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 84fd3124107d8..073210c5b6857 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1755,18 +1755,6 @@ pub(crate) fn is_aligned_and_not_null(ptr: *const T) -> bool { !ptr.is_null() && ptr as usize % mem::align_of::() == 0 } -/// Checks whether the regions of memory starting at `src` and `dst` of size -/// `count * size_of::()` do *not* overlap. -pub(crate) fn is_nonoverlapping(src: *const T, dst: *const T, count: usize) -> bool { - let src_usize = src as usize; - let dst_usize = dst as usize; - let size = mem::size_of::().checked_mul(count).unwrap(); - let diff = if src_usize > dst_usize { src_usize - dst_usize } else { dst_usize - src_usize }; - // If the absolute distance between the ptrs is at least as big as the size of the buffer, - // they do not overlap. - diff >= size -} - /// Copies `count * size_of::()` bytes from `src` to `dst`. The source /// and destination must *not* overlap. /// diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 67185217d5e40..fd24469bd3cd7 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -583,8 +583,7 @@ const unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_replace", issue = "83164")] -pub const unsafe fn replace(dst: *mut T, mut src: T) -> T { +pub unsafe fn replace(dst: *mut T, mut src: T) -> T { // SAFETY: the caller must guarantee that `dst` is valid to be // cast to a mutable reference (valid for writes, aligned, initialized), // and cannot overlap `src` since `dst` must point to a distinct diff --git a/library/core/tests/const_ptr.rs b/library/core/tests/const_ptr.rs index 152fed803ecdb..4158a4dece729 100644 --- a/library/core/tests/const_ptr.rs +++ b/library/core/tests/const_ptr.rs @@ -50,52 +50,52 @@ fn mut_ptr_read() { assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45])); } -#[test] -fn write() { - use core::ptr; - - const fn write_aligned() -> i32 { - let mut res = 0; - unsafe { - ptr::write(&mut res as *mut _, 42); - } - res - } - const ALIGNED: i32 = write_aligned(); - assert_eq!(ALIGNED, 42); - - const fn write_unaligned() -> [u16; 2] { - let mut two_aligned = [0u16; 2]; - unsafe { - let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16; - ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45])); - } - two_aligned - } - const UNALIGNED: [u16; 2] = write_unaligned(); - assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]); -} - -#[test] -fn mut_ptr_write() { - const fn aligned() -> i32 { - let mut res = 0; - unsafe { - (&mut res as *mut i32).write(42); - } - res - } - const ALIGNED: i32 = aligned(); - assert_eq!(ALIGNED, 42); - - const fn write_unaligned() -> [u16; 2] { - let mut two_aligned = [0u16; 2]; - unsafe { - let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16; - unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45])); - } - two_aligned - } - const UNALIGNED: [u16; 2] = write_unaligned(); - assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]); -} +//#[test] +//fn write() { +// use core::ptr; +// +// const fn write_aligned() -> i32 { +// let mut res = 0; +// unsafe { +// ptr::write(&mut res as *mut _, 42); +// } +// res +// } +// const ALIGNED: i32 = write_aligned(); +// assert_eq!(ALIGNED, 42); +// +// const fn write_unaligned() -> [u16; 2] { +// let mut two_aligned = [0u16; 2]; +// unsafe { +// let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16; +// ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45])); +// } +// two_aligned +// } +// const UNALIGNED: [u16; 2] = write_unaligned(); +// assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]); +//} + +//#[test] +//fn mut_ptr_write() { +// const fn aligned() -> i32 { +// let mut res = 0; +// unsafe { +// (&mut res as *mut i32).write(42); +// } +// res +// } +// const ALIGNED: i32 = aligned(); +// assert_eq!(ALIGNED, 42); +// +// const fn write_unaligned() -> [u16; 2] { +// let mut two_aligned = [0u16; 2]; +// unsafe { +// let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16; +// unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45])); +// } +// two_aligned +// } +// const UNALIGNED: [u16; 2] = write_unaligned(); +// assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]); +//} From 47c7b9c5788055ddbbb59d0d1fc909af7b48668d Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 3 May 2021 15:20:12 -0400 Subject: [PATCH 18/18] remove copy intrinsic test - no longer const --- src/test/ui/consts/copy-intrinsic.rs | 45 ---------------- src/test/ui/consts/copy-intrinsic.stderr | 69 ------------------------ 2 files changed, 114 deletions(-) delete mode 100644 src/test/ui/consts/copy-intrinsic.rs delete mode 100644 src/test/ui/consts/copy-intrinsic.stderr diff --git a/src/test/ui/consts/copy-intrinsic.rs b/src/test/ui/consts/copy-intrinsic.rs deleted file mode 100644 index 9dc595f37faae..0000000000000 --- a/src/test/ui/consts/copy-intrinsic.rs +++ /dev/null @@ -1,45 +0,0 @@ -// ignore-tidy-linelength -#![feature(const_mut_refs, const_intrinsic_copy, const_ptr_offset)] -use std::{ptr, mem}; - -const COPY_ZERO: () = unsafe { - // Since we are not copying anything, this should be allowed. - let src = (); - let mut dst = (); - ptr::copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0); -}; - -const COPY_OOB_1: () = unsafe { - let mut x = 0i32; - let dangle = (&mut x as *mut i32).wrapping_add(10); - // Even if the first ptr is an int ptr and this is a ZST copy, we should detect dangling 2nd ptrs. - ptr::copy_nonoverlapping(0x100 as *const i32, dangle, 0); //~ ERROR any use of this value will cause an error - //~| memory access failed: pointer must be in-bounds - //~| previously accepted -}; -const COPY_OOB_2: () = unsafe { - let x = 0i32; - let dangle = (&x as *const i32).wrapping_add(10); - // Even if the second ptr is an int ptr and this is a ZST copy, we should detect dangling 1st ptrs. - ptr::copy_nonoverlapping(dangle, 0x100 as *mut i32, 0); //~ ERROR any use of this value will cause an error - //~| memory access failed: pointer must be in-bounds - //~| previously accepted -}; - -const COPY_SIZE_OVERFLOW: () = unsafe { - let x = 0; - let mut y = 0; - ptr::copy(&x, &mut y, 1usize << (mem::size_of::() * 8 - 1)); //~ ERROR any use of this value will cause an error - //~| overflow computing total size of `copy` - //~| previously accepted -}; -const COPY_NONOVERLAPPING_SIZE_OVERFLOW: () = unsafe { - let x = 0; - let mut y = 0; - ptr::copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::() * 8 - 1)); //~ ERROR any use of this value will cause an error - //~| overflow computing total size of `copy_nonoverlapping` - //~| previously accepted -}; - -fn main() { -} diff --git a/src/test/ui/consts/copy-intrinsic.stderr b/src/test/ui/consts/copy-intrinsic.stderr deleted file mode 100644 index 2736cdeac690e..0000000000000 --- a/src/test/ui/consts/copy-intrinsic.stderr +++ /dev/null @@ -1,69 +0,0 @@ -error: any use of this value will cause an error - --> $DIR/copy-intrinsic.rs:16:5 - | -LL | / const COPY_OOB_1: () = unsafe { -LL | | let mut x = 0i32; -LL | | let dangle = (&mut x as *mut i32).wrapping_add(10); -LL | | // Even if the first ptr is an int ptr and this is a ZST copy, we should detect dangling 2nd ptrs. -LL | | ptr::copy_nonoverlapping(0x100 as *const i32, dangle, 0); - | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 40, but is outside bounds of alloc4 which has size 4 -LL | | -LL | | -LL | | }; - | |__- - | - = note: `#[deny(const_err)]` on by default - = 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 #71800 - -error: any use of this value will cause an error - --> $DIR/copy-intrinsic.rs:24:5 - | -LL | / const COPY_OOB_2: () = unsafe { -LL | | let x = 0i32; -LL | | let dangle = (&x as *const i32).wrapping_add(10); -LL | | // Even if the second ptr is an int ptr and this is a ZST copy, we should detect dangling 1st ptrs. -LL | | ptr::copy_nonoverlapping(dangle, 0x100 as *mut i32, 0); - | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 40, but is outside bounds of alloc6 which has size 4 -LL | | -LL | | -LL | | }; - | |__- - | - = 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 #71800 - -error: any use of this value will cause an error - --> $DIR/copy-intrinsic.rs:32:5 - | -LL | / const COPY_SIZE_OVERFLOW: () = unsafe { -LL | | let x = 0; -LL | | let mut y = 0; -LL | | ptr::copy(&x, &mut y, 1usize << (mem::size_of::() * 8 - 1)); - | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy` -LL | | -LL | | -LL | | }; - | |__- - | - = 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 #71800 - -error: any use of this value will cause an error - --> $DIR/copy-intrinsic.rs:39:5 - | -LL | / const COPY_NONOVERLAPPING_SIZE_OVERFLOW: () = unsafe { -LL | | let x = 0; -LL | | let mut y = 0; -LL | | ptr::copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::() * 8 - 1)); - | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy_nonoverlapping` -LL | | -LL | | -LL | | }; - | |__- - | - = 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 #71800 - -error: aborting due to 4 previous errors -