Skip to content

Rollup of 11 pull requests #76377

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

Closed
wants to merge 25 commits into from
Closed
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
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
8783c62
Add missing link in README
camelid Sep 2, 2020
3e29fdb
Remove a number of vec UI tests, make them unit tests in the alloc li…
CraftSpider Sep 3, 2020
791f93c
Allow try blocks as the argument to return expressions
scottmcm Sep 3, 2020
2278c72
Remove vec-to_str.rs, merge the remaining test in with vec
CraftSpider Sep 3, 2020
2bc4c03
Disable use of `--eh-frame-hdr` on wasm32.
sunfishcode Sep 4, 2020
a3ee65f
Remove a useless allowed attr
tesuji Sep 4, 2020
a2fbf39
Fix rust.use-lld when linker is not set
mati865 Sep 4, 2020
8f2d906
Implementation of incompatible features error
Amjad50 Sep 3, 2020
9e7ef65
Account for version number in NtIdent hack
Aaron1011 Sep 4, 2020
ceffb46
Update llvm-project to include PR 73
richkadel Sep 4, 2020
cff5f56
rename MaybeUninit slice methods
RalfJung Sep 1, 2020
3506832
document remaining unsafety in maybe_uninit.rs
RalfJung Sep 2, 2020
9c0fe54
Rollup merge of #76128 - poliorcetics:doc-use-arc-clone, r=KodrAus
Dylan-DPC Sep 5, 2020
fa61b8e
Rollup merge of #76217 - RalfJung:maybe-uninit-slice, r=KodrAus
Dylan-DPC Sep 5, 2020
984e417
Rollup merge of #76229 - camelid:patch-3, r=jonas-schievink
Dylan-DPC Sep 5, 2020
c5444df
Rollup merge of #76273 - CraftSpider:master, r=matklad
Dylan-DPC Sep 5, 2020
6ff4b80
Rollup merge of #76274 - scottmcm:fix-76271, r=petrochenkov
Dylan-DPC Sep 5, 2020
efea057
Rollup merge of #76287 - lzutao:rm-allowed, r=jyn514
Dylan-DPC Sep 5, 2020
600a080
Rollup merge of #76293 - Amjad50:incompatible_features_error, r=lcnr
Dylan-DPC Sep 5, 2020
055815b
Rollup merge of #76307 - sunfishcode:wasm-no-eh-frame-header, r=alexc…
Dylan-DPC Sep 5, 2020
16e7251
Rollup merge of #76326 - mati865:use_lld-no-linker, r=Mark-Simulacrum
Dylan-DPC Sep 5, 2020
0ac652b
Rollup merge of #76331 - Aaron1011:fix/group-compat-hack-test, r=petr…
Dylan-DPC Sep 5, 2020
1410253
Rollup merge of #76341 - richkadel:ignore-gcc-destructor-priority, r=…
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
17 changes: 14 additions & 3 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
@@ -173,6 +173,7 @@ pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: bool) -> bool {
kw::Move,
kw::Return,
kw::True,
kw::Try,
kw::Unsafe,
kw::While,
kw::Yield,
@@ -809,9 +810,19 @@ impl Nonterminal {
if let ExpnKind::Macro(_, macro_name) = orig_span.ctxt().outer_expn_data().kind {
let filename = source_map.span_to_filename(orig_span);
if let FileName::Real(RealFileName::Named(path)) = filename {
if (path.ends_with("time-macros-impl/src/lib.rs")
&& macro_name == sym::impl_macros)
|| (path.ends_with("js-sys/src/lib.rs") && macro_name == sym::arrays)
let matches_prefix = |prefix| {
// Check for a path that ends with 'prefix*/src/lib.rs'
let mut iter = path.components().rev();
iter.next().and_then(|p| p.as_os_str().to_str()) == Some("lib.rs")
&& iter.next().and_then(|p| p.as_os_str().to_str()) == Some("src")
&& iter
.next()
.and_then(|p| p.as_os_str().to_str())
.map_or(false, |p| p.starts_with(prefix))
};

if (macro_name == sym::impl_macros && matches_prefix("time-macros-impl"))
|| (macro_name == sym::arrays && matches_prefix("js-sys"))
{
let snippet = source_map.span_to_snippet(orig_span);
if snippet.as_deref() == Ok("$name") {
34 changes: 34 additions & 0 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
@@ -608,6 +608,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {

pub fn check_crate(krate: &ast::Crate, sess: &Session) {
maybe_stage_features(sess, krate);
check_incompatible_features(sess);
let mut visitor = PostExpansionVisitor { sess, features: &sess.features_untracked() };

let spans = sess.parse_sess.gated_spans.spans.borrow();
@@ -677,3 +678,36 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
}
}
}

fn check_incompatible_features(sess: &Session) {
let features = sess.features_untracked();

let declared_features = features
.declared_lang_features
.iter()
.copied()
.map(|(name, span, _)| (name, span))
.chain(features.declared_lib_features.iter().copied());

for (f1, f2) in rustc_feature::INCOMPATIBLE_FEATURES
.iter()
.filter(|&&(f1, f2)| features.enabled(f1) && features.enabled(f2))
{
if let Some((f1_name, f1_span)) = declared_features.clone().find(|(name, _)| name == f1) {
if let Some((f2_name, f2_span)) = declared_features.clone().find(|(name, _)| name == f2)
{
let spans = vec![f1_span, f2_span];
sess.struct_span_err(
spans.clone(),
&format!(
"features `{}` and `{}` are incompatible, using them at the same time \
is not allowed",
f1_name, f2_name
),
)
.help("remove one of these features")
.emit();
}
}
}
}
5 changes: 5 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
@@ -605,3 +605,8 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
sym::lazy_normalization_consts,
sym::specialization,
];

/// Some features are not allowed to be used together at the same time, if
/// the two are present, produce an error
pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] =
&[(sym::const_generics, sym::min_const_generics)];
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/lib.rs
Original file line number Diff line number Diff line change
@@ -131,7 +131,7 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option<NonZeroU3
}

pub use accepted::ACCEPTED_FEATURES;
pub use active::{Features, ACTIVE_FEATURES, INCOMPLETE_FEATURES};
pub use active::{Features, ACTIVE_FEATURES, INCOMPATIBLE_FEATURES, INCOMPLETE_FEATURES};
pub use builtin_attrs::{
deprecated_attributes, find_gated_cfg, is_builtin_attr_name, AttributeGate, AttributeTemplate,
AttributeType, BuiltinAttribute, GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/wasm32_base.rs
Original file line number Diff line number Diff line change
@@ -83,6 +83,7 @@ pub fn options() -> TargetOptions {
dll_prefix: String::new(),
dll_suffix: ".wasm".to_string(),
linker_is_gnu: false,
eh_frame_header: false,

max_atomic_width: Some(64),

26 changes: 15 additions & 11 deletions library/alloc/src/collections/btree/node.rs
Original file line number Diff line number Diff line change
@@ -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())
}
}
}

@@ -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(),
)
}
@@ -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(),
)
}
@@ -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)
}
@@ -536,9 +540,9 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::ValMut<'a>, K, V, Type> {
let len = self.len();
let leaf = self.node.as_ptr();
// SAFETY: The keys and values of a node must always be initialized up to length.
let keys = unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&(*leaf).keys), len) };
let keys = unsafe { slice::from_raw_parts(MaybeUninit::slice_as_ptr(&(*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)
}
@@ -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,
@@ -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,
@@ -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,
56 changes: 56 additions & 0 deletions library/alloc/tests/vec.rs
Original file line number Diff line number Diff line change
@@ -74,6 +74,42 @@ fn test_zst_capacity() {
assert_eq!(Vec::<()>::new().capacity(), usize::MAX);
}

#[test]
fn test_indexing() {
let v: Vec<isize> = vec![10, 20];
assert_eq!(v[0], 10);
assert_eq!(v[1], 20);
let mut x: usize = 0;
assert_eq!(v[x], 10);
assert_eq!(v[x + 1], 20);
x = x + 1;
assert_eq!(v[x], 20);
assert_eq!(v[x - 1], 10);
}

#[test]
fn test_debug_fmt() {
let vec1: Vec<isize> = vec![];
assert_eq!("[]", format!("{:?}", vec1));

let vec2 = vec![0, 1];
assert_eq!("[0, 1]", format!("{:?}", vec2));

let slice: &[isize] = &[4, 5];
assert_eq!("[4, 5]", format!("{:?}", slice));
}

#[test]
fn test_push() {
let mut v = vec![];
v.push(1);
assert_eq!(v, [1]);
v.push(2);
assert_eq!(v, [1, 2]);
v.push(3);
assert_eq!(v, [1, 2, 3]);
}

#[test]
fn test_extend() {
let mut v = Vec::new();
@@ -119,6 +155,18 @@ fn test_extend() {
assert_eq!(count_x, 1);
}

#[test]
fn test_extend_from_slice() {
let a: Vec<isize> = vec![1, 2, 3, 4, 5];
let b: Vec<isize> = vec![6, 7, 8, 9, 0];

let mut v: Vec<isize> = a;

v.extend_from_slice(&b);

assert_eq!(v, [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
}

#[test]
fn test_extend_ref() {
let mut v = vec![1, 2];
@@ -134,6 +182,14 @@ fn test_extend_ref() {
assert_eq!(v, [1, 2, 3, 4, 5, 6, 7]);
}

#[test]
fn test_slice_from_ref() {
let values = vec![1, 2, 3, 4, 5];
let slice = &values[1..3];

assert_eq!(slice, [2, 3]);
}

#[test]
fn test_slice_from_mut() {
let mut values = vec![1, 2, 3, 4, 5];
4 changes: 2 additions & 2 deletions library/core/src/array/iter.rs
Original file line number Diff line number Diff line change
@@ -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)
}
}

@@ -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)
}
}
}
2 changes: 1 addition & 1 deletion library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
@@ -410,7 +410,7 @@ impl<T, const N: usize> [T; N] {
}
let mut dst = MaybeUninit::uninit_array::<N>();
let mut guard: Guard<U, N> =
Guard { dst: MaybeUninit::first_ptr_mut(&mut dst), initialized: 0 };
Guard { dst: MaybeUninit::slice_as_mut_ptr(&mut dst), initialized: 0 };
for (src, dst) in IntoIter::new(self).zip(&mut dst) {
dst.write(f(src));
guard.initialized += 1;
11 changes: 7 additions & 4 deletions library/core/src/fmt/num.rs
Original file line number Diff line number Diff line change
@@ -85,7 +85,10 @@ trait GenericRadix {
// SAFETY: The only chars in `buf` are created by `Self::digit` which are assumed to be
// valid UTF-8
let buf = unsafe {
str::from_utf8_unchecked(slice::from_raw_parts(MaybeUninit::first_ptr(buf), buf.len()))
str::from_utf8_unchecked(slice::from_raw_parts(
MaybeUninit::slice_as_ptr(buf),
buf.len(),
))
};
f.pad_integral(is_nonnegative, Self::PREFIX, buf)
}
@@ -192,7 +195,7 @@ macro_rules! impl_Display {
// 2^128 is about 3*10^38, so 39 gives an extra byte of space
let mut buf = [MaybeUninit::<u8>::uninit(); 39];
let mut curr = buf.len() as isize;
let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf);
let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
let lut_ptr = DEC_DIGITS_LUT.as_ptr();

// SAFETY: Since `d1` and `d2` are always less than or equal to `198`, we
@@ -322,7 +325,7 @@ macro_rules! impl_Exp {
// that `curr >= 0`.
let mut buf = [MaybeUninit::<u8>::uninit(); 40];
let mut curr = buf.len() as isize; //index for buf
let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf);
let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
let lut_ptr = DEC_DIGITS_LUT.as_ptr();

// decode 2 chars at a time
@@ -370,7 +373,7 @@ macro_rules! impl_Exp {

// stores 'e' (or 'E') and the up to 2-digit exponent
let mut exp_buf = [MaybeUninit::<u8>::uninit(); 3];
let exp_ptr = MaybeUninit::first_ptr_mut(&mut exp_buf);
let exp_ptr = MaybeUninit::slice_as_mut_ptr(&mut exp_buf);
// SAFETY: In either case, `exp_buf` is written within bounds and `exp_ptr[..len]`
// is contained within `exp_buf` since `len <= 3`.
let exp_slice = unsafe {
35 changes: 21 additions & 14 deletions library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
@@ -3,8 +3,6 @@ use crate::fmt;
use crate::intrinsics;
use crate::mem::ManuallyDrop;

// ignore-tidy-undocumented-unsafe

/// A wrapper type to construct uninitialized instances of `T`.
///
/// # Initialization invariant
@@ -281,7 +279,7 @@ impl<T> MaybeUninit<T> {
/// # Examples
///
/// ```no_run
/// #![feature(maybe_uninit_uninit_array, maybe_uninit_extra, maybe_uninit_slice_assume_init)]
/// #![feature(maybe_uninit_uninit_array, maybe_uninit_extra, maybe_uninit_slice)]
///
/// use std::mem::MaybeUninit;
///
@@ -293,7 +291,7 @@ impl<T> MaybeUninit<T> {
/// fn read(buf: &mut [MaybeUninit<u8>]) -> &[u8] {
/// unsafe {
/// let len = read_into_buffer(buf.as_mut_ptr() as *mut u8, buf.len());
/// MaybeUninit::slice_get_ref(&buf[..len])
/// MaybeUninit::slice_assume_init_ref(&buf[..len])
/// }
/// }
///
@@ -303,6 +301,7 @@ impl<T> MaybeUninit<T> {
#[unstable(feature = "maybe_uninit_uninit_array", issue = "none")]
#[inline(always)]
pub fn uninit_array<const LEN: usize>() -> [Self; LEN] {
// SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
unsafe { MaybeUninit::<[MaybeUninit<T>; LEN]>::uninit().assume_init() }
}

@@ -354,6 +353,7 @@ impl<T> MaybeUninit<T> {
#[rustc_diagnostic_item = "maybe_uninit_zeroed"]
pub fn zeroed() -> MaybeUninit<T> {
let mut u = MaybeUninit::<T>::uninit();
// SAFETY: `u.as_mut_ptr()` points to allocated memory.
unsafe {
u.as_mut_ptr().write_bytes(0u8, 1);
}
@@ -367,10 +367,9 @@ impl<T> MaybeUninit<T> {
#[unstable(feature = "maybe_uninit_extra", issue = "63567")]
#[inline(always)]
pub fn write(&mut self, val: T) -> &mut T {
unsafe {
self.value = ManuallyDrop::new(val);
self.assume_init_mut()
}
*self = MaybeUninit::new(val);
// SAFETY: We just initialized this value.
unsafe { self.assume_init_mut() }
}

/// Gets a pointer to the contained value. Reading from this pointer or turning it
@@ -769,9 +768,13 @@ impl<T> MaybeUninit<T> {
/// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
/// really are in an initialized state.
/// Calling this when the content is not yet fully initialized causes undefined behavior.
#[unstable(feature = "maybe_uninit_slice_assume_init", issue = "none")]
///
/// See [`assume_init_ref`] for more details and examples.
///
/// [`assume_init_ref`]: MaybeUninit::assume_init_ref
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
pub unsafe fn slice_get_ref(slice: &[Self]) -> &[T] {
pub unsafe fn slice_assume_init_ref(slice: &[Self]) -> &[T] {
// SAFETY: casting slice to a `*const [T]` is safe since the caller guarantees that
// `slice` is initialized, and`MaybeUninit` is guaranteed to have the same layout as `T`.
// The pointer obtained is valid since it refers to memory owned by `slice` which is a
@@ -786,9 +789,13 @@ impl<T> MaybeUninit<T> {
/// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
/// really are in an initialized state.
/// Calling this when the content is not yet fully initialized causes undefined behavior.
#[unstable(feature = "maybe_uninit_slice_assume_init", issue = "none")]
///
/// See [`assume_init_mut`] for more details and examples.
///
/// [`assume_init_mut`]: MaybeUninit::assume_init_mut
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
pub unsafe fn slice_get_mut(slice: &mut [Self]) -> &mut [T] {
pub unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] {
// SAFETY: similar to safety notes for `slice_get_ref`, but we have a
// mutable reference which is also guaranteed to be valid for writes.
unsafe { &mut *(slice as *mut [Self] as *mut [T]) }
@@ -797,14 +804,14 @@ impl<T> MaybeUninit<T> {
/// Gets a pointer to the first element of the array.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
pub fn first_ptr(this: &[MaybeUninit<T>]) -> *const T {
pub fn slice_as_ptr(this: &[MaybeUninit<T>]) -> *const T {
this as *const [MaybeUninit<T>] as *const T
}

/// Gets a mutable pointer to the first element of the array.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
pub fn first_ptr_mut(this: &mut [MaybeUninit<T>]) -> *mut T {
pub fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
this as *mut [MaybeUninit<T>] as *mut T
}
}
88 changes: 56 additions & 32 deletions library/core/src/num/flt2dec/mod.rs
Original file line number Diff line number Diff line change
@@ -311,10 +311,10 @@ fn digits_to_dec_str<'a>(
if frac_digits > buf.len() && frac_digits - buf.len() > minus_exp {
parts[3] = MaybeUninit::new(Part::Zero((frac_digits - buf.len()) - minus_exp));
// SAFETY: we just initialized the elements `..4`.
unsafe { MaybeUninit::slice_get_ref(&parts[..4]) }
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..4]) }
} else {
// SAFETY: we just initialized the elements `..3`.
unsafe { MaybeUninit::slice_get_ref(&parts[..3]) }
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..3]) }
}
} else {
let exp = exp as usize;
@@ -326,10 +326,10 @@ fn digits_to_dec_str<'a>(
if frac_digits > buf.len() - exp {
parts[3] = MaybeUninit::new(Part::Zero(frac_digits - (buf.len() - exp)));
// SAFETY: we just initialized the elements `..4`.
unsafe { MaybeUninit::slice_get_ref(&parts[..4]) }
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..4]) }
} else {
// SAFETY: we just initialized the elements `..3`.
unsafe { MaybeUninit::slice_get_ref(&parts[..3]) }
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..3]) }
}
} else {
// the decimal point is after rendered digits: [1234][____0000] or [1234][__][.][__].
@@ -339,10 +339,10 @@ fn digits_to_dec_str<'a>(
parts[2] = MaybeUninit::new(Part::Copy(b"."));
parts[3] = MaybeUninit::new(Part::Zero(frac_digits));
// SAFETY: we just initialized the elements `..4`.
unsafe { MaybeUninit::slice_get_ref(&parts[..4]) }
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..4]) }
} else {
// SAFETY: we just initialized the elements `..2`.
unsafe { MaybeUninit::slice_get_ref(&parts[..2]) }
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) }
}
}
}
@@ -393,7 +393,7 @@ fn digits_to_exp_str<'a>(
parts[n + 1] = MaybeUninit::new(Part::Num(exp as u16));
}
// SAFETY: we just initialized the elements `..n + 2`.
unsafe { MaybeUninit::slice_get_ref(&parts[..n + 2]) }
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..n + 2]) }
}

/// Sign formatting options.
@@ -487,24 +487,30 @@ where
FullDecoded::Nan => {
parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
// SAFETY: we just initialized the elements `..1`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Infinite => {
parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
// SAFETY: we just initialized the elements `..1`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Zero => {
if frac_digits > 0 {
// [0.][0000]
parts[0] = MaybeUninit::new(Part::Copy(b"0."));
parts[1] = MaybeUninit::new(Part::Zero(frac_digits));
// SAFETY: we just initialized the elements `..2`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..2]) } }
Formatted {
sign,
// SAFETY: we just initialized the elements `..2`.
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) },
}
} else {
parts[0] = MaybeUninit::new(Part::Copy(b"0"));
// SAFETY: we just initialized the elements `..1`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
Formatted {
sign,
// SAFETY: we just initialized the elements `..1`.
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) },
}
}
}
FullDecoded::Finite(ref decoded) => {
@@ -557,12 +563,12 @@ where
FullDecoded::Nan => {
parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
// SAFETY: we just initialized the elements `..1`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Infinite => {
parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
// SAFETY: we just initialized the elements `..1`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Zero => {
parts[0] = if dec_bounds.0 <= 0 && 0 < dec_bounds.1 {
@@ -571,7 +577,7 @@ where
MaybeUninit::new(Part::Copy(if upper { b"0E0" } else { b"0e0" }))
};
// SAFETY: we just initialized the elements `..1`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Finite(ref decoded) => {
let (buf, exp) = format_shortest(decoded, buf);
@@ -648,25 +654,31 @@ where
FullDecoded::Nan => {
parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
// SAFETY: we just initialized the elements `..1`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Infinite => {
parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
// SAFETY: we just initialized the elements `..1`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Zero => {
if ndigits > 1 {
// [0.][0000][e0]
parts[0] = MaybeUninit::new(Part::Copy(b"0."));
parts[1] = MaybeUninit::new(Part::Zero(ndigits - 1));
parts[2] = MaybeUninit::new(Part::Copy(if upper { b"E0" } else { b"e0" }));
// SAFETY: we just initialized the elements `..3`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..3]) } }
Formatted {
sign,
// SAFETY: we just initialized the elements `..3`.
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..3]) },
}
} else {
parts[0] = MaybeUninit::new(Part::Copy(if upper { b"0E0" } else { b"0e0" }));
// SAFETY: we just initialized the elements `..1`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
Formatted {
sign,
// SAFETY: we just initialized the elements `..1`.
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) },
}
}
}
FullDecoded::Finite(ref decoded) => {
@@ -716,24 +728,30 @@ where
FullDecoded::Nan => {
parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
// SAFETY: we just initialized the elements `..1`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Infinite => {
parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
// SAFETY: we just initialized the elements `..1`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Zero => {
if frac_digits > 0 {
// [0.][0000]
parts[0] = MaybeUninit::new(Part::Copy(b"0."));
parts[1] = MaybeUninit::new(Part::Zero(frac_digits));
// SAFETY: we just initialized the elements `..2`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..2]) } }
Formatted {
sign,
// SAFETY: we just initialized the elements `..2`.
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) },
}
} else {
parts[0] = MaybeUninit::new(Part::Copy(b"0"));
// SAFETY: we just initialized the elements `..1`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
Formatted {
sign,
// SAFETY: we just initialized the elements `..1`.
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) },
}
}
}
FullDecoded::Finite(ref decoded) => {
@@ -754,12 +772,18 @@ where
// [0.][0000]
parts[0] = MaybeUninit::new(Part::Copy(b"0."));
parts[1] = MaybeUninit::new(Part::Zero(frac_digits));
// SAFETY: we just initialized the elements `..2`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..2]) } }
Formatted {
sign,
// SAFETY: we just initialized the elements `..2`.
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) },
}
} else {
parts[0] = MaybeUninit::new(Part::Copy(b"0"));
// SAFETY: we just initialized the elements `..1`.
Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
Formatted {
sign,
// SAFETY: we just initialized the elements `..1`.
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) },
}
}
} else {
Formatted { sign, parts: digits_to_dec_str(buf, exp, frac_digits, parts) }
10 changes: 5 additions & 5 deletions library/core/src/num/flt2dec/strategy/dragon.rs
Original file line number Diff line number Diff line change
@@ -246,15 +246,15 @@ pub fn format_shortest<'a>(
// it seems that this condition is very hard to satisfy (possibly impossible),
// but we are just being safe and consistent here.
// SAFETY: we initialized that memory above.
if let Some(c) = round_up(unsafe { MaybeUninit::slice_get_mut(&mut buf[..i]) }) {
if let Some(c) = round_up(unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..i]) }) {
buf[i] = MaybeUninit::new(c);
i += 1;
k += 1;
}
}

// SAFETY: we initialized that memory above.
(unsafe { MaybeUninit::slice_get_ref(&buf[..i]) }, k)
(unsafe { MaybeUninit::slice_assume_init_ref(&buf[..i]) }, k)
}

/// The exact and fixed mode implementation for Dragon.
@@ -332,7 +332,7 @@ pub fn format_exact<'a>(
*c = MaybeUninit::new(b'0');
}
// SAFETY: we initialized that memory above.
return (unsafe { MaybeUninit::slice_get_ref(&buf[..len]) }, k);
return (unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, k);
}

let mut d = 0;
@@ -371,7 +371,7 @@ pub fn format_exact<'a>(
// if rounding up changes the length, the exponent should also change.
// but we've been requested a fixed number of digits, so do not alter the buffer...
// SAFETY: we initialized that memory above.
if let Some(c) = round_up(unsafe { MaybeUninit::slice_get_mut(&mut buf[..len]) }) {
if let Some(c) = round_up(unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..len]) }) {
// ...unless we've been requested the fixed precision instead.
// we also need to check that, if the original buffer was empty,
// the additional digit can only be added when `k == limit` (edge case).
@@ -384,5 +384,5 @@ pub fn format_exact<'a>(
}

// SAFETY: we initialized that memory above.
(unsafe { MaybeUninit::slice_get_ref(&buf[..len]) }, k)
(unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, k)
}
14 changes: 8 additions & 6 deletions library/core/src/num/flt2dec/strategy/grisu.rs
Original file line number Diff line number Diff line change
@@ -276,7 +276,7 @@ pub fn format_shortest_opt<'a>(
let ten_kappa = (ten_kappa as u64) << e; // scale 10^kappa back to the shared exponent
return round_and_weed(
// SAFETY: we initialized that memory above.
unsafe { MaybeUninit::slice_get_mut(&mut buf[..i]) },
unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..i]) },
exp,
plus1rem,
delta1,
@@ -327,7 +327,7 @@ pub fn format_shortest_opt<'a>(
let ten_kappa = 1 << e; // implicit divisor
return round_and_weed(
// SAFETY: we initialized that memory above.
unsafe { MaybeUninit::slice_get_mut(&mut buf[..i]) },
unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..i]) },
exp,
r,
threshold,
@@ -701,7 +701,7 @@ pub fn format_exact_opt<'a>(
// `10^kappa` did not overflow after all, the second check is fine.
if ten_kappa - remainder > remainder && ten_kappa - 2 * remainder >= 2 * ulp {
// SAFETY: our caller initialized that memory.
return Some((unsafe { MaybeUninit::slice_get_ref(&buf[..len]) }, exp));
return Some((unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, exp));
}

// :<------- remainder ------>| :
@@ -722,8 +722,10 @@ pub fn format_exact_opt<'a>(
// as `10^kappa` is never zero). also note that `remainder - ulp <= 10^kappa`,
// so the second check does not overflow.
if remainder > ulp && ten_kappa - (remainder - ulp) <= remainder - ulp {
// SAFETY: our caller must have initialized that memory.
if let Some(c) = round_up(unsafe { MaybeUninit::slice_get_mut(&mut buf[..len]) }) {
if let Some(c) =
// SAFETY: our caller must have initialized that memory.
round_up(unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..len]) })
{
// only add an additional digit when we've been requested the fixed precision.
// we also need to check that, if the original buffer was empty,
// the additional digit can only be added when `exp == limit` (edge case).
@@ -734,7 +736,7 @@ pub fn format_exact_opt<'a>(
}
}
// SAFETY: we and our caller initialized that memory.
return Some((unsafe { MaybeUninit::slice_get_ref(&buf[..len]) }, exp));
return Some((unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, exp));
}

// otherwise we are doomed (i.e., some values between `v - 1 ulp` and `v + 1 ulp` are
2 changes: 1 addition & 1 deletion library/core/src/pin.rs
Original file line number Diff line number Diff line change
@@ -541,7 +541,7 @@ impl<P: Deref> Pin<P> {
/// use std::pin::Pin;
///
/// fn move_pinned_rc<T>(mut x: Rc<T>) {
/// let pinned = unsafe { Pin::new_unchecked(x.clone()) };
/// let pinned = unsafe { Pin::new_unchecked(Rc::clone(&x)) };
/// {
/// let p: Pin<&T> = pinned.as_ref();
/// // This should mean the pointee can never move again.
1 change: 0 additions & 1 deletion library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
@@ -66,7 +66,6 @@ impl<T> [T] {
#[rustc_const_stable(feature = "const_slice_len", since = "1.32.0")]
#[inline]
// SAFETY: const sound because we transmute out the length field as a usize (which it must be)
#[allow(unused_attributes)]
#[allow_internal_unstable(const_fn_union)]
pub const fn len(&self) -> usize {
// SAFETY: this is safe because `&[T]` and `FatPtr<T>` have the same layout.
8 changes: 4 additions & 4 deletions library/core/src/slice/sort.rs
Original file line number Diff line number Diff line change
@@ -299,8 +299,8 @@ where

if start_l == end_l {
// Trace `block_l` elements from the left side.
start_l = MaybeUninit::first_ptr_mut(&mut offsets_l);
end_l = MaybeUninit::first_ptr_mut(&mut offsets_l);
start_l = MaybeUninit::slice_as_mut_ptr(&mut offsets_l);
end_l = MaybeUninit::slice_as_mut_ptr(&mut offsets_l);
let mut elem = l;

for i in 0..block_l {
@@ -325,8 +325,8 @@ where

if start_r == end_r {
// Trace `block_r` elements from the right side.
start_r = MaybeUninit::first_ptr_mut(&mut offsets_r);
end_r = MaybeUninit::first_ptr_mut(&mut offsets_r);
start_r = MaybeUninit::slice_as_mut_ptr(&mut offsets_r);
end_r = MaybeUninit::slice_as_mut_ptr(&mut offsets_r);
let mut elem = r;

for i in 0..block_r {
2 changes: 1 addition & 1 deletion library/core/src/sync/atomic.rs
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@
//! fn main() {
//! let spinlock = Arc::new(AtomicUsize::new(1));
//!
//! let spinlock_clone = spinlock.clone();
//! let spinlock_clone = Arc::clone(&spinlock);
//! let thread = thread::spawn(move|| {
//! spinlock_clone.store(0, Ordering::SeqCst);
//! });
4 changes: 2 additions & 2 deletions library/std/src/collections/hash/map.rs
Original file line number Diff line number Diff line change
@@ -2382,15 +2382,15 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
/// use std::rc::Rc;
///
/// let mut map: HashMap<Rc<String>, u32> = HashMap::new();
/// let mut known_strings: Vec<Rc<String>> = Vec::new();
/// let known_strings: Vec<Rc<String>> = Vec::new();
///
/// // Initialise known strings, run program, etc.
///
/// reclaim_memory(&mut map, &known_strings);
///
/// fn reclaim_memory(map: &mut HashMap<Rc<String>, u32>, known_strings: &[Rc<String>] ) {
/// for s in known_strings {
/// if let Entry::Occupied(entry) = map.entry(s.clone()) {
/// if let Entry::Occupied(entry) = map.entry(Rc::clone(s)) {
/// // Replaces the entry's key with our version of it in `known_strings`.
/// entry.replace_key();
/// }
1 change: 0 additions & 1 deletion library/std/src/os/raw/mod.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,6 @@
#![stable(feature = "raw_os", since = "1.1.0")]

#[cfg(test)]
#[allow(unused_imports)]
mod tests;

#[doc(include = "char.md")]
1 change: 0 additions & 1 deletion library/std/src/os/raw/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::any::TypeId;
use crate::mem;

macro_rules! ok {
($($t:ident)*) => {$(
4 changes: 2 additions & 2 deletions library/std/src/sync/barrier.rs
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ use crate::sync::{Condvar, Mutex};
/// let mut handles = Vec::with_capacity(10);
/// let barrier = Arc::new(Barrier::new(10));
/// for _ in 0..10 {
/// let c = barrier.clone();
/// let c = Arc::clone(&barrier);
/// // The same messages will be printed together.
/// // You will NOT see any interleaving.
/// handles.push(thread::spawn(move|| {
@@ -113,7 +113,7 @@ impl Barrier {
/// let mut handles = Vec::with_capacity(10);
/// let barrier = Arc::new(Barrier::new(10));
/// for _ in 0..10 {
/// let c = barrier.clone();
/// let c = Arc::clone(&barrier);
/// // The same messages will be printed together.
/// // You will NOT see any interleaving.
/// handles.push(thread::spawn(move|| {
18 changes: 9 additions & 9 deletions library/std/src/sync/condvar.rs
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@ impl WaitTimeoutResult {
/// use std::time::Duration;
///
/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
/// let pair2 = pair.clone();
/// let pair2 = Arc::clone(&pair);
///
/// thread::spawn(move || {
/// let (lock, cvar) = &*pair2;
@@ -93,7 +93,7 @@ impl WaitTimeoutResult {
/// use std::thread;
///
/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
/// let pair2 = pair.clone();
/// let pair2 = Arc::clone(&pair);
///
/// // Inside of our lock, spawn a new thread, and then wait for it to start.
/// thread::spawn(move|| {
@@ -176,7 +176,7 @@ impl Condvar {
/// use std::thread;
///
/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
/// let pair2 = pair.clone();
/// let pair2 = Arc::clone(&pair);
///
/// thread::spawn(move|| {
/// let (lock, cvar) = &*pair2;
@@ -232,7 +232,7 @@ impl Condvar {
/// use std::thread;
///
/// let pair = Arc::new((Mutex::new(true), Condvar::new()));
/// let pair2 = pair.clone();
/// let pair2 = Arc::clone(&pair);
///
/// thread::spawn(move|| {
/// let (lock, cvar) = &*pair2;
@@ -291,7 +291,7 @@ impl Condvar {
/// use std::thread;
///
/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
/// let pair2 = pair.clone();
/// let pair2 = Arc::clone(&pair);
///
/// thread::spawn(move|| {
/// let (lock, cvar) = &*pair2;
@@ -363,7 +363,7 @@ impl Condvar {
/// use std::time::Duration;
///
/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
/// let pair2 = pair.clone();
/// let pair2 = Arc::clone(&pair);
///
/// thread::spawn(move|| {
/// let (lock, cvar) = &*pair2;
@@ -432,7 +432,7 @@ impl Condvar {
/// use std::time::Duration;
///
/// let pair = Arc::new((Mutex::new(true), Condvar::new()));
/// let pair2 = pair.clone();
/// let pair2 = Arc::clone(&pair);
///
/// thread::spawn(move|| {
/// let (lock, cvar) = &*pair2;
@@ -496,7 +496,7 @@ impl Condvar {
/// use std::thread;
///
/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
/// let pair2 = pair.clone();
/// let pair2 = Arc::clone(&pair);
///
/// thread::spawn(move|| {
/// let (lock, cvar) = &*pair2;
@@ -536,7 +536,7 @@ impl Condvar {
/// use std::thread;
///
/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
/// let pair2 = pair.clone();
/// let pair2 = Arc::clone(&pair);
///
/// thread::spawn(move|| {
/// let (lock, cvar) = &*pair2;
8 changes: 4 additions & 4 deletions library/std/src/sync/mutex.rs
Original file line number Diff line number Diff line change
@@ -88,7 +88,7 @@ use crate::sys_common::poison::{self, LockResult, TryLockError, TryLockResult};
/// use std::thread;
///
/// let lock = Arc::new(Mutex::new(0_u32));
/// let lock2 = lock.clone();
/// let lock2 = Arc::clone(&lock);
///
/// let _ = thread::spawn(move || -> () {
/// // This thread will acquire the mutex first, unwrapping the result of
@@ -259,7 +259,7 @@ impl<T: ?Sized> Mutex<T> {
/// use std::thread;
///
/// let mutex = Arc::new(Mutex::new(0));
/// let c_mutex = mutex.clone();
/// let c_mutex = Arc::clone(&mutex);
///
/// thread::spawn(move || {
/// *c_mutex.lock().unwrap() = 10;
@@ -295,7 +295,7 @@ impl<T: ?Sized> Mutex<T> {
/// use std::thread;
///
/// let mutex = Arc::new(Mutex::new(0));
/// let c_mutex = mutex.clone();
/// let c_mutex = Arc::clone(&mutex);
///
/// thread::spawn(move || {
/// let mut lock = c_mutex.try_lock();
@@ -331,7 +331,7 @@ impl<T: ?Sized> Mutex<T> {
/// use std::thread;
///
/// let mutex = Arc::new(Mutex::new(0));
/// let c_mutex = mutex.clone();
/// let c_mutex = Arc::clone(&mutex);
///
/// let _ = thread::spawn(move || {
/// let _lock = c_mutex.lock().unwrap();
4 changes: 2 additions & 2 deletions library/std/src/sync/rwlock.rs
Original file line number Diff line number Diff line change
@@ -165,7 +165,7 @@ impl<T: ?Sized> RwLock<T> {
/// use std::thread;
///
/// let lock = Arc::new(RwLock::new(1));
/// let c_lock = lock.clone();
/// let c_lock = Arc::clone(&lock);
///
/// let n = lock.read().unwrap();
/// assert_eq!(*n, 1);
@@ -321,7 +321,7 @@ impl<T: ?Sized> RwLock<T> {
/// use std::thread;
///
/// let lock = Arc::new(RwLock::new(0));
/// let c_lock = lock.clone();
/// let c_lock = Arc::clone(&lock);
///
/// let _ = thread::spawn(move || {
/// let _lock = c_lock.write().unwrap();
4 changes: 2 additions & 2 deletions library/std/src/sys_common/poison.rs
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@ pub struct Guard {
/// let mutex = Arc::new(Mutex::new(1));
///
/// // poison the mutex
/// let c_mutex = mutex.clone();
/// let c_mutex = Arc::clone(&mutex);
/// let _ = thread::spawn(move || {
/// let mut data = c_mutex.lock().unwrap();
/// *data = 2;
@@ -168,7 +168,7 @@ impl<T> PoisonError<T> {
/// let mutex = Arc::new(Mutex::new(HashSet::new()));
///
/// // poison the mutex
/// let c_mutex = mutex.clone();
/// let c_mutex = Arc::clone(&mutex);
/// let _ = thread::spawn(move || {
/// let mut data = c_mutex.lock().unwrap();
/// data.insert(10);
7 changes: 6 additions & 1 deletion src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
@@ -863,7 +863,12 @@ impl Build {
&& !target.contains("msvc")
{
Some(self.cc(target))
} else if can_use_lld && self.config.use_lld && self.build == target {
} else if target.contains("msvc")
&& can_use_lld
&& self.config.use_lld
&& self.build == target
{
// Currently we support using LLD directly via `rust.use_lld` option only with MSVC
Some(&self.initial_lld)
} else {
None
2 changes: 1 addition & 1 deletion src/llvm-project
14 changes: 0 additions & 14 deletions src/test/ui/array-slice-vec/vec-concat.rs

This file was deleted.

16 changes: 0 additions & 16 deletions src/test/ui/array-slice-vec/vec-growth.rs

This file was deleted.

3 changes: 0 additions & 3 deletions src/test/ui/array-slice-vec/vec-push.rs

This file was deleted.

9 changes: 0 additions & 9 deletions src/test/ui/array-slice-vec/vec-slice.rs

This file was deleted.

12 changes: 0 additions & 12 deletions src/test/ui/array-slice-vec/vec-to_str.rs

This file was deleted.

15 changes: 0 additions & 15 deletions src/test/ui/array-slice-vec/vec.rs

This file was deleted.

7 changes: 7 additions & 0 deletions src/test/ui/const-generics/min-and-full-same-time.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![feature(const_generics)]
//~^ ERROR features `const_generics` and `min_const_generics` are incompatible
#![allow(incomplete_features)]
#![feature(min_const_generics)]


fn main() {}
13 changes: 13 additions & 0 deletions src/test/ui/const-generics/min-and-full-same-time.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error: features `const_generics` and `min_const_generics` are incompatible, using them at the same time is not allowed
--> $DIR/min-and-full-same-time.rs:1:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
...
LL | #![feature(min_const_generics)]
| ^^^^^^^^^^^^^^^^^^
|
= help: remove one of these features

error: aborting due to previous error

31 changes: 25 additions & 6 deletions src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs
Original file line number Diff line number Diff line change
@@ -13,18 +13,37 @@ extern crate std;
// place of a `None`-delimited group. This allows us to maintain
// backwards compatibility for older versions of these crates.

include!("js-sys/src/lib.rs");
include!("time-macros-impl/src/lib.rs");
mod no_version {
include!("js-sys/src/lib.rs");
include!("time-macros-impl/src/lib.rs");

macro_rules! other {
($name:ident) => {
#[my_macro] struct Three($name);
macro_rules! other {
($name:ident) => {
#[my_macro] struct Three($name);
}
}

struct Foo;
impl_macros!(Foo);
arrays!(Foo);
other!(Foo);
}

fn main() {
mod with_version {
include!("js-sys-0.3.17/src/lib.rs");
include!("time-macros-impl-0.1.0/src/lib.rs");

macro_rules! other {
($name:ident) => {
#[my_macro] struct Three($name);
}
}

struct Foo;
impl_macros!(Foo);
arrays!(Foo);
other!(Foo);
}


fn main() {}
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/time-macros-impl/src/lib.rs:5:21: 5:27 (#5) }, Ident { ident: "One", span: $DIR/time-macros-impl/src/lib.rs:5:28: 5:31 (#5) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:27:18: 27:21 (#0) }], span: $DIR/time-macros-impl/src/lib.rs:5:31: 5:38 (#5) }, Punct { ch: ';', spacing: Alone, span: $DIR/time-macros-impl/src/lib.rs:5:38: 5:39 (#5) }]
Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys/src/lib.rs:5:21: 5:27 (#9) }, Ident { ident: "Two", span: $DIR/js-sys/src/lib.rs:5:28: 5:31 (#9) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:28:13: 28:16 (#0) }], span: $DIR/js-sys/src/lib.rs:5:31: 5:38 (#9) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys/src/lib.rs:5:38: 5:39 (#9) }]
Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:21:21: 21:27 (#13) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:21:28: 21:33 (#13) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:29:12: 29:15 (#0) }], span: $DIR/group-compat-hack.rs:21:34: 21:39 (#13) }], span: $DIR/group-compat-hack.rs:21:33: 21:40 (#13) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:21:40: 21:41 (#13) }]
Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:22:25: 22:31 (#13) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:22:32: 22:37 (#13) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:29:12: 29:15 (#0) }], span: $DIR/group-compat-hack.rs:22:38: 22:43 (#13) }], span: $DIR/group-compat-hack.rs:22:37: 22:44 (#13) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:22:44: 22:45 (#13) }]
Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:21: 5:27 (#19) }, Ident { ident: "One", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:28: 5:31 (#19) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:43:18: 43:21 (#0) }], span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:31: 5:38 (#19) }, Punct { ch: ';', spacing: Alone, span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:38: 5:39 (#19) }]
Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys-0.3.17/src/lib.rs:5:21: 5:27 (#23) }, Ident { ident: "Two", span: $DIR/js-sys-0.3.17/src/lib.rs:5:28: 5:31 (#23) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:44:13: 44:16 (#0) }], span: $DIR/js-sys-0.3.17/src/lib.rs:5:31: 5:38 (#23) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys-0.3.17/src/lib.rs:5:38: 5:39 (#23) }]
Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:38:25: 38:31 (#27) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:38:32: 38:37 (#27) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:45:12: 45:15 (#0) }], span: $DIR/group-compat-hack.rs:38:38: 38:43 (#27) }], span: $DIR/group-compat-hack.rs:38:37: 38:44 (#27) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:38:44: 38:45 (#27) }]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// ignore-test this is not a test

macro_rules! arrays {
($name:ident) => {
#[my_macro] struct Two($name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// ignore-test this is not a test

macro_rules! impl_macros {
($name:ident) => {
#[my_macro] struct One($name);
}
}
12 changes: 12 additions & 0 deletions src/test/ui/try-block/try-block-in-return.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// run-pass
// compile-flags: --edition 2018

#![feature(try_blocks)]

fn issue_76271() -> Option<i32> {
return try { 4 }
}

fn main() {
assert_eq!(issue_76271(), Some(4));
}