Skip to content

Commit a66cac9

Browse files
committed
Add spread arg and missing CoroutineKind
1 parent c3a2302 commit a66cac9

File tree

6 files changed

+84
-11
lines changed

6 files changed

+84
-11
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
3636
.collect(),
3737
self.arg_count,
3838
self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
39+
self.spread_arg.stable(tables),
3940
)
4041
}
4142
}

compiler/rustc_smir/src/rustc_smir/convert/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
5757
stable_mir::mir::CoroutineKind::Gen(source.stable(tables))
5858
}
5959
CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine,
60-
CoroutineKind::AsyncGen(_) => todo!(),
60+
CoroutineKind::AsyncGen(source) => {
61+
stable_mir::mir::CoroutineKind::AsyncGen(source.stable(tables))
62+
}
6163
}
6264
}
6365
}

compiler/stable_mir/src/mir/body.rs

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ pub struct Body {
2222

2323
/// Debug information pertaining to user variables, including captures.
2424
pub var_debug_info: Vec<VarDebugInfo>,
25+
26+
/// Mark an argument (which must be a tuple) as getting passed as its individual components.
27+
///
28+
/// This is used for the "rust-call" ABI such as closures.
29+
pub(super) spread_arg: Option<Local>,
2530
}
2631

2732
pub type BasicBlockIdx = usize;
@@ -36,14 +41,15 @@ impl Body {
3641
locals: LocalDecls,
3742
arg_count: usize,
3843
var_debug_info: Vec<VarDebugInfo>,
44+
spread_arg: Option<Local>,
3945
) -> Self {
4046
// If locals doesn't contain enough entries, it can lead to panics in
4147
// `ret_local`, `arg_locals`, and `inner_locals`.
4248
assert!(
4349
locals.len() > arg_count,
4450
"A Body must contain at least a local for the return value and each of the function's arguments"
4551
);
46-
Self { blocks, locals, arg_count, var_debug_info }
52+
Self { blocks, locals, arg_count, var_debug_info, spread_arg }
4753
}
4854

4955
/// Return local that holds this function's return value.
@@ -75,6 +81,11 @@ impl Body {
7581
self.locals.get(local)
7682
}
7783

84+
/// Get an iterator for all local declarations.
85+
pub fn local_decls(&self) -> impl Iterator<Item = (Local, &LocalDecl)> {
86+
self.locals.iter().enumerate()
87+
}
88+
7889
pub fn dump<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
7990
writeln!(w, "{}", function_body(self))?;
8091
self.blocks
@@ -98,6 +109,10 @@ impl Body {
98109
.collect::<Result<Vec<_>, _>>()?;
99110
Ok(())
100111
}
112+
113+
pub fn spread_arg(&self) -> Option<Local> {
114+
self.spread_arg
115+
}
101116
}
102117

103118
type LocalDecls = Vec<LocalDecl>;
@@ -248,6 +263,57 @@ pub enum AssertMessage {
248263
MisalignedPointerDereference { required: Operand, found: Operand },
249264
}
250265

266+
impl AssertMessage {
267+
pub fn description(&self) -> Result<&'static str, Error> {
268+
match self {
269+
AssertMessage::Overflow(BinOp::Add, _, _) => Ok("attempt to add with overflow"),
270+
AssertMessage::Overflow(BinOp::Sub, _, _) => Ok("attempt to subtract with overflow"),
271+
AssertMessage::Overflow(BinOp::Mul, _, _) => Ok("attempt to multiply with overflow"),
272+
AssertMessage::Overflow(BinOp::Div, _, _) => Ok("attempt to divide with overflow"),
273+
AssertMessage::Overflow(BinOp::Rem, _, _) => {
274+
Ok("attempt to calculate the remainder with overflow")
275+
}
276+
AssertMessage::OverflowNeg(_) => Ok("attempt to negate with overflow"),
277+
AssertMessage::Overflow(BinOp::Shr, _, _) => Ok("attempt to shift right with overflow"),
278+
AssertMessage::Overflow(BinOp::Shl, _, _) => Ok("attempt to shift left with overflow"),
279+
AssertMessage::Overflow(op, _, _) => Err(error!("`{:?}` cannot overflow", op)),
280+
AssertMessage::DivisionByZero(_) => Ok("attempt to divide by zero"),
281+
AssertMessage::RemainderByZero(_) => {
282+
Ok("attempt to calculate the remainder with a divisor of zero")
283+
}
284+
AssertMessage::ResumedAfterReturn(CoroutineKind::Coroutine) => {
285+
Ok("coroutine resumed after completion")
286+
}
287+
AssertMessage::ResumedAfterReturn(CoroutineKind::Async(_)) => {
288+
Ok("`async fn` resumed after completion")
289+
}
290+
AssertMessage::ResumedAfterReturn(CoroutineKind::Gen(_)) => {
291+
Ok("`async gen fn` resumed after completion")
292+
}
293+
AssertMessage::ResumedAfterReturn(CoroutineKind::AsyncGen(_)) => {
294+
Ok("`gen fn` should just keep returning `AssertMessage::None` after completion")
295+
}
296+
AssertMessage::ResumedAfterPanic(CoroutineKind::Coroutine) => {
297+
Ok("coroutine resumed after panicking")
298+
}
299+
AssertMessage::ResumedAfterPanic(CoroutineKind::Async(_)) => {
300+
Ok("`async fn` resumed after panicking")
301+
}
302+
AssertMessage::ResumedAfterPanic(CoroutineKind::Gen(_)) => {
303+
Ok("`async gen fn` resumed after panicking")
304+
}
305+
AssertMessage::ResumedAfterPanic(CoroutineKind::AsyncGen(_)) => {
306+
Ok("`gen fn` should just keep returning `AssertMessage::None` after panicking")
307+
}
308+
309+
AssertMessage::BoundsCheck { .. } => Ok("index out of bounds"),
310+
AssertMessage::MisalignedPointerDereference { .. } => {
311+
Ok("misaligned pointer dereference")
312+
}
313+
}
314+
}
315+
}
316+
251317
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
252318
pub enum BinOp {
253319
Add,
@@ -325,6 +391,7 @@ pub enum CoroutineKind {
325391
Async(CoroutineSource),
326392
Coroutine,
327393
Gen(CoroutineSource),
394+
AsyncGen(CoroutineSource),
328395
}
329396

330397
#[derive(Copy, Clone, Debug, Eq, PartialEq)]

compiler/stable_mir/src/mir/pretty.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ pub fn pretty_assert_message(msg: &AssertMessage) -> String {
243243
);
244244
pretty
245245
}
246+
AssertMessage::Overflow(op, _, _) => unreachable!("`{:?}` cannot overflow", op),
246247
AssertMessage::OverflowNeg(op) => {
247248
let pretty_op = pretty_operand(op);
248249
pretty.push_str(
@@ -262,17 +263,15 @@ pub fn pretty_assert_message(msg: &AssertMessage) -> String {
262263
);
263264
pretty
264265
}
265-
AssertMessage::ResumedAfterReturn(_) => {
266-
format!("attempt to resume a generator after completion")
267-
}
268-
AssertMessage::ResumedAfterPanic(_) => format!("attempt to resume a panicked generator"),
269266
AssertMessage::MisalignedPointerDereference { required, found } => {
270267
let pretty_required = pretty_operand(required);
271268
let pretty_found = pretty_operand(found);
272269
pretty.push_str(format!("\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\",{pretty_required}, {pretty_found}").as_str());
273270
pretty
274271
}
275-
_ => todo!(),
272+
AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => {
273+
msg.description().unwrap().to_string()
274+
}
276275
}
277276
}
278277

compiler/stable_mir/src/mir/visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ pub trait MirVisitor {
133133
}
134134

135135
fn super_body(&mut self, body: &Body) {
136-
let Body { blocks, locals: _, arg_count, var_debug_info } = body;
136+
let Body { blocks, locals: _, arg_count, var_debug_info, spread_arg: _ } = body;
137137

138138
for bb in blocks {
139139
self.visit_basic_block(bb);

compiler/stable_mir/src/ty.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use super::{
66
use crate::crate_def::CrateDef;
77
use crate::mir::alloc::{read_target_int, read_target_uint, AllocId};
88
use crate::target::MachineInfo;
9+
use crate::ty::UintTy::U8;
910
use crate::{Filename, Opaque};
1011
use std::fmt::{self, Debug, Display, Formatter};
1112
use std::ops::Range;
@@ -22,9 +23,7 @@ impl Debug for Ty {
2223
/// Constructors for `Ty`.
2324
impl Ty {
2425
/// Create a new type from a given kind.
25-
///
26-
/// Note that not all types may be supported at this point.
27-
fn from_rigid_kind(kind: RigidTy) -> Ty {
26+
pub fn from_rigid_kind(kind: RigidTy) -> Ty {
2827
with(|cx| cx.new_rigid_ty(kind))
2928
}
3029

@@ -77,6 +76,11 @@ impl Ty {
7776
pub fn bool_ty() -> Ty {
7877
Ty::from_rigid_kind(RigidTy::Bool)
7978
}
79+
80+
/// Create a type representing `u8`.
81+
pub fn u8_ty() -> Ty {
82+
Ty::from_rigid_kind(RigidTy::Uint(U8))
83+
}
8084
}
8185

8286
impl Ty {

0 commit comments

Comments
 (0)