Skip to content

Commit

Permalink
Rollup merge of #112717 - celinval:stable-mir-rvalue-1, r=oli-obk
Browse files Browse the repository at this point in the history
Implement a few more rvalue translation to smir

Add the implementation for a few more RValue variants. For now, I simplified the stable version of `RValue::Ref` by removing the notion of Region.

r? `@oli-obk`
  • Loading branch information
matthiaskrgr committed Jul 11, 2023
2 parents b3ab80c + b9f378b commit 3f73a7d
Show file tree
Hide file tree
Showing 7 changed files with 371 additions and 41 deletions.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4233,6 +4233,7 @@ dependencies = [
"rustc_hir",
"rustc_middle",
"rustc_span",
"rustc_target",
"scoped-tls",
"tracing",
]
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_smir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ version = "0.0.0"
edition = "2021"

[dependencies]
rustc_hir = { path = "../rustc_hir" }
# Use optional dependencies for rustc_* in order to support building this crate separately.
rustc_hir = { path = "../rustc_hir", optional = true }
rustc_middle = { path = "../rustc_middle", optional = true }
rustc_span = { path = "../rustc_span", optional = true }
rustc_target = { path = "../rustc_target", optional = true }
tracing = "0.1"
scoped-tls = "1.0"

[features]
default = [
"rustc_hir",
"rustc_middle",
"rustc_span",
"rustc_target",
]
2 changes: 1 addition & 1 deletion compiler/rustc_smir/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2023-02-28"
channel = "nightly-2023-06-14"
components = [ "rustfmt", "rustc-dev" ]
11 changes: 11 additions & 0 deletions compiler/rustc_smir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@
#![cfg_attr(not(feature = "default"), feature(rustc_private))]
#![feature(local_key_cell_methods)]
#![feature(ptr_metadata)]
#![feature(type_alias_impl_trait)] // Used to define opaque types.

// Declare extern rustc_* crates to enable building this crate separately from the compiler.
#[cfg(not(feature = "default"))]
extern crate rustc_hir;
#[cfg(not(feature = "default"))]
extern crate rustc_middle;
#[cfg(not(feature = "default"))]
extern crate rustc_span;
#[cfg(not(feature = "default"))]
extern crate rustc_target;

pub mod rustc_internal;
pub mod stable_mir;
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_smir/src/rustc_internal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
//! until stable MIR is complete.

use std::fmt::Debug;
use std::string::ToString;

use crate::{
rustc_smir::Tables,
stable_mir::{self, with},
Expand Down Expand Up @@ -49,3 +52,10 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
crate::stable_mir::run(Tables { tcx, def_ids: vec![], types: vec![] }, f);
}

/// A type that provides internal information but that can still be used for debug purpose.
pub type Opaque = impl Debug + ToString + Clone;

pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque {
format!("{value:?}")
}
201 changes: 164 additions & 37 deletions compiler/rustc_smir/src/rustc_smir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
//!
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.

use crate::rustc_internal::{self, opaque};
use crate::stable_mir::ty::{FloatTy, IntTy, RigidTy, TyKind, UintTy};
use crate::stable_mir::{self, Context};
use rustc_middle::mir;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_target::abi::FieldIdx;
use tracing::debug;

impl<'tcx> Context for Tables<'tcx> {
Expand Down Expand Up @@ -137,11 +139,21 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local }
}

pub trait Stable {
/// Trait used to convert between an internal MIR type to a Stable MIR type.
pub(crate) trait Stable {
/// The stable representation of the type implementing Stable.
type T;
/// Converts an object to the equivalent Stable MIR representation.
fn stable(&self) -> Self::T;
}

impl Stable for DefId {
type T = stable_mir::CrateItem;
fn stable(&self) -> Self::T {
rustc_internal::crate_item(*self)
}
}

impl<'tcx> Stable for mir::Statement<'tcx> {
type T = stable_mir::mir::Statement;
fn stable(&self) -> Self::T {
Expand Down Expand Up @@ -173,27 +185,138 @@ impl<'tcx> Stable for mir::Rvalue<'tcx> {
match self {
Use(op) => stable_mir::mir::Rvalue::Use(op.stable()),
Repeat(_, _) => todo!(),
Ref(_, _, _) => todo!(),
ThreadLocalRef(_) => todo!(),
AddressOf(_, _) => todo!(),
Len(_) => todo!(),
Ref(region, kind, place) => {
stable_mir::mir::Rvalue::Ref(opaque(region), kind.stable(), place.stable())
}
ThreadLocalRef(def_id) => stable_mir::mir::Rvalue::ThreadLocalRef(def_id.stable()),
AddressOf(mutability, place) => {
stable_mir::mir::Rvalue::AddressOf(mutability.stable(), place.stable())
}
Len(place) => stable_mir::mir::Rvalue::Len(place.stable()),
Cast(_, _, _) => todo!(),
BinaryOp(_, _) => todo!(),
BinaryOp(bin_op, ops) => {
stable_mir::mir::Rvalue::BinaryOp(bin_op.stable(), ops.0.stable(), ops.1.stable())
}
CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp(
bin_op.stable(),
ops.0.stable(),
ops.1.stable(),
),
NullaryOp(_, _) => todo!(),
UnaryOp(un_op, op) => stable_mir::mir::Rvalue::UnaryOp(un_op.stable(), op.stable()),
Discriminant(_) => todo!(),
Discriminant(place) => stable_mir::mir::Rvalue::Discriminant(place.stable()),
Aggregate(_, _) => todo!(),
ShallowInitBox(_, _) => todo!(),
CopyForDeref(_) => todo!(),
CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable()),
}
}
}

impl Stable for mir::Mutability {
type T = stable_mir::mir::Mutability;
fn stable(&self) -> Self::T {
use mir::Mutability::*;
match *self {
Not => stable_mir::mir::Mutability::Not,
Mut => stable_mir::mir::Mutability::Mut,
}
}
}

impl Stable for mir::BorrowKind {
type T = stable_mir::mir::BorrowKind;
fn stable(&self) -> Self::T {
use mir::BorrowKind::*;
match *self {
Shared => stable_mir::mir::BorrowKind::Shared,
Shallow => stable_mir::mir::BorrowKind::Shallow,
Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable() },
}
}
}

impl Stable for mir::MutBorrowKind {
type T = stable_mir::mir::MutBorrowKind;
fn stable(&self) -> Self::T {
use mir::MutBorrowKind::*;
match *self {
Default => stable_mir::mir::MutBorrowKind::Default,
TwoPhaseBorrow => stable_mir::mir::MutBorrowKind::TwoPhaseBorrow,
ClosureCapture => stable_mir::mir::MutBorrowKind::ClosureCapture,
}
}
}

impl<'tcx> Stable for mir::NullOp<'tcx> {
type T = stable_mir::mir::NullOp;
fn stable(&self) -> Self::T {
use mir::NullOp::*;
match self {
SizeOf => stable_mir::mir::NullOp::SizeOf,
AlignOf => stable_mir::mir::NullOp::AlignOf,
OffsetOf(indices) => {
stable_mir::mir::NullOp::OffsetOf(indices.iter().map(|idx| idx.stable()).collect())
}
}
}
}

impl Stable for mir::CastKind {
type T = stable_mir::mir::CastKind;
fn stable(&self) -> Self::T {
use mir::CastKind::*;
match self {
PointerExposeAddress => stable_mir::mir::CastKind::PointerExposeAddress,
PointerFromExposedAddress => stable_mir::mir::CastKind::PointerFromExposedAddress,
PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable()),
DynStar => stable_mir::mir::CastKind::DynStar,
IntToInt => stable_mir::mir::CastKind::IntToInt,
FloatToInt => stable_mir::mir::CastKind::FloatToInt,
FloatToFloat => stable_mir::mir::CastKind::FloatToFloat,
IntToFloat => stable_mir::mir::CastKind::IntToFloat,
PtrToPtr => stable_mir::mir::CastKind::PtrToPtr,
FnPtrToPtr => stable_mir::mir::CastKind::FnPtrToPtr,
Transmute => stable_mir::mir::CastKind::Transmute,
}
}
}

impl Stable for ty::adjustment::PointerCoercion {
type T = stable_mir::mir::PointerCoercion;
fn stable(&self) -> Self::T {
use ty::adjustment::PointerCoercion;
match self {
PointerCoercion::ReifyFnPointer => stable_mir::mir::PointerCoercion::ReifyFnPointer,
PointerCoercion::UnsafeFnPointer => stable_mir::mir::PointerCoercion::UnsafeFnPointer,
PointerCoercion::ClosureFnPointer(unsafety) => {
stable_mir::mir::PointerCoercion::ClosureFnPointer(unsafety.stable())
}
PointerCoercion::MutToConstPointer => {
stable_mir::mir::PointerCoercion::MutToConstPointer
}
PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer,
PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize,
}
}
}

impl Stable for rustc_hir::Unsafety {
type T = stable_mir::mir::Safety;
fn stable(&self) -> Self::T {
match self {
rustc_hir::Unsafety::Unsafe => stable_mir::mir::Safety::Unsafe,
rustc_hir::Unsafety::Normal => stable_mir::mir::Safety::Normal,
}
}
}

impl Stable for FieldIdx {
type T = usize;
fn stable(&self) -> Self::T {
self.as_usize()
}
}

impl<'tcx> Stable for mir::Operand<'tcx> {
type T = stable_mir::mir::Operand;
fn stable(&self) -> Self::T {
Expand Down Expand Up @@ -229,34 +352,38 @@ impl Stable for mir::UnwindAction {
}
}

fn rustc_assert_msg_to_msg<'tcx>(
assert_message: &rustc_middle::mir::AssertMessage<'tcx>,
) -> stable_mir::mir::AssertMessage {
use rustc_middle::mir::AssertKind;
match assert_message {
AssertKind::BoundsCheck { len, index } => {
stable_mir::mir::AssertMessage::BoundsCheck { len: len.stable(), index: index.stable() }
}
AssertKind::Overflow(bin_op, op1, op2) => {
stable_mir::mir::AssertMessage::Overflow(bin_op.stable(), op1.stable(), op2.stable())
}
AssertKind::OverflowNeg(op) => stable_mir::mir::AssertMessage::OverflowNeg(op.stable()),
AssertKind::DivisionByZero(op) => {
stable_mir::mir::AssertMessage::DivisionByZero(op.stable())
}
AssertKind::RemainderByZero(op) => {
stable_mir::mir::AssertMessage::RemainderByZero(op.stable())
}
AssertKind::ResumedAfterReturn(generator) => {
stable_mir::mir::AssertMessage::ResumedAfterReturn(generator.stable())
}
AssertKind::ResumedAfterPanic(generator) => {
stable_mir::mir::AssertMessage::ResumedAfterPanic(generator.stable())
}
AssertKind::MisalignedPointerDereference { required, found } => {
stable_mir::mir::AssertMessage::MisalignedPointerDereference {
required: required.stable(),
found: found.stable(),
impl<'tcx> Stable for mir::AssertMessage<'tcx> {
type T = stable_mir::mir::AssertMessage;
fn stable(&self) -> Self::T {
use rustc_middle::mir::AssertKind;
match self {
AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck {
len: len.stable(),
index: index.stable(),
},
AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow(
bin_op.stable(),
op1.stable(),
op2.stable(),
),
AssertKind::OverflowNeg(op) => stable_mir::mir::AssertMessage::OverflowNeg(op.stable()),
AssertKind::DivisionByZero(op) => {
stable_mir::mir::AssertMessage::DivisionByZero(op.stable())
}
AssertKind::RemainderByZero(op) => {
stable_mir::mir::AssertMessage::RemainderByZero(op.stable())
}
AssertKind::ResumedAfterReturn(generator) => {
stable_mir::mir::AssertMessage::ResumedAfterReturn(generator.stable())
}
AssertKind::ResumedAfterPanic(generator) => {
stable_mir::mir::AssertMessage::ResumedAfterPanic(generator.stable())
}
AssertKind::MisalignedPointerDereference { required, found } => {
stable_mir::mir::AssertMessage::MisalignedPointerDereference {
required: required.stable(),
found: found.stable(),
}
}
}
}
Expand Down Expand Up @@ -381,7 +508,7 @@ impl<'tcx> Stable for mir::Terminator<'tcx> {
Assert { cond, expected, msg, target, unwind } => Terminator::Assert {
cond: cond.stable(),
expected: *expected,
msg: rustc_assert_msg_to_msg(msg),
msg: msg.stable(),
target: target.as_usize(),
unwind: unwind.stable(),
},
Expand Down
Loading

0 comments on commit 3f73a7d

Please sign in to comment.