mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Add spread arg and missing CoroutineKind
This commit is contained in:
parent
c3a2302fb0
commit
a66cac92cc
@ -36,6 +36,7 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
|
|||||||
.collect(),
|
.collect(),
|
||||||
self.arg_count,
|
self.arg_count,
|
||||||
self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
|
self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
|
||||||
|
self.spread_arg.stable(tables),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,9 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
|
|||||||
stable_mir::mir::CoroutineKind::Gen(source.stable(tables))
|
stable_mir::mir::CoroutineKind::Gen(source.stable(tables))
|
||||||
}
|
}
|
||||||
CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine,
|
CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine,
|
||||||
CoroutineKind::AsyncGen(_) => todo!(),
|
CoroutineKind::AsyncGen(source) => {
|
||||||
|
stable_mir::mir::CoroutineKind::AsyncGen(source.stable(tables))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,11 @@ pub struct Body {
|
|||||||
|
|
||||||
/// Debug information pertaining to user variables, including captures.
|
/// Debug information pertaining to user variables, including captures.
|
||||||
pub var_debug_info: Vec<VarDebugInfo>,
|
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;
|
pub type BasicBlockIdx = usize;
|
||||||
@ -36,6 +41,7 @@ impl Body {
|
|||||||
locals: LocalDecls,
|
locals: LocalDecls,
|
||||||
arg_count: usize,
|
arg_count: usize,
|
||||||
var_debug_info: Vec<VarDebugInfo>,
|
var_debug_info: Vec<VarDebugInfo>,
|
||||||
|
spread_arg: Option<Local>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// If locals doesn't contain enough entries, it can lead to panics in
|
// If locals doesn't contain enough entries, it can lead to panics in
|
||||||
// `ret_local`, `arg_locals`, and `inner_locals`.
|
// `ret_local`, `arg_locals`, and `inner_locals`.
|
||||||
@ -43,7 +49,7 @@ impl Body {
|
|||||||
locals.len() > arg_count,
|
locals.len() > arg_count,
|
||||||
"A Body must contain at least a local for the return value and each of the function's arguments"
|
"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.
|
/// Return local that holds this function's return value.
|
||||||
@ -75,6 +81,11 @@ impl Body {
|
|||||||
self.locals.get(local)
|
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<()> {
|
pub fn dump<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
|
||||||
writeln!(w, "{}", function_body(self))?;
|
writeln!(w, "{}", function_body(self))?;
|
||||||
self.blocks
|
self.blocks
|
||||||
@ -98,6 +109,10 @@ impl Body {
|
|||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn spread_arg(&self) -> Option<Local> {
|
||||||
|
self.spread_arg
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type LocalDecls = Vec<LocalDecl>;
|
type LocalDecls = Vec<LocalDecl>;
|
||||||
@ -248,6 +263,57 @@ pub enum AssertMessage {
|
|||||||
MisalignedPointerDereference { required: Operand, found: Operand },
|
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)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum BinOp {
|
pub enum BinOp {
|
||||||
Add,
|
Add,
|
||||||
@ -325,6 +391,7 @@ pub enum CoroutineKind {
|
|||||||
Async(CoroutineSource),
|
Async(CoroutineSource),
|
||||||
Coroutine,
|
Coroutine,
|
||||||
Gen(CoroutineSource),
|
Gen(CoroutineSource),
|
||||||
|
AsyncGen(CoroutineSource),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
|
@ -243,6 +243,7 @@ pub fn pretty_assert_message(msg: &AssertMessage) -> String {
|
|||||||
);
|
);
|
||||||
pretty
|
pretty
|
||||||
}
|
}
|
||||||
|
AssertMessage::Overflow(op, _, _) => unreachable!("`{:?}` cannot overflow", op),
|
||||||
AssertMessage::OverflowNeg(op) => {
|
AssertMessage::OverflowNeg(op) => {
|
||||||
let pretty_op = pretty_operand(op);
|
let pretty_op = pretty_operand(op);
|
||||||
pretty.push_str(
|
pretty.push_str(
|
||||||
@ -262,17 +263,15 @@ pub fn pretty_assert_message(msg: &AssertMessage) -> String {
|
|||||||
);
|
);
|
||||||
pretty
|
pretty
|
||||||
}
|
}
|
||||||
AssertMessage::ResumedAfterReturn(_) => {
|
|
||||||
format!("attempt to resume a generator after completion")
|
|
||||||
}
|
|
||||||
AssertMessage::ResumedAfterPanic(_) => format!("attempt to resume a panicked generator"),
|
|
||||||
AssertMessage::MisalignedPointerDereference { required, found } => {
|
AssertMessage::MisalignedPointerDereference { required, found } => {
|
||||||
let pretty_required = pretty_operand(required);
|
let pretty_required = pretty_operand(required);
|
||||||
let pretty_found = pretty_operand(found);
|
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.push_str(format!("\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\",{pretty_required}, {pretty_found}").as_str());
|
||||||
pretty
|
pretty
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => {
|
||||||
|
msg.description().unwrap().to_string()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ pub trait MirVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn super_body(&mut self, body: &Body) {
|
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 {
|
for bb in blocks {
|
||||||
self.visit_basic_block(bb);
|
self.visit_basic_block(bb);
|
||||||
|
@ -6,6 +6,7 @@ use super::{
|
|||||||
use crate::crate_def::CrateDef;
|
use crate::crate_def::CrateDef;
|
||||||
use crate::mir::alloc::{read_target_int, read_target_uint, AllocId};
|
use crate::mir::alloc::{read_target_int, read_target_uint, AllocId};
|
||||||
use crate::target::MachineInfo;
|
use crate::target::MachineInfo;
|
||||||
|
use crate::ty::UintTy::U8;
|
||||||
use crate::{Filename, Opaque};
|
use crate::{Filename, Opaque};
|
||||||
use std::fmt::{self, Debug, Display, Formatter};
|
use std::fmt::{self, Debug, Display, Formatter};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
@ -22,9 +23,7 @@ impl Debug for Ty {
|
|||||||
/// Constructors for `Ty`.
|
/// Constructors for `Ty`.
|
||||||
impl Ty {
|
impl Ty {
|
||||||
/// Create a new type from a given kind.
|
/// Create a new type from a given kind.
|
||||||
///
|
pub fn from_rigid_kind(kind: RigidTy) -> Ty {
|
||||||
/// Note that not all types may be supported at this point.
|
|
||||||
fn from_rigid_kind(kind: RigidTy) -> Ty {
|
|
||||||
with(|cx| cx.new_rigid_ty(kind))
|
with(|cx| cx.new_rigid_ty(kind))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +76,11 @@ impl Ty {
|
|||||||
pub fn bool_ty() -> Ty {
|
pub fn bool_ty() -> Ty {
|
||||||
Ty::from_rigid_kind(RigidTy::Bool)
|
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 {
|
impl Ty {
|
||||||
|
Loading…
Reference in New Issue
Block a user