Skip to content

Commit

Permalink
Auto merge of #103105 - JohnTitor:rollup-x4ivrix, r=JohnTitor
Browse files Browse the repository at this point in the history
Rollup of 6 pull requests

Successful merges:

 - #101717 (Add documentation about the memory layout of `UnsafeCell<T>`)
 - #102023 (Add MaybeUninit array transpose From impls)
 - #103033 (Update pkg-config)
 - #103080 (pretty: fix to print some lifetimes on HIR pretty-print)
 - #103082 (Surround type with backticks)
 - #103088 (Fix settings page)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Oct 16, 2022
2 parents 75dbd5b + 66a2bba commit e928a46
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 7 deletions.
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

0 comments on commit e928a46

Please sign in to comment.