]> git.proxmox.com Git - rustc.git/commitdiff
New upstream version 1.52.0+dfsg1
authorXimin Luo <infinity0@debian.org>
Fri, 7 May 2021 19:27:40 +0000 (20:27 +0100)
committerXimin Luo <infinity0@debian.org>
Fri, 7 May 2021 19:27:40 +0000 (20:27 +0100)
78 files changed:
RELEASES.md
compiler/rustc_codegen_ssa/src/lib.rs
compiler/rustc_middle/src/ich/impls_syntax.rs
compiler/rustc_middle/src/lib.rs
compiler/rustc_middle/src/mir/interpret/allocation.rs
compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
compiler/rustc_mir/src/interpret/memory.rs
compiler/rustc_mir/src/lib.rs
compiler/rustc_mir_build/src/build/mod.rs
compiler/rustc_passes/src/dead.rs
compiler/rustc_target/src/spec/i386_apple_ios.rs
compiler/rustc_target/src/spec/i686_apple_darwin.rs
compiler/rustc_target/src/spec/i686_linux_android.rs
compiler/rustc_target/src/spec/i686_unknown_freebsd.rs
compiler/rustc_target/src/spec/i686_unknown_haiku.rs
compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs
compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs
compiler/rustc_target/src/spec/i686_unknown_netbsd.rs
compiler/rustc_target/src/spec/i686_unknown_openbsd.rs
compiler/rustc_target/src/spec/i686_wrs_vxworks.rs
compiler/rustc_target/src/spec/linux_kernel_base.rs
compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
compiler/rustc_target/src/spec/x86_64_apple_ios.rs
compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs
compiler/rustc_target/src/spec/x86_64_apple_tvos.rs
compiler/rustc_target/src/spec/x86_64_fuchsia.rs
compiler/rustc_target/src/spec/x86_64_linux_android.rs
compiler/rustc_target/src/spec/x86_64_pc_solaris.rs
compiler/rustc_target/src/spec/x86_64_sun_solaris.rs
compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs
compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs
compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs
compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs
compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs
compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs
compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs
compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs
compiler/rustc_target/src/spec/x86_64_unknown_none_hermitkernel.rs
compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs
compiler/rustc_target/src/spec/x86_64_unknown_redox.rs
compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs
git-commit-hash
library/alloc/src/str.rs
library/alloc/src/vec/into_iter.rs
library/alloc/src/vec/source_iter_marker.rs
library/alloc/tests/str.rs
library/alloc/tests/vec.rs
library/core/src/intrinsics.rs
library/core/src/macros/mod.rs
library/core/src/mem/mod.rs
library/core/src/panicking.rs
library/core/src/ptr/mod.rs
library/core/src/ptr/mut_ptr.rs
library/core/tests/const_ptr.rs
library/std/src/keyword_docs.rs
library/std/src/lib.rs
src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config
src/ci/run.sh
src/librustdoc/html/render/context.rs
src/librustdoc/html/render/mod.rs
src/librustdoc/passes/collect_trait_impls.rs
src/test/assembly/stack-probes.rs [deleted file]
src/test/codegen/stack-probes.rs
src/test/rustdoc-ui/deref-recursive-cycle.rs [deleted file]
src/test/rustdoc/deref-recursive-pathbuf.rs [deleted file]
src/test/rustdoc/deref-recursive.rs [deleted file]
src/test/rustdoc/deref-typedef.rs
src/test/rustdoc/issue-82465-asref-for-and-of-local.rs [new file with mode: 0644]
src/test/ui/borrowck/borrowck-assign-to-subfield.rs
src/test/ui/borrowck/issue-83309-ice-immut-in-for-loop.rs [new file with mode: 0644]
src/test/ui/borrowck/issue-83309-ice-immut-in-for-loop.stderr [new file with mode: 0644]
src/test/ui/const-ptr/out_of_bounds_read.stderr
src/test/ui/consts/copy-intrinsic.rs [deleted file]
src/test/ui/consts/copy-intrinsic.stderr [deleted file]
src/test/ui/lint/dead-code/write-only-field.rs [deleted file]
src/test/ui/lint/dead-code/write-only-field.stderr [deleted file]
src/test/ui/macros/assert-matches-macro-msg.rs [deleted file]
version

index 5dca7abcb26290408e96f09e7cce771b2ba83b9d..1e94fb8e42f04787cf29c7aabb9c5161d0ce66ca 100644 (file)
@@ -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<impl Error>` 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<T, const LENGTH: usize> {
+      inner: [T; LENGTH]
+  }
+
+  impl<T, const LENGTH: usize> GenericArray<T, LENGTH> {
+      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<str>`.][80279]
+- [`u64` and `u128` now implement `From<char>`.][79502]
+- [`Error` is now implemented for `&T` where `T` implements `Error`.][75180]
+- [`Poll::{map_ok, map_err}` are now implemented for `Poll<Option<Result<T, E>>>`.][80968]
+- [`unsigned_abs` is now implemented for all signed integer types.][80959]
+- [`io::Empty` now implements `io::Seek`.][78044]
+- [`rc::Weak<T>` and `sync::Weak<T>`'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<T>`.][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)
index dd04d3e548f8ccaf9858e06a2b7d4a3170b62f6a..ab9ea2f3e91daae80e2f57f07be32da9e8f00d6e 100644 (file)
@@ -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)]
index 31374429940cafaf14beae40478d35f7a96bf49e..aacec860711979b293917429034ff99e27c7eee6 100644 (file)
@@ -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!();
         }
index 6ddc38b0066875b2c7b58379402ae00d6a2d7ffe..49765166c871d008324bed6e10dbfac23c2ea7cc 100644 (file)
@@ -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)]
index 766d6a06f7e59815c987d642729e853ba0b7ef9e..898c375e9ae1a736ff56eeb821d023c714a40aee 100644 (file)
@@ -339,7 +339,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
         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(())
     }
 
index 28f6508cab2dadf449e32e0a5f3380b07a977a2c..d1fb999e518ca59b46dda2ce97d4193e2a51f0a8 100644 (file)
@@ -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,
+                        );
+                    }
                 }
             }
         };
index fe5ebf0b6fe972c5cf70114aba0b5e7ef55a4c4d..3648748a909086278d7c9f02cf32cad554fb5c3a 100644 (file)
@@ -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(())
     }
 
index f73d5dc0c116d8b1f0e06203d9152f360b267e01..bf4eeb408ec847561f68319833673877c2af3da5 100644 (file)
@@ -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)]
index 9f1de3349a56e04528233b20a7a981d64e75fc94..af4aaef902187cdbca978c883c6ff214d9ee75f9 100644 (file)
@@ -579,7 +579,7 @@ fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: LocalDefId, abi: Abi) -> bo
         Some(UnwindAttr::Aborts) => true,
         // If no attribute was found and the panic strategy is `unwind`, then we should examine
         // the function's ABI string to determine whether it should abort upon panic.
-        None => {
+        None if tcx.features().c_unwind => {
             use Abi::*;
             match abi {
                 // In the case of ABI's that have an `-unwind` equivalent, check whether the ABI
@@ -609,6 +609,10 @@ fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: LocalDefId, abi: Abi) -> bo
                 | Unadjusted => true,
             }
         }
+        // If the `c_unwind` feature gate is not active, follow the behavior that was in place
+        // prior to #76570. This is a special case: some functions have a C ABI but are meant to
+        // unwind anyway. Don't stop them.
+        None => false, // FIXME(#58794); should be `!(abi == Abi::Rust || abi == Abi::RustCall)`
     }
 }
 
index c63edf365a1aa1e27bbc58b7fa4f0e8e1cf2bc91..9d70bc4a82d0e43f3878c574c05620da64454812 100644 (file)
@@ -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);
             }
index cfaf020175b7f4e12bc479bfd6b36843bfedd028..f5d7be4537be097a98d6a49b20ec597edfdea359 100644 (file)
@@ -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
         },
     }
index 2d3310c7582eff4dd1fdde208474cecfe6618555..06d71db4af2410264730ccfae91177b2ac4f4b13 100644 (file)
@@ -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
index 18cd8847abd390e5650304561720f8f5207fe940..19d7b3c95cf6d3d53e9bd24b697fdbf85275ad50 100644 (file)
@@ -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(),
index fc425babb69484e1fb80238aa83fb1ec618a3861..75c3ea6a9adb157714eea13bef60b8b8624d5983 100644 (file)
@@ -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(),
index 5fba4e3f14a253c6100664c94debd98cc87d992f..e4c01db543980035011ca832f268a06823246706 100644 (file)
@@ -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(),
index fe1e6a4299daba3290d9d7835e89ebb091908114..9daf1d37dd267e7d5abc02db06ad8dc1bc6c686f 100644 (file)
@@ -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(),
index 623fd1b9ae801d098b40d8b8d6287b5e08df39ac..5fd54007edf2e1fef77e95423027fff6374c7fd2 100644 (file)
@@ -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.
index c4d11bfb13ece496999e9151256ef35f61a127d9..716bb9e24607317643d1381672f9e5dfd3b68895 100644 (file)
@@ -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(),
index fdaaf6c741e897944167a9279278960a07b314b1..e53462c099a96db553b4259c08c9c72ec7880ae3 100644 (file)
@@ -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(),
index ec8a2493b4e42434a6e4ff64e53553772bb919e3..2f8702d464d326aefb459039e07559610ca289ef 100644 (file)
@@ -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(),
index 522015689536715b922fd310aafadae958f497e9..738ff38b094de11dbbf6b72cad7481ad91c7c44e 100644 (file)
@@ -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,
index 8c40baccda84a1cac436cd49969882493ead44fa..570cf7974fe28a8a847cbf42a0df4d3ddbf4e7da 100644 (file)
@@ -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
index 6feeeac451b2760c8bd45713fbbe457c72ea970c..adb877185897bcbf540caa5f1ecc0caac9cedad2 100644 (file)
@@ -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
         },
     }
index a6e066213e7f97ea4b707cb4f5327ccbff1f87d7..c228e42ef300408a662c0bd34aec209e4f57ca8a 100644 (file)
@@ -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
         },
     }
index f8c47168da87f189e6414b302d388c6d31c9d41e..e3a5de4cbd1a403cfb900092cf00d969d3346720 100644 (file)
@@ -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
         },
     }
index a39e7f8c341058d0125d093b961b652c539668df..7774308b4ca5223950e3b26dc0dcf7bb438861a0 100644 (file)
@@ -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(),
index d436242e62b30bcd737b37ca367c79eb976b9dea..19bf27c457e8390e798c812df8237f979ce0e93f 100644 (file)
@@ -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(),
index 75eece74ff97d8b4b4f6f760b17a5ab789892cde..b78e43d4fe9b6f842db4d179d5437936bfde8c8b 100644 (file)
@@ -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(),
index 63e524fa8a9a2cf6a75e90085d84599cc4bc952a..2fa53470f74f2af8ddef69fd88998b4c8e542df8 100644 (file)
@@ -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(),
index d86b0d67acd15374e465f39e242925edf8b460c6..d551ce6d3715f26cae81796cb03fd263fadd75e1 100644 (file)
@@ -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(),
index c7d3b3feed50e79a2f6ff1d69beefaa540b7e16e..e51f6c1a75417cf6cec1dd0be7957d88c4954372 100644 (file)
@@ -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(),
index 963d4fdb12f2dcfb76231bc50531cfd4a23450bb..fcd96ddd61b33cb0016efa69bf397127cc691aa9 100644 (file)
@@ -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;
 
index 31164f8408dcb34f254b9d7b80c3bc55f99dda80..1ef24b6eb365eaca18ed01736c71544e5459db31 100644 (file)
@@ -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(),
index 99906764dfc6e86b730ab0f9aa47c8a55bf9c917..04499bc5bbe069b9faef690e7aa0515fd94892ce 100644 (file)
@@ -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(),
index 4b2bce37470cca9869b0feb78fedcbe7e6cf19c7..5bf9a195756ba9bf6cede90bd0b7cd9e3a9adbb5 100644 (file)
@@ -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
index fa9fdf5aa09928192cc5967f1d29686711f73bcf..658dc977c1cc750e52ed746db983279008beed11 100644 (file)
@@ -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 {
index 6d19dec00b411aea1db0d91da8a4d5337ae6ae4c..4718ad2be4ae92142c1e550fe4eeb3a5e7a87815 100644 (file)
@@ -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(),
index a357def190b83f489947272205f852986488a607..28d9801b78cb581cf835339b45c39171c6666234 100644 (file)
@@ -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(),
index ac5939bcb3c4326d057db817d94f454f436883b2..2c5ac43f24661b8457085a64e9527d7fbd8728bc 100644 (file)
@@ -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(),
index ddabe95ab83945c6464dc30b614b903ec7928452..b5aa37d032ee0a50a7130deb64f99f331b74299b 100644 (file)
@@ -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(),
index 1b35e813fcd8f1406033dfb4fcab3543800c81ab..6c59817259f8edc7ff9fefe2623a7f4fe0aa1a96 100644 (file)
@@ -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 {
index 29604f16e79c158448358ae8f947fae9c22c93c1..186c1d8f9cc1e1a1c8f2678174d9f3476c5a70c0 100644 (file)
@@ -1 +1 @@
-215738137bcbef2c3637a5bd290ef612cffe6ba5
\ No newline at end of file
+88f19c6dab716c6281af7602e30f413e809c5974
\ No newline at end of file
index 8c64bc0801259ca706b27f3da3854007db42f46d..73401fcc8a9dc9f871e32b8428100015c0b753fe 100644 (file)
@@ -90,8 +90,8 @@ impl<S: Borrow<str>> Join<&str> for [S] {
     }
 }
 
-macro_rules! spezialize_for_lengths {
-    ($separator:expr, $target:expr, $iter:expr; $($num:expr),*) => {
+macro_rules! specialize_for_lengths {
+    ($separator:expr, $target:expr, $iter:expr; $($num:expr),*) => {{
         let mut target = $target;
         let iter = $iter;
         let sep_bytes = $separator;
@@ -102,7 +102,8 @@ macro_rules! spezialize_for_lengths {
                 $num => {
                     for s in iter {
                         copy_slice_and_advance!(target, sep_bytes);
-                        copy_slice_and_advance!(target, s.borrow().as_ref());
+                        let content_bytes = s.borrow().as_ref();
+                        copy_slice_and_advance!(target, content_bytes);
                     }
                 },
             )*
@@ -110,11 +111,13 @@ macro_rules! spezialize_for_lengths {
                 // arbitrary non-zero size fallback
                 for s in iter {
                     copy_slice_and_advance!(target, sep_bytes);
-                    copy_slice_and_advance!(target, s.borrow().as_ref());
+                    let content_bytes = s.borrow().as_ref();
+                    copy_slice_and_advance!(target, content_bytes);
                 }
             }
         }
-    };
+        target
+    }}
 }
 
 macro_rules! copy_slice_and_advance {
@@ -153,30 +156,33 @@ where
     // if the `len` calculation overflows, we'll panic
     // we would have run out of memory anyway and the rest of the function requires
     // the entire Vec pre-allocated for safety
-    let len = sep_len
+    let reserved_len = sep_len
         .checked_mul(iter.len())
         .and_then(|n| {
             slice.iter().map(|s| s.borrow().as_ref().len()).try_fold(n, usize::checked_add)
         })
         .expect("attempt to join into collection with len > usize::MAX");
 
-    // crucial for safety
-    let mut result = Vec::with_capacity(len);
-    assert!(result.capacity() >= len);
+    // prepare an uninitialized buffer
+    let mut result = Vec::with_capacity(reserved_len);
+    debug_assert!(result.capacity() >= reserved_len);
 
     result.extend_from_slice(first.borrow().as_ref());
 
     unsafe {
-        {
-            let pos = result.len();
-            let target = result.get_unchecked_mut(pos..len);
-
-            // copy separator and slices over without bounds checks
-            // generate loops with hardcoded offsets for small separators
-            // massive improvements possible (~ x2)
-            spezialize_for_lengths!(sep, target, iter; 0, 1, 2, 3, 4);
-        }
-        result.set_len(len);
+        let pos = result.len();
+        let target = result.get_unchecked_mut(pos..reserved_len);
+
+        // copy separator and slices over without bounds checks
+        // generate loops with hardcoded offsets for small separators
+        // massive improvements possible (~ x2)
+        let remain = specialize_for_lengths!(sep, target, iter; 0, 1, 2, 3, 4);
+
+        // A weird borrow implementation may return different
+        // slices for the length calculation and the actual copy.
+        // Make sure we don't expose uninitialized bytes to the caller.
+        let result_len = reserved_len - remain.len();
+        result.set_len(result_len);
     }
     result
 }
index bcbdffabc7fbea221905aa647ec3934953068841..324e894bafd23a0d698573a507dd57a2bcf6e13e 100644 (file)
@@ -85,20 +85,29 @@ impl<T, A: Allocator> IntoIter<T, A> {
         ptr::slice_from_raw_parts_mut(self.ptr as *mut T, self.len())
     }
 
-    pub(super) fn drop_remaining(&mut self) {
-        unsafe {
-            ptr::drop_in_place(self.as_mut_slice());
-        }
-        self.ptr = self.end;
-    }
+    /// Drops remaining elements and relinquishes the backing allocation.
+    ///
+    /// This is roughly equivalent to the following, but more efficient
+    ///
+    /// ```
+    /// # let mut into_iter = Vec::<u8>::with_capacity(10).into_iter();
+    /// (&mut into_iter).for_each(core::mem::drop);
+    /// unsafe { core::ptr::write(&mut into_iter, Vec::new().into_iter()); }
+    /// ```
+    pub(super) fn forget_allocation_drop_remaining(&mut self) {
+        let remaining = self.as_raw_mut_slice();
 
-    /// Relinquishes the backing allocation, equivalent to
-    /// `ptr::write(&mut self, Vec::new().into_iter())`
-    pub(super) fn forget_allocation(&mut self) {
+        // overwrite the individual fields instead of creating a new
+        // struct and then overwriting &mut self.
+        // this creates less assembly
         self.cap = 0;
         self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
         self.ptr = self.buf.as_ptr();
         self.end = self.buf.as_ptr();
+
+        unsafe {
+            ptr::drop_in_place(remaining);
+        }
     }
 }
 
index 8c0e95559fa15e83fc4a07fea4951a533a233ed5..9301f7a5184e17b4fb46cce0c08819eb56215621 100644 (file)
@@ -78,9 +78,9 @@ where
         }
 
         // drop any remaining values at the tail of the source
-        src.drop_remaining();
         // but prevent drop of the allocation itself once IntoIter goes out of scope
-        src.forget_allocation();
+        // if the drop panics then we also leak any elements collected into dst_buf
+        src.forget_allocation_drop_remaining();
 
         let vec = unsafe {
             let len = dst.offset_from(dst_buf) as usize;
index 604835e6cc4a695ecc13bc1f0baea0f9a088fd68..6df8d8c2f354f9a6256bde30bc4e97fa9bfd68d4 100644 (file)
@@ -160,6 +160,36 @@ fn test_join_for_different_lengths_with_long_separator() {
     test_join!("~~~~~a~~~~~bc", ["", "a", "bc"], "~~~~~");
 }
 
+#[test]
+fn test_join_isue_80335() {
+    use core::{borrow::Borrow, cell::Cell};
+
+    struct WeirdBorrow {
+        state: Cell<bool>,
+    }
+
+    impl Default for WeirdBorrow {
+        fn default() -> Self {
+            WeirdBorrow { state: Cell::new(false) }
+        }
+    }
+
+    impl Borrow<str> for WeirdBorrow {
+        fn borrow(&self) -> &str {
+            let state = self.state.get();
+            if state {
+                "0"
+            } else {
+                self.state.set(true);
+                "123456"
+            }
+        }
+    }
+
+    let arr: [WeirdBorrow; 3] = Default::default();
+    test_join!("0-0-0", arr, "-");
+}
+
 #[test]
 #[cfg_attr(miri, ignore)] // Miri is too slow
 fn test_unsafe_slice() {
index c142536cd2dfbfc9664ecb3d795565dd2a227d6f..b926c697d58abe739526f809d274ae6fa4be0fc2 100644 (file)
@@ -1027,7 +1027,7 @@ fn test_from_iter_specialization_head_tail_drop() {
 }
 
 #[test]
-fn test_from_iter_specialization_panic_drop() {
+fn test_from_iter_specialization_panic_during_iteration_drops() {
     let drop_count: Vec<_> = (0..=2).map(|_| Rc::new(())).collect();
     let src: Vec<_> = drop_count.iter().cloned().collect();
     let iter = src.into_iter();
@@ -1050,6 +1050,42 @@ fn test_from_iter_specialization_panic_drop() {
     );
 }
 
+#[test]
+fn test_from_iter_specialization_panic_during_drop_leaks() {
+    static mut DROP_COUNTER: usize = 0;
+
+    #[derive(Debug)]
+    enum Droppable {
+        DroppedTwice(Box<i32>),
+        PanicOnDrop,
+    }
+
+    impl Drop for Droppable {
+        fn drop(&mut self) {
+            match self {
+                Droppable::DroppedTwice(_) => {
+                    unsafe {
+                        DROP_COUNTER += 1;
+                    }
+                    println!("Dropping!")
+                }
+                Droppable::PanicOnDrop => {
+                    if !std::thread::panicking() {
+                        panic!();
+                    }
+                }
+            }
+        }
+    }
+
+    let _ = std::panic::catch_unwind(AssertUnwindSafe(|| {
+        let v = vec![Droppable::DroppedTwice(Box::new(123)), Droppable::PanicOnDrop];
+        let _ = v.into_iter().take(0).collect::<Vec<_>>();
+    }));
+
+    assert_eq!(unsafe { DROP_COUNTER }, 1);
+}
+
 #[test]
 fn test_cow_from() {
     let borrowed: &[_] = &["borrowed", "(slice)"];
index b5371d6b69dbb075d4585b756a9121d74044d35f..073210c5b68573c4d06cca1569ba39c285b626c7 100644 (file)
@@ -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::<T>()` 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::<T>()` bytes.
-    ///
-    /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
-    ///
-    /// * Both `src` and `dst` must be properly aligned.
-    ///
-    /// * The region of memory beginning at `src` with a size of `count *
-    ///   size_of::<T>()` 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::<T>()`) 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<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
-    ///     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<T>(src: *const T, dst: *mut T, count: usize);
-
-    /// Copies `count * size_of::<T>()` 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::<T>()` bytes.
-    ///
-    /// * `dst` must be [valid] for writes of `count * size_of::<T>()` 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::<T>()`) 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<T>(ptr: *const T, elts: usize) -> Vec<T> {
-    ///     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<T>(src: *const T, dst: *mut T, count: usize);
 }
 
 // Some functions are defined here because they accidentally got made
@@ -1906,6 +1755,192 @@ pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
     !ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
 }
 
+/// Copies `count * size_of::<T>()` 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::<T>()` bytes.
+///
+/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
+///
+/// * Both `src` and `dst` must be properly aligned.
+///
+/// * The region of memory beginning at `src` with a size of `count *
+///   size_of::<T>()` 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::<T>()`) 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<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
+///     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<T>(src: *const T, dst: *mut T, count: usize) {
+    extern "rust-intrinsic" {
+        #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+        fn copy_nonoverlapping<T>(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::<T>()` 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::<T>()` bytes.
+///
+/// * `dst` must be [valid] for writes of `count * size_of::<T>()` 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::<T>()`) 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<T>(ptr: *const T, elts: usize) -> Vec<T> {
+///     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<T>(src: *const T, dst: *mut T, count: usize) {
+    extern "rust-intrinsic" {
+        #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+        fn copy<T>(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::<T>()` bytes of memory starting at `dst` to
 /// `val`.
 ///
index 99894b5605e6deb7a92099a0431ffdb0b1159db3..a0a8eecbc252752a541573ef9fc2a76e490387dd 100644 (file)
@@ -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
@@ -262,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`
index 37e8d65db6a38a5fdae75da762bf7dbaae1d920c..c4f0d9176741efd6cfaa4f330083f93a0983438f 100644 (file)
@@ -682,8 +682,7 @@ pub unsafe fn uninitialized<T>() -> T {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
-pub const fn swap<T>(x: &mut T, y: &mut T) {
+pub fn swap<T>(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<T: Default>(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<T>(dest: &mut T, src: T) -> T {
+pub fn replace<T>(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.
index 3e3e96fcd7f7843fb8a993cc63f46a8602a785e6..35d9b2c5d267f36e2716e7148543495e3a12b889 100644 (file)
@@ -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<T: fmt::Debug + ?Sized>(
-    left: &T,
-    right: &str,
-    args: Option<fmt::Arguments<'_>>,
-) -> ! {
-    // 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<fmt::Arguments<'_>>,
-) -> ! {
-    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<fmt::Arguments<'_>>,
+    ) -> ! {
+        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)
 }
index 3a27f01444be8e5cc3c5e7ee39cbedee81fcb670..fd24469bd3cd70f029f976a4b68c51a6a3bc991b 100644 (file)
@@ -463,8 +463,7 @@ pub const unsafe fn swap_nonoverlapping<T>(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<T>(x: *mut T, y: *mut T) {
+pub(crate) unsafe fn swap_nonoverlapping_one<T>(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::<T>() < 32 {
@@ -584,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<T>(dst: *mut T, mut src: T) -> T {
+pub unsafe fn replace<T>(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
@@ -898,14 +896,18 @@ pub const unsafe fn read_unaligned<T>(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<T>(dst: *mut T, src: T) {
+pub unsafe fn write<T>(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<T>(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);
     }
 }
index fa09cf854353d21e15a0a5f8d5272ea540406290..a9de2333bc0e2a70c669cbcb1281e8300d696fc4 100644 (file)
@@ -1013,9 +1013,8 @@ impl<T: ?Sized> *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,
     {
index 152fed803ecdb751167ccbb31a3155958920523a..4158a4dece729fa15e9cee9a9ae7ebeead4ecdc4 100644 (file)
@@ -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])]);
+//}
index 383eaf2e3a206db4b21e72bd4940ce43e2b0e8c2..46bfd834f81a23441773ab2191629ae5a87fc3aa 100644 (file)
@@ -1310,7 +1310,11 @@ mod return_keyword {}
 /// [Reference]: ../reference/items/associated-items.html#methods
 mod self_keyword {}
 
-#[doc(keyword = "Self")]
+// FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we can remove the
+// three next lines and put back: `#[doc(keyword = "Self")]`.
+#[doc(alias = "Self")]
+#[allow(rustc::existing_doc_keyword)]
+#[doc(keyword = "SelfTy")]
 //
 /// The implementing type within a [`trait`] or [`impl`] block, or the current type within a type
 /// definition.
index 8149858e10338846d04da9eda1da899e2c4462af..1f53a4c783c7aa45c47c9d7ec864b7350e4be1cf 100644 (file)
 #![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_ne, matches, r#try, todo,
+    unimplemented, unreachable, write, writeln,
 };
 
 // Re-export built-in macros defined through libcore.
index dbb4be550dd70072efaaa4b525c901892ffc75e4..7124ee3aeb53b6506ffc287a19f6f0da1aa41cfe 100644 (file)
@@ -644,7 +644,7 @@ CT_EXPAT_PATCH_GLOBAL=y
 CT_EXPAT_PATCH_ORDER="global"
 CT_EXPAT_V_2_2=y
 # CT_EXPAT_NO_VERSIONS is not set
-CT_EXPAT_VERSION="2.2.6"
+CT_EXPAT_VERSION="2.3.0"
 CT_EXPAT_MIRRORS="http://downloads.sourceforge.net/project/expat/expat/${CT_EXPAT_VERSION}"
 CT_EXPAT_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
 CT_EXPAT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
index 02d868f8f2a37f10b5b27ca0e45758ceed64611e..a408fa83e555384a4235730d3117a0c3180230e2 100755 (executable)
@@ -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
index 864fbccbcc45172e85051686f0933a2876380bd2..1d90122af15785c11ffc2b9fe27d5ebccce996b4 100644 (file)
@@ -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<IdMap>,
-    /// Tracks section IDs for `Deref` targets so they match in both the main
-    /// body and the sidebar.
-    pub(super) deref_id_map: RefCell<FxHashMap<DefId, String>>,
     /// 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),
         }
index 66c47f14655baaea4a1c607e4655b4e0fb1740c3..820a5098bb41165334f86e18b636a91c54891eff 100644 (file)
@@ -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,
-                    "<h2 id=\"{id}\" class=\"small-section-header\">\
+                    "<h2 id=\"deref-methods\" class=\"small-section-header\">\
                          Methods from {trait_}&lt;Target = {type_}&gt;\
-                         <a href=\"#{id}\" class=\"anchor\"></a>\
+                         <a href=\"#deref-methods\" class=\"anchor\"></a>\
                      </h2>",
-                    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::<Vec<_>>();
             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,
-                    "<a class=\"sidebar-title\" href=\"#{}\">Methods from {}&lt;Target={}&gt;</a>",
-                    id,
+                    "<a class=\"sidebar-title\" href=\"#deref-methods\">Methods from {}&lt;Target={}&gt;</a>",
                     Escape(&format!("{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print(c))),
                     Escape(&format!("{:#}", real_target.print(c))),
                 );
index 685451b87eda99f528eda378a4039599d09a2da3..492cc9118fe609067050ce78d8c6327d2a7fded7 100644 (file)
@@ -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<DefId, &Type> = 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<DefId, &Type>,
-        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<Target = S> 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/assembly/stack-probes.rs b/src/test/assembly/stack-probes.rs
deleted file mode 100644 (file)
index 9597e24..0000000
+++ /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);
-}
index b05787df8e30be23df28956a628329a2526695f4..9bd351df3eaa069d45a1356c1582fc2b638382de 100644 (file)
 // 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"{{.*}} }
 }
diff --git a/src/test/rustdoc-ui/deref-recursive-cycle.rs b/src/test/rustdoc-ui/deref-recursive-cycle.rs
deleted file mode 100644 (file)
index 4cb518c..0000000
+++ /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 (file)
index 759e881..0000000
+++ /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<Target = PathBuf>'
-// @has '-' '//*[@class="impl-items"]//*[@id="method.as_path"]' 'pub fn as_path(&self)'
-// @has '-' '//*[@id="deref-methods-Path"]' 'Methods from Deref<Target = Path>'
-// @has '-' '//*[@class="impl-items"]//*[@id="method.exists"]' 'pub fn exists(&self)'
-// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-PathBuf"]' 'Methods from Deref<Target=PathBuf>'
-// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.as_path"]' 'as_path'
-// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-Path"]' 'Methods from Deref<Target=Path>'
-// @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 (file)
index 5aef87c..0000000
+++ /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<Target = Bar>'
-// @has '-' '//*[@class="impl-items"]//*[@id="method.bar"]' 'pub fn bar(&self)'
-// @has '-' '//*[@id="deref-methods-Baz"]' 'Methods from Deref<Target = Baz>'
-// @has '-' '//*[@class="impl-items"]//*[@id="method.baz"]' 'pub fn baz(&self)'
-// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-Bar"]' 'Methods from Deref<Target=Bar>'
-// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.bar"]' 'bar'
-// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-Baz"]' 'Methods from Deref<Target=Baz>'
-// @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) {}
-}
index 589f133b975a509046fa9c0cda4e3430fd63d8d2..3fc48b46d7410f1a83e3dfab2c1140e4907005a9 100644 (file)
@@ -1,14 +1,12 @@
-// ignore-tidy-linelength
-
 #![crate_name = "foo"]
 
 // @has 'foo/struct.Bar.html'
-// @has '-' '//*[@id="deref-methods-FooJ"]' 'Methods from Deref<Target = FooJ>'
+// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref<Target = FooJ>'
 // @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<Target=FooJ>'
+// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods"]' 'Methods from Deref<Target=FooJ>'
 // @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'
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 (file)
index 0000000..618ac20
--- /dev/null
@@ -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<str> for Local'
+impl AsRef<str> for Local {
+    fn as_ref(&self) -> &str {
+        todo!()
+    }
+}
+
+// @has - '//code' 'impl AsRef<Local> for str'
+impl AsRef<Local> for str {
+    fn as_ref(&self) -> &Local {
+        todo!()
+    }
+}
index dfa3a561ec7ee1b9968635620b200094a89407a6..050d702b625ab4f4a49121ec609251f563d300cd 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 // pretty-expanded FIXME #23616
-#![allow(dead_code)]
 
 pub fn main() {
     struct A {
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 (file)
index 0000000..6da88be
--- /dev/null
@@ -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<Self::Item> {
+        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 (file)
index 0000000..143b74c
--- /dev/null
@@ -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`.
index 6c4092e3e5cc82d9c9f79eb753be09e41a338630..87b7c377b00368b9312f20875c752c3aebf3d373 100644 (file)
@@ -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::<u32>` 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::<u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+   |              inside `std::ptr::read::<u32>` 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 <https://github.com/rust-lang/rust/issues/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::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-   |         inside `ptr::const_ptr::<impl *const u32>::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::<u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+   |              inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |              inside `ptr::const_ptr::<impl *const u32>::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 <https://github.com/rust-lang/rust/issues/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::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-   |         inside `ptr::mut_ptr::<impl *mut u32>::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::<u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+   |              inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |              inside `ptr::mut_ptr::<impl *mut u32>::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
    |
diff --git a/src/test/ui/consts/copy-intrinsic.rs b/src/test/ui/consts/copy-intrinsic.rs
deleted file mode 100644 (file)
index 9dc595f..0000000
+++ /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::<usize>() * 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::<usize>() * 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 (file)
index 2736cde..0000000
+++ /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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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::<usize>() * 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 <https://github.com/rust-lang/rust/issues/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::<usize>() * 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 <https://github.com/rust-lang/rust/issues/71800>
-
-error: aborting due to 4 previous errors
-
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 (file)
index 7b3f1e9..0000000
+++ /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<B>,
-    }
-
-    struct B {
-        c: Box<C>,
-    }
-
-    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 (file)
index a191d22..0000000
+++ /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
-
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 (file)
index 43be953..0000000
+++ /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");
-}
diff --git a/version b/version
index 4fc37672f7ba3a8082bfb5a6ad15beccbf1b78dd..fa11e2f7fc358e431376dc9312ff1ee97c10f7ae 100644 (file)
--- a/version
+++ b/version
@@ -1 +1 @@
-1.52.0-beta.3 (215738137 2021-04-06)
\ No newline at end of file
+1.52.0 (88f19c6da 2021-05-03)
\ No newline at end of file