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 12 pull requests #78831

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9412a89
Stabilize `Poll::is_ready` and `is_pending` as const
CDirkx Sep 2, 2020
ce1d5ed
Move const tests for `Poll` to `library\core`
CDirkx Sep 3, 2020
91a9f83
Define `fs::hard_link` to not follow symlinks.
sunfishcode Oct 16, 2020
5e80c65
Bump version to 1.49.0
CDirkx Oct 16, 2020
23a5c21
Fix a typo in a comment.
sunfishcode Oct 19, 2020
ce00b3e
Use `link` on platforms which lack `linkat`.
sunfishcode Oct 19, 2020
628fb9f
make concurrency helper more pleasant to read
tshepang Oct 21, 2020
d0178b4
Make it platform-specific whether `hard_link` follows symlinks.
sunfishcode Oct 20, 2020
6249cda
Disable use of `linkat` on Android as well.
sunfishcode Oct 23, 2020
e099138
BTreeMap: stop mistaking node for an orderly place
ssomers Oct 26, 2020
b0df3f7
fix some incorrect aliasing in the BTree
RalfJung Oct 28, 2020
59c6ae6
Use SOCK_CLOEXEC and accept4() on more platforms.
de-vri-es Oct 30, 2020
39103ce
Fix run-make tests running when LLVM is disabled
bjorn3 Nov 3, 2020
5fc22f1
Add a tool to run `x.py` from any subdirectory
casey Nov 2, 2020
9a12d72
Constantify `UnsafeCell::into_inner` and related
a1phyr Nov 4, 2020
795bbfe
Add tracking issue
a1phyr Nov 4, 2020
eed0ceb
Recognize `private_intra_doc_links` as a lint
jyn514 Oct 19, 2020
47b21b8
Add PRIVATE_INTRA_DOC_LINKS to rustdoc special-casing
jyn514 Nov 5, 2020
3bee37c
Disable accept4 on Android.
de-vri-es Oct 31, 2020
e8b5be5
Stabilize hint::spin_loop
pickfire Aug 30, 2020
ae059b5
Make some std::io functions `const`
a1phyr Nov 6, 2020
001dd7e
Add tracking issue
a1phyr Nov 6, 2020
8a27822
Rollup merge of #76097 - pickfire:stabilize-spin-loop, r=KodrAus
m-ou-se Nov 7, 2020
e8c698b
Rollup merge of #76227 - CDirkx:const-poll, r=KodrAus
m-ou-se Nov 7, 2020
5e42ef6
Rollup merge of #78026 - sunfishcode:symlink-hard-link, r=dtolnay
m-ou-se Nov 7, 2020
95a4908
Rollup merge of #78065 - tshepang:nits, r=dtolnay
m-ou-se Nov 7, 2020
e35a8b9
Rollup merge of #78114 - jyn514:private, r=oli-obk
m-ou-se Nov 7, 2020
7c1ec23
Rollup merge of #78437 - ssomers:btree_no_ord_at_node_level, r=Mark-S…
m-ou-se Nov 7, 2020
784040a
Rollup merge of #78476 - RalfJung:btree-alias, r=Mark-Simulacrum
m-ou-se Nov 7, 2020
5e64cd9
Rollup merge of #78572 - de-vri-es:bsd-cloexec, r=m-ou-se
m-ou-se Nov 7, 2020
3ead902
Rollup merge of #78658 - casey:x, r=Mark-Simulacrum
m-ou-se Nov 7, 2020
f03c56a
Rollup merge of #78706 - bjorn3:fix_run_make_without_llvm, r=Mark-Sim…
m-ou-se Nov 7, 2020
31c3252
Rollup merge of #78728 - a1phyr:const_cell_into_inner, r=dtolnay
m-ou-se Nov 7, 2020
e78fd66
Rollup merge of #78811 - a1phyr:const_io_structs, r=dtolnay
m-ou-se Nov 7, 2020
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ __pycache__/
/inst/
/llvm/
/mingw-build/
/src/tools/x/target
# Created by default with `src/ci/docker/run.sh`:
/obj/
/unicode-downloads
Expand Down
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,17 @@ members = [
"src/tools/unicode-table-generator",
"src/tools/expand-yaml-anchors",
]

exclude = [
"build",
"compiler/rustc_codegen_cranelift",
# HACK(eddyb) This hardcodes the fact that our CI uses `/checkout/obj`.
"obj",
# The `x` binary is a thin wrapper that calls `x.py`, which initializes
# submodules, before which workspace members cannot be invoked because
# not all `Cargo.toml` files are available, so we exclude the `x` binary,
# so it can be invoked before the current checkout is set up.
"src/tools/x",
]

[profile.release.package.compiler_builtins]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2801,6 +2801,7 @@ declare_lint_pass! {
UNSTABLE_NAME_COLLISIONS,
IRREFUTABLE_LET_PATTERNS,
BROKEN_INTRA_DOC_LINKS,
PRIVATE_INTRA_DOC_LINKS,
INVALID_CODEBLOCK_ATTRIBUTES,
MISSING_CRATE_LEVEL_DOCS,
MISSING_DOC_CODE_EXAMPLES,
Expand Down
26 changes: 22 additions & 4 deletions library/alloc/src/collections/btree/map/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fn test_all_refs<'a, T: 'a>(dummy: &mut T, iter: impl Iterator<Item = &'a mut T>
}
}

impl<'a, K: 'a, V: 'a> BTreeMap<K, V> {
impl<K, V> BTreeMap<K, V> {
/// Panics if the map (or the code navigating it) is corrupted.
fn check(&self)
where
Expand All @@ -54,14 +54,14 @@ impl<'a, K: 'a, V: 'a> BTreeMap<K, V> {
assert!(root_node.ascend().is_err());
root_node.assert_back_pointers();

let counted = root_node.assert_ascending();
assert_eq!(self.length, counted);
assert_eq!(self.length, root_node.calc_length());

root_node.assert_min_len(if root_node.height() > 0 { 1 } else { 0 });
} else {
assert_eq!(self.length, 0);
}

self.assert_ascending();
}

/// Returns the height of the root, if any.
Expand All @@ -79,10 +79,28 @@ impl<'a, K: 'a, V: 'a> BTreeMap<K, V> {
String::from("not yet allocated")
}
}

/// Asserts that the keys are in strictly ascending order.
fn assert_ascending(&self)
where
K: Copy + Debug + Ord,
{
let mut num_seen = 0;
let mut keys = self.keys();
if let Some(mut previous) = keys.next() {
num_seen = 1;
for next in keys {
assert!(previous < next, "{:?} >= {:?}", previous, next);
previous = next;
num_seen += 1;
}
}
assert_eq!(num_seen, self.len());
}
}

impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal> {
pub fn assert_min_len(self, min_len: usize) {
fn assert_min_len(self, min_len: usize) {
assert!(self.len() >= min_len, "{} < {}", self.len(), min_len);
if let node::ForceResult::Internal(node) = self.force() {
for idx in 0..=node.len() {
Expand Down
12 changes: 8 additions & 4 deletions library/alloc/src/collections/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1608,15 +1608,19 @@ pub mod marker {

unsafe fn slice_insert<T>(slice: &mut [T], idx: usize, val: T) {
unsafe {
ptr::copy(slice.as_ptr().add(idx), slice.as_mut_ptr().add(idx + 1), slice.len() - idx);
ptr::write(slice.get_unchecked_mut(idx), val);
let len = slice.len();
let slice_ptr = slice.as_mut_ptr();
ptr::copy(slice_ptr.add(idx), slice_ptr.add(idx + 1), len - idx);
ptr::write(slice_ptr.add(idx), val);
}
}

unsafe fn slice_remove<T>(slice: &mut [T], idx: usize) -> T {
unsafe {
let ret = ptr::read(slice.get_unchecked(idx));
ptr::copy(slice.as_ptr().add(idx + 1), slice.as_mut_ptr().add(idx), slice.len() - idx - 1);
let len = slice.len();
let slice_ptr = slice.as_mut_ptr();
let ret = ptr::read(slice_ptr.add(idx));
ptr::copy(slice_ptr.add(idx + 1), slice_ptr.add(idx), len - idx - 1);
ret
}
}
Expand Down
37 changes: 0 additions & 37 deletions library/alloc/src/collections/btree/node/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,43 +17,6 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>
}
}

/// Asserts that the keys are in strictly ascending order.
/// Returns how many keys it encountered.
pub fn assert_ascending(self) -> usize
where
K: Copy + Debug + Ord,
{
struct SeriesChecker<T> {
num_seen: usize,
previous: Option<T>,
}
impl<T: Copy + Debug + Ord> SeriesChecker<T> {
fn is_ascending(&mut self, next: T) {
if let Some(previous) = self.previous {
assert!(previous < next, "{:?} >= {:?}", previous, next);
}
self.previous = Some(next);
self.num_seen += 1;
}
}

let mut checker = SeriesChecker { num_seen: 0, previous: None };
self.visit_nodes_in_order(|pos| match pos {
navigate::Position::Leaf(node) => {
for idx in 0..node.len() {
let key = *unsafe { node.key_at(idx) };
checker.is_ascending(key);
}
}
navigate::Position::InternalKV(kv) => {
let key = *kv.into_kv().0;
checker.is_ascending(key);
}
navigate::Position::Internal(_) => {}
});
checker.num_seen
}

pub fn dump_keys(self) -> String
where
K: Debug,
Expand Down
1 change: 0 additions & 1 deletion library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@
#![feature(raw_ref_op)]
#![feature(rustc_attrs)]
#![feature(receiver_trait)]
#![feature(renamed_spin_loop)]
#![feature(min_specialization)]
#![feature(slice_ptr_get)]
#![feature(slice_ptr_len)]
Expand Down
11 changes: 6 additions & 5 deletions library/core/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,8 @@ impl<T> Cell<T> {
/// assert_eq!(five, 5);
/// ```
#[stable(feature = "move_cell", since = "1.17.0")]
pub fn into_inner(self) -> T {
#[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
pub const fn into_inner(self) -> T {
self.value.into_inner()
}
}
Expand Down Expand Up @@ -668,12 +669,11 @@ impl<T> RefCell<T> {
/// let five = c.into_inner();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
#[inline]
pub fn into_inner(self) -> T {
pub const fn into_inner(self) -> T {
// Since this function takes `self` (the `RefCell`) by value, the
// compiler statically verifies that it is not currently borrowed.
// Therefore the following assertion is just a `debug_assert!`.
debug_assert!(self.borrow.get() == UNUSED);
self.value.into_inner()
}

Expand Down Expand Up @@ -1682,7 +1682,8 @@ impl<T> UnsafeCell<T> {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_inner(self) -> T {
#[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
pub const fn into_inner(self) -> T {
self.value
}
}
Expand Down
62 changes: 53 additions & 9 deletions library/core/src/hint.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![stable(feature = "core_hint", since = "1.27.0")]

//! Hints to compiler that affects how code should be emitted or optimized.
//! Hints may be compile time or runtime.

use crate::intrinsics;

Expand All @@ -24,7 +25,6 @@ use crate::intrinsics;
/// Otherwise, consider using the [`unreachable!`] macro, which does not allow
/// optimizations but will panic when executed.
///
///
/// # Example
///
/// ```
Expand All @@ -51,18 +51,62 @@ pub const unsafe fn unreachable_unchecked() -> ! {
unsafe { intrinsics::unreachable() }
}

/// Emits a machine instruction hinting to the processor that it is running in busy-wait
/// spin-loop ("spin lock").
/// Emits a machine instruction to signal the processor that it is running in
/// a busy-wait spin-loop ("spin lock").
///
/// Upon receiving the spin-loop signal the processor can optimize its behavior by,
/// for example, saving power or switching hyper-threads.
///
/// This function is different from [`thread::yield_now`] which directly
/// yields to the system's scheduler, whereas `spin_loop` does not interact
/// with the operating system.
///
/// A common use case for `spin_loop` is implementing bounded optimistic
/// spinning in a CAS loop in synchronization primitives. To avoid problems
/// like priority inversion, it is strongly recommended that the spin loop is
/// terminated after a finite amount of iterations and an appropriate blocking
/// syscall is made.
///
/// **Note**: On platforms that do not support receiving spin-loop hints this
/// function does not do anything at all.
///
/// # Examples
///
/// For a discussion of different locking strategies and their trade-offs, see
/// [`core::sync::atomic::spin_loop_hint`].
/// ```
/// use std::sync::atomic::{AtomicBool, Ordering};
/// use std::sync::Arc;
/// use std::{hint, thread};
///
/// // A shared atomic value that threads will use to coordinate
/// let live = Arc::new(AtomicBool::new(false));
///
/// // In a background thread we'll eventually set the value
/// let bg_work = {
/// let live = live.clone();
/// thread::spawn(move || {
/// // Do some work, then make the value live
/// do_some_work();
/// live.store(true, Ordering::Release);
/// })
/// };
///
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
/// do anything at all.
/// // Back on our current thread, we wait for the value to be set
/// while live.load(Ordering::Acquire) {
/// // The spin loop is a hint to the CPU that we're waiting, but probably
/// // not for very long
/// hint::spin_loop();
/// }
///
/// // The value is now set
/// # fn do_some_work() {}
/// do_some_work();
/// bg_work.join()?;
/// # Ok::<(), Box<dyn core::any::Any + Send + 'static>>(())
/// ```
///
/// [`core::sync::atomic::spin_loop_hint`]: crate::sync::atomic::spin_loop_hint
/// [`thread::yield_now`]: ../../std/thread/fn.yield_now.html
#[inline]
#[unstable(feature = "renamed_spin_loop", issue = "55002")]
#[stable(feature = "renamed_spin_loop", since = "1.49.0")]
pub fn spin_loop() {
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2"))]
{
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
#![feature(cfg_target_has_atomic)]
#![feature(const_alloc_layout)]
#![feature(const_discriminant)]
#![feature(const_cell_into_inner)]
#![feature(const_checked_int_methods)]
#![feature(const_euclidean_int_methods)]
#![feature(const_float_classify)]
Expand Down
25 changes: 9 additions & 16 deletions library/core/src/sync/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,23 +115,13 @@ use crate::hint::spin_loop;

/// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
///
/// Upon receiving spin-loop signal the processor can optimize its behavior by, for example, saving
/// power or switching hyper-threads.
///
/// This function is different from [`std::thread::yield_now`] which directly yields to the
/// system's scheduler, whereas `spin_loop_hint` does not interact with the operating system.
///
/// A common use case for `spin_loop_hint` is implementing bounded optimistic spinning in a CAS
/// loop in synchronization primitives. To avoid problems like priority inversion, it is strongly
/// recommended that the spin loop is terminated after a finite amount of iterations and an
/// appropriate blocking syscall is made.
/// This function is expected to be deprecated in favor of
/// [`hint::spin_loop`].
///
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
/// do anything at all.
///
/// [`std::thread::yield_now`]: ../../../std/thread/fn.yield_now.html
/// [`std::thread::sleep`]: ../../../std/thread/fn.sleep.html
/// [`std::sync::Mutex`]: ../../../std/sync/struct.Mutex.html
/// [`hint::spin_loop`]: crate::hint::spin_loop
#[inline]
#[stable(feature = "spin_loop_hint", since = "1.24.0")]
pub fn spin_loop_hint() {
Expand Down Expand Up @@ -365,7 +355,8 @@ impl AtomicBool {
/// ```
#[inline]
#[stable(feature = "atomic_access", since = "1.15.0")]
pub fn into_inner(self) -> bool {
#[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
pub const fn into_inner(self) -> bool {
self.v.into_inner() != 0
}

Expand Down Expand Up @@ -941,7 +932,8 @@ impl<T> AtomicPtr<T> {
/// ```
#[inline]
#[stable(feature = "atomic_access", since = "1.15.0")]
pub fn into_inner(self) -> *mut T {
#[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
pub const fn into_inner(self) -> *mut T {
self.p.into_inner()
}

Expand Down Expand Up @@ -1462,7 +1454,8 @@ assert_eq!(some_var.into_inner(), 5);
```"),
#[inline]
#[$stable_access]
pub fn into_inner(self) -> $int_type {
#[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
pub const fn into_inner(self) -> $int_type {
self.v.into_inner()
}
}
Expand Down
6 changes: 4 additions & 2 deletions library/core/src/task/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,17 @@ impl<T> Poll<T> {

/// Returns `true` if this is `Poll::Ready`
#[inline]
#[rustc_const_stable(feature = "const_poll", since = "1.49.0")]
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn is_ready(&self) -> bool {
pub const fn is_ready(&self) -> bool {
matches!(*self, Poll::Ready(_))
}

/// Returns `true` if this is `Poll::Pending`
#[inline]
#[rustc_const_stable(feature = "const_poll", since = "1.49.0")]
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn is_pending(&self) -> bool {
pub const fn is_pending(&self) -> bool {
!self.is_ready()
}
}
Expand Down
12 changes: 12 additions & 0 deletions library/core/tests/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,3 +422,15 @@ fn refcell_format() {
let msg = format!("{name} {}", &*what.borrow(), name = &*name.borrow());
assert_eq!(msg, "rust rocks".to_string());
}

#[allow(dead_code)]
fn const_cells() {
const UNSAFE_CELL: UnsafeCell<i32> = UnsafeCell::new(3);
const _: i32 = UNSAFE_CELL.into_inner();

const REF_CELL: RefCell<i32> = RefCell::new(3);
const _: i32 = REF_CELL.into_inner();

const CELL: Cell<i32> = Cell::new(3);
const _: i32 = CELL.into_inner();
}
Loading