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:
parent
151256bd4b
commit
3f60165d27
10 changed files with 144 additions and 404 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -477,7 +477,7 @@ impl Operand {
|
|||
|
||||
impl Constant {
|
||||
pub fn ty(&self) -> Ty {
|
||||
self.literal.ty
|
||||
self.literal.ty()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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:?}"),
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue