Remove fold code and add Const::internal()

We are not planning to support user generated constant in the
foreseeable future, so we are removing the Fold logic for now in
favor of the Instance::resolve logic.

The Instance::resolve was however incomplete, since we weren't handling
internalizing constants yet. Thus, I added that.

I decided to keep the Const fields private in case we decide to
translate them lazily.
This commit is contained in:
Celina G. Val 2023-10-23 20:32:31 -07:00
parent 151256bd4b
commit 3f60165d27
10 changed files with 144 additions and 404 deletions

View file

@ -13,6 +13,7 @@
#![cfg_attr(not(bootstrap), doc(rust_logo))]
#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
#![cfg_attr(not(bootstrap), allow(internal_features))]
#![allow(rustc::usage_of_ty_tykind)]
pub mod rustc_internal;

View file

@ -4,7 +4,7 @@
//! due to incomplete stable coverage.
// Prefer importing stable_mir over internal rustc constructs to make this file more readable.
use crate::rustc_smir::{MaybeStable, Tables};
use crate::rustc_smir::Tables;
use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy};
use stable_mir::ty::{Const, GenericArgKind, GenericArgs, Region, Ty};
use stable_mir::DefId;
@ -31,7 +31,7 @@ impl<'tcx> RustcInternal<'tcx> for GenericArgKind {
match self {
GenericArgKind::Lifetime(reg) => reg.internal(tables).into(),
GenericArgKind::Type(ty) => ty.internal(tables).into(),
GenericArgKind::Const(cnst) => cnst.internal(tables).into(),
GenericArgKind::Const(cnst) => ty_const(cnst, tables).into(),
}
}
}
@ -46,16 +46,22 @@ impl<'tcx> RustcInternal<'tcx> for Region {
impl<'tcx> RustcInternal<'tcx> for Ty {
type T = InternalTy<'tcx>;
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
match tables.types[self.0] {
MaybeStable::Stable(_) => todo!(),
MaybeStable::Rustc(ty) => ty,
tables.types[self.0]
}
}
fn ty_const<'tcx>(constant: &Const, tables: &mut Tables<'tcx>) -> rustc_ty::Const<'tcx> {
match constant.internal(tables) {
rustc_middle::mir::Const::Ty(c) => c,
cnst => {
panic!("Trying to covert constant `{constant:?}` to type constant, but found {cnst:?}")
}
}
}
impl<'tcx> RustcInternal<'tcx> for Const {
type T = rustc_ty::Const<'tcx>;
fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
todo!()
type T = rustc_middle::mir::Const<'tcx>;
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
tables.constants[self.id]
}
}

View file

@ -169,6 +169,7 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
spans: IndexMap::default(),
types: vec![],
instances: IndexMap::default(),
constants: IndexMap::default(),
}));
stable_mir::run(&tables, || init(&tables, f));
}

View file

@ -20,7 +20,8 @@ use rustc_target::abi::FieldIdx;
use stable_mir::mir::mono::InstanceDef;
use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx};
use stable_mir::ty::{
FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span, TyKind, UintTy,
Const, ConstId, ConstantKind, FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy,
Span, TyKind, UintTy,
};
use stable_mir::{self, opaque, Context, Filename};
use std::cell::RefCell;
@ -147,14 +148,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind {
let mut tables = self.0.borrow_mut();
tables.types[ty.0].clone().stable(&mut *tables)
}
fn mk_ty(&self, kind: TyKind) -> stable_mir::ty::Ty {
let mut tables = self.0.borrow_mut();
let n = tables.types.len();
tables.types.push(MaybeStable::Stable(kind));
stable_mir::ty::Ty(n)
tables.types[ty.0].kind().stable(&mut *tables)
}
fn generics_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
@ -213,8 +207,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
let mut tables = self.0.borrow_mut();
let instance = tables.instances[def];
let ty = instance.ty(tables.tcx, ParamEnv::empty());
tables.intern_ty(ty)
instance.ty(tables.tcx, ParamEnv::empty()).stable(&mut *tables)
}
fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
@ -252,33 +245,6 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
}
}
#[derive(Clone)]
pub enum MaybeStable<S, R> {
Stable(S),
Rustc(R),
}
impl<'tcx, S, R> MaybeStable<S, R> {
fn stable(self, tables: &mut Tables<'tcx>) -> S
where
R: Stable<'tcx, T = S>,
{
match self {
MaybeStable::Stable(s) => s,
MaybeStable::Rustc(r) => r.stable(tables),
}
}
}
impl<S, R: PartialEq> PartialEq<R> for MaybeStable<S, R> {
fn eq(&self, other: &R) -> bool {
match self {
MaybeStable::Stable(_) => false,
MaybeStable::Rustc(r) => r == other,
}
}
}
pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell<Tables<'tcx>>);
pub struct Tables<'tcx> {
@ -286,8 +252,9 @@ pub struct Tables<'tcx> {
pub(crate) def_ids: IndexMap<DefId, stable_mir::DefId>,
pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
pub(crate) spans: IndexMap<rustc_span::Span, Span>,
pub(crate) types: Vec<MaybeStable<TyKind, Ty<'tcx>>>,
pub(crate) types: Vec<Ty<'tcx>>,
pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
pub(crate) constants: IndexMap<mir::Const<'tcx>, ConstId>,
}
impl<'tcx> Tables<'tcx> {
@ -296,9 +263,13 @@ impl<'tcx> Tables<'tcx> {
return stable_mir::ty::Ty(id);
}
let id = self.types.len();
self.types.push(MaybeStable::Rustc(ty));
self.types.push(ty);
stable_mir::ty::Ty(id)
}
fn intern_const(&mut self, constant: mir::Const<'tcx>) -> ConstId {
self.constants.create_or_fetch(constant)
}
}
/// Build a stable mir crate from a given crate number.
@ -338,7 +309,7 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
.local_decls
.iter()
.map(|decl| stable_mir::mir::LocalDecl {
ty: tables.intern_ty(decl.ty),
ty: decl.ty.stable(tables),
span: decl.source_info.span.stable(tables),
})
.collect(),
@ -436,7 +407,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast(
cast_kind.stable(tables),
op.stable(tables),
tables.intern_ty(*ty),
ty.stable(tables),
),
BinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::BinaryOp(
bin_op.stable(tables),
@ -449,7 +420,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
ops.1.stable(tables),
),
NullaryOp(null_op, ty) => {
stable_mir::mir::Rvalue::NullaryOp(null_op.stable(tables), tables.intern_ty(*ty))
stable_mir::mir::Rvalue::NullaryOp(null_op.stable(tables), ty.stable(tables))
}
UnaryOp(un_op, op) => {
stable_mir::mir::Rvalue::UnaryOp(un_op.stable(tables), op.stable(tables))
@ -460,7 +431,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables), operands)
}
ShallowInitBox(op, ty) => {
stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), tables.intern_ty(*ty))
stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), ty.stable(tables))
}
CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables)),
}
@ -604,7 +575,7 @@ impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> {
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
use stable_mir::ty::TermKind;
match self {
ty::TermKind::Ty(ty) => TermKind::Type(tables.intern_ty(*ty)),
ty::TermKind::Ty(ty) => TermKind::Type(ty.stable(tables)),
ty::TermKind::Const(cnst) => {
let cnst = cnst.stable(tables);
TermKind::Const(cnst)
@ -885,7 +856,7 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
match self {
mir::AggregateKind::Array(ty) => {
stable_mir::mir::AggregateKind::Array(tables.intern_ty(*ty))
stable_mir::mir::AggregateKind::Array(ty.stable(tables))
}
mir::AggregateKind::Tuple => stable_mir::mir::AggregateKind::Tuple,
mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => {
@ -1053,7 +1024,7 @@ impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> {
use stable_mir::ty::GenericArgKind;
match self {
ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(region.stable(tables)),
ty::GenericArgKind::Type(ty) => GenericArgKind::Type(tables.intern_ty(*ty)),
ty::GenericArgKind::Type(ty) => GenericArgKind::Type(ty.stable(tables)),
ty::GenericArgKind::Const(cnst) => GenericArgKind::Const(cnst.stable(tables)),
}
}
@ -1099,11 +1070,7 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
use stable_mir::ty::{Abi, FnSig};
FnSig {
inputs_and_output: self
.inputs_and_output
.iter()
.map(|ty| tables.intern_ty(ty))
.collect(),
inputs_and_output: self.inputs_and_output.iter().map(|ty| ty.stable(tables)).collect(),
c_variadic: self.c_variadic,
unsafety: self.unsafety.stable(tables),
abi: match self.abi {
@ -1241,9 +1208,16 @@ impl<'tcx> Stable<'tcx> for hir::Movability {
}
impl<'tcx> Stable<'tcx> for Ty<'tcx> {
type T = stable_mir::ty::Ty;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
tables.intern_ty(*self)
}
}
impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> {
type T = stable_mir::ty::TyKind;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
match self.kind() {
match self {
ty::Bool => TyKind::RigidTy(RigidTy::Bool),
ty::Char => TyKind::RigidTy(RigidTy::Char),
ty::Int(int_ty) => TyKind::RigidTy(RigidTy::Int(int_ty.stable(tables))),
@ -1256,15 +1230,15 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
ty::Foreign(def_id) => TyKind::RigidTy(RigidTy::Foreign(tables.foreign_def(*def_id))),
ty::Str => TyKind::RigidTy(RigidTy::Str),
ty::Array(ty, constant) => {
TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), constant.stable(tables)))
TyKind::RigidTy(RigidTy::Array(ty.stable(tables), constant.stable(tables)))
}
ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(tables.intern_ty(*ty))),
ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(ty.stable(tables))),
ty::RawPtr(ty::TypeAndMut { ty, mutbl }) => {
TyKind::RigidTy(RigidTy::RawPtr(tables.intern_ty(*ty), mutbl.stable(tables)))
TyKind::RigidTy(RigidTy::RawPtr(ty.stable(tables), mutbl.stable(tables)))
}
ty::Ref(region, ty, mutbl) => TyKind::RigidTy(RigidTy::Ref(
region.stable(tables),
tables.intern_ty(*ty),
ty.stable(tables),
mutbl.stable(tables),
)),
ty::FnDef(def_id, generic_args) => {
@ -1291,9 +1265,9 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
movability.stable(tables),
)),
ty::Never => TyKind::RigidTy(RigidTy::Never),
ty::Tuple(fields) => TyKind::RigidTy(RigidTy::Tuple(
fields.iter().map(|ty| tables.intern_ty(ty)).collect(),
)),
ty::Tuple(fields) => {
TyKind::RigidTy(RigidTy::Tuple(fields.iter().map(|ty| ty.stable(tables)).collect()))
}
ty::Alias(alias_kind, alias_ty) => {
TyKind::Alias(alias_kind.stable(tables), alias_ty.stable(tables))
}
@ -1312,32 +1286,32 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
type T = stable_mir::ty::Const;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
stable_mir::ty::Const {
literal: match self.kind() {
ty::Value(val) => {
let const_val = tables.tcx.valtree_to_const_val((self.ty(), val));
stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
self.ty(),
const_val,
tables,
))
}
ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)),
ty::ErrorCt(_) => unreachable!(),
ty::InferCt(_) => unreachable!(),
ty::BoundCt(_, _) => unimplemented!(),
ty::PlaceholderCt(_) => unimplemented!(),
ty::Unevaluated(uv) => {
stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
def: tables.const_def(uv.def),
args: uv.args.stable(tables),
promoted: None,
})
}
ty::ExprCt(_) => unimplemented!(),
},
ty: tables.intern_ty(self.ty()),
}
let kind = match self.kind() {
ty::Value(val) => {
let const_val = tables.tcx.valtree_to_const_val((self.ty(), val));
stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
self.ty(),
const_val,
tables,
))
}
ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)),
ty::ErrorCt(_) => unreachable!(),
ty::InferCt(_) => unreachable!(),
ty::BoundCt(_, _) => unimplemented!(),
ty::PlaceholderCt(_) => unimplemented!(),
ty::Unevaluated(uv) => {
stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
def: tables.const_def(uv.def),
args: uv.args.stable(tables),
promoted: None,
})
}
ty::ExprCt(_) => unimplemented!(),
};
let ty = self.ty().stable(tables);
let id = tables.intern_const(mir::Const::Ty(*self));
Const::new(kind, ty, id)
}
}
@ -1422,22 +1396,23 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
match *self {
mir::Const::Ty(c) => c.stable(tables),
mir::Const::Unevaluated(unev_const, ty) => stable_mir::ty::Const {
literal: stable_mir::ty::ConstantKind::Unevaluated(
stable_mir::ty::UnevaluatedConst {
mir::Const::Unevaluated(unev_const, ty) => {
let kind =
stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
def: tables.const_def(unev_const.def),
args: unev_const.args.stable(tables),
promoted: unev_const.promoted.map(|u| u.as_u32()),
},
),
ty: tables.intern_ty(ty),
},
mir::Const::Val(val, ty) => stable_mir::ty::Const {
literal: stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
ty, val, tables,
)),
ty: tables.intern_ty(ty),
},
});
let ty = ty.stable(tables);
let id = tables.intern_const(*self);
Const::new(kind, ty, id)
}
mir::Const::Val(val, ty) => {
let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables));
let ty = ty.stable(tables);
let id = tables.intern_const(*self);
Const::new(kind, ty, id)
}
}
}
}
@ -1560,7 +1535,7 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
TypeOutlives(type_outlives) => {
let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives;
stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate(
tables.intern_ty(a),
a.stable(tables),
b.stable(tables),
))
}
@ -1569,7 +1544,7 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
}
ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType(
const_.stable(tables),
tables.intern_ty(ty),
ty.stable(tables),
),
WellFormed(generic_arg) => {
stable_mir::ty::ClauseKind::WellFormed(generic_arg.unpack().stable(tables))
@ -1599,7 +1574,7 @@ impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> {
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
let ty::SubtypePredicate { a, b, a_is_expected: _ } = self;
stable_mir::ty::SubtypePredicate { a: tables.intern_ty(*a), b: tables.intern_ty(*b) }
stable_mir::ty::SubtypePredicate { a: a.stable(tables), b: b.stable(tables) }
}
}
@ -1608,7 +1583,7 @@ impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> {
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
let ty::CoercePredicate { a, b } = self;
stable_mir::ty::CoercePredicate { a: tables.intern_ty(*a), b: tables.intern_ty(*b) }
stable_mir::ty::CoercePredicate { a: a.stable(tables), b: b.stable(tables) }
}
}

View file

@ -1,245 +0,0 @@
use std::ops::ControlFlow;
use crate::Opaque;
use super::ty::{
Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind,
GenericArgs, Promoted, Region, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst,
};
pub trait Folder: Sized {
type Break;
fn fold_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
ty.super_fold(self)
}
fn fold_const(&mut self, c: &Const) -> ControlFlow<Self::Break, Const> {
c.super_fold(self)
}
fn fold_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break, Region> {
reg.super_fold(self)
}
}
pub trait Foldable: Sized + Clone {
fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
self.super_fold(folder)
}
fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self>;
}
impl Foldable for Ty {
fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
folder.fold_ty(self)
}
fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
let mut kind = self.kind();
match &mut kind {
super::ty::TyKind::RigidTy(ty) => *ty = ty.fold(folder)?,
super::ty::TyKind::Alias(_, alias) => alias.args = alias.args.fold(folder)?,
super::ty::TyKind::Param(_) => {}
super::ty::TyKind::Bound(_, _) => {}
}
ControlFlow::Continue(kind.into())
}
}
impl Foldable for Const {
fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
folder.fold_const(self)
}
fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
let mut this = self.clone();
match &mut this.literal {
super::ty::ConstantKind::Allocated(alloc) => *alloc = alloc.fold(folder)?,
super::ty::ConstantKind::Unevaluated(uv) => *uv = uv.fold(folder)?,
super::ty::ConstantKind::Param(_) => {}
}
this.ty = this.ty.fold(folder)?;
ControlFlow::Continue(this)
}
}
impl Foldable for Opaque {
fn super_fold<V: Folder>(&self, _folder: &mut V) -> ControlFlow<V::Break, Self> {
ControlFlow::Continue(self.clone())
}
}
impl Foldable for Allocation {
fn super_fold<V: Folder>(&self, _folder: &mut V) -> ControlFlow<V::Break, Self> {
ControlFlow::Continue(self.clone())
}
}
impl Foldable for UnevaluatedConst {
fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
let UnevaluatedConst { def, args, promoted } = self;
ControlFlow::Continue(UnevaluatedConst {
def: def.fold(folder)?,
args: args.fold(folder)?,
promoted: promoted.fold(folder)?,
})
}
}
impl Foldable for ConstDef {
fn super_fold<V: Folder>(&self, _folder: &mut V) -> ControlFlow<V::Break, Self> {
ControlFlow::Continue(*self)
}
}
impl<T: Foldable> Foldable for Option<T> {
fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
ControlFlow::Continue(match self {
Some(val) => Some(val.fold(folder)?),
None => None,
})
}
}
impl Foldable for Promoted {
fn super_fold<V: Folder>(&self, _folder: &mut V) -> ControlFlow<V::Break, Self> {
ControlFlow::Continue(*self)
}
}
impl Foldable for GenericArgs {
fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
ControlFlow::Continue(GenericArgs(self.0.fold(folder)?))
}
}
impl Foldable for Region {
fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
folder.fold_reg(self)
}
fn super_fold<V: Folder>(&self, _: &mut V) -> ControlFlow<V::Break, Self> {
ControlFlow::Continue(self.clone())
}
}
impl Foldable for GenericArgKind {
fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
let mut this = self.clone();
match &mut this {
GenericArgKind::Lifetime(lt) => *lt = lt.fold(folder)?,
GenericArgKind::Type(t) => *t = t.fold(folder)?,
GenericArgKind::Const(c) => *c = c.fold(folder)?,
}
ControlFlow::Continue(this)
}
}
impl Foldable for RigidTy {
fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
let mut this = self.clone();
match &mut this {
RigidTy::Bool
| RigidTy::Char
| RigidTy::Int(_)
| RigidTy::Uint(_)
| RigidTy::Float(_)
| RigidTy::Never
| RigidTy::Foreign(_)
| RigidTy::Str => {}
RigidTy::Array(t, c) => {
*t = t.fold(folder)?;
*c = c.fold(folder)?;
}
RigidTy::Slice(inner) => *inner = inner.fold(folder)?,
RigidTy::RawPtr(ty, _) => *ty = ty.fold(folder)?,
RigidTy::Ref(reg, ty, _) => {
*reg = reg.fold(folder)?;
*ty = ty.fold(folder)?
}
RigidTy::FnDef(_, args) => *args = args.fold(folder)?,
RigidTy::FnPtr(sig) => *sig = sig.fold(folder)?,
RigidTy::Closure(_, args) => *args = args.fold(folder)?,
RigidTy::Coroutine(_, args, _) => *args = args.fold(folder)?,
RigidTy::Dynamic(pred, r, _) => {
*pred = pred.fold(folder)?;
*r = r.fold(folder)?;
}
RigidTy::Tuple(fields) => *fields = fields.fold(folder)?,
RigidTy::Adt(_, args) => *args = args.fold(folder)?,
}
ControlFlow::Continue(this)
}
}
impl<T: Foldable> Foldable for Vec<T> {
fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
let mut this = self.clone();
for arg in &mut this {
*arg = arg.fold(folder)?;
}
ControlFlow::Continue(this)
}
}
impl<T: Foldable> Foldable for Binder<T> {
fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
ControlFlow::Continue(Self {
value: self.value.fold(folder)?,
bound_vars: self.bound_vars.clone(),
})
}
}
impl Foldable for ExistentialPredicate {
fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
let mut this = self.clone();
match &mut this {
ExistentialPredicate::Trait(tr) => tr.generic_args = tr.generic_args.fold(folder)?,
ExistentialPredicate::Projection(p) => {
p.term = p.term.fold(folder)?;
p.generic_args = p.generic_args.fold(folder)?;
}
ExistentialPredicate::AutoTrait(_) => {}
}
ControlFlow::Continue(this)
}
}
impl Foldable for TermKind {
fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
ControlFlow::Continue(match self {
TermKind::Type(t) => TermKind::Type(t.fold(folder)?),
TermKind::Const(c) => TermKind::Const(c.fold(folder)?),
})
}
}
impl Foldable for FnSig {
fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
ControlFlow::Continue(Self {
inputs_and_output: self.inputs_and_output.fold(folder)?,
c_variadic: self.c_variadic,
unsafety: self.unsafety,
abi: self.abi.clone(),
})
}
}
pub enum Never {}
/// In order to instantiate a `Foldable`'s generic parameters with specific arguments,
/// `GenericArgs` can be used as a `Folder` that replaces all mentions of generic params
/// with the entries in its list.
impl Folder for GenericArgs {
type Break = Never;
fn fold_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
ControlFlow::Continue(match ty.kind() {
TyKind::Param(p) => self[p],
_ => *ty,
})
}
fn fold_const(&mut self, c: &Const) -> ControlFlow<Self::Break, Const> {
ControlFlow::Continue(match &c.literal {
ConstantKind::Param(p) => self[p.clone()].clone(),
_ => c.clone(),
})
}
}

View file

@ -32,7 +32,6 @@ use self::ty::{
extern crate scoped_tls;
pub mod error;
pub mod fold;
pub mod mir;
pub mod ty;
pub mod visitor;
@ -215,9 +214,6 @@ pub trait Context {
/// Obtain the representation of a type.
fn ty_kind(&self, ty: Ty) -> TyKind;
/// Create a new `Ty` from scratch without information from rustc.
fn mk_ty(&self, kind: TyKind) -> Ty;
/// Get the body of an Instance.
/// FIXME: Monomorphize the body.
fn instance_body(&self, instance: InstanceDef) -> Body;

View file

@ -477,7 +477,7 @@ impl Operand {
impl Constant {
pub fn ty(&self) -> Ty {
self.literal.ty
self.literal.ty()
}
}

View file

@ -21,16 +21,44 @@ impl Ty {
}
}
impl From<TyKind> for Ty {
fn from(value: TyKind) -> Self {
with(|context| context.mk_ty(value))
/// Represents a constant in MIR or from the Type system.
#[derive(Clone, Debug)]
pub struct Const {
/// The constant kind.
kind: ConstantKind,
/// The constant type.
ty: Ty,
/// Used for internal tracking of the internal constant.
pub id: ConstId,
}
impl Const {
/// Build a constant. Note that this should only be used by the compiler.
pub fn new(kind: ConstantKind, ty: Ty, id: ConstId) -> Const {
Const { kind, ty, id }
}
/// Retrieve the constant kind.
pub fn kind(&self) -> &ConstantKind {
&self.kind
}
/// Get the constant type.
pub fn ty(&self) -> Ty {
self.ty
}
}
#[derive(Debug, Clone)]
pub struct Const {
pub literal: ConstantKind,
pub ty: Ty,
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ConstId(pub usize);
impl IndexedVal for ConstId {
fn to_val(index: usize) -> Self {
ConstId(index)
}
fn to_index(&self) -> usize {
self.0
}
}
type Ident = Opaque;

View file

@ -47,12 +47,12 @@ impl Visitable for Const {
visitor.visit_const(self)
}
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
match &self.literal {
match &self.kind() {
super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor)?,
super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor)?,
super::ty::ConstantKind::Param(_) => {}
}
self.ty.visit(visitor)
self.ty().visit(visitor)
}
}

View file

@ -22,8 +22,8 @@ extern crate stable_mir;
use rustc_hir::def::DefKind;
use rustc_middle::ty::TyCtxt;
use rustc_smir::rustc_internal;
use stable_mir::fold::Foldable;
use stable_mir::mir::mono::Instance;
use stable_mir::ty::{RigidTy, TyKind};
use std::assert_matches::assert_matches;
use std::io::Write;
use std::ops::ControlFlow;
@ -119,40 +119,18 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
}
let monomorphic = get_item(&items, (DefKind::Fn, "monomorphic")).unwrap();
for block in monomorphic.body().blocks {
let instance = Instance::try_from(monomorphic.clone()).unwrap();
for block in instance.body().blocks {
match &block.terminator.kind {
stable_mir::mir::TerminatorKind::Call { func, .. } => match func {
stable_mir::mir::Operand::Constant(c) => match &c.literal.literal {
stable_mir::ty::ConstantKind::Allocated(alloc) => {
assert!(alloc.bytes.is_empty());
match c.literal.ty.kind() {
stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::FnDef(
def,
mut args,
)) => {
let func = def.body();
match func.locals[1].ty
.fold(&mut args)
.continue_value()
.unwrap()
.kind()
{
stable_mir::ty::TyKind::RigidTy(
stable_mir::ty::RigidTy::Uint(_),
) => {}
stable_mir::ty::TyKind::RigidTy(
stable_mir::ty::RigidTy::Tuple(_),
) => {}
other => panic!("{other:?}"),
}
}
other => panic!("{other:?}"),
}
}
stable_mir::mir::TerminatorKind::Call { func, .. } => {
let TyKind::RigidTy(ty) = func.ty(&body.locals).kind() else { unreachable!() };
let RigidTy::FnDef(def, args) = ty else { unreachable!() };
let next_func = Instance::resolve(def, &args).unwrap();
match next_func.body().locals[1].ty.kind() {
TyKind::RigidTy(RigidTy::Uint(_)) | TyKind::RigidTy(RigidTy::Tuple(_)) => {}
other => panic!("{other:?}"),
},
other => panic!("{other:?}"),
},
}
}
stable_mir::mir::TerminatorKind::Return => {}
other => panic!("{other:?}"),
}