Skip to content

Commit efaf425

Browse files
committed
Add Variant and a few more APIs to stable_mir
1 parent e281163 commit efaf425

File tree

7 files changed

+153
-39
lines changed

7 files changed

+153
-39
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
@@ -13,7 +13,7 @@ use stable_mir::mir::mono::{InstanceDef, StaticDef};
1313
use stable_mir::mir::Body;
1414
use stable_mir::ty::{
1515
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FnDef, GenericArgs, LineInfo,
16-
PolyFnSig, RigidTy, Span, TyKind,
16+
PolyFnSig, RigidTy, Span, TyKind, VariantDef,
1717
};
1818
use stable_mir::{self, Crate, CrateItem, DefId, Error, Filename, ItemKind, Symbol};
1919
use std::cell::RefCell;
@@ -209,6 +209,16 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
209209
sig.stable(&mut *tables)
210210
}
211211

212+
fn adt_variants_len(&self, def: AdtDef) -> usize {
213+
let mut tables = self.0.borrow_mut();
214+
def.internal(&mut *tables).variants().len()
215+
}
216+
217+
fn variant_name(&self, def: VariantDef) -> Symbol {
218+
let mut tables = self.0.borrow_mut();
219+
def.internal(&mut *tables).name.to_string()
220+
}
221+
212222
fn eval_target_usize(&self, cnst: &Const) -> Result<u64, Error> {
213223
let mut tables = self.0.borrow_mut();
214224
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/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, PolyFnSig, RigidTy, Span, TraitDecl,
14-
TraitDef, Ty, TyKind,
14+
TraitDef, Ty, TyKind, VariantDef,
1515
};
1616
use crate::{
1717
mir, Crate, CrateItem, CrateItems, DefId, Error, Filename, ImplTraitDecls, ItemKind, Symbol,
@@ -71,6 +71,12 @@ pub trait Context {
7171
/// Retrieve the function signature for the given generic arguments.
7272
fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig;
7373

74+
/// The number of variants in this ADT.
75+
fn adt_variants_len(&self, def: AdtDef) -> usize;
76+
77+
/// The name of a variant.
78+
fn variant_name(&self, def: VariantDef) -> Symbol;
79+
7480
/// Evaluate constant as a target usize.
7581
fn eval_target_usize(&self, cnst: &Const) -> Result<u64, Error>;
7682

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/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 {
@@ -369,6 +379,49 @@ impl AdtDef {
369379
pub fn is_box(&self) -> bool {
370380
with(|cx| cx.adt_is_box(*self))
371381
}
382+
383+
/// The number of variants in this ADT.
384+
pub fn num_variants(&self) -> usize {
385+
with(|cx| cx.adt_variants_len(*self))
386+
}
387+
388+
/// Retrieve the variants in this ADT.
389+
pub fn variants(&self) -> Vec<VariantDef> {
390+
self.variants_iter().collect()
391+
}
392+
393+
/// Iterate over the variants in this ADT.
394+
pub fn variants_iter(&self) -> impl Iterator<Item = VariantDef> + '_ {
395+
(0..self.num_variants())
396+
.map(|idx| VariantDef { idx: VariantIdx::to_val(idx), adt_def: *self })
397+
}
398+
399+
pub fn variant(&self, idx: VariantIdx) -> Option<VariantDef> {
400+
self.variants().get(idx.to_index()).copied()
401+
}
402+
}
403+
404+
/// Definition of a variant, which can be either a struct / union field or an enum variant.
405+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
406+
pub struct VariantDef {
407+
/// The variant index.
408+
///
409+
/// ## Warning
410+
/// Do not access this field directly!
411+
pub idx: VariantIdx,
412+
/// The data type where this variant comes from.
413+
/// For now, we use this to retrieve information about the variant itself so we don't need to
414+
/// cache more information.
415+
///
416+
/// ## Warning
417+
/// Do not access this field directly!
418+
pub adt_def: AdtDef,
419+
}
420+
421+
impl VariantDef {
422+
pub fn name(&self) -> Symbol {
423+
with(|cx| cx.variant_name(*self))
424+
}
372425
}
373426

374427
impl Display for AdtKind {
@@ -906,3 +959,21 @@ macro_rules! index_impl {
906959
index_impl!(ConstId);
907960
index_impl!(Ty);
908961
index_impl!(Span);
962+
963+
/// The source-order index of a variant in a type.
964+
///
965+
/// For example, in the following types,
966+
/// ```ignore(illustrative)
967+
/// enum Demo1 {
968+
/// Variant0 { a: bool, b: i32 },
969+
/// Variant1 { c: u8, d: u64 },
970+
/// }
971+
/// struct Demo2 { e: u8, f: u16, g: u8 }
972+
/// ```
973+
/// `a` is in the variant with the `VariantIdx` of `0`,
974+
/// `c` is in the variant with the `VariantIdx` of `1`, and
975+
/// `g` is in the variant with the `VariantIdx` of `0`.
976+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
977+
pub struct VariantIdx(usize);
978+
979+
index_impl!(VariantIdx);

0 commit comments

Comments
 (0)