Skip to content

Commit b7a6d74

Browse files
committed
Auto merge of rust-lang#107071 - Mark-Simulacrum:beta-next, r=Mark-Simulacrum
[beta] backport rollup * Revert "Make nested RPITIT inherit the parent opaque's generics." rust-lang#106759 * Fix mpsc::SyncSender spinning behavior rust-lang#106701 * rustdoc: fix outdated lint section of the book rust-lang#106605 * Do not filter substs in remap_generic_params_to_declaration_params. rust-lang#106503 * Correct detection of elided lifetimes in impl-trait. rust-lang#106501 * Bump rust-installer rust-lang#106196 * Don't panic on stable since miri is not available there rust-lang#105901
2 parents 7a9ae0c + 8669f7e commit b7a6d74

File tree

18 files changed

+127
-71
lines changed

18 files changed

+127
-71
lines changed

Diff for: compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
250250
}
251251

252252
let definition_ty = instantiated_ty
253-
.remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false, origin)
253+
.remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false)
254254
.ty;
255255

256256
if !check_opaque_type_parameter_valid(

Diff for: compiler/rustc_hir_analysis/src/collect/generics_of.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use hir::{
44
GenericParamKind, HirId, Node,
55
};
66
use rustc_hir as hir;
7+
use rustc_hir::def::DefKind;
78
use rustc_hir::def_id::DefId;
89
use rustc_middle::ty::{self, TyCtxt};
910
use rustc_session::lint;
@@ -142,7 +143,20 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
142143
Some(tcx.typeck_root_def_id(def_id))
143144
}
144145
Node::Item(item) => match item.kind {
145-
ItemKind::OpaqueTy(hir::OpaqueTy { .. }) => {
146+
ItemKind::OpaqueTy(hir::OpaqueTy {
147+
origin:
148+
hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
149+
in_trait,
150+
..
151+
}) => {
152+
if in_trait {
153+
assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn))
154+
} else {
155+
assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn))
156+
}
157+
Some(fn_def_id.to_def_id())
158+
}
159+
ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
146160
let parent_id = tcx.hir().get_parent_item(hir_id);
147161
assert_ne!(parent_id, hir::CRATE_OWNER_ID);
148162
debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id);

Diff for: compiler/rustc_hir_analysis/src/collect/lifetimes.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1195,8 +1195,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
11951195
// Fresh lifetimes in APIT used to be allowed in async fns and forbidden in
11961196
// regular fns.
11971197
if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin
1198-
&& let hir::LifetimeName::Param(_) = lifetime_ref.res
1199-
&& lifetime_ref.is_anonymous()
1198+
&& let hir::LifetimeName::Param(param_id) = lifetime_ref.res
1199+
&& let Some(generics) = self.tcx.hir().get_generics(self.tcx.local_parent(param_id))
1200+
&& let Some(param) = generics.params.iter().find(|p| p.def_id == param_id)
1201+
&& param.is_elided_lifetime()
12001202
&& let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id)
12011203
&& !self.tcx.features().anonymous_lifetime_in_impl_trait
12021204
{

Diff for: compiler/rustc_hir_typeck/src/writeback.rs

-1
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
565565
opaque_type_key,
566566
self.fcx.infcx.tcx,
567567
true,
568-
decl.origin,
569568
);
570569

571570
self.typeck_results.concrete_opaque_types.insert(opaque_type_key.def_id, hidden_type);

Diff for: compiler/rustc_middle/src/ty/mod.rs

+1-26
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ use crate::ty::util::Discr;
2828
pub use adt::*;
2929
pub use assoc::*;
3030
pub use generics::*;
31-
use hir::OpaqueTyOrigin;
3231
use rustc_ast as ast;
3332
use rustc_ast::node_id::NodeMap;
3433
use rustc_attr as attr;
@@ -1287,7 +1286,6 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
12871286
tcx: TyCtxt<'tcx>,
12881287
// typeck errors have subpar spans for opaque types, so delay error reporting until borrowck.
12891288
ignore_errors: bool,
1290-
origin: OpaqueTyOrigin,
12911289
) -> Self {
12921290
let OpaqueTypeKey { def_id, substs } = opaque_type_key;
12931291

@@ -1303,30 +1301,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
13031301
// This zip may have several times the same lifetime in `substs` paired with a different
13041302
// lifetime from `id_substs`. Simply `collect`ing the iterator is the correct behaviour:
13051303
// it will pick the last one, which is the one we introduced in the impl-trait desugaring.
1306-
let map = substs.iter().zip(id_substs);
1307-
1308-
let map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>> = match origin {
1309-
// HACK: The HIR lowering for async fn does not generate
1310-
// any `+ Captures<'x>` bounds for the `impl Future<...>`, so all async fns with lifetimes
1311-
// would now fail to compile. We should probably just make hir lowering fill this in properly.
1312-
OpaqueTyOrigin::AsyncFn(_) => map.collect(),
1313-
OpaqueTyOrigin::FnReturn(_) | OpaqueTyOrigin::TyAlias => {
1314-
// Opaque types may only use regions that are bound. So for
1315-
// ```rust
1316-
// type Foo<'a, 'b, 'c> = impl Trait<'a> + 'b;
1317-
// ```
1318-
// we may not use `'c` in the hidden type.
1319-
let variances = tcx.variances_of(def_id);
1320-
debug!(?variances);
1321-
1322-
map.filter(|(_, v)| {
1323-
let ty::GenericArgKind::Lifetime(lt) = v.unpack() else { return true };
1324-
let ty::ReEarlyBound(ebr) = lt.kind() else { bug!() };
1325-
variances[ebr.index as usize] == ty::Variance::Invariant
1326-
})
1327-
.collect()
1328-
}
1329-
};
1304+
let map = substs.iter().zip(id_substs).collect();
13301305
debug!("map = {:#?}", map);
13311306

13321307
// Convert the type from the function into a type valid outside

Diff for: library/std/src/sync/mpmc/array.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ impl<T> Channel<T> {
168168
return true;
169169
}
170170
Err(_) => {
171-
backoff.spin();
171+
backoff.spin_light();
172172
tail = self.tail.load(Ordering::Relaxed);
173173
}
174174
}
@@ -182,11 +182,11 @@ impl<T> Channel<T> {
182182
return false;
183183
}
184184

185-
backoff.spin();
185+
backoff.spin_light();
186186
tail = self.tail.load(Ordering::Relaxed);
187187
} else {
188188
// Snooze because we need to wait for the stamp to get updated.
189-
backoff.snooze();
189+
backoff.spin_heavy();
190190
tail = self.tail.load(Ordering::Relaxed);
191191
}
192192
}
@@ -251,7 +251,7 @@ impl<T> Channel<T> {
251251
return true;
252252
}
253253
Err(_) => {
254-
backoff.spin();
254+
backoff.spin_light();
255255
head = self.head.load(Ordering::Relaxed);
256256
}
257257
}
@@ -273,11 +273,11 @@ impl<T> Channel<T> {
273273
}
274274
}
275275

276-
backoff.spin();
276+
backoff.spin_light();
277277
head = self.head.load(Ordering::Relaxed);
278278
} else {
279279
// Snooze because we need to wait for the stamp to get updated.
280-
backoff.snooze();
280+
backoff.spin_heavy();
281281
head = self.head.load(Ordering::Relaxed);
282282
}
283283
}
@@ -330,7 +330,7 @@ impl<T> Channel<T> {
330330
if backoff.is_completed() {
331331
break;
332332
} else {
333-
backoff.spin();
333+
backoff.spin_light();
334334
}
335335
}
336336

Diff for: library/std/src/sync/mpmc/list.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl<T> Slot<T> {
4646
fn wait_write(&self) {
4747
let backoff = Backoff::new();
4848
while self.state.load(Ordering::Acquire) & WRITE == 0 {
49-
backoff.snooze();
49+
backoff.spin_heavy();
5050
}
5151
}
5252
}
@@ -82,7 +82,7 @@ impl<T> Block<T> {
8282
if !next.is_null() {
8383
return next;
8484
}
85-
backoff.snooze();
85+
backoff.spin_heavy();
8686
}
8787
}
8888

@@ -191,7 +191,7 @@ impl<T> Channel<T> {
191191

192192
// If we reached the end of the block, wait until the next one is installed.
193193
if offset == BLOCK_CAP {
194-
backoff.snooze();
194+
backoff.spin_heavy();
195195
tail = self.tail.index.load(Ordering::Acquire);
196196
block = self.tail.block.load(Ordering::Acquire);
197197
continue;
@@ -247,7 +247,7 @@ impl<T> Channel<T> {
247247
return true;
248248
},
249249
Err(_) => {
250-
backoff.spin();
250+
backoff.spin_light();
251251
tail = self.tail.index.load(Ordering::Acquire);
252252
block = self.tail.block.load(Ordering::Acquire);
253253
}
@@ -286,7 +286,7 @@ impl<T> Channel<T> {
286286

287287
// If we reached the end of the block, wait until the next one is installed.
288288
if offset == BLOCK_CAP {
289-
backoff.snooze();
289+
backoff.spin_heavy();
290290
head = self.head.index.load(Ordering::Acquire);
291291
block = self.head.block.load(Ordering::Acquire);
292292
continue;
@@ -320,7 +320,7 @@ impl<T> Channel<T> {
320320
// The block can be null here only if the first message is being sent into the channel.
321321
// In that case, just wait until it gets initialized.
322322
if block.is_null() {
323-
backoff.snooze();
323+
backoff.spin_heavy();
324324
head = self.head.index.load(Ordering::Acquire);
325325
block = self.head.block.load(Ordering::Acquire);
326326
continue;
@@ -351,7 +351,7 @@ impl<T> Channel<T> {
351351
return true;
352352
},
353353
Err(_) => {
354-
backoff.spin();
354+
backoff.spin_light();
355355
head = self.head.index.load(Ordering::Acquire);
356356
block = self.head.block.load(Ordering::Acquire);
357357
}
@@ -542,7 +542,7 @@ impl<T> Channel<T> {
542542
// New updates to tail will be rejected by MARK_BIT and aborted unless it's
543543
// at boundary. We need to wait for the updates take affect otherwise there
544544
// can be memory leaks.
545-
backoff.snooze();
545+
backoff.spin_heavy();
546546
tail = self.tail.index.load(Ordering::Acquire);
547547
}
548548

Diff for: library/std/src/sync/mpmc/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ mod zero;
4343
use crate::fmt;
4444
use crate::panic::{RefUnwindSafe, UnwindSafe};
4545
use crate::time::{Duration, Instant};
46-
use error::*;
46+
pub use error::*;
4747

4848
/// Creates a channel of unbounded capacity.
4949
///

Diff for: library/std/src/sync/mpmc/utils.rs

+15-16
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,8 @@ impl<T> DerefMut for CachePadded<T> {
9191
}
9292

9393
const SPIN_LIMIT: u32 = 6;
94-
const YIELD_LIMIT: u32 = 10;
9594

96-
/// Performs exponential backoff in spin loops.
95+
/// Performs quadratic backoff in spin loops.
9796
pub struct Backoff {
9897
step: Cell<u32>,
9998
}
@@ -104,25 +103,27 @@ impl Backoff {
104103
Backoff { step: Cell::new(0) }
105104
}
106105

107-
/// Backs off in a lock-free loop.
106+
/// Backs off using lightweight spinning.
108107
///
109-
/// This method should be used when we need to retry an operation because another thread made
110-
/// progress.
108+
/// This method should be used for:
109+
/// - Retrying an operation because another thread made progress. i.e. on CAS failure.
110+
/// - Waiting for an operation to complete by spinning optimistically for a few iterations
111+
/// before falling back to parking the thread (see `Backoff::is_completed`).
111112
#[inline]
112-
pub fn spin(&self) {
113+
pub fn spin_light(&self) {
113114
let step = self.step.get().min(SPIN_LIMIT);
114115
for _ in 0..step.pow(2) {
115116
crate::hint::spin_loop();
116117
}
117118

118-
if self.step.get() <= SPIN_LIMIT {
119-
self.step.set(self.step.get() + 1);
120-
}
119+
self.step.set(self.step.get() + 1);
121120
}
122121

123-
/// Backs off in a blocking loop.
122+
/// Backs off using heavyweight spinning.
123+
///
124+
/// This method should be used in blocking loops where parking the thread is not an option.
124125
#[inline]
125-
pub fn snooze(&self) {
126+
pub fn spin_heavy(&self) {
126127
if self.step.get() <= SPIN_LIMIT {
127128
for _ in 0..self.step.get().pow(2) {
128129
crate::hint::spin_loop()
@@ -131,14 +132,12 @@ impl Backoff {
131132
crate::thread::yield_now();
132133
}
133134

134-
if self.step.get() <= YIELD_LIMIT {
135-
self.step.set(self.step.get() + 1);
136-
}
135+
self.step.set(self.step.get() + 1);
137136
}
138137

139-
/// Returns `true` if exponential backoff has completed and blocking the thread is advised.
138+
/// Returns `true` if quadratic backoff has completed and parking the thread is advised.
140139
#[inline]
141140
pub fn is_completed(&self) -> bool {
142-
self.step.get() > YIELD_LIMIT
141+
self.step.get() > SPIN_LIMIT
143142
}
144143
}

Diff for: library/std/src/sync/mpmc/zero.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl<T> Packet<T> {
5757
fn wait_ready(&self) {
5858
let backoff = Backoff::new();
5959
while !self.ready.load(Ordering::Acquire) {
60-
backoff.snooze();
60+
backoff.spin_heavy();
6161
}
6262
}
6363
}

Diff for: library/std/src/sync/mpsc/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,15 @@ impl<T> SyncSender<T> {
738738
pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
739739
self.inner.try_send(t)
740740
}
741+
742+
// Attempts to send for a value on this receiver, returning an error if the
743+
// corresponding channel has hung up, or if it waits more than `timeout`.
744+
//
745+
// This method is currently private and only used for tests.
746+
#[allow(unused)]
747+
fn send_timeout(&self, t: T, timeout: Duration) -> Result<(), mpmc::SendTimeoutError<T>> {
748+
self.inner.send_timeout(t, timeout)
749+
}
741750
}
742751

743752
#[stable(feature = "rust1", since = "1.0.0")]

Diff for: library/std/src/sync/mpsc/sync_tests.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::*;
22
use crate::env;
3+
use crate::sync::mpmc::SendTimeoutError;
34
use crate::thread;
45
use crate::time::Duration;
56

@@ -41,6 +42,13 @@ fn recv_timeout() {
4142
assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(1));
4243
}
4344

45+
#[test]
46+
fn send_timeout() {
47+
let (tx, _rx) = sync_channel::<i32>(1);
48+
assert_eq!(tx.send_timeout(1, Duration::from_millis(1)), Ok(()));
49+
assert_eq!(tx.send_timeout(1, Duration::from_millis(1)), Err(SendTimeoutError::Timeout(1)));
50+
}
51+
4452
#[test]
4553
fn smoke_threads() {
4654
let (tx, rx) = sync_channel::<i32>(0);

Diff for: src/bootstrap/install.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,14 @@ install!((self, builder, _config),
200200
install_sh(builder, "clippy", self.compiler.stage, Some(self.target), &tarball);
201201
};
202202
Miri, alias = "miri", Self::should_build(_config), only_hosts: true, {
203-
let tarball = builder
204-
.ensure(dist::Miri { compiler: self.compiler, target: self.target })
205-
.expect("missing miri");
206-
install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball);
203+
if let Some(tarball) = builder.ensure(dist::Miri { compiler: self.compiler, target: self.target }) {
204+
install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball);
205+
} else {
206+
// Miri is only available on nightly
207+
builder.info(
208+
&format!("skipping Install miri stage{} ({})", self.compiler.stage, self.target),
209+
);
210+
}
207211
};
208212
Rustfmt, alias = "rustfmt", Self::should_build(_config), only_hosts: true, {
209213
if let Some(tarball) = builder.ensure(dist::Rustfmt {

Diff for: src/doc/rustdoc/src/lints.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ typo mistakes for some common attributes.
261261

262262
## `invalid_html_tags`
263263

264-
This lint is **allowed by default** and is **nightly-only**. It detects unclosed
264+
This lint **warns by default**. It detects unclosed
265265
or invalid HTML tags. For example:
266266

267267
```rust

Diff for: src/test/ui/async-await/in-trait/nested-rpit.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
// check-pass
21
// edition: 2021
2+
// known-bug: #105197
3+
// failure-status:101
4+
// dont-check-compiler-stderr
35

46
#![feature(async_fn_in_trait)]
57
#![feature(return_position_impl_trait_in_trait)]

0 commit comments

Comments
 (0)