Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #103105

Merged
merged 16 commits into from
Oct 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2652,9 +2652,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"

[[package]]
name = "pkg-config"
version = "0.3.18"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33"
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"

[[package]]
name = "polonius-engine"
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
this.fail(
location,
format!(
"Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is {:?}",
"Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is `{:?}`",
parent, f, ty, f_ty
)
)
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1687,7 +1687,11 @@ impl<'a> State<'a> {

let mut nonelided_generic_args: bool = false;
let elide_lifetimes = generic_args.args.iter().all(|arg| match arg {
GenericArg::Lifetime(lt) => lt.is_elided(),
GenericArg::Lifetime(lt) if lt.is_elided() => true,
GenericArg::Lifetime(_) => {
nonelided_generic_args = true;
false
}
_ => {
nonelided_generic_args = true;
true
Expand Down
44 changes: 44 additions & 0 deletions library/core/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1816,6 +1816,50 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
///
/// [`.get_mut()`]: `UnsafeCell::get_mut`
///
/// `UnsafeCell<T>` has the same in-memory representation as its inner type `T`. A consequence
/// of this guarantee is that it is possible to convert between `T` and `UnsafeCell<T>`.
/// Special care has to be taken when converting a nested `T` inside of an `Outer<T>` type
/// to an `Outer<UnsafeCell<T>>` type: this is not sound when the `Outer<T>` type enables [niche]
/// optimizations. For example, the type `Option<NonNull<u8>>` is typically 8 bytes large on
/// 64-bit platforms, but the type `Option<UnsafeCell<NonNull<u8>>>` takes up 16 bytes of space.
/// Therefore this is not a valid conversion, despite `NonNull<u8>` and `UnsafeCell<NonNull<u8>>>`
/// having the same memory layout. This is because `UnsafeCell` disables niche optimizations in
/// order to avoid its interior mutability property from spreading from `T` into the `Outer` type,
/// thus this can cause distortions in the type size in these cases. Furthermore, it is only valid
/// to obtain a `*mut T` pointer to the contents of a _shared_ `UnsafeCell<T>` through [`.get()`]
/// or [`.raw_get()`]. A `&mut T` reference can be obtained by either dereferencing this pointer or
/// by calling [`.get_mut()`] on an _exclusive_ `UnsafeCell<T>`, e.g.:
///
/// ```rust
/// use std::cell::UnsafeCell;
///
/// let mut x: UnsafeCell<u32> = UnsafeCell::new(5);
/// let shared: &UnsafeCell<u32> = &x;
/// // using `.get()` is okay:
/// unsafe {
/// // SAFETY: there exist no other references to the contents of `x`
/// let exclusive: &mut u32 = &mut *shared.get();
/// };
/// // using `.raw_get()` is also okay:
/// unsafe {
/// // SAFETY: there exist no other references to the contents of `x` in this scope
/// let exclusive: &mut u32 = &mut *UnsafeCell::raw_get(shared as *const _);
/// };
/// // using `.get_mut()` is always safe:
/// let exclusive: &mut u32 = x.get_mut();
///
/// // when we have exclusive access, we can convert it to a shared `&UnsafeCell`:
/// unsafe {
/// // SAFETY: `u32` has no niche, therefore it has the same layout as `UnsafeCell<u32>`
/// let shared: &UnsafeCell<u32> = &*(exclusive as *mut _ as *const UnsafeCell<u32>);
/// // SAFETY: there exist no other *active* references to the contents of `x` in this scope
/// let exclusive: &mut u32 = &mut *shared.get();
/// }
/// ```
///
/// [niche]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#niche
/// [`.raw_get()`]: `UnsafeCell::raw_get`
///
/// # Examples
///
/// Here is an example showcasing how to soundly mutate the contents of an `UnsafeCell<_>` despite
Expand Down
37 changes: 37 additions & 0 deletions library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1284,3 +1284,40 @@ impl<T> MaybeUninit<T> {
}
}
}

impl<T, const N: usize> MaybeUninit<[T; N]> {
/// Transposes a `MaybeUninit<[T; N]>` into a `[MaybeUninit<T>; N]`.
///
/// # Examples
///
/// ```
/// #![feature(maybe_uninit_uninit_array_transpose)]
/// # use std::mem::MaybeUninit;
///
/// let data: [MaybeUninit<u8>; 1000] = MaybeUninit::uninit().transpose();
/// ```
#[unstable(feature = "maybe_uninit_uninit_array_transpose", issue = "96097")]
pub fn transpose(self) -> [MaybeUninit<T>; N] {
// SAFETY: T and MaybeUninit<T> have the same layout
unsafe { super::transmute_copy(&ManuallyDrop::new(self)) }
}
}

impl<T, const N: usize> [MaybeUninit<T>; N] {
/// Transposes a `[MaybeUninit<T>; N]` into a `MaybeUninit<[T; N]>`.
///
/// # Examples
///
/// ```
/// #![feature(maybe_uninit_uninit_array_transpose)]
/// # use std::mem::MaybeUninit;
///
/// let data = [MaybeUninit::<u8>::uninit(); 1000];
/// let data: MaybeUninit<[u8; 1000]> = data.transpose();
/// ```
#[unstable(feature = "maybe_uninit_uninit_array_transpose", issue = "96097")]
pub fn transpose(self) -> MaybeUninit<[T; N]> {
// SAFETY: T and MaybeUninit<T> have the same layout
unsafe { super::transmute_copy(&ManuallyDrop::new(self)) }
}
}
4 changes: 3 additions & 1 deletion src/librustdoc/html/static/js/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,9 @@
const innerHTML = `<div class="settings">${buildSettingsPageSections(settings)}</div>`;
const el = document.createElement(elementKind);
el.id = "settings";
el.className = "popover";
if (!isSettingsPage) {
el.className = "popover";
}
el.innerHTML = innerHTML;

if (isSettingsPage) {
Expand Down
20 changes: 20 additions & 0 deletions src/test/pretty/issue-85089.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#[prelude_import]
use ::std::prelude::rust_2015::*;
#[macro_use]
extern crate std;
// Test to print lifetimes on HIR pretty-printing.

// pretty-compare-only
// pretty-mode:hir
// pp-exact:issue-85089.pp

trait A<'x> { }
trait B<'x> { }

struct Foo<'b> {
bar: &'b dyn for<'a> A<'a>,
}

impl <'a> B<'a> for dyn for<'b> A<'b> { }

impl <'a> A<'a> for Foo<'a> { }
16 changes: 16 additions & 0 deletions src/test/pretty/issue-85089.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Test to print lifetimes on HIR pretty-printing.

// pretty-compare-only
// pretty-mode:hir
// pp-exact:issue-85089.pp

trait A<'x> {}
trait B<'x> {}

struct Foo<'b> {
pub bar: &'b dyn for<'a> A<'a>,
}

impl<'a> B<'a> for dyn for<'b> A<'b> {}

impl<'a> A<'a> for Foo<'a> {}
11 changes: 9 additions & 2 deletions src/test/rustdoc-gui/settings.goml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// This test ensures that the settings menu display is working as expected.
// This test ensures that the settings menu display is working as expected and that
// the settings page is also rendered as expected.
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
show-text: true // needed when we check for colors below.
// First, we check that the settings page doesn't exist.
Expand Down Expand Up @@ -140,7 +141,13 @@ assert-css: ("#settings-menu .popover", {"display": "none"})
// Now we go to the settings page to check that the CSS is loaded as expected.
goto: "file://" + |DOC_PATH| + "/settings.html"
wait-for: "#settings"
assert-css: (".setting-line .toggle .slider", {"width": "45px", "margin-right": "20px"})
assert-css: (
".setting-line .toggle .slider",
{"width": "45px", "margin-right": "20px", "border": "0px none rgb(0, 0, 0)"},
)

assert-attribute-false: ("#settings", {"class": "popover"}, CONTAINS)
compare-elements-position: (".sub-container", "#settings", ("x"))

// We now check the display with JS disabled.
assert-false: "noscript section"
Expand Down