Skip to content

Commit 1720b10

Browse files
committed
Add FieldDef to StableMIR and methods to get type
1 parent e19c7cd commit 1720b10

File tree

6 files changed

+95
-5
lines changed

6 files changed

+95
-5
lines changed

compiler/rustc_smir/src/rustc_smir/context.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use stable_mir::mir::alloc::GlobalAlloc;
1212
use stable_mir::mir::mono::{InstanceDef, StaticDef};
1313
use stable_mir::mir::Body;
1414
use stable_mir::ty::{
15-
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FnDef, GenericArgs, LineInfo,
16-
PolyFnSig, RigidTy, Span, TyKind, VariantDef,
15+
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, GenericArgs,
16+
LineInfo, PolyFnSig, RigidTy, Span, TyKind, VariantDef,
1717
};
1818
use stable_mir::{self, Crate, CrateItem, DefId, Error, Filename, ItemKind, Symbol};
1919
use std::cell::RefCell;
@@ -219,6 +219,11 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
219219
def.internal(&mut *tables).name.to_string()
220220
}
221221

222+
fn variant_fields(&self, def: VariantDef) -> Vec<FieldDef> {
223+
let mut tables = self.0.borrow_mut();
224+
def.internal(&mut *tables).fields.iter().map(|f| f.stable(&mut *tables)).collect()
225+
}
226+
222227
fn eval_target_usize(&self, cnst: &Const) -> Result<u64, Error> {
223228
let mut tables = self.0.borrow_mut();
224229
let mir_const = cnst.internal(&mut *tables);
@@ -250,6 +255,18 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
250255
tables.tcx.type_of(item.internal(&mut *tables)).instantiate_identity().stable(&mut *tables)
251256
}
252257

258+
fn def_ty_with_args(
259+
&self,
260+
item: stable_mir::DefId,
261+
args: &GenericArgs,
262+
) -> Result<stable_mir::ty::Ty, Error> {
263+
let mut tables = self.0.borrow_mut();
264+
let args = args.internal(&mut *tables);
265+
let def_ty = tables.tcx.type_of(item.internal(&mut *tables));
266+
// FIXME(celinval): use try_fold instead to avoid crashing.
267+
Ok(def_ty.instantiate(tables.tcx, args).stable(&mut *tables))
268+
}
269+
253270
fn const_literal(&self, cnst: &stable_mir::ty::Const) -> String {
254271
internal(cnst).to_string()
255272
}

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

+18
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
6060
}
6161
}
6262

63+
impl<'tcx> Stable<'tcx> for rustc_span::Symbol {
64+
type T = stable_mir::Symbol;
65+
66+
fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
67+
self.to_string()
68+
}
69+
}
70+
6371
impl<'tcx> Stable<'tcx> for rustc_span::Span {
6472
type T = stable_mir::ty::Span;
6573

@@ -68,6 +76,16 @@ impl<'tcx> Stable<'tcx> for rustc_span::Span {
6876
}
6977
}
7078

79+
impl<'tcx, T> Stable<'tcx> for &[T]
80+
where
81+
T: Stable<'tcx>,
82+
{
83+
type T = Vec<T::T>;
84+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
85+
self.iter().map(|e| e.stable(tables)).collect()
86+
}
87+
}
88+
7189
impl<'tcx, T, U> Stable<'tcx> for (T, U)
7290
where
7391
T: Stable<'tcx>,

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

+11
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,17 @@ impl<'tcx> Stable<'tcx> for ty::AdtKind {
137137
}
138138
}
139139

140+
impl<'tcx> Stable<'tcx> for ty::FieldDef {
141+
type T = stable_mir::ty::FieldDef;
142+
143+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
144+
stable_mir::ty::FieldDef {
145+
def: tables.create_def_id(self.did),
146+
name: self.name.stable(tables),
147+
}
148+
}
149+
}
150+
140151
impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> {
141152
type T = stable_mir::ty::GenericArgs;
142153
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {

compiler/stable_mir/src/compiler_interface.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::mir::alloc::{AllocId, GlobalAlloc};
99
use crate::mir::mono::{Instance, InstanceDef, StaticDef};
1010
use crate::mir::Body;
1111
use crate::ty::{
12-
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FnDef, GenericArgs,
12+
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, GenericArgs,
1313
GenericPredicates, Generics, ImplDef, ImplTrait, LineInfo, PolyFnSig, RigidTy, Span, TraitDecl,
1414
TraitDef, Ty, TyKind, VariantDef,
1515
};
@@ -76,6 +76,7 @@ pub trait Context {
7676

7777
/// The name of a variant.
7878
fn variant_name(&self, def: VariantDef) -> Symbol;
79+
fn variant_fields(&self, def: VariantDef) -> Vec<FieldDef>;
7980

8081
/// Evaluate constant as a target usize.
8182
fn eval_target_usize(&self, cnst: &Const) -> Result<u64, Error>;
@@ -89,6 +90,9 @@ pub trait Context {
8990
/// Returns the type of given crate item.
9091
fn def_ty(&self, item: DefId) -> Ty;
9192

93+
/// Returns the type of given definition instantiated with the given arguments.
94+
fn def_ty_with_args(&self, item: DefId, args: &GenericArgs) -> Result<Ty, Error>;
95+
9296
/// Returns literal value of a const as a string.
9397
fn const_literal(&self, cnst: &Const) -> String;
9498

compiler/stable_mir/src/mir/body.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ pub const RETURN_LOCAL: Local = 0;
658658
/// `b`'s `FieldIdx` is `1`,
659659
/// `c`'s `FieldIdx` is `0`, and
660660
/// `g`'s `FieldIdx` is `2`.
661-
type FieldIdx = usize;
661+
pub type FieldIdx = usize;
662662

663663
type UserTypeAnnotationIndex = usize;
664664

compiler/stable_mir/src/ty.rs

+41-1
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,16 @@ impl AdtDef {
376376
with(|cx| cx.adt_kind(*self))
377377
}
378378

379+
/// Retrieve the type of this Adt.
380+
pub fn ty(&self) -> Ty {
381+
with(|cx| cx.def_ty(self.0))
382+
}
383+
384+
/// Retrieve the type of this Adt instantiating the type with the given arguments.
385+
pub fn ty_with_args(&self, args: &GenericArgs) -> Result<Ty, Error> {
386+
with(|cx| cx.def_ty_with_args(self.0, args))
387+
}
388+
379389
pub fn is_box(&self) -> bool {
380390
with(|cx| cx.adt_is_box(*self))
381391
}
@@ -397,7 +407,7 @@ impl AdtDef {
397407
}
398408

399409
pub fn variant(&self, idx: VariantIdx) -> Option<VariantDef> {
400-
self.variants().get(idx.to_index()).copied()
410+
(idx.to_index() < self.num_variants()).then_some(VariantDef { idx, adt_def: *self })
401411
}
402412
}
403413

@@ -422,6 +432,36 @@ impl VariantDef {
422432
pub fn name(&self) -> Symbol {
423433
with(|cx| cx.variant_name(*self))
424434
}
435+
436+
/// Retrieve all the fields in this variant.
437+
// We expect user to cache this and use it directly since today it is expensive to generate all
438+
// fields name.
439+
pub fn fields(&self) -> Vec<FieldDef> {
440+
with(|cx| cx.variant_fields(*self))
441+
}
442+
}
443+
444+
pub struct FieldDef {
445+
/// The field definition.
446+
///
447+
/// ## Warning
448+
/// Do not access this field directly! This is public for the compiler to have access to it.
449+
pub def: DefId,
450+
451+
/// The field name.
452+
pub name: Symbol,
453+
}
454+
455+
impl FieldDef {
456+
/// Retrieve the type of this field instantiating the type with the given arguments.
457+
pub fn ty_with_args(&self, args: &GenericArgs) -> Result<Ty, Error> {
458+
with(|cx| cx.def_ty_with_args(self.def, args))
459+
}
460+
461+
/// Retrieve the type of this field.
462+
pub fn ty(&self) -> Ty {
463+
with(|cx| cx.def_ty(self.def))
464+
}
425465
}
426466

427467
impl Display for AdtKind {

0 commit comments

Comments
 (0)