Skip to content

Commit

Permalink
Auto merge of #85588 - Mark-Simulacrum:beta-next, r=Mark-Simulacrum
Browse files Browse the repository at this point in the history
[beta] backports

 * Backport 1.52.1 release notes #85404
 * remove InPlaceIterable marker from Peekable due to unsoundness #85340
 * rustdoc: Call initSidebarItems in root module of crate #85304
 * Update LLVM submodule #85236
 * Do not ICE on invalid const param #84913
 * Disallows #![feature(no_coverage)] on stable and beta (using standard crate-level gating) #84871
 * Ensure TLS destructors run before thread joins in SGX #84409
  • Loading branch information
bors committed May 22, 2021
2 parents 4bac69d + 0e49ff0 commit 82b8621
Show file tree
Hide file tree
Showing 24 changed files with 294 additions and 112 deletions.
21 changes: 21 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
Version 1.52.1 (2021-05-10)
============================

This release disables incremental compilation, unless the user has explicitly
opted in via the newly added RUSTC_FORCE_INCREMENTAL=1 environment variable.

This is due to the widespread, and frequently occuring, breakage encountered by
Rust users due to newly enabled incremental verification in 1.52.0. Notably,
Rust users **should** upgrade to 1.52.0 or 1.52.1: the bugs that are detected by
newly added incremental verification are still present in past stable versions,
and are not yet fixed on any channel. These bugs can lead to miscompilation of
Rust binaries.

These problems only affect incremental builds, so release builds with Cargo
should not be affected unless the user has explicitly opted into incremental.
Debug and check builds are affected.

See [84970] for more details.

[84970]: https://github.com/rust-lang/rust/issues/84970

Version 1.52.0 (2021-05-06)
============================

Expand Down
14 changes: 3 additions & 11 deletions compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,12 @@ pub fn expand_deriving_eq(
item: &Annotatable,
push: &mut dyn FnMut(Annotatable),
) {
let span = cx.with_def_site_ctxt(span);
let inline = cx.meta_word(span, sym::inline);
let no_coverage_ident =
rustc_ast::attr::mk_nested_word_item(Ident::new(sym::no_coverage, span));
let no_coverage_feature =
rustc_ast::attr::mk_list_item(Ident::new(sym::feature, span), vec![no_coverage_ident]);
let no_coverage = cx.meta_word(span, sym::no_coverage);
let hidden = rustc_ast::attr::mk_nested_word_item(Ident::new(sym::hidden, span));
let doc = rustc_ast::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]);
let attrs = vec![
cx.attribute(inline),
cx.attribute(no_coverage_feature),
cx.attribute(no_coverage),
cx.attribute(doc),
];
let no_coverage = cx.meta_word(span, sym::no_coverage);
let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)];
let trait_def = TraitDef {
span,
attributes: Vec::new(),
Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,13 +273,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
template!(List: "address, memory, thread"),
experimental!(no_sanitize)
),
ungated!(
// Not exclusively gated at the crate level (though crate-level is
// supported). The feature can alternatively be enabled on individual
// functions.
no_coverage, AssumedUsed,
template!(Word),
),
gated!(no_coverage, AssumedUsed, template!(Word), experimental!(no_coverage)),

// FIXME: #14408 assume docs are used since rustdoc looks at them.
ungated!(doc, AssumedUsed, template!(List: "hidden|inline|...", NameValueStr: "string")),
Expand Down
28 changes: 1 addition & 27 deletions compiler/rustc_typeck/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2661,8 +2661,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
let mut inline_span = None;
let mut link_ordinal_span = None;
let mut no_sanitize_span = None;
let mut no_coverage_feature_enabled = false;
let mut no_coverage_attr = None;
for attr in attrs.iter() {
if tcx.sess.check_name(attr, sym::cold) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
Expand Down Expand Up @@ -2726,15 +2724,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED;
} else if tcx.sess.check_name(attr, sym::no_mangle) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
} else if attr.has_name(sym::feature) {
if let Some(list) = attr.meta_item_list() {
if list.iter().any(|nested_meta_item| nested_meta_item.has_name(sym::no_coverage)) {
tcx.sess.mark_attr_used(attr);
no_coverage_feature_enabled = true;
}
}
} else if tcx.sess.check_name(attr, sym::no_coverage) {
no_coverage_attr = Some(attr);
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE;
} else if tcx.sess.check_name(attr, sym::rustc_std_internal_symbol) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
} else if tcx.sess.check_name(attr, sym::used) {
Expand Down Expand Up @@ -2945,23 +2936,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
}
}

if let Some(no_coverage_attr) = no_coverage_attr {
if tcx.sess.features_untracked().no_coverage || no_coverage_feature_enabled {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE
} else {
let mut err = feature_err(
&tcx.sess.parse_sess,
sym::no_coverage,
no_coverage_attr.span,
"the `#[no_coverage]` attribute is an experimental feature",
);
if tcx.sess.parse_sess.unstable_features.is_nightly_build() {
err.help("or, alternatively, add `#[feature(no_coverage)]` to the function");
}
err.emit();
}
}

codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
if !attr.has_name(sym::inline) {
return ia;
Expand Down
20 changes: 19 additions & 1 deletion compiler/rustc_typeck/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,25 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
Res::Def(DefKind::Ctor(..), def_id) => {
tcx.generics_of(tcx.parent(def_id).unwrap())
}
Res::Def(_, def_id) => tcx.generics_of(def_id),
// Other `DefKind`s don't have generics and would ICE when calling
// `generics_of`.
Res::Def(
DefKind::Struct
| DefKind::Union
| DefKind::Enum
| DefKind::Variant
| DefKind::Trait
| DefKind::OpaqueTy
| DefKind::TyAlias
| DefKind::ForeignTy
| DefKind::TraitAlias
| DefKind::AssocTy
| DefKind::Fn
| DefKind::AssocFn
| DefKind::AssocConst
| DefKind::Impl,
def_id,
) => tcx.generics_of(def_id),
Res::Err => {
tcx.sess.delay_span_bug(tcx.def_span(def_id), "anon const with Res::Err");
return None;
Expand Down
1 change: 0 additions & 1 deletion library/alloc/benches/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,6 @@ fn bench_in_place_recycle(b: &mut Bencher) {
.enumerate()
.map(|(idx, e)| idx.wrapping_add(e))
.fuse()
.peekable()
.collect::<Vec<usize>>(),
);
});
Expand Down
13 changes: 12 additions & 1 deletion library/alloc/tests/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,6 @@ fn test_from_iter_specialization_with_iterator_adapters() {
.zip(std::iter::repeat(1usize))
.map(|(a, b)| a + b)
.map_while(Option::Some)
.peekable()
.skip(1)
.map(|e| if e != usize::MAX { Ok(std::num::NonZeroUsize::new(e)) } else { Err(()) });
assert_in_place_trait(&iter);
Expand Down Expand Up @@ -1095,6 +1094,18 @@ fn test_from_iter_specialization_panic_during_drop_leaks() {
}
}

// regression test for issue #85322. Peekable previously implemented InPlaceIterable,
// but due to an interaction with IntoIter's current Clone implementation it failed to uphold
// the contract.
#[test]
fn test_collect_after_iterator_clone() {
let v = vec![0; 5];
let mut i = v.into_iter().map(|i| i + 1).peekable();
i.peek();
let v = i.clone().collect::<Vec<_>>();
assert_eq!(v, [1, 1, 1, 1, 1]);
assert!(v.len() <= v.capacity());
}
#[test]
fn test_cow_from() {
let borrowed: &[_] = &["borrowed", "(slice)"];
Expand Down
5 changes: 2 additions & 3 deletions library/core/src/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,7 @@ pub trait Eq: PartialEq<Self> {
//
// This should never be implemented by hand.
#[doc(hidden)]
#[cfg_attr(not(bootstrap), feature(no_coverage))]
#[cfg_attr(not(bootstrap), no_coverage)]
#[cfg_attr(not(bootstrap), no_coverage)] // rust-lang/rust#84605
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn assert_receiver_is_total_eq(&self) {}
Expand All @@ -284,7 +283,7 @@ pub trait Eq: PartialEq<Self> {
/// Derive macro generating an impl of the trait `Eq`.
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics, derive_eq, structural_match)]
#[allow_internal_unstable(core_intrinsics, derive_eq, structural_match, no_coverage)]
pub macro Eq($item:item) {
/* compiler built-in */
}
Expand Down
5 changes: 1 addition & 4 deletions library/core/src/iter/adapters/peekable.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen};
use crate::iter::{adapters::SourceIter, FusedIterator, TrustedLen};
use crate::ops::Try;

/// An iterator with a `peek()` that returns an optional reference to the next
Expand Down Expand Up @@ -333,6 +333,3 @@ where
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}

#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable> InPlaceIterable for Peekable<I> {}
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@
#![feature(const_caller_location)]
#![feature(slice_ptr_get)]
#![feature(no_niche)] // rust-lang/rust#68303
#![cfg_attr(not(bootstrap), feature(no_coverage))] // rust-lang/rust#84605
#![feature(int_error_matching)]
#![deny(unsafe_op_in_unsafe_fn)]

Expand Down
6 changes: 4 additions & 2 deletions library/std/src/sys/sgx/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,12 @@ unsafe extern "C" fn tcs_init(secondary: bool) {
extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> EntryReturn {
// FIXME: how to support TLS in library mode?
let tls = Box::new(tls::Tls::new());
let _tls_guard = unsafe { tls.activate() };
let tls_guard = unsafe { tls.activate() };

if secondary {
super::thread::Thread::entry();
let join_notifier = super::thread::Thread::entry();
drop(tls_guard);
drop(join_notifier);

EntryReturn(0, 0)
} else {
Expand Down
69 changes: 61 additions & 8 deletions library/std/src/sys/sgx/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,37 @@ pub struct Thread(task_queue::JoinHandle);

pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;

pub use self::task_queue::JoinNotifier;

mod task_queue {
use crate::sync::mpsc;
use super::wait_notify;
use crate::sync::{Mutex, MutexGuard, Once};

pub type JoinHandle = mpsc::Receiver<()>;
pub type JoinHandle = wait_notify::Waiter;

pub struct JoinNotifier(Option<wait_notify::Notifier>);

impl Drop for JoinNotifier {
fn drop(&mut self) {
self.0.take().unwrap().notify();
}
}

pub(super) struct Task {
p: Box<dyn FnOnce()>,
done: mpsc::Sender<()>,
done: JoinNotifier,
}

impl Task {
pub(super) fn new(p: Box<dyn FnOnce()>) -> (Task, JoinHandle) {
let (done, recv) = mpsc::channel();
let (done, recv) = wait_notify::new();
let done = JoinNotifier(Some(done));
(Task { p, done }, recv)
}

pub(super) fn run(self) {
pub(super) fn run(self) -> JoinNotifier {
(self.p)();
let _ = self.done.send(());
self.done
}
}

Expand All @@ -47,6 +58,48 @@ mod task_queue {
}
}

/// This module provides a synchronization primitive that does not use thread
/// local variables. This is needed for signaling that a thread has finished
/// execution. The signal is sent once all TLS destructors have finished at
/// which point no new thread locals should be created.
pub mod wait_notify {
use super::super::waitqueue::{SpinMutex, WaitQueue, WaitVariable};
use crate::sync::Arc;

pub struct Notifier(Arc<SpinMutex<WaitVariable<bool>>>);

impl Notifier {
/// Notify the waiter. The waiter is either notified right away (if
/// currently blocked in `Waiter::wait()`) or later when it calls the
/// `Waiter::wait()` method.
pub fn notify(self) {
let mut guard = self.0.lock();
*guard.lock_var_mut() = true;
let _ = WaitQueue::notify_one(guard);
}
}

pub struct Waiter(Arc<SpinMutex<WaitVariable<bool>>>);

impl Waiter {
/// Wait for a notification. If `Notifier::notify()` has already been
/// called, this will return immediately, otherwise the current thread
/// is blocked until notified.
pub fn wait(self) {
let guard = self.0.lock();
if *guard.lock_var() {
return;
}
WaitQueue::wait(guard, || {});
}
}

pub fn new() -> (Notifier, Waiter) {
let inner = Arc::new(SpinMutex::new(WaitVariable::new(false)));
(Notifier(inner.clone()), Waiter(inner))
}
}

impl Thread {
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
Expand All @@ -57,7 +110,7 @@ impl Thread {
Ok(Thread(handle))
}

pub(super) fn entry() {
pub(super) fn entry() -> JoinNotifier {
let mut pending_tasks = task_queue::lock();
let task = rtunwrap!(Some, pending_tasks.pop());
drop(pending_tasks); // make sure to not hold the task queue lock longer than necessary
Expand All @@ -78,7 +131,7 @@ impl Thread {
}

pub fn join(self) {
let _ = self.0.recv();
self.0.wait();
}
}

Expand Down
Loading

0 comments on commit 82b8621

Please sign in to comment.