summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELEASES.md355
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs3
-rw-r--r--library/alloc/tests/string.rs126
-rw-r--r--library/alloc/tests/vec.rs166
-rw-r--r--library/alloc/tests/vec_deque.rs161
-rw-r--r--library/core/src/alloc/layout.rs76
-rw-r--r--library/core/src/mem/valid_align.rs11
-rw-r--r--library/std/src/sys/windows/path.rs9
-rw-r--r--library/std/src/sys/windows/path/tests.rs29
-rw-r--r--src/bootstrap/bootstrap.py2
-rw-r--r--src/bootstrap/lib.rs13
-rw-r--r--src/ci/channel2
-rw-r--r--src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2015.stderr9
-rw-r--r--src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr22
-rw-r--r--src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs12
m---------src/tools/cargo0
16 files changed, 778 insertions, 218 deletions
diff --git a/RELEASES.md b/RELEASES.md
index 8154eab2059..694bd09658f 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,352 @@
+Version 1.64.0 (2022-09-22)
+===========================
+
+Language
+--------
+- [Unions with mutable references or tuples of allowed types are now allowed](https://github.com/rust-lang/rust/pull/97995/)
+- It is now considered valid to deallocate memory pointed to by a shared reference `&T` [if every byte in `T` is inside an `UnsafeCell`](https://github.com/rust-lang/rust/pull/98017/)
+- Unused tuple struct fields are now warned against in an allow-by-default lint, [`unused_tuple_struct_fields`](https://github.com/rust-lang/rust/pull/95977/), similar to the existing warning for unused struct fields. This lint will become warn-by-default in the future.
+
+Compiler
+--------
+- [Add Nintendo Switch as tier 3 target](https://github.com/rust-lang/rust/pull/88991/)
+ - Refer to Rust's [platform support page][platform-support-doc] for more
+ information on Rust's tiered platform support.
+- [Only compile `#[used]` as llvm.compiler.used for ELF targets](https://github.com/rust-lang/rust/pull/93718/)
+- [Add the `--diagnostic-width` compiler flag to define the terminal width.](https://github.com/rust-lang/rust/pull/95635/)
+- [Add support for link-flavor `rust-lld` for iOS, tvOS and watchOS](https://github.com/rust-lang/rust/pull/98771/)
+
+Libraries
+---------
+- [Remove restrictions on compare-exchange memory ordering.](https://github.com/rust-lang/rust/pull/98383/)
+- You can now `write!` or `writeln!` into an `OsString`: [Implement `fmt::Write` for `OsString`](https://github.com/rust-lang/rust/pull/97915/)
+- [Make RwLockReadGuard covariant](https://github.com/rust-lang/rust/pull/96820/)
+- [Implement `FusedIterator` for `std::net::[Into]Incoming`](https://github.com/rust-lang/rust/pull/97300/)
+- [`impl<T: AsRawFd> AsRawFd for {Arc,Box}<T>`](https://github.com/rust-lang/rust/pull/97437/)
+- [`ptr::copy` and `ptr::swap` are doing untyped copies](https://github.com/rust-lang/rust/pull/97712/)
+- [Add cgroupv1 support to `available_parallelism`](https://github.com/rust-lang/rust/pull/97925/)
+- [Mitigate many incorrect uses of `mem::uninitialized`](https://github.com/rust-lang/rust/pull/99182/)
+
+Stabilized APIs
+---------------
+
+- [`future::IntoFuture`](https://doc.rust-lang.org/stable/std/future/trait.IntoFuture.html)
+- [`future::poll_fn`](https://doc.rust-lang.org/stable/std/future/fn.poll_fn.html)
+- [`task::ready!`](https://doc.rust-lang.org/stable/std/task/macro.ready.html)
+- [`num::NonZero*::checked_mul`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_mul)
+- [`num::NonZero*::checked_pow`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_pow)
+- [`num::NonZero*::saturating_mul`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_mul)
+- [`num::NonZero*::saturating_pow`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_pow)
+- [`num::NonZeroI*::abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.abs)
+- [`num::NonZeroI*::checked_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.checked_abs)
+- [`num::NonZeroI*::overflowing_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.overflowing_abs)
+- [`num::NonZeroI*::saturating_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.saturating_abs)
+- [`num::NonZeroI*::unsigned_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.unsigned_abs)
+- [`num::NonZeroI*::wrapping_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.wrapping_abs)
+- [`num::NonZeroU*::checked_add`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_add)
+- [`num::NonZeroU*::checked_next_power_of_two`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_next_power_of_two)
+- [`num::NonZeroU*::saturating_add`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_add)
+- [`os::unix::process::CommandExt::process_group`](https://doc.rust-lang.org/stable/std/os/unix/process/trait.CommandExt.html#tymethod.process_group)
+- [`os::windows::fs::FileTypeExt::is_symlink_dir`](https://doc.rust-lang.org/stable/std/os/windows/fs/trait.FileTypeExt.html#tymethod.is_symlink_dir)
+- [`os::windows::fs::FileTypeExt::is_symlink_file`](https://doc.rust-lang.org/stable/std/os/windows/fs/trait.FileTypeExt.html#tymethod.is_symlink_file)
+
+These types were previously stable in `std::ffi`, but are now also available in `core` and `alloc`:
+
+- [`core::ffi::CStr`](https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html)
+- [`core::ffi::FromBytesWithNulError`](https://doc.rust-lang.org/stable/core/ffi/struct.FromBytesWithNulError.html)
+- [`alloc::ffi::CString`](https://doc.rust-lang.org/stable/alloc/ffi/struct.CString.html)
+- [`alloc::ffi::FromVecWithNulError`](https://doc.rust-lang.org/stable/alloc/ffi/struct.FromVecWithNulError.html)
+- [`alloc::ffi::IntoStringError`](https://doc.rust-lang.org/stable/alloc/ffi/struct.IntoStringError.html)
+- [`alloc::ffi::NulError`](https://doc.rust-lang.org/stable/alloc/ffi/struct.NulError.html)
+
+These types were previously stable in `std::os::raw`, but are now also available in `core::ffi` and `std::ffi`:
+
+- [`ffi::c_char`](https://doc.rust-lang.org/stable/std/ffi/type.c_char.html)
+- [`ffi::c_double`](https://doc.rust-lang.org/stable/std/ffi/type.c_double.html)
+- [`ffi::c_float`](https://doc.rust-lang.org/stable/std/ffi/type.c_float.html)
+- [`ffi::c_int`](https://doc.rust-lang.org/stable/std/ffi/type.c_int.html)
+- [`ffi::c_long`](https://doc.rust-lang.org/stable/std/ffi/type.c_long.html)
+- [`ffi::c_longlong`](https://doc.rust-lang.org/stable/std/ffi/type.c_longlong.html)
+- [`ffi::c_schar`](https://doc.rust-lang.org/stable/std/ffi/type.c_schar.html)
+- [`ffi::c_short`](https://doc.rust-lang.org/stable/std/ffi/type.c_short.html)
+- [`ffi::c_uchar`](https://doc.rust-lang.org/stable/std/ffi/type.c_uchar.html)
+- [`ffi::c_uint`](https://doc.rust-lang.org/stable/std/ffi/type.c_uint.html)
+- [`ffi::c_ulong`](https://doc.rust-lang.org/stable/std/ffi/type.c_ulong.html)
+- [`ffi::c_ulonglong`](https://doc.rust-lang.org/stable/std/ffi/type.c_ulonglong.html)
+- [`ffi::c_ushort`](https://doc.rust-lang.org/stable/std/ffi/type.c_ushort.html)
+
+These APIs are now usable in const contexts:
+
+- [`slice::from_raw_parts`](https://doc.rust-lang.org/stable/core/slice/fn.from_raw_parts.html)
+
+Cargo
+-----
+- [Packages can now inherit settings from the workspace so that the settings
+ can be centralized in one place.](https://github.com/rust-lang/cargo/pull/10859) See
+ [`workspace.package`](https://doc.rust-lang.org/nightly/cargo/reference/workspaces.html#the-workspacepackage-table)
+ and
+ [`workspace.dependencies`](https://doc.rust-lang.org/nightly/cargo/reference/workspaces.html#the-workspacedependencies-table)
+ for more details on how to define these common settings.
+- [Cargo commands can now accept multiple `--target` flags to build for
+ multiple targets at once](https://github.com/rust-lang/cargo/pull/10766), and the
+ [`build.target`](https://doc.rust-lang.org/nightly/cargo/reference/config.html#buildtarget)
+ config option may now take an array of multiple targets.
+- [The `--jobs` argument can now take a negative number to count backwards from
+ the max CPUs.](https://github.com/rust-lang/cargo/pull/10844)
+- [`cargo add` will now update `Cargo.lock`.](https://github.com/rust-lang/cargo/pull/10902)
+- [Added](https://github.com/rust-lang/cargo/pull/10838) the
+ [`--crate-type`](https://doc.rust-lang.org/nightly/cargo/commands/cargo-rustc.html#option-cargo-rustc---crate-type)
+ flag to `cargo rustc` to override the crate type.
+- [Significantly improved the performance fetching git dependencies from GitHub
+ when using a hash in the `rev` field.](https://github.com/rust-lang/cargo/pull/10079)
+
+Misc
+----
+- [The `rust-analyzer` rustup component is now available on the stable channel.](https://github.com/rust-lang/rust/pull/98640/)
+
+Compatibility Notes
+-------------------
+- The minimum required versions for all `-linux-gnu` targets are now at least kernel 3.2 and glibc 2.17, for targets that previously supported older versions: [Increase the minimum linux-gnu versions](https://github.com/rust-lang/rust/pull/95026/)
+- [Network primitives are now implemented with the ideal Rust layout, not the C system layout](https://github.com/rust-lang/rust/pull/78802/). This can cause problems when transmuting the types.
+- [Add assertion that `transmute_copy`'s `U` is not larger than `T`](https://github.com/rust-lang/rust/pull/98839/)
+- [A soundness bug in `BTreeMap` was fixed](https://github.com/rust-lang/rust/pull/99413/) that allowed data it was borrowing to be dropped before the container.
+- [The Drop behavior of C-like enums cast to ints has changed](https://github.com/rust-lang/rust/pull/96862/). These are already discouraged by a compiler warning.
+- [Relate late-bound closure lifetimes to parent fn in NLL](https://github.com/rust-lang/rust/pull/98835/)
+- [Errors at const-eval time are now in future incompatibility reports](https://github.com/rust-lang/rust/pull/97743/)
+- On the `thumbv6m-none-eabi` target, some incorrect `asm!` statements were erroneously accepted if they used the high registers (r8 to r14) as an input/output operand. [This is no longer accepted](https://github.com/rust-lang/rust/pull/99155/).
+- [`impl Trait` was accidentally accepted as the associated type value of return-position `impl Trait`](https://github.com/rust-lang/rust/pull/97346/), without fulfilling all the trait bounds of that associated type, as long as the hidden type satisfies said bounds. This has been fixed.
+
+Internal Changes
+----------------
+
+These changes do not affect any public interfaces of Rust, but they represent
+significant improvements to the performance or internals of rustc and related
+tools.
+
+- Windows builds now use profile-guided optimization, providing 10-20% improvements to compiler performance: [Utilize PGO for windows x64 rustc dist builds](https://github.com/rust-lang/rust/pull/96978/)
+- [Stop keeping metadata in memory before writing it to disk](https://github.com/rust-lang/rust/pull/96544/)
+- [compiletest: strip debuginfo by default for mode=ui](https://github.com/rust-lang/rust/pull/98140/)
+- Many improvements to generated code for derives, including performance improvements:
+ - [Don't use match-destructuring for derived ops on structs.](https://github.com/rust-lang/rust/pull/98446/)
+ - [Many small deriving cleanups](https://github.com/rust-lang/rust/pull/98741/)
+ - [More derive output improvements](https://github.com/rust-lang/rust/pull/98758/)
+ - [Clarify deriving code](https://github.com/rust-lang/rust/pull/98915/)
+ - [Final derive output improvements](https://github.com/rust-lang/rust/pull/99046/)
+ - [Stop injecting `#[allow(unused_qualifications)]` in generated `derive` implementations](https://github.com/rust-lang/rust/pull/99485/)
+ - [Improve `derive(Debug)`](https://github.com/rust-lang/rust/pull/98190/)
+- [Bump to clap 3](https://github.com/rust-lang/rust/pull/98213/)
+- [fully move dropck to mir](https://github.com/rust-lang/rust/pull/98641/)
+- [Optimize `Vec::insert` for the case where `index == len`.](https://github.com/rust-lang/rust/pull/98755/)
+- [Convert rust-analyzer to an in-tree tool](https://github.com/rust-lang/rust/pull/99603/)
+
+Version 1.63.0 (2022-08-11)
+==========================
+
+Language
+--------
+- [Remove migrate borrowck mode for pre-NLL errors.][95565]
+- [Modify MIR building to drop repeat expressions with length zero.][95953]
+- [Remove label/lifetime shadowing warnings.][96296]
+- [Allow explicit generic arguments in the presence of `impl Trait` args.][96868]
+- [Make `cenum_impl_drop_cast` warnings deny-by-default.][97652]
+- [Prevent unwinding when `-C panic=abort` is used regardless of declared ABI.][96959]
+- [lub: don't bail out due to empty binders.][97867]
+
+Compiler
+--------
+- [Stabilize the `bundle` native library modifier,][95818] also removing the
+ deprecated `static-nobundle` linking kind.
+- [Add Apple WatchOS compile targets\*.][95243]
+- [Add a Windows application manifest to rustc-main.][96737]
+
+\* Refer to Rust's [platform support page][platform-support-doc] for more
+ information on Rust's tiered platform support.
+
+Libraries
+---------
+- [Implement `Copy`, `Clone`, `PartialEq` and `Eq` for `core::fmt::Alignment`.][94530]
+- [Extend `ptr::null` and `null_mut` to all thin (including extern) types.][94954]
+- [`impl Read and Write for VecDeque<u8>`.][95632]
+- [STD support for the Nintendo 3DS.][95897]
+- [Use rounding in float to Duration conversion methods.][96051]
+- [Make write/print macros eagerly drop temporaries.][96455]
+- [Implement internal traits that enable `[OsStr]::join`.][96881]
+- [Implement `Hash` for `core::alloc::Layout`.][97034]
+- [Add capacity documentation for `OsString`.][97202]
+- [Put a bound on collection misbehavior.][97316]
+- [Make `std::mem::needs_drop` accept `?Sized`.][97675]
+- [`impl Termination for Infallible` and then make the `Result` impls of `Termination` more generic.][97803]
+- [Document Rust's stance on `/proc/self/mem`.][97837]
+
+Stabilized APIs
+---------------
+
+- [`array::from_fn`]
+- [`Box::into_pin`]
+- [`BinaryHeap::try_reserve`]
+- [`BinaryHeap::try_reserve_exact`]
+- [`OsString::try_reserve`]
+- [`OsString::try_reserve_exact`]
+- [`PathBuf::try_reserve`]
+- [`PathBuf::try_reserve_exact`]
+- [`Path::try_exists`]
+- [`Ref::filter_map`]
+- [`RefMut::filter_map`]
+- [`NonNull::<[T]>::len`][`NonNull::<slice>::len`]
+- [`ToOwned::clone_into`]
+- [`Ipv6Addr::to_ipv4_mapped`]
+- [`unix::io::AsFd`]
+- [`unix::io::BorrowedFd<'fd>`]
+- [`unix::io::OwnedFd`]
+- [`windows::io::AsHandle`]
+- [`windows::io::BorrowedHandle<'handle>`]
+- [`windows::io::OwnedHandle`]
+- [`windows::io::HandleOrInvalid`]
+- [`windows::io::HandleOrNull`]
+- [`windows::io::InvalidHandleError`]
+- [`windows::io::NullHandleError`]
+- [`windows::io::AsSocket`]
+- [`windows::io::BorrowedSocket<'handle>`]
+- [`windows::io::OwnedSocket`]
+- [`thread::scope`]
+- [`thread::Scope`]
+- [`thread::ScopedJoinHandle`]
+
+These APIs are now usable in const contexts:
+
+- [`array::from_ref`]
+- [`slice::from_ref`]
+- [`intrinsics::copy`]
+- [`intrinsics::copy_nonoverlapping`]
+- [`<*const T>::copy_to`]
+- [`<*const T>::copy_to_nonoverlapping`]
+- [`<*mut T>::copy_to`]
+- [`<*mut T>::copy_to_nonoverlapping`]
+- [`<*mut T>::copy_from`]
+- [`<*mut T>::copy_from_nonoverlapping`]
+- [`str::from_utf8`]
+- [`Utf8Error::error_len`]
+- [`Utf8Error::valid_up_to`]
+- [`Condvar::new`]
+- [`Mutex::new`]
+- [`RwLock::new`]
+
+Cargo
+-----
+- [Stabilize the `--config path` command-line argument.][cargo/10755]
+- [Expose rust-version in the environment as `CARGO_PKG_RUST_VERSION`.][cargo/10713]
+
+Compatibility Notes
+-------------------
+
+- [`#[link]` attributes are now checked more strictly,][96885] which may introduce
+ errors for invalid attribute arguments that were previously ignored.
+- [Rounding is now used when converting a float to a `Duration`.][96051] The converted
+ duration can differ slightly from what it was.
+
+Internal Changes
+----------------
+
+These changes provide no direct user facing benefits, but represent significant
+improvements to the internals and overall performance of rustc
+and related tools.
+
+- [Prepare Rust for LLVM opaque pointers.][94214]
+
+[94214]: https://github.com/rust-lang/rust/pull/94214/
+[94530]: https://github.com/rust-lang/rust/pull/94530/
+[94954]: https://github.com/rust-lang/rust/pull/94954/
+[95243]: https://github.com/rust-lang/rust/pull/95243/
+[95565]: https://github.com/rust-lang/rust/pull/95565/
+[95632]: https://github.com/rust-lang/rust/pull/95632/
+[95818]: https://github.com/rust-lang/rust/pull/95818/
+[95897]: https://github.com/rust-lang/rust/pull/95897/
+[95953]: https://github.com/rust-lang/rust/pull/95953/
+[96051]: https://github.com/rust-lang/rust/pull/96051/
+[96296]: https://github.com/rust-lang/rust/pull/96296/
+[96455]: https://github.com/rust-lang/rust/pull/96455/
+[96737]: https://github.com/rust-lang/rust/pull/96737/
+[96868]: https://github.com/rust-lang/rust/pull/96868/
+[96881]: https://github.com/rust-lang/rust/pull/96881/
+[96885]: https://github.com/rust-lang/rust/pull/96885/
+[96959]: https://github.com/rust-lang/rust/pull/96959/
+[97034]: https://github.com/rust-lang/rust/pull/97034/
+[97202]: https://github.com/rust-lang/rust/pull/97202/
+[97316]: https://github.com/rust-lang/rust/pull/97316/
+[97652]: https://github.com/rust-lang/rust/pull/97652/
+[97675]: https://github.com/rust-lang/rust/pull/97675/
+[97803]: https://github.com/rust-lang/rust/pull/97803/
+[97837]: https://github.com/rust-lang/rust/pull/97837/
+[97867]: https://github.com/rust-lang/rust/pull/97867/
+[cargo/10713]: https://github.com/rust-lang/cargo/pull/10713/
+[cargo/10755]: https://github.com/rust-lang/cargo/pull/10755/
+
+[`array::from_fn`]: https://doc.rust-lang.org/stable/std/array/fn.from_fn.html
+[`Box::into_pin`]: https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.into_pin
+[`BinaryHeap::try_reserve_exact`]: https://doc.rust-lang.org/stable/alloc/collections/binary_heap/struct.BinaryHeap.html#method.try_reserve_exact
+[`BinaryHeap::try_reserve`]: https://doc.rust-lang.org/stable/std/collections/struct.BinaryHeap.html#method.try_reserve
+[`OsString::try_reserve`]: https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.try_reserve
+[`OsString::try_reserve_exact`]: https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.try_reserve_exact
+[`PathBuf::try_reserve`]: https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.try_reserve
+[`PathBuf::try_reserve_exact`]: https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.try_reserve_exact
+[`Path::try_exists`]: https://doc.rust-lang.org/stable/std/path/struct.Path.html#method.try_exists
+[`Ref::filter_map`]: https://doc.rust-lang.org/stable/std/cell/struct.Ref.html#method.filter_map
+[`RefMut::filter_map`]: https://doc.rust-lang.org/stable/std/cell/struct.RefMut.html#method.filter_map
+[`NonNull::<slice>::len`]: https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.len
+[`ToOwned::clone_into`]: https://doc.rust-lang.org/stable/std/borrow/trait.ToOwned.html#method.clone_into
+[`Ipv6Addr::to_ipv4_mapped`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.to_ipv4_mapped
+[`unix::io::AsFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.AsFd.html
+[`unix::io::BorrowedFd<'fd>`]: https://doc.rust-lang.org/stable/std/os/unix/io/struct.BorrowedFd.html
+[`unix::io::OwnedFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/struct.OwnedFd.html
+[`windows::io::AsHandle`]: https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsHandle.html
+[`windows::io::BorrowedHandle<'handle>`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.BorrowedHandle.html
+[`windows::io::OwnedHandle`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.OwnedHandle.html
+[`windows::io::HandleOrInvalid`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.HandleOrInvalid.html
+[`windows::io::HandleOrNull`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.HandleOrNull.html
+[`windows::io::InvalidHandleError`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.InvalidHandleError.html
+[`windows::io::NullHandleError`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.NullHandleError.html
+[`windows::io::AsSocket`]: https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsSocket.html
+[`windows::io::BorrowedSocket<'handle>`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.BorrowedSocket.html
+[`windows::io::OwnedSocket`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.OwnedSocket.html
+[`thread::scope`]: https://doc.rust-lang.org/stable/std/thread/fn.scope.html
+[`thread::Scope`]: https://doc.rust-lang.org/stable/std/thread/struct.Scope.html
+[`thread::ScopedJoinHandle`]: https://doc.rust-lang.org/stable/std/thread/struct.ScopedJoinHandle.html
+
+[`array::from_ref`]: https://doc.rust-lang.org/stable/std/array/fn.from_ref.html
+[`slice::from_ref`]: https://doc.rust-lang.org/stable/std/slice/fn.from_ref.html
+[`intrinsics::copy`]: https://doc.rust-lang.org/stable/std/intrinsics/fn.copy.html
+[`intrinsics::copy_nonoverlapping`]: https://doc.rust-lang.org/stable/std/intrinsics/fn.copy_nonoverlapping.html
+[`<*const T>::copy_to`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.copy_to
+[`<*const T>::copy_to_nonoverlapping`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.copy_to_nonoverlapping
+[`<*mut T>::copy_to`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.copy_to-1
+[`<*mut T>::copy_to_nonoverlapping`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.copy_to_nonoverlapping-1
+[`<*mut T>::copy_from`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.copy_from
+[`<*mut T>::copy_from_nonoverlapping`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.copy_from_nonoverlapping
+[`str::from_utf8`]: https://doc.rust-lang.org/stable/std/str/fn.from_utf8.html
+[`Utf8Error::error_len`]: https://doc.rust-lang.org/stable/std/str/struct.Utf8Error.html#method.error_len
+[`Utf8Error::valid_up_to`]: https://doc.rust-lang.org/stable/std/str/struct.Utf8Error.html#method.valid_up_to
+[`Condvar::new`]: https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html#method.new
+[`Mutex::new`]: https://doc.rust-lang.org/stable/std/sync/struct.Mutex.html#method.new
+[`RwLock::new`]: https://doc.rust-lang.org/stable/std/sync/struct.RwLock.html#method.new
+
+Version 1.62.1 (2022-07-19)
+==========================
+
+Rust 1.62.1 addresses a few recent regressions in the compiler and standard
+library, and also mitigates a CPU vulnerability on Intel SGX.
+
+* [The compiler fixed unsound function coercions involving `impl Trait` return types.][98608]
+* [The compiler fixed an incremental compilation bug with `async fn` lifetimes.][98890]
+* [Windows added a fallback for overlapped I/O in synchronous reads and writes.][98950]
+* [The `x86_64-fortanix-unknown-sgx` target added a mitigation for the
+ MMIO stale data vulnerability][98126], advisory [INTEL-SA-00615].
+
+[98608]: https://github.com/rust-lang/rust/issues/98608
+[98890]: https://github.com/rust-lang/rust/issues/98890
+[98950]: https://github.com/rust-lang/rust/pull/98950
+[98126]: https://github.com/rust-lang/rust/pull/98126
+[INTEL-SA-00615]: https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00615.html
+
Version 1.62.0 (2022-06-30)
==========================
@@ -9,6 +358,7 @@ Language
- [Fix constants not getting dropped if part of a diverging expression][94775]
- [Support unit struct/enum variant in destructuring assignment][95380]
- [Remove mutable_borrow_reservation_conflict lint and allow the code pattern][96268]
+- [`const` functions may now specify `extern "C"` or `extern "Rust"`][95346]
Compiler
--------
@@ -98,6 +448,7 @@ and related tools.
[94872]: https://github.com/rust-lang/rust/pull/94872/
[95006]: https://github.com/rust-lang/rust/pull/95006/
[95035]: https://github.com/rust-lang/rust/pull/95035/
+[95346]: https://github.com/rust-lang/rust/pull/95346/
[95372]: https://github.com/rust-lang/rust/pull/95372/
[95380]: https://github.com/rust-lang/rust/pull/95380/
[95431]: https://github.com/rust-lang/rust/pull/95431/
@@ -1234,7 +1585,7 @@ Compatibility Notes
- [Mixing Option and Result via `?` is no longer permitted in closures for inferred types.][86831]
- [Previously unsound code is no longer permitted where different constructors in branches
could require different lifetimes.][85574]
-- As previously mentioned the [`std::arch` instrinsics now uses stricter const checking][83278]
+- As previously mentioned the [`std::arch` intrinsics now uses stricter const checking][83278]
than before and may reject some previously accepted code.
- [`i128` multiplication on Cortex M0+ platforms currently unconditionally causes overflow
when compiled with `codegen-units = 1`.][86063]
@@ -2312,7 +2663,7 @@ Compatibility Notes
- [Fixed a regression parsing `{} && false` in tail expressions.][74650]
- [Added changes to how proc-macros are expanded in `macro_rules!` that should
help to preserve more span information.][73084] These changes may cause
- compiliation errors if your macro was unhygenic or didn't correctly handle
+ compilation errors if your macro was unhygenic or didn't correctly handle
`Delimiter::None`.
- [Moved support for the CloudABI target to tier 3.][75568]
- [`linux-gnu` targets now require minimum kernel 2.6.32 and glibc 2.11.][74163]
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index f387743c915..224dc3c23d4 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1577,8 +1577,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
LifetimeRes::Fresh { param, binder: _ } => {
debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime);
- let old_def_id = self.local_def_id(param);
- if remapping.get(&old_def_id).is_none() {
+ if let Some(old_def_id) = self.opt_local_def_id(param) && remapping.get(&old_def_id).is_none() {
let node_id = self.next_node_id();
let new_def_id = self.create_def(
diff --git a/library/alloc/tests/string.rs b/library/alloc/tests/string.rs
index 99d1296a4c9..b6836fdc88e 100644
--- a/library/alloc/tests/string.rs
+++ b/library/alloc/tests/string.rs
@@ -693,6 +693,12 @@ fn test_try_reserve() {
const MAX_CAP: usize = isize::MAX as usize;
const MAX_USIZE: usize = usize::MAX;
+ // On 16/32-bit, we check that allocations don't exceed isize::MAX,
+ // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
+ // Any platform that succeeds for these requests is technically broken with
+ // ptr::offset because LLVM is the worst.
+ let guards_against_isize = usize::BITS < 64;
+
{
// Note: basic stuff is checked by test_reserve
let mut empty_string: String = String::new();
@@ -706,19 +712,35 @@ fn test_try_reserve() {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- // Check isize::MAX + 1 does count as overflow
- assert_matches!(
- empty_string.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
- // Check usize::MAX does count as overflow
- assert_matches!(
- empty_string.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "usize::MAX should trigger an overflow!"
- );
+ if guards_against_isize {
+ // Check isize::MAX + 1 does count as overflow
+ assert_matches!(
+ empty_string.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
+ // Check usize::MAX does count as overflow
+ assert_matches!(
+ empty_string.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "usize::MAX should trigger an overflow!"
+ );
+ } else {
+ // Check isize::MAX + 1 is an OOM
+ assert_matches!(
+ empty_string.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+
+ // Check usize::MAX is an OOM
+ assert_matches!(
+ empty_string.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "usize::MAX should trigger an OOM!"
+ );
+ }
}
{
@@ -731,13 +753,19 @@ fn test_try_reserve() {
if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
panic!("isize::MAX shouldn't trigger an overflow!");
}
-
- assert_matches!(
- ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
+ if guards_against_isize {
+ assert_matches!(
+ ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+ } else {
+ assert_matches!(
+ ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+ }
// Should always overflow in the add-to-len
assert_matches!(
ten_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
@@ -757,6 +785,8 @@ fn test_try_reserve_exact() {
const MAX_CAP: usize = isize::MAX as usize;
const MAX_USIZE: usize = usize::MAX;
+ let guards_against_isize = usize::BITS < 64;
+
{
let mut empty_string: String = String::new();
@@ -769,17 +799,31 @@ fn test_try_reserve_exact() {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- assert_matches!(
- empty_string.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
- assert_matches!(
- empty_string.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "usize::MAX should trigger an overflow!"
- );
+ if guards_against_isize {
+ assert_matches!(
+ empty_string.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
+ assert_matches!(
+ empty_string.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "usize::MAX should trigger an overflow!"
+ );
+ } else {
+ assert_matches!(
+ empty_string.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+
+ assert_matches!(
+ empty_string.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "usize::MAX should trigger an OOM!"
+ );
+ }
}
{
@@ -795,13 +839,19 @@ fn test_try_reserve_exact() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
-
- assert_matches!(
- ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
+ if guards_against_isize {
+ assert_matches!(
+ ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+ } else {
+ assert_matches!(
+ ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+ }
assert_matches!(
ten_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
Err(CapacityOverflow),
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index d94da8f5f5a..b797e237535 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -1527,6 +1527,12 @@ fn test_try_reserve() {
const MAX_CAP: usize = isize::MAX as usize;
const MAX_USIZE: usize = usize::MAX;
+ // On 16/32-bit, we check that allocations don't exceed isize::MAX,
+ // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
+ // Any platform that succeeds for these requests is technically broken with
+ // ptr::offset because LLVM is the worst.
+ let guards_against_isize = usize::BITS < 64;
+
{
// Note: basic stuff is checked by test_reserve
let mut empty_bytes: Vec<u8> = Vec::new();
@@ -1540,19 +1546,35 @@ fn test_try_reserve() {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- // Check isize::MAX + 1 does count as overflow
- assert_matches!(
- empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
- // Check usize::MAX does count as overflow
- assert_matches!(
- empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "usize::MAX should trigger an overflow!"
- );
+ if guards_against_isize {
+ // Check isize::MAX + 1 does count as overflow
+ assert_matches!(
+ empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
+ // Check usize::MAX does count as overflow
+ assert_matches!(
+ empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "usize::MAX should trigger an overflow!"
+ );
+ } else {
+ // Check isize::MAX + 1 is an OOM
+ assert_matches!(
+ empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+
+ // Check usize::MAX is an OOM
+ assert_matches!(
+ empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "usize::MAX should trigger an OOM!"
+ );
+ }
}
{
@@ -1565,13 +1587,19 @@ fn test_try_reserve() {
if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
panic!("isize::MAX shouldn't trigger an overflow!");
}
-
- assert_matches!(
- ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
+ if guards_against_isize {
+ assert_matches!(
+ ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+ } else {
+ assert_matches!(
+ ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+ }
// Should always overflow in the add-to-len
assert_matches!(
ten_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
@@ -1592,13 +1620,19 @@ fn test_try_reserve() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
-
- assert_matches!(
- ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
+ if guards_against_isize {
+ assert_matches!(
+ ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+ } else {
+ assert_matches!(
+ ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+ }
// Should fail in the mul-by-size
assert_matches!(
ten_u32s.try_reserve(MAX_USIZE - 20).map_err(|e| e.kind()),
@@ -1618,6 +1652,8 @@ fn test_try_reserve_exact() {
const MAX_CAP: usize = isize::MAX as usize;
const MAX_USIZE: usize = usize::MAX;
+ let guards_against_isize = size_of::<usize>() < 8;
+
{
let mut empty_bytes: Vec<u8> = Vec::new();
@@ -1630,17 +1666,31 @@ fn test_try_reserve_exact() {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- assert_matches!(
- empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
- assert_matches!(
- empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "usize::MAX should trigger an overflow!"
- );
+ if guards_against_isize {
+ assert_matches!(
+ empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
+ assert_matches!(
+ empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "usize::MAX should trigger an overflow!"
+ );
+ } else {
+ assert_matches!(
+ empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+
+ assert_matches!(
+ empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "usize::MAX should trigger an OOM!"
+ );
+ }
}
{
@@ -1656,13 +1706,19 @@ fn test_try_reserve_exact() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
-
- assert_matches!(
- ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
+ if guards_against_isize {
+ assert_matches!(
+ ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+ } else {
+ assert_matches!(
+ ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+ }
assert_matches!(
ten_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
Err(CapacityOverflow),
@@ -1683,13 +1739,19 @@ fn test_try_reserve_exact() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
-
- assert_matches!(
- ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
+ if guards_against_isize {
+ assert_matches!(
+ ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+ } else {
+ assert_matches!(
+ ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+ }
assert_matches!(
ten_u32s.try_reserve_exact(MAX_USIZE - 20).map_err(|e| e.kind()),
Err(CapacityOverflow),
diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs
index 019d73c0b16..89cc7f905be 100644
--- a/library/alloc/tests/vec_deque.rs
+++ b/library/alloc/tests/vec_deque.rs
@@ -2,6 +2,7 @@ use std::assert_matches::assert_matches;
use std::collections::TryReserveErrorKind::*;
use std::collections::{vec_deque::Drain, VecDeque};
use std::fmt::Debug;
+use std::mem::size_of;
use std::ops::Bound::*;
use std::panic::{catch_unwind, AssertUnwindSafe};
@@ -1160,6 +1161,12 @@ fn test_try_reserve() {
const MAX_CAP: usize = (isize::MAX as usize + 1) / 2 - 1;
const MAX_USIZE: usize = usize::MAX;
+ // On 16/32-bit, we check that allocations don't exceed isize::MAX,
+ // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
+ // Any platform that succeeds for these requests is technically broken with
+ // ptr::offset because LLVM is the worst.
+ let guards_against_isize = size_of::<usize>() < 8;
+
{
// Note: basic stuff is checked by test_reserve
let mut empty_bytes: VecDeque<u8> = VecDeque::new();
@@ -1173,19 +1180,31 @@ fn test_try_reserve() {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- // Check isize::MAX + 1 does count as overflow
- assert_matches!(
- empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
- // Check usize::MAX does count as overflow
- assert_matches!(
- empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "usize::MAX should trigger an overflow!"
- );
+ if guards_against_isize {
+ // Check isize::MAX + 1 does count as overflow
+ assert_matches!(
+ empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
+ // Check usize::MAX does count as overflow
+ assert_matches!(
+ empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "usize::MAX should trigger an overflow!"
+ );
+ } else {
+ // Check isize::MAX is an OOM
+ // VecDeque starts with capacity 7, always adds 1 to the capacity
+ // and also rounds the number to next power of 2 so this is the
+ // furthest we can go without triggering CapacityOverflow
+ assert_matches!(
+ empty_bytes.try_reserve(MAX_CAP).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+ }
}
{
@@ -1198,13 +1217,19 @@ fn test_try_reserve() {
if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
panic!("isize::MAX shouldn't trigger an overflow!");
}
-
- assert_matches!(
- ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
+ if guards_against_isize {
+ assert_matches!(
+ ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+ } else {
+ assert_matches!(
+ ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+ }
// Should always overflow in the add-to-len
assert_matches!(
ten_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
@@ -1225,13 +1250,19 @@ fn test_try_reserve() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
-
- assert_matches!(
- ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
+ if guards_against_isize {
+ assert_matches!(
+ ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+ } else {
+ assert_matches!(
+ ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+ }
// Should fail in the mul-by-size
assert_matches!(
ten_u32s.try_reserve(MAX_USIZE - 20).map_err(|e| e.kind()),
@@ -1251,6 +1282,8 @@ fn test_try_reserve_exact() {
const MAX_CAP: usize = (isize::MAX as usize + 1) / 2 - 1;
const MAX_USIZE: usize = usize::MAX;
+ let guards_against_isize = size_of::<usize>() < 8;
+
{
let mut empty_bytes: VecDeque<u8> = VecDeque::new();
@@ -1263,17 +1296,29 @@ fn test_try_reserve_exact() {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- assert_matches!(
- empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
- assert_matches!(
- empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "usize::MAX should trigger an overflow!"
- );
+ if guards_against_isize {
+ assert_matches!(
+ empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
+ assert_matches!(
+ empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "usize::MAX should trigger an overflow!"
+ );
+ } else {
+ // Check isize::MAX is an OOM
+ // VecDeque starts with capacity 7, always adds 1 to the capacity
+ // and also rounds the number to next power of 2 so this is the
+ // furthest we can go without triggering CapacityOverflow
+ assert_matches!(
+ empty_bytes.try_reserve_exact(MAX_CAP).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+ }
}
{
@@ -1289,13 +1334,19 @@ fn test_try_reserve_exact() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
-
- assert_matches!(
- ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
+ if guards_against_isize {
+ assert_matches!(
+ ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+ } else {
+ assert_matches!(
+ ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+ }
assert_matches!(
ten_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
Err(CapacityOverflow),
@@ -1316,13 +1367,19 @@ fn test_try_reserve_exact() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
-
- assert_matches!(
- ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
+ if guards_against_isize {
+ assert_matches!(
+ ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+ } else {
+ assert_matches!(
+ ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+ Err(AllocError { .. }),
+ "isize::MAX + 1 should trigger an OOM!"
+ );
+ }
assert_matches!(
ten_u32s.try_reserve_exact(MAX_USIZE - 20).map_err(|e| e.kind()),
Err(CapacityOverflow),
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index 59ebe5fbe02..2f378836cbb 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -1,9 +1,3 @@
-// Seemingly inconsequential code changes to this file can lead to measurable
-// performance impact on compilation times, due at least in part to the fact
-// that the layout code gets called from many instantiations of the various
-// collections, resulting in having to optimize down excess IR multiple times.
-// Your performance intuition is useless. Run perf.
-
use crate::cmp;
use crate::fmt;
use crate::mem::{self, ValidAlign};
@@ -58,8 +52,8 @@ impl Layout {
/// * `align` must be a power of two,
///
/// * `size`, when rounded up to the nearest multiple of `align`,
- /// must not overflow isize (i.e., the rounded value must be
- /// less than or equal to `isize::MAX`).
+ /// must not overflow (i.e., the rounded value must be less than
+ /// or equal to `usize::MAX`).
#[stable(feature = "alloc_layout", since = "1.28.0")]
#[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")]
#[inline]
@@ -68,13 +62,6 @@ impl Layout {
return Err(LayoutError);
}
- // SAFETY: just checked that align is a power of two.
- Layout::from_size_valid_align(size, unsafe { ValidAlign::new_unchecked(align) })
- }
-
- /// Internal helper constructor to skip revalidating alignment validity.
- #[inline]
- const fn from_size_valid_align(size: usize, align: ValidAlign) -> Result<Self, LayoutError> {
// (power-of-two implies align != 0.)
// Rounded up size is:
@@ -89,12 +76,13 @@ impl Layout {
//
// Above implies that checking for summation overflow is both
// necessary and sufficient.
- if size > isize::MAX as usize - (align.as_nonzero().get() - 1) {
+ if size > usize::MAX - (align - 1) {
return Err(LayoutError);
}
- // SAFETY: Layout::size invariants checked above.
- Ok(Layout { size, align })
+ // SAFETY: the conditions for `from_size_align_unchecked` have been
+ // checked above.
+ unsafe { Ok(Layout::from_size_align_unchecked(size, align)) }
}
/// Creates a layout, bypassing all checks.
@@ -108,8 +96,8 @@ impl Layout {
#[must_use]
#[inline]
pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
- // SAFETY: the caller is required to uphold the preconditions.
- unsafe { Layout { size, align: ValidAlign::new_unchecked(align) } }
+ // SAFETY: the caller must ensure that `align` is a power of two.
+ Layout { size, align: unsafe { ValidAlign::new_unchecked(align) } }
}
/// The minimum size in bytes for a memory block of this layout.
@@ -138,9 +126,10 @@ impl Layout {
#[inline]
pub const fn new<T>() -> Self {
let (size, align) = size_align::<T>();
- // SAFETY: if the type is instantiated, rustc already ensures that its
- // layout is valid. Use the unchecked constructor to avoid inserting a
- // panicking codepath that needs to be optimized out.
+ // SAFETY: the align is guaranteed by Rust to be a power of two and
+ // the size+align combo is guaranteed to fit in our address space. As a
+ // result use the unchecked constructor here to avoid inserting code
+ // that panics if it isn't optimized well enough.
unsafe { Layout::from_size_align_unchecked(size, align) }
}
@@ -152,6 +141,7 @@ impl Layout {
#[inline]
pub fn for_value<T: ?Sized>(t: &T) -> Self {
let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
+ debug_assert!(Layout::from_size_align(size, align).is_ok());
// SAFETY: see rationale in `new` for why this is using the unsafe variant
unsafe { Layout::from_size_align_unchecked(size, align) }
}
@@ -186,6 +176,7 @@ impl Layout {
pub unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
// SAFETY: we pass along the prerequisites of these functions to the caller
let (size, align) = unsafe { (mem::size_of_val_raw(t), mem::align_of_val_raw(t)) };
+ debug_assert!(Layout::from_size_align(size, align).is_ok());
// SAFETY: see rationale in `new` for why this is using the unsafe variant
unsafe { Layout::from_size_align_unchecked(size, align) }
}
@@ -285,11 +276,12 @@ impl Layout {
let pad = self.padding_needed_for(self.align());
// This cannot overflow. Quoting from the invariant of Layout:
// > `size`, when rounded up to the nearest multiple of `align`,
- // > must not overflow isize (i.e., the rounded value must be
- // > less than or equal to `isize::MAX`)
+ // > must not overflow (i.e., the rounded value must be less than
+ // > `usize::MAX`)
let new_size = self.size() + pad;
- // SAFETY: padded size is guaranteed to not exceed `isize::MAX`.
+ // SAFETY: self.align is already known to be valid and new_size has been
+ // padded already.
unsafe { Layout::from_size_align_unchecked(new_size, self.align()) }
}
@@ -306,13 +298,14 @@ impl Layout {
pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> {
// This cannot overflow. Quoting from the invariant of Layout:
// > `size`, when rounded up to the nearest multiple of `align`,
- // > must not overflow isize (i.e., the rounded value must be
- // > less than or equal to `isize::MAX`)
+ // > must not overflow (i.e., the rounded value must be less than
+ // > `usize::MAX`)
let padded_size = self.size() + self.padding_needed_for(self.align());
let alloc_size = padded_size.checked_mul(n).ok_or(LayoutError)?;
- // The safe constructor is called here to enforce the isize size limit.
- Layout::from_size_valid_align(alloc_size, self.align).map(|layout| (layout, padded_size))
+ // SAFETY: self.align is already known to be valid and alloc_size has been
+ // padded already.
+ unsafe { Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size)) }
}
/// Creates a layout describing the record for `self` followed by
@@ -363,14 +356,13 @@ impl Layout {
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
#[inline]
pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> {
- let new_align = cmp::max(self.align, next.align);
+ let new_align = cmp::max(self.align(), next.align());
let pad = self.padding_needed_for(next.align());
let offset = self.size().checked_add(pad).ok_or(LayoutError)?;
let new_size = offset.checked_add(next.size()).ok_or(LayoutError)?;
- // The safe constructor is called here to enforce the isize size limit.
- let layout = Layout::from_size_valid_align(new_size, new_align)?;
+ let layout = Layout::from_size_align(new_size, new_align)?;
Ok((layout, offset))
}
@@ -390,8 +382,7 @@ impl Layout {
#[inline]
pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
let size = self.size().checked_mul(n).ok_or(LayoutError)?;
- // The safe constructor is called here to enforce the isize size limit.
- Layout::from_size_valid_align(size, self.align)
+ Layout::from_size_align(size, self.align())
}
/// Creates a layout describing the record for `self` followed by
@@ -404,8 +395,7 @@ impl Layout {
#[inline]
pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> {
let new_size = self.size().checked_add(next.size()).ok_or(LayoutError)?;
- // The safe constructor is called here to enforce the isize size limit.
- Layout::from_size_valid_align(new_size, self.align)
+ Layout::from_size_align(new_size, self.align())
}
/// Creates a layout describing the record for a `[T; n]`.
@@ -415,8 +405,16 @@ impl Layout {
#[inline]
pub fn array<T>(n: usize) -> Result<Self, LayoutError> {
let array_size = mem::size_of::<T>().checked_mul(n).ok_or(LayoutError)?;
- // The safe constructor is called here to enforce the isize size limit.
- Layout::from_size_valid_align(array_size, ValidAlign::of::<T>())
+
+ // SAFETY:
+ // - Size: `array_size` cannot be too big because `size_of::<T>()` must
+ // be a multiple of `align_of::<T>()`. Therefore, `array_size`
+ // rounded up to the nearest multiple of `align_of::<T>()` is just
+ // `array_size`. And `array_size` cannot be too big because it was
+ // just checked by the `checked_mul()`.
+ // - Alignment: `align_of::<T>()` will always give an acceptable
+ // (non-zero, power of two) alignment.
+ Ok(unsafe { Layout::from_size_align_unchecked(array_size, mem::align_of::<T>()) })
}
}
diff --git a/library/core/src/mem/valid_align.rs b/library/core/src/mem/valid_align.rs
index 4ce6d13cf90..fcfa95120df 100644
--- a/library/core/src/mem/valid_align.rs
+++ b/library/core/src/mem/valid_align.rs
@@ -1,5 +1,4 @@
use crate::convert::TryFrom;
-use crate::intrinsics::assert_unsafe_precondition;
use crate::num::NonZeroUsize;
use crate::{cmp, fmt, hash, mem, num};
@@ -27,8 +26,7 @@ impl ValidAlign {
/// It must *not* be zero.
#[inline]
pub(crate) const unsafe fn new_unchecked(align: usize) -> Self {
- // SAFETY: Precondition passed to the caller.
- unsafe { assert_unsafe_precondition!(align.is_power_of_two()) };
+ debug_assert!(align.is_power_of_two());
// SAFETY: By precondition, this must be a power of two, and
// our variants encompass all possible powers of two.
@@ -48,13 +46,6 @@ impl ValidAlign {
pub(crate) fn log2(self) -> u32 {
self.as_nonzero().trailing_zeros()
}
-
- /// Returns the alignment for a type.
- #[inline]
- pub(crate) fn of<T>() -> Self {
- // SAFETY: rustc ensures that type alignment is always a power of two.
- unsafe { ValidAlign::new_unchecked(mem::align_of::<T>()) }
- }
}
impl fmt::Debug for ValidAlign {
diff --git a/library/std/src/sys/windows/path.rs b/library/std/src/sys/windows/path.rs
index a0f82207099..beeca1917a9 100644
--- a/library/std/src/sys/windows/path.rs
+++ b/library/std/src/sys/windows/path.rs
@@ -198,14 +198,7 @@ fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
match path.bytes().iter().position(|&x| separator(x)) {
Some(separator_start) => {
- let mut separator_end = separator_start + 1;
-
- // a series of multiple separator characters is treated as a single separator,
- // except in verbatim paths
- while !verbatim && separator_end < path.len() && separator(path.bytes()[separator_end])
- {
- separator_end += 1;
- }
+ let separator_end = separator_start + 1;
let component = &path.bytes()[..separator_start];
diff --git a/library/std/src/sys/windows/path/tests.rs b/library/std/src/sys/windows/path/tests.rs
index 2f7ec433bf2..6eab38cabfd 100644
--- a/library/std/src/sys/windows/path/tests.rs
+++ b/library/std/src/sys/windows/path/tests.rs
@@ -31,16 +31,6 @@ fn test_parse_next_component() {
parse_next_component(OsStr::new(r"servershare"), false),
(OsStr::new(r"servershare"), OsStr::new(""))
);
-
- assert_eq!(
- parse_next_component(OsStr::new(r"server/\//\/\\\\/////\/share"), false),
- (OsStr::new(r"server"), OsStr::new(r"share"))
- );
-
- assert_eq!(
- parse_next_component(OsStr::new(r"server\\\\\\\\\\\\\\share"), true),
- (OsStr::new(r"server"), OsStr::new(r"\\\\\\\\\\\\\share"))
- );
}
#[test]
@@ -126,3 +116,22 @@ fn test_windows_prefix_components() {
assert_eq!(drive.as_os_str(), OsStr::new("C:"));
assert_eq!(components.as_path(), Path::new(""));
}
+
+/// See #101358.
+///
+/// Note that the exact behaviour here may change in the future.
+/// In which case this test will need to adjusted.
+#[test]
+fn broken_unc_path() {
+ use crate::path::Component;
+
+ let mut components = Path::new(r"\\foo\\bar\\").components();
+ assert_eq!(components.next(), Some(Component::RootDir));
+ assert_eq!(components.next(), Some(Component::Normal("foo".as_ref())));
+ assert_eq!(components.next(), Some(Component::Normal("bar".as_ref())));
+
+ let mut components = Path::new("//foo//bar//").components();
+ assert_eq!(components.next(), Some(Component::RootDir));
+ assert_eq!(components.next(), Some(Component::Normal("foo".as_ref())));
+ assert_eq!(components.next(), Some(Component::Normal("bar".as_ref())));
+}
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 9301c5a2ff3..03eec02a8bf 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -793,6 +793,8 @@ class RustBuild(object):
def check_vendored_status(self):
"""Check that vendoring is configured properly"""
+ # keep this consistent with the equivalent check in rustbuild:
+ # https://github.com/rust-lang/rust/blob/a8a33cf27166d3eabaffc58ed3799e054af3b0c6/src/bootstrap/lib.rs#L399-L405
if 'SUDO_USER' in os.environ and not self.use_vendored_sources:
if os.getuid() == 0:
self.use_vendored_sources = True
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index f84de73297a..d265277b406 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -396,13 +396,18 @@ impl Build {
let src = config.src.clone();
let out = config.out.clone();
+ #[cfg(unix)]
+ // keep this consistent with the equivalent check in x.py:
+ // https://github.com/rust-lang/rust/blob/a8a33cf27166d3eabaffc58ed3799e054af3b0c6/src/bootstrap/bootstrap.py#L796-L797
let is_sudo = match env::var_os("SUDO_USER") {
- Some(sudo_user) => match env::var_os("USER") {
- Some(user) => user != sudo_user,
- None => false,
- },
+ Some(_sudo_user) => {
+ let uid = unsafe { libc::getuid() };
+ uid == 0
+ }
None => false,
};
+ #[cfg(not(unix))]
+ let is_sudo = false;
let ignore_git = config.ignore_git;
let rust_info = channel::GitInfo::new(ignore_git, &src);
diff --git a/src/ci/channel b/src/ci/channel
index 65b2df87f7d..2bf5ad0447d 100644
--- a/src/ci/channel
+++ b/src/ci/channel
@@ -1 +1 @@
-beta
+stable
diff --git a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2015.stderr b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2015.stderr
new file mode 100644
index 00000000000..fd2e454e7e4
--- /dev/null
+++ b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2015.stderr
@@ -0,0 +1,9 @@
+error[E0277]: the trait bound `(): AsRef<(dyn for<'r> Fn(&'r ()) + 'static)>` is not satisfied
+ --> $DIR/generic-with-implicit-hrtb-without-dyn.rs:6:13
+ |
+LL | fn ice() -> impl AsRef<Fn(&())> {
+ | ^^^^^^^^^^^^^^^^^^^ the trait `AsRef<(dyn for<'r> Fn(&'r ()) + 'static)>` is not implemented for `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr
new file mode 100644
index 00000000000..c01c33a8931
--- /dev/null
+++ b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr
@@ -0,0 +1,22 @@
+error[E0782]: trait objects must include the `dyn` keyword
+ --> $DIR/generic-with-implicit-hrtb-without-dyn.rs:6:24
+ |
+LL | fn ice() -> impl AsRef<Fn(&())> {
+ | ^^^^^^^
+ |
+help: add `dyn` keyword before this trait
+ |
+LL - fn ice() -> impl AsRef<Fn(&())> {
+LL + fn ice() -> impl AsRef<dyn Fn(&())> {
+ |
+
+error[E0277]: the trait bound `(): AsRef<(dyn for<'r> Fn(&'r ()) + 'static)>` is not satisfied
+ --> $DIR/generic-with-implicit-hrtb-without-dyn.rs:6:13
+ |
+LL | fn ice() -> impl AsRef<Fn(&())> {
+ | ^^^^^^^^^^^^^^^^^^^ the trait `AsRef<(dyn for<'r> Fn(&'r ()) + 'static)>` is not implemented for `()`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0782.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs
new file mode 100644
index 00000000000..856dc7a3f5a
--- /dev/null
+++ b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs
@@ -0,0 +1,12 @@
+// revisions: edition2015 edition2021
+//[edition2021]edition:2021
+
+#![allow(warnings)]
+
+fn ice() -> impl AsRef<Fn(&())> {
+ //~^ ERROR: the trait bound `(): AsRef<(dyn for<'r> Fn(&'r ()) + 'static)>` is not satisfied [E0277]
+ //[edition2021]~| ERROR: trait objects must include the `dyn` keyword [E0782]
+ todo!()
+}
+
+fn main() {}
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 4bcb3c65e440a12044092b85ffea8fac6cb96f4
+Subproject 387270bc7f446d17869c7f208207c73231d6a25