Skip to content

Rollup of 2 pull requests #118970

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add spread arg and missing CoroutineKind
  • Loading branch information
celinval committed Dec 14, 2023
commit a66cac92ccde181dfeb5278595b99e2d2394feb2
1 change: 1 addition & 0 deletions compiler/rustc_smir/src/rustc_smir/convert/mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
.collect(),
self.arg_count,
self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
self.spread_arg.stable(tables),
)
}
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_smir/src/rustc_smir/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
stable_mir::mir::CoroutineKind::Gen(source.stable(tables))
}
CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine,
CoroutineKind::AsyncGen(_) => todo!(),
CoroutineKind::AsyncGen(source) => {
stable_mir::mir::CoroutineKind::AsyncGen(source.stable(tables))
}
}
}
}
Expand Down
69 changes: 68 additions & 1 deletion compiler/stable_mir/src/mir/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ pub struct Body {

/// Debug information pertaining to user variables, including captures.
pub var_debug_info: Vec<VarDebugInfo>,

/// Mark an argument (which must be a tuple) as getting passed as its individual components.
///
/// This is used for the "rust-call" ABI such as closures.
pub(super) spread_arg: Option<Local>,
}

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

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

/// Get an iterator for all local declarations.
pub fn local_decls(&self) -> impl Iterator<Item = (Local, &LocalDecl)> {
self.locals.iter().enumerate()
}

pub fn dump<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
writeln!(w, "{}", function_body(self))?;
self.blocks
Expand All @@ -98,6 +109,10 @@ impl Body {
.collect::<Result<Vec<_>, _>>()?;
Ok(())
}

pub fn spread_arg(&self) -> Option<Local> {
self.spread_arg
}
}

type LocalDecls = Vec<LocalDecl>;
Expand Down Expand Up @@ -248,6 +263,57 @@ pub enum AssertMessage {
MisalignedPointerDereference { required: Operand, found: Operand },
}

impl AssertMessage {
pub fn description(&self) -> Result<&'static str, Error> {
match self {
AssertMessage::Overflow(BinOp::Add, _, _) => Ok("attempt to add with overflow"),
AssertMessage::Overflow(BinOp::Sub, _, _) => Ok("attempt to subtract with overflow"),
AssertMessage::Overflow(BinOp::Mul, _, _) => Ok("attempt to multiply with overflow"),
AssertMessage::Overflow(BinOp::Div, _, _) => Ok("attempt to divide with overflow"),
AssertMessage::Overflow(BinOp::Rem, _, _) => {
Ok("attempt to calculate the remainder with overflow")
}
AssertMessage::OverflowNeg(_) => Ok("attempt to negate with overflow"),
AssertMessage::Overflow(BinOp::Shr, _, _) => Ok("attempt to shift right with overflow"),
AssertMessage::Overflow(BinOp::Shl, _, _) => Ok("attempt to shift left with overflow"),
AssertMessage::Overflow(op, _, _) => Err(error!("`{:?}` cannot overflow", op)),
AssertMessage::DivisionByZero(_) => Ok("attempt to divide by zero"),
AssertMessage::RemainderByZero(_) => {
Ok("attempt to calculate the remainder with a divisor of zero")
}
AssertMessage::ResumedAfterReturn(CoroutineKind::Coroutine) => {
Ok("coroutine resumed after completion")
}
AssertMessage::ResumedAfterReturn(CoroutineKind::Async(_)) => {
Ok("`async fn` resumed after completion")
}
AssertMessage::ResumedAfterReturn(CoroutineKind::Gen(_)) => {
Ok("`async gen fn` resumed after completion")
}
AssertMessage::ResumedAfterReturn(CoroutineKind::AsyncGen(_)) => {
Ok("`gen fn` should just keep returning `AssertMessage::None` after completion")
}
AssertMessage::ResumedAfterPanic(CoroutineKind::Coroutine) => {
Ok("coroutine resumed after panicking")
}
AssertMessage::ResumedAfterPanic(CoroutineKind::Async(_)) => {
Ok("`async fn` resumed after panicking")
}
AssertMessage::ResumedAfterPanic(CoroutineKind::Gen(_)) => {
Ok("`async gen fn` resumed after panicking")
}
AssertMessage::ResumedAfterPanic(CoroutineKind::AsyncGen(_)) => {
Ok("`gen fn` should just keep returning `AssertMessage::None` after panicking")
}

AssertMessage::BoundsCheck { .. } => Ok("index out of bounds"),
AssertMessage::MisalignedPointerDereference { .. } => {
Ok("misaligned pointer dereference")
}
}
}
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum BinOp {
Add,
Expand Down Expand Up @@ -325,6 +391,7 @@ pub enum CoroutineKind {
Async(CoroutineSource),
Coroutine,
Gen(CoroutineSource),
AsyncGen(CoroutineSource),
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Expand Down
9 changes: 4 additions & 5 deletions compiler/stable_mir/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ pub fn pretty_assert_message(msg: &AssertMessage) -> String {
);
pretty
}
AssertMessage::Overflow(op, _, _) => unreachable!("`{:?}` cannot overflow", op),
AssertMessage::OverflowNeg(op) => {
let pretty_op = pretty_operand(op);
pretty.push_str(
Expand All @@ -262,17 +263,15 @@ pub fn pretty_assert_message(msg: &AssertMessage) -> String {
);
pretty
}
AssertMessage::ResumedAfterReturn(_) => {
format!("attempt to resume a generator after completion")
}
AssertMessage::ResumedAfterPanic(_) => format!("attempt to resume a panicked generator"),
AssertMessage::MisalignedPointerDereference { required, found } => {
let pretty_required = pretty_operand(required);
let pretty_found = pretty_operand(found);
pretty.push_str(format!("\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\",{pretty_required}, {pretty_found}").as_str());
pretty
}
_ => todo!(),
AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => {
msg.description().unwrap().to_string()
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/stable_mir/src/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ pub trait MirVisitor {
}

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

for bb in blocks {
self.visit_basic_block(bb);
Expand Down
10 changes: 7 additions & 3 deletions compiler/stable_mir/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use super::{
use crate::crate_def::CrateDef;
use crate::mir::alloc::{read_target_int, read_target_uint, AllocId};
use crate::target::MachineInfo;
use crate::ty::UintTy::U8;
use crate::{Filename, Opaque};
use std::fmt::{self, Debug, Display, Formatter};
use std::ops::Range;
Expand All @@ -22,9 +23,7 @@ impl Debug for Ty {
/// Constructors for `Ty`.
impl Ty {
/// Create a new type from a given kind.
///
/// Note that not all types may be supported at this point.
fn from_rigid_kind(kind: RigidTy) -> Ty {
pub fn from_rigid_kind(kind: RigidTy) -> Ty {
with(|cx| cx.new_rigid_ty(kind))
}

Expand Down Expand Up @@ -77,6 +76,11 @@ impl Ty {
pub fn bool_ty() -> Ty {
Ty::from_rigid_kind(RigidTy::Bool)
}

/// Create a type representing `u8`.
pub fn u8_ty() -> Ty {
Ty::from_rigid_kind(RigidTy::Uint(U8))
}
}

impl Ty {
Expand Down