Skip to content

Commit edaf9ce

Browse files
committed
Prereq2 for async drop - ResumedAfterDrop panic messages
1 parent f954f0c commit edaf9ce

File tree

12 files changed

+133
-51
lines changed

12 files changed

+133
-51
lines changed

compiler/rustc_const_eval/src/const_eval/machine.rs

+1
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
570570
RemainderByZero(op) => RemainderByZero(eval_to_int(op)?),
571571
ResumedAfterReturn(coroutine_kind) => ResumedAfterReturn(*coroutine_kind),
572572
ResumedAfterPanic(coroutine_kind) => ResumedAfterPanic(*coroutine_kind),
573+
ResumedAfterDrop(coroutine_kind) => ResumedAfterDrop(*coroutine_kind),
573574
MisalignedPointerDereference { ref required, ref found } => {
574575
MisalignedPointerDereference {
575576
required: eval_to_int(required)?,

compiler/rustc_hir/src/lang_items.rs

+4
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,10 @@ language_item_table! {
306306
PanicAsyncFnResumedPanic, sym::panic_const_async_fn_resumed_panic, panic_const_async_fn_resumed_panic, Target::Fn, GenericRequirement::None;
307307
PanicAsyncGenFnResumedPanic, sym::panic_const_async_gen_fn_resumed_panic, panic_const_async_gen_fn_resumed_panic, Target::Fn, GenericRequirement::None;
308308
PanicGenFnNonePanic, sym::panic_const_gen_fn_none_panic, panic_const_gen_fn_none_panic, Target::Fn, GenericRequirement::None;
309+
PanicCoroutineResumedDrop, sym::panic_const_coroutine_resumed_drop, panic_const_coroutine_resumed_drop, Target::Fn, GenericRequirement::None;
310+
PanicAsyncFnResumedDrop, sym::panic_const_async_fn_resumed_drop, panic_const_async_fn_resumed_drop, Target::Fn, GenericRequirement::None;
311+
PanicAsyncGenFnResumedDrop, sym::panic_const_async_gen_fn_resumed_drop, panic_const_async_gen_fn_resumed_drop, Target::Fn, GenericRequirement::None;
312+
PanicGenFnNoneDrop, sym::panic_const_gen_fn_none_drop, panic_const_gen_fn_none_drop, Target::Fn, GenericRequirement::None;
309313
/// libstd panic entry point. Necessary for const eval to be able to catch it
310314
BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None;
311315

compiler/rustc_middle/messages.ftl

+6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
middle_adjust_for_foreign_abi_error =
22
target architecture {$arch} does not support `extern {$abi}` ABI
33
4+
middle_assert_async_resume_after_drop = `async fn` resumed after async drop
5+
46
middle_assert_async_resume_after_panic = `async fn` resumed after panicking
57
68
middle_assert_async_resume_after_return = `async fn` resumed after completion
79
10+
middle_assert_coroutine_resume_after_drop = coroutine resumed after async drop
11+
812
middle_assert_coroutine_resume_after_panic = coroutine resumed after panicking
913
1014
middle_assert_coroutine_resume_after_return = coroutine resumed after completion
1115
1216
middle_assert_divide_by_zero =
1317
attempt to divide `{$val}` by zero
1418
19+
middle_assert_gen_resume_after_drop = `gen` fn or block cannot be further iterated on after it async dropped
20+
1521
middle_assert_gen_resume_after_panic = `gen` fn or block cannot be further iterated on after it panicked
1622
1723
middle_assert_misaligned_ptr_deref =

compiler/rustc_middle/src/mir/syntax.rs

+1
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,7 @@ pub enum AssertKind<O> {
997997
RemainderByZero(O),
998998
ResumedAfterReturn(CoroutineKind),
999999
ResumedAfterPanic(CoroutineKind),
1000+
ResumedAfterDrop(CoroutineKind),
10001001
MisalignedPointerDereference { required: O, found: O },
10011002
}
10021003

compiler/rustc_middle/src/mir/terminator.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,16 @@ impl<O> AssertKind<O> {
195195
ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
196196
LangItem::PanicGenFnNonePanic
197197
}
198+
ResumedAfterDrop(CoroutineKind::Coroutine(_)) => LangItem::PanicCoroutineResumedDrop,
199+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
200+
LangItem::PanicAsyncFnResumedDrop
201+
}
202+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => {
203+
LangItem::PanicAsyncGenFnResumedDrop
204+
}
205+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
206+
LangItem::PanicGenFnNoneDrop
207+
}
198208

199209
BoundsCheck { .. } | MisalignedPointerDereference { .. } => {
200210
bug!("Unexpected AssertKind")
@@ -284,6 +294,18 @@ impl<O> AssertKind<O> {
284294
ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
285295
write!(f, "\"`gen fn` should just keep returning `None` after panicking\"")
286296
}
297+
ResumedAfterDrop(CoroutineKind::Coroutine(_)) => {
298+
write!(f, "\"coroutine resumed after async drop\"")
299+
}
300+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
301+
write!(f, "\"`async fn` resumed after async drop\"")
302+
}
303+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => {
304+
write!(f, "\"`async gen fn` resumed after async drop\"")
305+
}
306+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
307+
write!(f, "\"`gen fn` resumed after drop\"")
308+
}
287309
}
288310
}
289311

@@ -330,6 +352,18 @@ impl<O> AssertKind<O> {
330352
ResumedAfterPanic(CoroutineKind::Coroutine(_)) => {
331353
middle_assert_coroutine_resume_after_panic
332354
}
355+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
356+
middle_assert_async_resume_after_drop
357+
}
358+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => {
359+
todo!()
360+
}
361+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
362+
middle_assert_gen_resume_after_drop
363+
}
364+
ResumedAfterDrop(CoroutineKind::Coroutine(_)) => {
365+
middle_assert_coroutine_resume_after_drop
366+
}
333367

334368
MisalignedPointerDereference { .. } => middle_assert_misaligned_ptr_deref,
335369
}
@@ -363,7 +397,7 @@ impl<O> AssertKind<O> {
363397
add!("left", format!("{left:#?}"));
364398
add!("right", format!("{right:#?}"));
365399
}
366-
ResumedAfterReturn(_) | ResumedAfterPanic(_) => {}
400+
ResumedAfterReturn(_) | ResumedAfterPanic(_) | ResumedAfterDrop(_) => {}
367401
MisalignedPointerDereference { required, found } => {
368402
add!("required", format!("{required:#?}"));
369403
add!("found", format!("{found:#?}"));

compiler/rustc_middle/src/mir/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ macro_rules! make_mir_visitor {
636636
OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) => {
637637
self.visit_operand(op, location);
638638
}
639-
ResumedAfterReturn(_) | ResumedAfterPanic(_) => {
639+
ResumedAfterReturn(_) | ResumedAfterPanic(_) | ResumedAfterDrop(_) => {
640640
// Nothing to visit
641641
}
642642
MisalignedPointerDereference { required, found } => {

compiler/rustc_smir/src/rustc_smir/convert/mir.rs

+3
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,9 @@ impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> {
473473
AssertKind::ResumedAfterPanic(coroutine) => {
474474
stable_mir::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables))
475475
}
476+
AssertKind::ResumedAfterDrop(coroutine) => {
477+
stable_mir::mir::AssertMessage::ResumedAfterDrop(coroutine.stable(tables))
478+
}
476479
AssertKind::MisalignedPointerDereference { required, found } => {
477480
stable_mir::mir::AssertMessage::MisalignedPointerDereference {
478481
required: required.stable(tables),

compiler/rustc_span/src/symbol.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1371,14 +1371,18 @@ symbols! {
13711371
panic_cannot_unwind,
13721372
panic_const_add_overflow,
13731373
panic_const_async_fn_resumed,
1374+
panic_const_async_fn_resumed_drop,
13741375
panic_const_async_fn_resumed_panic,
13751376
panic_const_async_gen_fn_resumed,
1377+
panic_const_async_gen_fn_resumed_drop,
13761378
panic_const_async_gen_fn_resumed_panic,
13771379
panic_const_coroutine_resumed,
1380+
panic_const_coroutine_resumed_drop,
13781381
panic_const_coroutine_resumed_panic,
13791382
panic_const_div_by_zero,
13801383
panic_const_div_overflow,
13811384
panic_const_gen_fn_none,
1385+
panic_const_gen_fn_none_drop,
13821386
panic_const_gen_fn_none_panic,
13831387
panic_const_mul_overflow,
13841388
panic_const_neg_overflow,

compiler/stable_mir/src/mir/body.rs

+17
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ pub enum AssertMessage {
250250
RemainderByZero(Operand),
251251
ResumedAfterReturn(CoroutineKind),
252252
ResumedAfterPanic(CoroutineKind),
253+
ResumedAfterDrop(CoroutineKind),
253254
MisalignedPointerDereference { required: Operand, found: Operand },
254255
}
255256

@@ -302,6 +303,22 @@ impl AssertMessage {
302303
_,
303304
)) => Ok("`gen fn` should just keep returning `AssertMessage::None` after panicking"),
304305

306+
AssertMessage::ResumedAfterDrop(CoroutineKind::Coroutine(_)) => {
307+
Ok("coroutine resumed after async drop")
308+
}
309+
AssertMessage::ResumedAfterDrop(CoroutineKind::Desugared(
310+
CoroutineDesugaring::Async,
311+
_,
312+
)) => Ok("`async fn` resumed after async drop"),
313+
AssertMessage::ResumedAfterDrop(CoroutineKind::Desugared(
314+
CoroutineDesugaring::Gen,
315+
_,
316+
)) => Ok("`async gen fn` resumed after async drop"),
317+
AssertMessage::ResumedAfterDrop(CoroutineKind::Desugared(
318+
CoroutineDesugaring::AsyncGen,
319+
_,
320+
)) => Ok("`gen fn` should just keep returning `AssertMessage::None` after async drop"),
321+
305322
AssertMessage::BoundsCheck { .. } => Ok("index out of bounds"),
306323
AssertMessage::MisalignedPointerDereference { .. } => {
307324
Ok("misaligned pointer dereference")

compiler/stable_mir/src/mir/pretty.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,9 @@ fn pretty_assert_message<W: Write>(writer: &mut W, msg: &AssertMessage) -> io::R
295295
"\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\",{pretty_required}, {pretty_found}"
296296
)
297297
}
298-
AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => {
298+
AssertMessage::ResumedAfterReturn(_)
299+
| AssertMessage::ResumedAfterPanic(_)
300+
| AssertMessage::ResumedAfterDrop(_) => {
299301
write!(writer, "{}", msg.description().unwrap())
300302
}
301303
}

compiler/stable_mir/src/mir/visit.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,9 @@ pub trait MirVisitor {
436436
| AssertMessage::RemainderByZero(op) => {
437437
self.visit_operand(op, location);
438438
}
439-
AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => { //nothing to visit
439+
AssertMessage::ResumedAfterReturn(_)
440+
| AssertMessage::ResumedAfterPanic(_)
441+
| AssertMessage::ResumedAfterDrop(_) => { //nothing to visit
440442
}
441443
AssertMessage::MisalignedPointerDereference { required, found } => {
442444
self.visit_operand(required, location);

library/core/src/panicking.rs

+55-47
Original file line numberDiff line numberDiff line change
@@ -158,56 +158,64 @@ pub const fn panic(expr: &'static str) -> ! {
158158
// reducing binary size impact.
159159
macro_rules! panic_const {
160160
($($lang:ident = $message:expr,)+) => {
161-
pub mod panic_const {
162-
use super::*;
163-
164-
$(
165-
/// This is a panic called with a message that's a result of a MIR-produced Assert.
166-
//
167-
// never inline unless panic_immediate_abort to avoid code
168-
// bloat at the call sites as much as possible
169-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
170-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
171-
#[track_caller]
172-
#[rustc_const_unstable(feature = "panic_internals", issue = "none")]
173-
#[lang = stringify!($lang)]
174-
pub const fn $lang() -> ! {
175-
// Use Arguments::new_const instead of format_args!("{expr}") to potentially
176-
// reduce size overhead. The format_args! macro uses str's Display trait to
177-
// write expr, which calls Formatter::pad, which must accommodate string
178-
// truncation and padding (even though none is used here). Using
179-
// Arguments::new_const may allow the compiler to omit Formatter::pad from the
180-
// output binary, saving up to a few kilobytes.
181-
panic_fmt(fmt::Arguments::new_const(&[$message]));
182-
}
183-
)+
184-
}
161+
$(
162+
/// This is a panic called with a message that's a result of a MIR-produced Assert.
163+
//
164+
// never inline unless panic_immediate_abort to avoid code
165+
// bloat at the call sites as much as possible
166+
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
167+
#[cfg_attr(feature = "panic_immediate_abort", inline)]
168+
#[track_caller]
169+
#[rustc_const_unstable(feature = "panic_internals", issue = "none")]
170+
#[lang = stringify!($lang)]
171+
pub const fn $lang() -> ! {
172+
// Use Arguments::new_const instead of format_args!("{expr}") to potentially
173+
// reduce size overhead. The format_args! macro uses str's Display trait to
174+
// write expr, which calls Formatter::pad, which must accommodate string
175+
// truncation and padding (even though none is used here). Using
176+
// Arguments::new_const may allow the compiler to omit Formatter::pad from the
177+
// output binary, saving up to a few kilobytes.
178+
panic_fmt(fmt::Arguments::new_const(&[$message]));
179+
}
180+
)+
185181
}
186182
}
187183

188-
// Unfortunately this set of strings is replicated here and in a few places in the compiler in
189-
// slightly different forms. It's not clear if there's a good way to deduplicate without adding
190-
// special cases to the compiler (e.g., a const generic function wouldn't have a single definition
191-
// shared across crates, which is exactly what we want here).
192-
panic_const! {
193-
panic_const_add_overflow = "attempt to add with overflow",
194-
panic_const_sub_overflow = "attempt to subtract with overflow",
195-
panic_const_mul_overflow = "attempt to multiply with overflow",
196-
panic_const_div_overflow = "attempt to divide with overflow",
197-
panic_const_rem_overflow = "attempt to calculate the remainder with overflow",
198-
panic_const_neg_overflow = "attempt to negate with overflow",
199-
panic_const_shr_overflow = "attempt to shift right with overflow",
200-
panic_const_shl_overflow = "attempt to shift left with overflow",
201-
panic_const_div_by_zero = "attempt to divide by zero",
202-
panic_const_rem_by_zero = "attempt to calculate the remainder with a divisor of zero",
203-
panic_const_coroutine_resumed = "coroutine resumed after completion",
204-
panic_const_async_fn_resumed = "`async fn` resumed after completion",
205-
panic_const_async_gen_fn_resumed = "`async gen fn` resumed after completion",
206-
panic_const_gen_fn_none = "`gen fn` should just keep returning `None` after completion",
207-
panic_const_coroutine_resumed_panic = "coroutine resumed after panicking",
208-
panic_const_async_fn_resumed_panic = "`async fn` resumed after panicking",
209-
panic_const_async_gen_fn_resumed_panic = "`async gen fn` resumed after panicking",
210-
panic_const_gen_fn_none_panic = "`gen fn` should just keep returning `None` after panicking",
184+
pub mod panic_const {
185+
use super::*;
186+
// Unfortunately this set of strings is replicated here and in a few places in the compiler in
187+
// slightly different forms. It's not clear if there's a good way to deduplicate without adding
188+
// special cases to the compiler (e.g., a const generic function wouldn't have a single definition
189+
// shared across crates, which is exactly what we want here).
190+
panic_const! {
191+
panic_const_add_overflow = "attempt to add with overflow",
192+
panic_const_sub_overflow = "attempt to subtract with overflow",
193+
panic_const_mul_overflow = "attempt to multiply with overflow",
194+
panic_const_div_overflow = "attempt to divide with overflow",
195+
panic_const_rem_overflow = "attempt to calculate the remainder with overflow",
196+
panic_const_neg_overflow = "attempt to negate with overflow",
197+
panic_const_shr_overflow = "attempt to shift right with overflow",
198+
panic_const_shl_overflow = "attempt to shift left with overflow",
199+
panic_const_div_by_zero = "attempt to divide by zero",
200+
panic_const_rem_by_zero = "attempt to calculate the remainder with a divisor of zero",
201+
panic_const_coroutine_resumed = "coroutine resumed after completion",
202+
panic_const_async_fn_resumed = "`async fn` resumed after completion",
203+
panic_const_async_gen_fn_resumed = "`async gen fn` resumed after completion",
204+
panic_const_gen_fn_none = "`gen fn` should just keep returning `None` after completion",
205+
panic_const_coroutine_resumed_panic = "coroutine resumed after panicking",
206+
panic_const_async_fn_resumed_panic = "`async fn` resumed after panicking",
207+
panic_const_async_gen_fn_resumed_panic = "`async gen fn` resumed after panicking",
208+
panic_const_gen_fn_none_panic = "`gen fn` should just keep returning `None` after panicking",
209+
}
210+
// Separated panic constants list for async drop feature
211+
// (May be joined when the corresponding lang items will be in the bootstrap)
212+
#[cfg(not(bootstrap))]
213+
panic_const! {
214+
panic_const_coroutine_resumed_drop = "coroutine resumed after async drop",
215+
panic_const_async_fn_resumed_drop = "`async fn` resumed after async drop",
216+
panic_const_async_gen_fn_resumed_drop = "`async gen fn` resumed after async drop",
217+
panic_const_gen_fn_none_drop = "`gen fn` resumed after async drop",
218+
}
211219
}
212220

213221
/// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize on the caller.

0 commit comments

Comments
 (0)