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 14 pull requests #76373

Closed
wants to merge 51 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
1316c78
Workaround for copy_file_range spuriously returning EOPNOTSUPP when a…
the8472 Aug 11, 2020
f078363
more concise error matching
the8472 Aug 12, 2020
4ddedd5
perform copy_file_range until EOF is reached instead of basing things…
the8472 Aug 14, 2020
18ad5a5
Add a regression test for issue-72793
JohnTitor Aug 19, 2020
aa40c02
Unstable Book: add links to tracking issues for FFI features
ArekPiekarz Aug 26, 2020
f03d0b3
`impl Rc::new_cyclic`
mental32 Aug 27, 2020
42fb270
typo
mental32 Aug 29, 2020
bb5e79c
Link vec doc to & reference
pickfire Aug 29, 2020
1b19354
[WIP] Fix intra-doc links on pub re-exports
jyn514 Aug 29, 2020
20a6866
Try removing [prim@reference]
pickfire Aug 30, 2020
e885f00
Comment out test for generated docs until rustdoc changes its behavio…
jyn514 Aug 30, 2020
d715015
Improve tests
jyn514 Aug 30, 2020
81e85ce
Move to Arc::clone(&x) over x.clone() in library/std
poliorcetics Aug 30, 2020
6b75e3d
Move to Arc::clone(&x) over x.clone() in library/core
poliorcetics Aug 30, 2020
0f301e8
Removed [inline] and copied over comments from Arc::new_cyclic
mental32 Sep 1, 2020
af19262
Fold length constant in Rvalue::Repeat
tmiasko Sep 2, 2020
2276991
Avoid spurious print outs during dryrun
Mark-Simulacrum Sep 2, 2020
8783c62
Add missing link in README
camelid Sep 2, 2020
89ae59a
Remove needless .to_owned() for link
jyn514 Jul 6, 2020
d5495e2
Refactor `ItemLink` into its own struct
jyn514 Jul 6, 2020
31a7b6e
Refactor RenderedLink into its own type
jyn514 Jul 6, 2020
9815010
Remove disambiguators from link text
jyn514 Jul 6, 2020
9d7e797
display_for -> suggestion_for
jyn514 Aug 29, 2020
4df6490
Link & primitive using relative link
pickfire Sep 3, 2020
af13338
Check test/example/benchmark on x.py check
Mark-Simulacrum Sep 2, 2020
85146b9
Add slice primitive link to vec
pickfire Sep 4, 2020
5d41aff
rename MaybeUninit slice methods
RalfJung Sep 1, 2020
41a047d
document remaining unsafety in maybe_uninit.rs
RalfJung Sep 2, 2020
18c14fd
Misc cleanup
jyn514 Aug 29, 2020
cbc396f
inliner: Check for target features compatibility
tmiasko Sep 3, 2020
326b772
inliner: Check for no_sanitize attribute compatibility
tmiasko Sep 3, 2020
c23151b
inliner: Add mir-opt tests for codegen attributes compatibility
tmiasko Sep 4, 2020
b97d413
Refactor byteorder to std in rustc_middle
workingjubilee Aug 20, 2020
74b4eea
Remove reference to byteorder limits
workingjubilee Aug 20, 2020
fe2a867
Be explicit that we're handling bytes
workingjubilee Aug 20, 2020
dc00eff
Explain contract of {read, write}_target_uint
workingjubilee Aug 21, 2020
2df552b
Fix big endian read/write
workingjubilee Aug 22, 2020
5e60cf8
Rollup merge of #75428 - the8472:fix-copy-eopnotsupp, r=joshtriplett
Dylan-DPC Sep 5, 2020
4794acc
Rollup merge of #75695 - JohnTitor:regression-test, r=Dylan-DPC
Dylan-DPC Sep 5, 2020
b1b4512
Rollup merge of #75741 - workingjubilee:refactor-byteorder, r=matthew…
Dylan-DPC Sep 5, 2020
1a824d8
Rollup merge of #75954 - ArekPiekarz:unstable_book_ffi_tracking_issue…
Dylan-DPC Sep 5, 2020
3854bb4
Rollup merge of #75994 - mental32:impl-rc-new-cyclic, r=KodrAus
Dylan-DPC Sep 5, 2020
0fbd5ba
Rollup merge of #76060 - pickfire:patch-12, r=jyn514
Dylan-DPC Sep 5, 2020
baded64
Rollup merge of #76078 - jyn514:no-disambiguator, r=manishearth
Dylan-DPC Sep 5, 2020
956216e
Rollup merge of #76082 - jyn514:top-level-links, r=ollie27,GuillaumeG…
Dylan-DPC Sep 5, 2020
fab6c82
Rollup merge of #76128 - poliorcetics:doc-use-arc-clone, r=KodrAus
Dylan-DPC Sep 5, 2020
c9ecaff
Rollup merge of #76217 - RalfJung:maybe-uninit-slice, r=KodrAus
Dylan-DPC Sep 5, 2020
727c83d
Rollup merge of #76229 - camelid:patch-3, r=jonas-schievink
Dylan-DPC Sep 5, 2020
3a67a1e
Rollup merge of #76254 - tmiasko:fold-len, r=wesleywiser
Dylan-DPC Sep 5, 2020
3ff23d7
Rollup merge of #76258 - Mark-Simulacrum:check-tests, r=ehuss
Dylan-DPC Sep 5, 2020
a99f842
Rollup merge of #76263 - tmiasko:inline-codegen-fn-attrs, r=ecstatic-…
Dylan-DPC Sep 5, 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: 0 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3722,7 +3722,6 @@ name = "rustc_middle"
version = "0.0.0"
dependencies = [
"bitflags",
"byteorder",
"chalk-ir",
"measureme",
"polonius-engine",
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ The Rust community congregates in a few places:
If you are interested in contributing to the Rust project, please take a look
at the [Getting Started][gettingstarted] guide in the [rustc-dev-guide].

[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org

## License

Rust is primarily distributed under the terms of both the MIT license
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_middle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ rustc_index = { path = "../rustc_index" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_ast = { path = "../rustc_ast" }
rustc_span = { path = "../rustc_span" }
byteorder = { version = "1.3" }
chalk-ir = "0.21.0"
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
measureme = "0.7.1"
Expand Down
12 changes: 4 additions & 8 deletions compiler/rustc_middle/src/mir/interpret/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,10 +345,8 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {

/// Reads a *non-ZST* scalar.
///
/// ZSTs can't be read for two reasons:
/// * byte-order cannot work with zero-element buffers;
/// * in order to obtain a `Pointer`, we need to check for ZSTness anyway due to integer
/// pointers being valid for ZSTs.
/// ZSTs can't be read because in order to obtain a `Pointer`, we need to check
/// for ZSTness anyway due to integer pointers being valid for ZSTs.
///
/// It is the caller's responsibility to check bounds and alignment beforehand.
/// Most likely, you want to call `InterpCx::read_scalar` instead of this method.
Expand Down Expand Up @@ -397,10 +395,8 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {

/// Writes a *non-ZST* scalar.
///
/// ZSTs can't be read for two reasons:
/// * byte-order cannot work with zero-element buffers;
/// * in order to obtain a `Pointer`, we need to check for ZSTness anyway due to integer
/// pointers being valid for ZSTs.
/// ZSTs can't be read because in order to obtain a `Pointer`, we need to check
/// for ZSTness anyway due to integer pointers being valid for ZSTs.
///
/// It is the caller's responsibility to check bounds and alignment beforehand.
/// Most likely, you want to call `InterpCx::write_scalar` instead of this method.
Expand Down
32 changes: 23 additions & 9 deletions compiler/rustc_middle/src/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ mod value;
use std::convert::TryFrom;
use std::fmt;
use std::io;
use std::io::{Read, Write};
use std::num::NonZeroU32;
use std::sync::atomic::{AtomicU32, Ordering};

use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
use rustc_ast::LitKind;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::{HashMapExt, Lock};
Expand Down Expand Up @@ -561,19 +561,33 @@ pub fn write_target_uint(
mut target: &mut [u8],
data: u128,
) -> Result<(), io::Error> {
let len = target.len();
// This u128 holds an "any-size uint" (since smaller uints can fits in it)
// So we do not write all bytes of the u128, just the "payload".
match endianness {
Endian::Little => target.write_uint128::<LittleEndian>(data, len),
Endian::Big => target.write_uint128::<BigEndian>(data, len),
}
Endian::Little => target.write(&data.to_le_bytes())?,
Endian::Big => target.write(&data.to_be_bytes()[16 - target.len()..])?,
};
debug_assert!(target.len() == 0); // We should have filled the target buffer.
Ok(())
}

#[inline]
pub fn read_target_uint(endianness: Endian, mut source: &[u8]) -> Result<u128, io::Error> {
match endianness {
Endian::Little => source.read_uint128::<LittleEndian>(source.len()),
Endian::Big => source.read_uint128::<BigEndian>(source.len()),
}
// This u128 holds an "any-size uint" (since smaller uints can fits in it)
let mut buf = [0u8; std::mem::size_of::<u128>()];
// So we do not read exactly 16 bytes into the u128, just the "payload".
let uint = match endianness {
Endian::Little => {
source.read(&mut buf)?;
Ok(u128::from_le_bytes(buf))
}
Endian::Big => {
source.read(&mut buf[16 - source.len()..])?;
Ok(u128::from_be_bytes(buf))
}
};
debug_assert!(source.len() == 0); // We should have consumed the source buffer.
uint
}

////////////////////////////////////////////////////////////////////////////////
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/type_foldable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
use crate::mir::Rvalue::*;
match *self {
Use(ref op) => Use(op.fold_with(folder)),
Repeat(ref op, len) => Repeat(op.fold_with(folder), len),
Repeat(ref op, len) => Repeat(op.fold_with(folder), len.fold_with(folder)),
ThreadLocalRef(did) => ThreadLocalRef(did.fold_with(folder)),
Ref(region, bk, ref place) => {
Ref(region.fold_with(folder), bk, place.fold_with(folder))
Expand Down
22 changes: 17 additions & 5 deletions compiler/rustc_mir/src/transform/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rustc_attr as attr;
use rustc_hir::def_id::DefId;
use rustc_index::bit_set::BitSet;
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
use rustc_middle::ty::subst::{Subst, SubstsRef};
Expand Down Expand Up @@ -45,7 +45,8 @@ impl<'tcx> MirPass<'tcx> for Inline {
// based function.
debug!("function inlining is disabled when compiling with `instrument_coverage`");
} else {
Inliner { tcx, source }.run_pass(body);
Inliner { tcx, source, codegen_fn_attrs: tcx.codegen_fn_attrs(source.def_id()) }
.run_pass(body);
}
}
}
Expand All @@ -54,6 +55,7 @@ impl<'tcx> MirPass<'tcx> for Inline {
struct Inliner<'tcx> {
tcx: TyCtxt<'tcx>,
source: MirSource<'tcx>,
codegen_fn_attrs: &'tcx CodegenFnAttrs,
}

impl Inliner<'tcx> {
Expand Down Expand Up @@ -242,9 +244,19 @@ impl Inliner<'tcx> {
return false;
}

// Avoid inlining functions marked as no_sanitize if sanitizer is enabled,
// since instrumentation might be enabled and performed on the caller.
if self.tcx.sess.opts.debugging_opts.sanitizer.intersects(codegen_fn_attrs.no_sanitize) {
let self_features = &self.codegen_fn_attrs.target_features;
let callee_features = &codegen_fn_attrs.target_features;
if callee_features.iter().any(|feature| !self_features.contains(feature)) {
debug!("`callee has extra target features - not inlining");
return false;
}

let self_no_sanitize =
self.codegen_fn_attrs.no_sanitize & self.tcx.sess.opts.debugging_opts.sanitizer;
let callee_no_sanitize =
codegen_fn_attrs.no_sanitize & self.tcx.sess.opts.debugging_opts.sanitizer;
if self_no_sanitize != callee_no_sanitize {
debug!("`callee has incompatible no_sanitize attribute - not inlining");
return false;
}

Expand Down
22 changes: 13 additions & 9 deletions library/alloc/src/collections/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,11 +474,15 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {

impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
fn into_key_slice(self) -> &'a [K] {
unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().keys), self.len()) }
unsafe {
slice::from_raw_parts(MaybeUninit::slice_as_ptr(&self.as_leaf().keys), self.len())
}
}

fn into_val_slice(self) -> &'a [V] {
unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().vals), self.len()) }
unsafe {
slice::from_raw_parts(MaybeUninit::slice_as_ptr(&self.as_leaf().vals), self.len())
}
}
}

Expand All @@ -493,7 +497,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
// SAFETY: The keys of a node must always be initialized up to length.
unsafe {
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).keys),
MaybeUninit::slice_as_mut_ptr(&mut (*self.as_leaf_mut()).keys),
self.len(),
)
}
Expand All @@ -503,7 +507,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
// SAFETY: The values of a node must always be initialized up to length.
unsafe {
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).vals),
MaybeUninit::slice_as_mut_ptr(&mut (*self.as_leaf_mut()).vals),
self.len(),
)
}
Expand All @@ -519,10 +523,10 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
let leaf = self.as_leaf_mut();
// SAFETY: The keys and values of a node must always be initialized up to length.
let keys = unsafe {
slice::from_raw_parts_mut(MaybeUninit::first_ptr_mut(&mut (*leaf).keys), len)
slice::from_raw_parts_mut(MaybeUninit::slice_as_mut_ptr(&mut (*leaf).keys), len)
};
let vals = unsafe {
slice::from_raw_parts_mut(MaybeUninit::first_ptr_mut(&mut (*leaf).vals), len)
slice::from_raw_parts_mut(MaybeUninit::slice_as_mut_ptr(&mut (*leaf).vals), len)
};
(keys, vals)
}
Expand Down Expand Up @@ -617,7 +621,7 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
slice_insert(self.vals_mut(), 0, val);
slice_insert(
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut self.as_internal_mut().edges),
MaybeUninit::slice_as_mut_ptr(&mut self.as_internal_mut().edges),
self.len() + 1,
),
0,
Expand Down Expand Up @@ -675,7 +679,7 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
ForceResult::Internal(mut internal) => {
let edge = slice_remove(
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut internal.as_internal_mut().edges),
MaybeUninit::slice_as_mut_ptr(&mut internal.as_internal_mut().edges),
old_len + 1,
),
0,
Expand Down Expand Up @@ -962,7 +966,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::

slice_insert(
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut self.node.as_internal_mut().edges),
MaybeUninit::slice_as_mut_ptr(&mut self.node.as_internal_mut().edges),
self.node.len(),
),
self.idx + 1,
Expand Down
44 changes: 44 additions & 0 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,50 @@ impl<T> Rc<T> {
)
}

/// Constructs a new `Rc<T>` using a weak reference to itself. Attempting
/// to upgrade the weak reference before this function returns will result
/// in a `None` value. However, the weak reference may be cloned freely and
/// stored for use at a later time.
#[unstable(feature = "arc_new_cyclic", issue = "75861")]
pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Rc<T> {
// Construct the inner in the "uninitialized" state with a single
// weak reference.
let uninit_ptr: NonNull<_> = Box::leak(box RcBox {
strong: Cell::new(0),
weak: Cell::new(1),
value: mem::MaybeUninit::<T>::uninit(),
})
.into();

let init_ptr: NonNull<RcBox<T>> = uninit_ptr.cast();

let weak = Weak { ptr: init_ptr };

// It's important we don't give up ownership of the weak pointer, or
// else the memory might be freed by the time `data_fn` returns. If
// we really wanted to pass ownership, we could create an additional
// weak pointer for ourselves, but this would result in additional
// updates to the weak reference count which might not be necessary
// otherwise.
let data = data_fn(&weak);

unsafe {
let inner = init_ptr.as_ptr();
ptr::write(&raw mut (*inner).value, data);

let prev_value = (*inner).strong.get();
debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
(*inner).strong.set(1);
}

let strong = Rc::from_inner(init_ptr);

// Strong references should collectively own a shared weak reference,
// so don't run the destructor for our old weak reference.
mem::forget(weak);
strong
}

/// Constructs a new `Rc` with uninitialized contents.
///
/// # Examples
Expand Down
66 changes: 66 additions & 0 deletions library/alloc/src/rc/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,3 +434,69 @@ fn test_array_from_slice() {
let a: Result<Rc<[u32; 2]>, _> = r.clone().try_into();
assert!(a.is_err());
}

#[test]
fn test_rc_cyclic_with_zero_refs() {
struct ZeroRefs {
inner: Weak<ZeroRefs>,
}

let zero_refs = Rc::new_cyclic(|inner| {
assert_eq!(inner.strong_count(), 0);
assert!(inner.upgrade().is_none());
ZeroRefs { inner: Weak::new() }
});

assert_eq!(Rc::strong_count(&zero_refs), 1);
assert_eq!(Rc::weak_count(&zero_refs), 0);
assert_eq!(zero_refs.inner.strong_count(), 0);
assert_eq!(zero_refs.inner.weak_count(), 0);
}

#[test]
fn test_rc_cyclic_with_one_ref() {
struct OneRef {
inner: Weak<OneRef>,
}

let one_ref = Rc::new_cyclic(|inner| {
assert_eq!(inner.strong_count(), 0);
assert!(inner.upgrade().is_none());
OneRef { inner: inner.clone() }
});

assert_eq!(Rc::strong_count(&one_ref), 1);
assert_eq!(Rc::weak_count(&one_ref), 1);

let one_ref2 = Weak::upgrade(&one_ref.inner).unwrap();
assert!(Rc::ptr_eq(&one_ref, &one_ref2));

assert_eq!(one_ref.inner.strong_count(), 2);
assert_eq!(one_ref.inner.weak_count(), 1);
}

#[test]
fn test_rc_cyclic_with_two_ref() {
struct TwoRefs {
inner: Weak<TwoRefs>,
inner1: Weak<TwoRefs>,
}

let two_refs = Rc::new_cyclic(|inner| {
assert_eq!(inner.strong_count(), 0);
assert!(inner.upgrade().is_none());
TwoRefs { inner: inner.clone(), inner1: inner.clone() }
});

assert_eq!(Rc::strong_count(&two_refs), 1);
assert_eq!(Rc::weak_count(&two_refs), 2);

let two_ref3 = Weak::upgrade(&two_refs.inner).unwrap();
assert!(Rc::ptr_eq(&two_refs, &two_ref3));

let two_ref2 = Weak::upgrade(&two_refs.inner1).unwrap();
assert!(Rc::ptr_eq(&two_refs, &two_ref2));

assert_eq!(Rc::strong_count(&two_refs), 3);
assert_eq!(Rc::weak_count(&two_refs), 2);
}
4 changes: 3 additions & 1 deletion library/alloc/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ use crate::raw_vec::RawVec;
/// # Slicing
///
/// A `Vec` can be mutable. Slices, on the other hand, are read-only objects.
/// To get a slice, use `&`. Example:
/// To get a [slice], use [`&`]. Example:
///
/// ```
/// fn read_slice(slice: &[usize]) {
Expand Down Expand Up @@ -287,6 +287,8 @@ use crate::raw_vec::RawVec;
/// [`insert`]: Vec::insert
/// [`reserve`]: Vec::reserve
/// [owned slice]: Box
/// [slice]: ../../std/primitive.slice.html
/// [`&`]: ../../std/primitive.reference.html
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_type")]
pub struct Vec<T> {
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/array/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl<T, const N: usize> IntoIter<T, N> {
// SAFETY: We know that all elements within `alive` are properly initialized.
unsafe {
let slice = self.data.get_unchecked(self.alive.clone());
MaybeUninit::slice_get_ref(slice)
MaybeUninit::slice_assume_init_ref(slice)
}
}

Expand All @@ -82,7 +82,7 @@ impl<T, const N: usize> IntoIter<T, N> {
// SAFETY: We know that all elements within `alive` are properly initialized.
unsafe {
let slice = self.data.get_unchecked_mut(self.alive.clone());
MaybeUninit::slice_get_mut(slice)
MaybeUninit::slice_assume_init_mut(slice)
}
}
}
Expand Down
Loading