Skip to content

Commit a28fd34

Browse files
committed
Add Variant and a few more APIs to stable_mir
1 parent 64d7e0d commit a28fd34

File tree

9 files changed

+158
-41
lines changed

9 files changed

+158
-41
lines changed

compiler/rustc_smir/src/rustc_internal/internal.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@ use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy};
99
use rustc_span::Symbol;
1010
use stable_mir::mir::alloc::AllocId;
1111
use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
12-
use stable_mir::ty::{
13-
AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const,
14-
ExistentialTraitRef, FloatTy, GenericArgKind, GenericArgs, IntTy, Region, RigidTy, Span,
15-
TraitRef, Ty, UintTy,
16-
};
12+
use stable_mir::ty::{AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const, ExistentialTraitRef, FloatTy, GenericArgKind, GenericArgs, IndexedVal, IntTy, Region, RigidTy, Span, TraitRef, Ty, UintTy, VariantDef, VariantIdx};
1713
use stable_mir::{CrateItem, DefId};
1814

1915
use super::RustcInternal;
@@ -141,6 +137,22 @@ impl<'tcx> RustcInternal<'tcx> for FloatTy {
141137
}
142138
}
143139

140+
impl<'tcx> RustcInternal<'tcx> for VariantIdx {
141+
type T = rustc_target::abi::VariantIdx;
142+
143+
fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
144+
rustc_target::abi::VariantIdx::from(self.to_index())
145+
}
146+
}
147+
148+
impl<'tcx> RustcInternal<'tcx> for VariantDef {
149+
type T = &'tcx rustc_ty::VariantDef;
150+
151+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
152+
self.adt_def.internal(tables).variant(self.idx.internal(tables))
153+
}
154+
}
155+
144156
fn ty_const<'tcx>(constant: &Const, tables: &mut Tables<'tcx>) -> rustc_ty::Const<'tcx> {
145157
match constant.internal(tables) {
146158
rustc_middle::mir::Const::Ty(c) => c,

compiler/rustc_smir/src/rustc_smir/context.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use stable_mir::mir::mono::{InstanceDef, StaticDef};
1212
use stable_mir::mir::Body;
1313
use stable_mir::ty::{
1414
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FnDef, GenericArgs, LineInfo,
15-
RigidTy, Span, TyKind,
15+
RigidTy, Span, TyKind, VariantDef,
1616
};
1717
use stable_mir::{self, Crate, CrateItem, Error, Filename, ItemKind, Symbol};
1818
use std::cell::RefCell;
@@ -195,6 +195,16 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
195195
def.internal(&mut *tables).is_box()
196196
}
197197

198+
fn adt_variants_len(&self, def: AdtDef) -> usize {
199+
let mut tables = self.0.borrow_mut();
200+
def.internal(&mut *tables).variants().len()
201+
}
202+
203+
fn variant_name(&self, def: VariantDef) -> Symbol {
204+
let mut tables = self.0.borrow_mut();
205+
def.internal(&mut *tables).name.to_string()
206+
}
207+
198208
fn eval_target_usize(&self, cnst: &Const) -> Result<u64, Error> {
199209
let mut tables = self.0.borrow_mut();
200210
let mir_const = cnst.internal(&mut *tables);

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
517517
mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => {
518518
stable_mir::mir::AggregateKind::Adt(
519519
tables.adt_def(*def_id),
520-
var_idx.index(),
520+
var_idx.stable(tables),
521521
generic_arg.stable(tables),
522522
user_ty_index.map(|idx| idx.index()),
523523
field_idx.map(|idx| idx.index()),

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

+13-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Conversion of internal Rust compiler items to stable ones.
22
33
use rustc_target::abi::FieldIdx;
4-
use stable_mir::mir::VariantIdx;
4+
use stable_mir::ty::{IndexedVal, VariantIdx};
55

66
use crate::rustc_smir::{Stable, Tables};
77

@@ -25,17 +25,10 @@ impl<'tcx> Stable<'tcx> for FieldIdx {
2525
}
2626
}
2727

28-
impl<'tcx> Stable<'tcx> for (rustc_target::abi::VariantIdx, FieldIdx) {
29-
type T = (usize, usize);
30-
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
31-
(self.0.as_usize(), self.1.as_usize())
32-
}
33-
}
34-
3528
impl<'tcx> Stable<'tcx> for rustc_target::abi::VariantIdx {
3629
type T = VariantIdx;
3730
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
38-
self.as_usize()
31+
VariantIdx::to_val(self.as_usize())
3932
}
4033
}
4134

@@ -74,3 +67,14 @@ impl<'tcx> Stable<'tcx> for rustc_span::Span {
7467
tables.create_span(*self)
7568
}
7669
}
70+
71+
impl<'tcx, T, U> Stable<'tcx> for (T, U)
72+
where
73+
T: Stable<'tcx>,
74+
U: Stable<'tcx>,
75+
{
76+
type T = (T::T, U::T);
77+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
78+
(self.0.stable(tables), self.1.stable(tables))
79+
}
80+
}

compiler/rustc_smir/src/rustc_smir/convert/ty.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,9 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
777777
let kind = match self.def {
778778
ty::InstanceDef::Item(..) => stable_mir::mir::mono::InstanceKind::Item,
779779
ty::InstanceDef::Intrinsic(..) => stable_mir::mir::mono::InstanceKind::Intrinsic,
780-
ty::InstanceDef::Virtual(..) => stable_mir::mir::mono::InstanceKind::Virtual,
780+
ty::InstanceDef::Virtual(_def_id, idx) => {
781+
stable_mir::mir::mono::InstanceKind::Virtual { idx }
782+
}
781783
ty::InstanceDef::VTableShim(..)
782784
| ty::InstanceDef::ReifyShim(..)
783785
| ty::InstanceDef::FnPtrAddrShim(..)

compiler/stable_mir/src/compiler_interface.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::mir::Body;
1111
use crate::ty::{
1212
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FnDef, GenericArgs,
1313
GenericPredicates, Generics, ImplDef, ImplTrait, LineInfo, RigidTy, Span, TraitDecl, TraitDef,
14-
Ty, TyKind,
14+
Ty, TyKind, VariantDef,
1515
};
1616
use crate::{
1717
mir, Crate, CrateItem, CrateItems, DefId, Error, Filename, ImplTraitDecls, ItemKind, Symbol,
@@ -64,6 +64,12 @@ pub trait Context {
6464
/// Returns if the ADT is a box.
6565
fn adt_is_box(&self, def: AdtDef) -> bool;
6666

67+
/// The number of variants in this ADT.
68+
fn adt_variants_len(&self, def: AdtDef) -> usize;
69+
70+
/// The name of a variant.
71+
fn variant_name(&self, def: VariantDef) -> Symbol;
72+
6773
/// Evaluate constant as a target usize.
6874
fn eval_target_usize(&self, cnst: &Const) -> Result<u64, Error>;
6975

compiler/stable_mir/src/mir/body.rs

+33-22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::mir::pretty::{function_body, pretty_statement, pretty_terminator};
22
use crate::ty::{
33
AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, RigidTy, Ty, TyKind,
4+
VariantIdx,
45
};
56
use crate::{Error, Opaque, Span, Symbol};
67
use std::io;
@@ -9,17 +10,17 @@ use std::io;
910
pub struct Body {
1011
pub blocks: Vec<BasicBlock>,
1112

12-
// Declarations of locals within the function.
13-
//
14-
// The first local is the return value pointer, followed by `arg_count`
15-
// locals for the function arguments, followed by any user-declared
16-
// variables and temporaries.
13+
/// Declarations of locals within the function.
14+
///
15+
/// The first local is the return value pointer, followed by `arg_count`
16+
/// locals for the function arguments, followed by any user-declared
17+
/// variables and temporaries.
1718
pub(super) locals: LocalDecls,
1819

19-
// The number of arguments this function takes.
20+
/// The number of arguments this function takes.
2021
pub(super) arg_count: usize,
2122

22-
// Debug information pertaining to user variables, including captures.
23+
/// Debug information pertaining to user variables, including captures.
2324
pub(super) var_debug_info: Vec<VarDebugInfo>,
2425
}
2526

@@ -69,6 +70,11 @@ impl Body {
6970
&self.locals
7071
}
7172

73+
/// Get the local declaration for this local.
74+
pub fn local_decl(&self, local: Local) -> Option<&LocalDecl> {
75+
self.locals.get(local)
76+
}
77+
7278
pub fn dump<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
7379
writeln!(w, "{}", function_body(self))?;
7480
self.blocks
@@ -492,12 +498,32 @@ pub struct Place {
492498
pub projection: Vec<ProjectionElem>,
493499
}
494500

501+
impl From<Local> for Place {
502+
fn from(local: Local) -> Self {
503+
Place { local, projection: vec![] }
504+
}
505+
}
506+
507+
/// Debug information pertaining to a user variable.
495508
#[derive(Clone, Debug, Eq, PartialEq)]
496509
pub struct VarDebugInfo {
510+
/// The variable name.
497511
pub name: Symbol,
512+
513+
/// Source info of the user variable, including the scope
514+
/// within which the variable is visible (to debuginfo)
498515
pub source_info: SourceInfo,
516+
517+
/// The user variable's data is split across several fragments,
518+
/// each described by a `VarDebugInfoFragment`.
499519
pub composite: Option<VarDebugInfoFragment>,
520+
521+
/// Where the data for this user variable is to be found.
500522
pub value: VarDebugInfoContents,
523+
524+
/// When present, indicates what argument number this variable is in the function that it
525+
/// originated from (starting from 1). Note, if MIR inlining is enabled, then this is the
526+
/// argument number in the original function before it was inlined.
501527
pub argument_index: Option<u16>,
502528
}
503529

@@ -634,21 +660,6 @@ pub const RETURN_LOCAL: Local = 0;
634660
/// `g`'s `FieldIdx` is `2`.
635661
type FieldIdx = usize;
636662

637-
/// The source-order index of a variant in a type.
638-
///
639-
/// For example, in the following types,
640-
/// ```ignore(illustrative)
641-
/// enum Demo1 {
642-
/// Variant0 { a: bool, b: i32 },
643-
/// Variant1 { c: u8, d: u64 },
644-
/// }
645-
/// struct Demo2 { e: u8, f: u16, g: u8 }
646-
/// ```
647-
/// `a` is in the variant with the `VariantIdx` of `0`,
648-
/// `c` is in the variant with the `VariantIdx` of `1`, and
649-
/// `g` is in the variant with the `VariantIdx` of `0`.
650-
pub type VariantIdx = usize;
651-
652663
type UserTypeAnnotationIndex = usize;
653664

654665
#[derive(Clone, Debug, Eq, PartialEq)]

compiler/stable_mir/src/mir/mono.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ pub enum InstanceKind {
2727
/// A compiler intrinsic function.
2828
Intrinsic,
2929
/// A virtual function definition stored in a VTable.
30-
Virtual,
30+
/// The `idx` field indicates the position in the VTable for this instance.
31+
Virtual { idx: usize },
3132
/// A compiler generated shim.
3233
Shim,
3334
}

compiler/stable_mir/src/ty.rs

+71
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ impl Ty {
3030
pub fn try_new_array(elem_ty: Ty, size: u64) -> Result<Ty, Error> {
3131
Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, Const::try_from_target_usize(size)?)))
3232
}
33+
34+
/// Create a new pointer type.
35+
pub fn new_ptr(pointee_ty: Ty, mutability: Mutability) -> Ty {
36+
Ty::from_rigid_kind(RigidTy::RawPtr(pointee_ty, mutability))
37+
}
38+
39+
/// Create a type representing `usize`.
40+
pub fn usize_ty() -> Ty {
41+
Ty::from_rigid_kind(RigidTy::Uint(UintTy::Usize))
42+
}
3343
}
3444

3545
impl Ty {
@@ -347,6 +357,49 @@ impl AdtDef {
347357
pub fn is_box(&self) -> bool {
348358
with(|cx| cx.adt_is_box(*self))
349359
}
360+
361+
/// The number of variants in this ADT.
362+
pub fn num_variants(&self) -> usize {
363+
with(|cx| cx.adt_variants_len(*self))
364+
}
365+
366+
/// Retrieve the variants in this ADT.
367+
pub fn variants(&self) -> Vec<VariantDef> {
368+
self.variants_iter().collect()
369+
}
370+
371+
/// Iterate over the variants in this ADT.
372+
pub fn variants_iter(&self) -> impl Iterator<Item = VariantDef> + '_ {
373+
(0..self.num_variants())
374+
.map(|idx| VariantDef { idx: VariantIdx::to_val(idx), adt_def: *self })
375+
}
376+
377+
pub fn variant(&self, idx: VariantIdx) -> Option<VariantDef> {
378+
self.variants().get(idx.to_index()).copied()
379+
}
380+
}
381+
382+
/// Definition of a variant, which can be either a struct / union field or an enum variant.
383+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
384+
pub struct VariantDef {
385+
/// The variant index.
386+
///
387+
/// ## Warning
388+
/// Do not access this field directly!
389+
pub idx: VariantIdx,
390+
/// The data type where this variant comes from.
391+
/// For now, we use this to retrieve information about the variant itself so we don't need to
392+
/// cache more information.
393+
///
394+
/// ## Warning
395+
/// Do not access this field directly!
396+
pub adt_def: AdtDef,
397+
}
398+
399+
impl VariantDef {
400+
pub fn name(&self) -> Symbol {
401+
with(|cx| cx.variant_name(*self))
402+
}
350403
}
351404

352405
impl Display for AdtKind {
@@ -874,3 +927,21 @@ macro_rules! index_impl {
874927
index_impl!(ConstId);
875928
index_impl!(Ty);
876929
index_impl!(Span);
930+
931+
/// The source-order index of a variant in a type.
932+
///
933+
/// For example, in the following types,
934+
/// ```ignore(illustrative)
935+
/// enum Demo1 {
936+
/// Variant0 { a: bool, b: i32 },
937+
/// Variant1 { c: u8, d: u64 },
938+
/// }
939+
/// struct Demo2 { e: u8, f: u16, g: u8 }
940+
/// ```
941+
/// `a` is in the variant with the `VariantIdx` of `0`,
942+
/// `c` is in the variant with the `VariantIdx` of `1`, and
943+
/// `g` is in the variant with the `VariantIdx` of `0`.
944+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
945+
pub struct VariantIdx(usize);
946+
947+
index_impl!(VariantIdx);

0 commit comments

Comments
 (0)