Skip to content

Commit 5d1ad9b

Browse files
committed
Prereq2 for async drop - ResumedAfterDrop panic messages
1 parent 09344ae commit 5d1ad9b

File tree

13 files changed

+135
-50
lines changed

13 files changed

+135
-50
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2087,10 +2087,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20872087
}
20882088
TerminatorKind::Unreachable => {}
20892089
TerminatorKind::Drop { target, unwind, drop, .. } => {
2090-
self.assert_iscleanup(body, block_data, target, is_cleanup);
2091-
self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup);
2090+
self.assert_iscleanup(block_data, target, is_cleanup);
2091+
self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
20922092
if let Some(drop) = drop {
2093-
self.assert_iscleanup(body, block_data, drop, is_cleanup);
2093+
self.assert_iscleanup(block_data, drop, is_cleanup);
20942094
}
20952095
}
20962096
TerminatorKind::Assert { target, unwind, .. } => {

compiler/rustc_const_eval/src/const_eval/machine.rs

+1
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
502502
RemainderByZero(op) => RemainderByZero(eval_to_int(op)?),
503503
ResumedAfterReturn(coroutine_kind) => ResumedAfterReturn(*coroutine_kind),
504504
ResumedAfterPanic(coroutine_kind) => ResumedAfterPanic(*coroutine_kind),
505+
ResumedAfterDrop(coroutine_kind) => ResumedAfterDrop(*coroutine_kind),
505506
MisalignedPointerDereference { required, found } => MisalignedPointerDereference {
506507
required: eval_to_int(required)?,
507508
found: eval_to_int(found)?,

compiler/rustc_hir/src/lang_items.rs

+4
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,10 @@ language_item_table! {
318318
PanicAsyncGenFnResumedPanic, sym::panic_const_async_gen_fn_resumed_panic, panic_const_async_gen_fn_resumed_panic, Target::Fn, GenericRequirement::None;
319319
PanicGenFnNonePanic, sym::panic_const_gen_fn_none_panic, panic_const_gen_fn_none_panic, Target::Fn, GenericRequirement::None;
320320
PanicNullPointerDereference, sym::panic_null_pointer_dereference, panic_null_pointer_dereference, Target::Fn, GenericRequirement::None;
321+
PanicCoroutineResumedDrop, sym::panic_const_coroutine_resumed_drop, panic_const_coroutine_resumed_drop, Target::Fn, GenericRequirement::None;
322+
PanicAsyncFnResumedDrop, sym::panic_const_async_fn_resumed_drop, panic_const_async_fn_resumed_drop, Target::Fn, GenericRequirement::None;
323+
PanicAsyncGenFnResumedDrop, sym::panic_const_async_gen_fn_resumed_drop, panic_const_async_gen_fn_resumed_drop, Target::Fn, GenericRequirement::None;
324+
PanicGenFnNoneDrop, sym::panic_const_gen_fn_none_drop, panic_const_gen_fn_none_drop, Target::Fn, GenericRequirement::None;
321325
/// libstd panic entry point. Necessary for const eval to be able to catch it
322326
BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None;
323327

compiler/rustc_middle/messages.ftl

+6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1+
middle_assert_async_resume_after_drop = `async fn` resumed after async drop
2+
13
middle_assert_async_resume_after_panic = `async fn` resumed after panicking
24
35
middle_assert_async_resume_after_return = `async fn` resumed after completion
46
7+
middle_assert_coroutine_resume_after_drop = coroutine resumed after async drop
8+
59
middle_assert_coroutine_resume_after_panic = coroutine resumed after panicking
610
711
middle_assert_coroutine_resume_after_return = coroutine resumed after completion
812
913
middle_assert_divide_by_zero =
1014
attempt to divide `{$val}` by zero
1115
16+
middle_assert_gen_resume_after_drop = `gen` fn or block cannot be further iterated on after it async dropped
17+
1218
middle_assert_gen_resume_after_panic = `gen` fn or block cannot be further iterated on after it panicked
1319
1420
middle_assert_misaligned_ptr_deref =

compiler/rustc_middle/src/mir/syntax.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,7 @@ pub enum AssertKind<O> {
10101010
RemainderByZero(O),
10111011
ResumedAfterReturn(CoroutineKind),
10121012
ResumedAfterPanic(CoroutineKind),
1013+
ResumedAfterDrop(CoroutineKind),
10131014
MisalignedPointerDereference { required: O, found: O },
10141015
NullPointerDereference,
10151016
}

compiler/rustc_middle/src/mir/terminator.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,16 @@ impl<O> AssertKind<O> {
208208
LangItem::PanicGenFnNonePanic
209209
}
210210
NullPointerDereference => LangItem::PanicNullPointerDereference,
211+
ResumedAfterDrop(CoroutineKind::Coroutine(_)) => LangItem::PanicCoroutineResumedDrop,
212+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
213+
LangItem::PanicAsyncFnResumedDrop
214+
}
215+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => {
216+
LangItem::PanicAsyncGenFnResumedDrop
217+
}
218+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
219+
LangItem::PanicGenFnNoneDrop
220+
}
211221

212222
BoundsCheck { .. } | MisalignedPointerDereference { .. } => {
213223
bug!("Unexpected AssertKind")
@@ -298,6 +308,18 @@ impl<O> AssertKind<O> {
298308
ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
299309
write!(f, "\"`gen fn` should just keep returning `None` after panicking\"")
300310
}
311+
ResumedAfterDrop(CoroutineKind::Coroutine(_)) => {
312+
write!(f, "\"coroutine resumed after async drop\"")
313+
}
314+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
315+
write!(f, "\"`async fn` resumed after async drop\"")
316+
}
317+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => {
318+
write!(f, "\"`async gen fn` resumed after async drop\"")
319+
}
320+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
321+
write!(f, "\"`gen fn` resumed after drop\"")
322+
}
301323
}
302324
}
303325

@@ -345,6 +367,19 @@ impl<O> AssertKind<O> {
345367
middle_assert_coroutine_resume_after_panic
346368
}
347369
NullPointerDereference => middle_assert_null_ptr_deref,
370+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
371+
middle_assert_async_resume_after_drop
372+
}
373+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => {
374+
todo!()
375+
}
376+
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
377+
middle_assert_gen_resume_after_drop
378+
}
379+
ResumedAfterDrop(CoroutineKind::Coroutine(_)) => {
380+
middle_assert_coroutine_resume_after_drop
381+
}
382+
348383
MisalignedPointerDereference { .. } => middle_assert_misaligned_ptr_deref,
349384
}
350385
}
@@ -377,7 +412,10 @@ impl<O> AssertKind<O> {
377412
add!("left", format!("{left:#?}"));
378413
add!("right", format!("{right:#?}"));
379414
}
380-
ResumedAfterReturn(_) | ResumedAfterPanic(_) | NullPointerDereference => {}
415+
ResumedAfterReturn(_)
416+
| ResumedAfterPanic(_)
417+
| NullPointerDereference
418+
| ResumedAfterDrop(_) => {}
381419
MisalignedPointerDereference { required, found } => {
382420
add!("required", format!("{required:#?}"));
383421
add!("found", format!("{found:#?}"));

compiler/rustc_middle/src/mir/visit.rs

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

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

+3
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,9 @@ impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> {
493493
AssertKind::ResumedAfterPanic(coroutine) => {
494494
stable_mir::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables))
495495
}
496+
AssertKind::ResumedAfterDrop(coroutine) => {
497+
stable_mir::mir::AssertMessage::ResumedAfterDrop(coroutine.stable(tables))
498+
}
496499
AssertKind::MisalignedPointerDereference { required, found } => {
497500
stable_mir::mir::AssertMessage::MisalignedPointerDereference {
498501
required: required.stable(tables),

compiler/rustc_span/src/symbol.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1507,14 +1507,18 @@ symbols! {
15071507
panic_cannot_unwind,
15081508
panic_const_add_overflow,
15091509
panic_const_async_fn_resumed,
1510+
panic_const_async_fn_resumed_drop,
15101511
panic_const_async_fn_resumed_panic,
15111512
panic_const_async_gen_fn_resumed,
1513+
panic_const_async_gen_fn_resumed_drop,
15121514
panic_const_async_gen_fn_resumed_panic,
15131515
panic_const_coroutine_resumed,
1516+
panic_const_coroutine_resumed_drop,
15141517
panic_const_coroutine_resumed_panic,
15151518
panic_const_div_by_zero,
15161519
panic_const_div_overflow,
15171520
panic_const_gen_fn_none,
1521+
panic_const_gen_fn_none_drop,
15181522
panic_const_gen_fn_none_panic,
15191523
panic_const_mul_overflow,
15201524
panic_const_neg_overflow,

compiler/stable_mir/src/mir/body.rs

+17
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ pub enum AssertMessage {
266266
RemainderByZero(Operand),
267267
ResumedAfterReturn(CoroutineKind),
268268
ResumedAfterPanic(CoroutineKind),
269+
ResumedAfterDrop(CoroutineKind),
269270
MisalignedPointerDereference { required: Operand, found: Operand },
270271
NullPointerDereference,
271272
}
@@ -319,6 +320,22 @@ impl AssertMessage {
319320
_,
320321
)) => Ok("`gen fn` should just keep returning `AssertMessage::None` after panicking"),
321322

323+
AssertMessage::ResumedAfterDrop(CoroutineKind::Coroutine(_)) => {
324+
Ok("coroutine resumed after async drop")
325+
}
326+
AssertMessage::ResumedAfterDrop(CoroutineKind::Desugared(
327+
CoroutineDesugaring::Async,
328+
_,
329+
)) => Ok("`async fn` resumed after async drop"),
330+
AssertMessage::ResumedAfterDrop(CoroutineKind::Desugared(
331+
CoroutineDesugaring::Gen,
332+
_,
333+
)) => Ok("`async gen fn` resumed after async drop"),
334+
AssertMessage::ResumedAfterDrop(CoroutineKind::Desugared(
335+
CoroutineDesugaring::AsyncGen,
336+
_,
337+
)) => Ok("`gen fn` should just keep returning `AssertMessage::None` after async drop"),
338+
322339
AssertMessage::BoundsCheck { .. } => Ok("index out of bounds"),
323340
AssertMessage::MisalignedPointerDereference { .. } => {
324341
Ok("misaligned pointer dereference")

compiler/stable_mir/src/mir/pretty.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,9 @@ fn pretty_assert_message<W: Write>(writer: &mut W, msg: &AssertMessage) -> io::R
301301
AssertMessage::NullPointerDereference => {
302302
write!(writer, "\"null pointer dereference occurred\"")
303303
}
304-
AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => {
304+
AssertMessage::ResumedAfterReturn(_)
305+
| AssertMessage::ResumedAfterPanic(_)
306+
| AssertMessage::ResumedAfterDrop(_) => {
305307
write!(writer, "{}", msg.description().unwrap())
306308
}
307309
}

compiler/stable_mir/src/mir/visit.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,8 @@ macro_rules! make_mir_visitor {
370370
}
371371
AssertMessage::ResumedAfterReturn(_)
372372
| AssertMessage::ResumedAfterPanic(_)
373-
| AssertMessage::NullPointerDereference => {
373+
| AssertMessage::NullPointerDereference
374+
| AssertMessage::ResumedAfterDrop(_) => {
374375
//nothing to visit
375376
}
376377
AssertMessage::MisalignedPointerDereference { required, found } => {

library/core/src/panicking.rs

+51-43
Original file line numberDiff line numberDiff line change
@@ -155,56 +155,64 @@ pub const fn panic(expr: &'static str) -> ! {
155155
// reducing binary size impact.
156156
macro_rules! panic_const {
157157
($($lang:ident = $message:expr,)+) => {
158-
pub mod panic_const {
159-
use super::*;
160-
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_stable_indirect] // must follow stable const rules since it is exposed to stable
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-
)+
181-
}
158+
$(
159+
/// This is a panic called with a message that's a result of a MIR-produced Assert.
160+
//
161+
// never inline unless panic_immediate_abort to avoid code
162+
// bloat at the call sites as much as possible
163+
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
164+
#[cfg_attr(feature = "panic_immediate_abort", inline)]
165+
#[track_caller]
166+
#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable
167+
#[lang = stringify!($lang)]
168+
pub const fn $lang() -> ! {
169+
// Use Arguments::new_const instead of format_args!("{expr}") to potentially
170+
// reduce size overhead. The format_args! macro uses str's Display trait to
171+
// write expr, which calls Formatter::pad, which must accommodate string
172+
// truncation and padding (even though none is used here). Using
173+
// Arguments::new_const may allow the compiler to omit Formatter::pad from the
174+
// output binary, saving up to a few kilobytes.
175+
panic_fmt(fmt::Arguments::new_const(&[$message]));
176+
}
177+
)+
182178
}
183179
}
184180

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

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

0 commit comments

Comments
 (0)