Skip to content

Commit 82b8621

Browse files
committed
Auto merge of rust-lang#85588 - Mark-Simulacrum:beta-next, r=Mark-Simulacrum
[beta] backports * Backport 1.52.1 release notes rust-lang#85404 * remove InPlaceIterable marker from Peekable due to unsoundness rust-lang#85340 * rustdoc: Call initSidebarItems in root module of crate rust-lang#85304 * Update LLVM submodule rust-lang#85236 * Do not ICE on invalid const param rust-lang#84913 * Disallows #![feature(no_coverage)] on stable and beta (using standard crate-level gating) rust-lang#84871 * Ensure TLS destructors run before thread joins in SGX rust-lang#84409
2 parents 4bac69d + 0e49ff0 commit 82b8621

File tree

24 files changed

+294
-112
lines changed

24 files changed

+294
-112
lines changed

RELEASES.md

+21
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
Version 1.52.1 (2021-05-10)
2+
============================
3+
4+
This release disables incremental compilation, unless the user has explicitly
5+
opted in via the newly added RUSTC_FORCE_INCREMENTAL=1 environment variable.
6+
7+
This is due to the widespread, and frequently occuring, breakage encountered by
8+
Rust users due to newly enabled incremental verification in 1.52.0. Notably,
9+
Rust users **should** upgrade to 1.52.0 or 1.52.1: the bugs that are detected by
10+
newly added incremental verification are still present in past stable versions,
11+
and are not yet fixed on any channel. These bugs can lead to miscompilation of
12+
Rust binaries.
13+
14+
These problems only affect incremental builds, so release builds with Cargo
15+
should not be affected unless the user has explicitly opted into incremental.
16+
Debug and check builds are affected.
17+
18+
See [84970] for more details.
19+
20+
[84970]: https://github.com/rust-lang/rust/issues/84970
21+
122
Version 1.52.0 (2021-05-06)
223
============================
324

compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,12 @@ pub fn expand_deriving_eq(
1515
item: &Annotatable,
1616
push: &mut dyn FnMut(Annotatable),
1717
) {
18+
let span = cx.with_def_site_ctxt(span);
1819
let inline = cx.meta_word(span, sym::inline);
19-
let no_coverage_ident =
20-
rustc_ast::attr::mk_nested_word_item(Ident::new(sym::no_coverage, span));
21-
let no_coverage_feature =
22-
rustc_ast::attr::mk_list_item(Ident::new(sym::feature, span), vec![no_coverage_ident]);
23-
let no_coverage = cx.meta_word(span, sym::no_coverage);
2420
let hidden = rustc_ast::attr::mk_nested_word_item(Ident::new(sym::hidden, span));
2521
let doc = rustc_ast::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]);
26-
let attrs = vec![
27-
cx.attribute(inline),
28-
cx.attribute(no_coverage_feature),
29-
cx.attribute(no_coverage),
30-
cx.attribute(doc),
31-
];
22+
let no_coverage = cx.meta_word(span, sym::no_coverage);
23+
let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)];
3224
let trait_def = TraitDef {
3325
span,
3426
attributes: Vec::new(),

compiler/rustc_feature/src/builtin_attrs.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
273273
template!(List: "address, memory, thread"),
274274
experimental!(no_sanitize)
275275
),
276-
ungated!(
277-
// Not exclusively gated at the crate level (though crate-level is
278-
// supported). The feature can alternatively be enabled on individual
279-
// functions.
280-
no_coverage, AssumedUsed,
281-
template!(Word),
282-
),
276+
gated!(no_coverage, AssumedUsed, template!(Word), experimental!(no_coverage)),
283277

284278
// FIXME: #14408 assume docs are used since rustdoc looks at them.
285279
ungated!(doc, AssumedUsed, template!(List: "hidden|inline|...", NameValueStr: "string")),

compiler/rustc_typeck/src/collect.rs

+1-27
Original file line numberDiff line numberDiff line change
@@ -2661,8 +2661,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
26612661
let mut inline_span = None;
26622662
let mut link_ordinal_span = None;
26632663
let mut no_sanitize_span = None;
2664-
let mut no_coverage_feature_enabled = false;
2665-
let mut no_coverage_attr = None;
26662664
for attr in attrs.iter() {
26672665
if tcx.sess.check_name(attr, sym::cold) {
26682666
codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
@@ -2726,15 +2724,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
27262724
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED;
27272725
} else if tcx.sess.check_name(attr, sym::no_mangle) {
27282726
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
2729-
} else if attr.has_name(sym::feature) {
2730-
if let Some(list) = attr.meta_item_list() {
2731-
if list.iter().any(|nested_meta_item| nested_meta_item.has_name(sym::no_coverage)) {
2732-
tcx.sess.mark_attr_used(attr);
2733-
no_coverage_feature_enabled = true;
2734-
}
2735-
}
27362727
} else if tcx.sess.check_name(attr, sym::no_coverage) {
2737-
no_coverage_attr = Some(attr);
2728+
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE;
27382729
} else if tcx.sess.check_name(attr, sym::rustc_std_internal_symbol) {
27392730
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
27402731
} else if tcx.sess.check_name(attr, sym::used) {
@@ -2945,23 +2936,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
29452936
}
29462937
}
29472938

2948-
if let Some(no_coverage_attr) = no_coverage_attr {
2949-
if tcx.sess.features_untracked().no_coverage || no_coverage_feature_enabled {
2950-
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE
2951-
} else {
2952-
let mut err = feature_err(
2953-
&tcx.sess.parse_sess,
2954-
sym::no_coverage,
2955-
no_coverage_attr.span,
2956-
"the `#[no_coverage]` attribute is an experimental feature",
2957-
);
2958-
if tcx.sess.parse_sess.unstable_features.is_nightly_build() {
2959-
err.help("or, alternatively, add `#[feature(no_coverage)]` to the function");
2960-
}
2961-
err.emit();
2962-
}
2963-
}
2964-
29652939
codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
29662940
if !attr.has_name(sym::inline) {
29672941
return ia;

compiler/rustc_typeck/src/collect/type_of.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,25 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
191191
Res::Def(DefKind::Ctor(..), def_id) => {
192192
tcx.generics_of(tcx.parent(def_id).unwrap())
193193
}
194-
Res::Def(_, def_id) => tcx.generics_of(def_id),
194+
// Other `DefKind`s don't have generics and would ICE when calling
195+
// `generics_of`.
196+
Res::Def(
197+
DefKind::Struct
198+
| DefKind::Union
199+
| DefKind::Enum
200+
| DefKind::Variant
201+
| DefKind::Trait
202+
| DefKind::OpaqueTy
203+
| DefKind::TyAlias
204+
| DefKind::ForeignTy
205+
| DefKind::TraitAlias
206+
| DefKind::AssocTy
207+
| DefKind::Fn
208+
| DefKind::AssocFn
209+
| DefKind::AssocConst
210+
| DefKind::Impl,
211+
def_id,
212+
) => tcx.generics_of(def_id),
195213
Res::Err => {
196214
tcx.sess.delay_span_bug(tcx.def_span(def_id), "anon const with Res::Err");
197215
return None;

library/alloc/benches/vec.rs

-1
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,6 @@ fn bench_in_place_recycle(b: &mut Bencher) {
468468
.enumerate()
469469
.map(|(idx, e)| idx.wrapping_add(e))
470470
.fuse()
471-
.peekable()
472471
.collect::<Vec<usize>>(),
473472
);
474473
});

library/alloc/tests/vec.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,6 @@ fn test_from_iter_specialization_with_iterator_adapters() {
10021002
.zip(std::iter::repeat(1usize))
10031003
.map(|(a, b)| a + b)
10041004
.map_while(Option::Some)
1005-
.peekable()
10061005
.skip(1)
10071006
.map(|e| if e != usize::MAX { Ok(std::num::NonZeroUsize::new(e)) } else { Err(()) });
10081007
assert_in_place_trait(&iter);
@@ -1095,6 +1094,18 @@ fn test_from_iter_specialization_panic_during_drop_leaks() {
10951094
}
10961095
}
10971096

1097+
// regression test for issue #85322. Peekable previously implemented InPlaceIterable,
1098+
// but due to an interaction with IntoIter's current Clone implementation it failed to uphold
1099+
// the contract.
1100+
#[test]
1101+
fn test_collect_after_iterator_clone() {
1102+
let v = vec![0; 5];
1103+
let mut i = v.into_iter().map(|i| i + 1).peekable();
1104+
i.peek();
1105+
let v = i.clone().collect::<Vec<_>>();
1106+
assert_eq!(v, [1, 1, 1, 1, 1]);
1107+
assert!(v.len() <= v.capacity());
1108+
}
10981109
#[test]
10991110
fn test_cow_from() {
11001111
let borrowed: &[_] = &["borrowed", "(slice)"];

library/core/src/cmp.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,7 @@ pub trait Eq: PartialEq<Self> {
274274
//
275275
// This should never be implemented by hand.
276276
#[doc(hidden)]
277-
#[cfg_attr(not(bootstrap), feature(no_coverage))]
278-
#[cfg_attr(not(bootstrap), no_coverage)]
277+
#[cfg_attr(not(bootstrap), no_coverage)] // rust-lang/rust#84605
279278
#[inline]
280279
#[stable(feature = "rust1", since = "1.0.0")]
281280
fn assert_receiver_is_total_eq(&self) {}
@@ -284,7 +283,7 @@ pub trait Eq: PartialEq<Self> {
284283
/// Derive macro generating an impl of the trait `Eq`.
285284
#[rustc_builtin_macro]
286285
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
287-
#[allow_internal_unstable(core_intrinsics, derive_eq, structural_match)]
286+
#[allow_internal_unstable(core_intrinsics, derive_eq, structural_match, no_coverage)]
288287
pub macro Eq($item:item) {
289288
/* compiler built-in */
290289
}

library/core/src/iter/adapters/peekable.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen};
1+
use crate::iter::{adapters::SourceIter, FusedIterator, TrustedLen};
22
use crate::ops::Try;
33

44
/// An iterator with a `peek()` that returns an optional reference to the next
@@ -333,6 +333,3 @@ where
333333
unsafe { SourceIter::as_inner(&mut self.iter) }
334334
}
335335
}
336-
337-
#[unstable(issue = "none", feature = "inplace_iteration")]
338-
unsafe impl<I: InPlaceIterable> InPlaceIterable for Peekable<I> {}

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@
166166
#![feature(const_caller_location)]
167167
#![feature(slice_ptr_get)]
168168
#![feature(no_niche)] // rust-lang/rust#68303
169+
#![cfg_attr(not(bootstrap), feature(no_coverage))] // rust-lang/rust#84605
169170
#![feature(int_error_matching)]
170171
#![deny(unsafe_op_in_unsafe_fn)]
171172

library/std/src/sys/sgx/abi/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,12 @@ unsafe extern "C" fn tcs_init(secondary: bool) {
6262
extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> EntryReturn {
6363
// FIXME: how to support TLS in library mode?
6464
let tls = Box::new(tls::Tls::new());
65-
let _tls_guard = unsafe { tls.activate() };
65+
let tls_guard = unsafe { tls.activate() };
6666

6767
if secondary {
68-
super::thread::Thread::entry();
68+
let join_notifier = super::thread::Thread::entry();
69+
drop(tls_guard);
70+
drop(join_notifier);
6971

7072
EntryReturn(0, 0)
7173
} else {

library/std/src/sys/sgx/thread.rs

+61-8
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,37 @@ pub struct Thread(task_queue::JoinHandle);
99

1010
pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
1111

12+
pub use self::task_queue::JoinNotifier;
13+
1214
mod task_queue {
13-
use crate::sync::mpsc;
15+
use super::wait_notify;
1416
use crate::sync::{Mutex, MutexGuard, Once};
1517

16-
pub type JoinHandle = mpsc::Receiver<()>;
18+
pub type JoinHandle = wait_notify::Waiter;
19+
20+
pub struct JoinNotifier(Option<wait_notify::Notifier>);
21+
22+
impl Drop for JoinNotifier {
23+
fn drop(&mut self) {
24+
self.0.take().unwrap().notify();
25+
}
26+
}
1727

1828
pub(super) struct Task {
1929
p: Box<dyn FnOnce()>,
20-
done: mpsc::Sender<()>,
30+
done: JoinNotifier,
2131
}
2232

2333
impl Task {
2434
pub(super) fn new(p: Box<dyn FnOnce()>) -> (Task, JoinHandle) {
25-
let (done, recv) = mpsc::channel();
35+
let (done, recv) = wait_notify::new();
36+
let done = JoinNotifier(Some(done));
2637
(Task { p, done }, recv)
2738
}
2839

29-
pub(super) fn run(self) {
40+
pub(super) fn run(self) -> JoinNotifier {
3041
(self.p)();
31-
let _ = self.done.send(());
42+
self.done
3243
}
3344
}
3445

@@ -47,6 +58,48 @@ mod task_queue {
4758
}
4859
}
4960

61+
/// This module provides a synchronization primitive that does not use thread
62+
/// local variables. This is needed for signaling that a thread has finished
63+
/// execution. The signal is sent once all TLS destructors have finished at
64+
/// which point no new thread locals should be created.
65+
pub mod wait_notify {
66+
use super::super::waitqueue::{SpinMutex, WaitQueue, WaitVariable};
67+
use crate::sync::Arc;
68+
69+
pub struct Notifier(Arc<SpinMutex<WaitVariable<bool>>>);
70+
71+
impl Notifier {
72+
/// Notify the waiter. The waiter is either notified right away (if
73+
/// currently blocked in `Waiter::wait()`) or later when it calls the
74+
/// `Waiter::wait()` method.
75+
pub fn notify(self) {
76+
let mut guard = self.0.lock();
77+
*guard.lock_var_mut() = true;
78+
let _ = WaitQueue::notify_one(guard);
79+
}
80+
}
81+
82+
pub struct Waiter(Arc<SpinMutex<WaitVariable<bool>>>);
83+
84+
impl Waiter {
85+
/// Wait for a notification. If `Notifier::notify()` has already been
86+
/// called, this will return immediately, otherwise the current thread
87+
/// is blocked until notified.
88+
pub fn wait(self) {
89+
let guard = self.0.lock();
90+
if *guard.lock_var() {
91+
return;
92+
}
93+
WaitQueue::wait(guard, || {});
94+
}
95+
}
96+
97+
pub fn new() -> (Notifier, Waiter) {
98+
let inner = Arc::new(SpinMutex::new(WaitVariable::new(false)));
99+
(Notifier(inner.clone()), Waiter(inner))
100+
}
101+
}
102+
50103
impl Thread {
51104
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
52105
pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
@@ -57,7 +110,7 @@ impl Thread {
57110
Ok(Thread(handle))
58111
}
59112

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

80133
pub fn join(self) {
81-
let _ = self.0.recv();
134+
self.0.wait();
82135
}
83136
}
84137

0 commit comments

Comments
 (0)