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), doc(rust_logo))]
#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
#![cfg_attr(not(bootstrap), allow(internal_features))] #![cfg_attr(not(bootstrap), allow(internal_features))]
#![allow(rustc::usage_of_ty_tykind)]
pub mod rustc_internal; pub mod rustc_internal;

View file

@ -4,7 +4,7 @@
//! due to incomplete stable coverage. //! due to incomplete stable coverage.
// Prefer importing stable_mir over internal rustc constructs to make this file more readable. // 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 rustc_middle::ty::{self as rustc_ty, Ty as InternalTy};
use stable_mir::ty::{Const, GenericArgKind, GenericArgs, Region, Ty}; use stable_mir::ty::{Const, GenericArgKind, GenericArgs, Region, Ty};
use stable_mir::DefId; use stable_mir::DefId;
@ -31,7 +31,7 @@ impl<'tcx> RustcInternal<'tcx> for GenericArgKind {
match self { match self {
GenericArgKind::Lifetime(reg) => reg.internal(tables).into(), GenericArgKind::Lifetime(reg) => reg.internal(tables).into(),
GenericArgKind::Type(ty) => ty.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 { impl<'tcx> RustcInternal<'tcx> for Ty {
type T = InternalTy<'tcx>; type T = InternalTy<'tcx>;
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T { fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
match tables.types[self.0] { tables.types[self.0]
MaybeStable::Stable(_) => todo!(), }
MaybeStable::Rustc(ty) => ty, }
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 { impl<'tcx> RustcInternal<'tcx> for Const {
type T = rustc_ty::Const<'tcx>; type T = rustc_middle::mir::Const<'tcx>;
fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T { fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
todo!() tables.constants[self.id]
} }
} }

View file

@ -169,6 +169,7 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
spans: IndexMap::default(), spans: IndexMap::default(),
types: vec![], types: vec![],
instances: IndexMap::default(), instances: IndexMap::default(),
constants: IndexMap::default(),
})); }));
stable_mir::run(&tables, || init(&tables, f)); 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::mono::InstanceDef;
use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx}; use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx};
use stable_mir::ty::{ 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 stable_mir::{self, opaque, Context, Filename};
use std::cell::RefCell; use std::cell::RefCell;
@ -147,14 +148,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind { fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind {
let mut tables = self.0.borrow_mut(); let mut tables = self.0.borrow_mut();
tables.types[ty.0].clone().stable(&mut *tables) tables.types[ty.0].kind().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)
} }
fn generics_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics { 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 { fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
let mut tables = self.0.borrow_mut(); let mut tables = self.0.borrow_mut();
let instance = tables.instances[def]; let instance = tables.instances[def];
let ty = instance.ty(tables.tcx, ParamEnv::empty()); instance.ty(tables.tcx, ParamEnv::empty()).stable(&mut *tables)
tables.intern_ty(ty)
} }
fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId { 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(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell<Tables<'tcx>>);
pub struct 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) def_ids: IndexMap<DefId, stable_mir::DefId>,
pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::AllocId>, pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
pub(crate) spans: IndexMap<rustc_span::Span, Span>, 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) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
pub(crate) constants: IndexMap<mir::Const<'tcx>, ConstId>,
} }
impl<'tcx> Tables<'tcx> { impl<'tcx> Tables<'tcx> {
@ -296,9 +263,13 @@ impl<'tcx> Tables<'tcx> {
return stable_mir::ty::Ty(id); return stable_mir::ty::Ty(id);
} }
let id = self.types.len(); let id = self.types.len();
self.types.push(MaybeStable::Rustc(ty)); self.types.push(ty);
stable_mir::ty::Ty(id) 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. /// Build a stable mir crate from a given crate number.
@ -338,7 +309,7 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
.local_decls .local_decls
.iter() .iter()
.map(|decl| stable_mir::mir::LocalDecl { .map(|decl| stable_mir::mir::LocalDecl {
ty: tables.intern_ty(decl.ty), ty: decl.ty.stable(tables),
span: decl.source_info.span.stable(tables), span: decl.source_info.span.stable(tables),
}) })
.collect(), .collect(),
@ -436,7 +407,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast( Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast(
cast_kind.stable(tables), cast_kind.stable(tables),
op.stable(tables), op.stable(tables),
tables.intern_ty(*ty), ty.stable(tables),
), ),
BinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::BinaryOp( BinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::BinaryOp(
bin_op.stable(tables), bin_op.stable(tables),
@ -449,7 +420,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
ops.1.stable(tables), ops.1.stable(tables),
), ),
NullaryOp(null_op, ty) => { 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) => { UnaryOp(un_op, op) => {
stable_mir::mir::Rvalue::UnaryOp(un_op.stable(tables), op.stable(tables)) 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) stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables), operands)
} }
ShallowInitBox(op, ty) => { 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)), 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 { fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
use stable_mir::ty::TermKind; use stable_mir::ty::TermKind;
match self { 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) => { ty::TermKind::Const(cnst) => {
let cnst = cnst.stable(tables); let cnst = cnst.stable(tables);
TermKind::Const(cnst) TermKind::Const(cnst)
@ -885,7 +856,7 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
match self { match self {
mir::AggregateKind::Array(ty) => { 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::Tuple => stable_mir::mir::AggregateKind::Tuple,
mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => { 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; use stable_mir::ty::GenericArgKind;
match self { match self {
ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(region.stable(tables)), 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)), 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}; use stable_mir::ty::{Abi, FnSig};
FnSig { FnSig {
inputs_and_output: self inputs_and_output: self.inputs_and_output.iter().map(|ty| ty.stable(tables)).collect(),
.inputs_and_output
.iter()
.map(|ty| tables.intern_ty(ty))
.collect(),
c_variadic: self.c_variadic, c_variadic: self.c_variadic,
unsafety: self.unsafety.stable(tables), unsafety: self.unsafety.stable(tables),
abi: match self.abi { abi: match self.abi {
@ -1241,9 +1208,16 @@ impl<'tcx> Stable<'tcx> for hir::Movability {
} }
impl<'tcx> Stable<'tcx> for Ty<'tcx> { 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; type T = stable_mir::ty::TyKind;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
match self.kind() { match self {
ty::Bool => TyKind::RigidTy(RigidTy::Bool), ty::Bool => TyKind::RigidTy(RigidTy::Bool),
ty::Char => TyKind::RigidTy(RigidTy::Char), ty::Char => TyKind::RigidTy(RigidTy::Char),
ty::Int(int_ty) => TyKind::RigidTy(RigidTy::Int(int_ty.stable(tables))), 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::Foreign(def_id) => TyKind::RigidTy(RigidTy::Foreign(tables.foreign_def(*def_id))),
ty::Str => TyKind::RigidTy(RigidTy::Str), ty::Str => TyKind::RigidTy(RigidTy::Str),
ty::Array(ty, constant) => { 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 }) => { 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( ty::Ref(region, ty, mutbl) => TyKind::RigidTy(RigidTy::Ref(
region.stable(tables), region.stable(tables),
tables.intern_ty(*ty), ty.stable(tables),
mutbl.stable(tables), mutbl.stable(tables),
)), )),
ty::FnDef(def_id, generic_args) => { ty::FnDef(def_id, generic_args) => {
@ -1291,9 +1265,9 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
movability.stable(tables), movability.stable(tables),
)), )),
ty::Never => TyKind::RigidTy(RigidTy::Never), ty::Never => TyKind::RigidTy(RigidTy::Never),
ty::Tuple(fields) => TyKind::RigidTy(RigidTy::Tuple( ty::Tuple(fields) => {
fields.iter().map(|ty| tables.intern_ty(ty)).collect(), TyKind::RigidTy(RigidTy::Tuple(fields.iter().map(|ty| ty.stable(tables)).collect()))
)), }
ty::Alias(alias_kind, alias_ty) => { ty::Alias(alias_kind, alias_ty) => {
TyKind::Alias(alias_kind.stable(tables), alias_ty.stable(tables)) TyKind::Alias(alias_kind.stable(tables), alias_ty.stable(tables))
} }
@ -1312,8 +1286,7 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
type T = stable_mir::ty::Const; type T = stable_mir::ty::Const;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
stable_mir::ty::Const { let kind = match self.kind() {
literal: match self.kind() {
ty::Value(val) => { ty::Value(val) => {
let const_val = tables.tcx.valtree_to_const_val((self.ty(), val)); let const_val = tables.tcx.valtree_to_const_val((self.ty(), val));
stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation( stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
@ -1335,9 +1308,10 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
}) })
} }
ty::ExprCt(_) => unimplemented!(), ty::ExprCt(_) => unimplemented!(),
}, };
ty: tables.intern_ty(self.ty()), 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 { fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
match *self { match *self {
mir::Const::Ty(c) => c.stable(tables), mir::Const::Ty(c) => c.stable(tables),
mir::Const::Unevaluated(unev_const, ty) => stable_mir::ty::Const { mir::Const::Unevaluated(unev_const, ty) => {
literal: stable_mir::ty::ConstantKind::Unevaluated( let kind =
stable_mir::ty::UnevaluatedConst { stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
def: tables.const_def(unev_const.def), def: tables.const_def(unev_const.def),
args: unev_const.args.stable(tables), args: unev_const.args.stable(tables),
promoted: unev_const.promoted.map(|u| u.as_u32()), promoted: unev_const.promoted.map(|u| u.as_u32()),
}, });
), let ty = ty.stable(tables);
ty: tables.intern_ty(ty), let id = tables.intern_const(*self);
}, Const::new(kind, ty, id)
mir::Const::Val(val, ty) => stable_mir::ty::Const { }
literal: stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation( mir::Const::Val(val, ty) => {
ty, val, tables, let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables));
)), let ty = ty.stable(tables);
ty: tables.intern_ty(ty), 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) => { TypeOutlives(type_outlives) => {
let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives; let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives;
stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate( stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate(
tables.intern_ty(a), a.stable(tables),
b.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( ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType(
const_.stable(tables), const_.stable(tables),
tables.intern_ty(ty), ty.stable(tables),
), ),
WellFormed(generic_arg) => { WellFormed(generic_arg) => {
stable_mir::ty::ClauseKind::WellFormed(generic_arg.unpack().stable(tables)) 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 { fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
let ty::SubtypePredicate { a, b, a_is_expected: _ } = self; 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 { fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
let ty::CoercePredicate { a, b } = self; 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; extern crate scoped_tls;
pub mod error; pub mod error;
pub mod fold;
pub mod mir; pub mod mir;
pub mod ty; pub mod ty;
pub mod visitor; pub mod visitor;
@ -215,9 +214,6 @@ pub trait Context {
/// Obtain the representation of a type. /// Obtain the representation of a type.
fn ty_kind(&self, ty: Ty) -> TyKind; 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. /// Get the body of an Instance.
/// FIXME: Monomorphize the body. /// FIXME: Monomorphize the body.
fn instance_body(&self, instance: InstanceDef) -> Body; fn instance_body(&self, instance: InstanceDef) -> Body;

View file

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

View file

@ -21,16 +21,44 @@ impl Ty {
} }
} }
impl From<TyKind> for Ty { /// Represents a constant in MIR or from the Type system.
fn from(value: TyKind) -> Self { #[derive(Clone, Debug)]
with(|context| context.mk_ty(value)) 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)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Const { pub struct ConstId(pub usize);
pub literal: ConstantKind,
pub ty: Ty, impl IndexedVal for ConstId {
fn to_val(index: usize) -> Self {
ConstId(index)
}
fn to_index(&self) -> usize {
self.0
}
} }
type Ident = Opaque; type Ident = Opaque;

View file

@ -47,12 +47,12 @@ impl Visitable for Const {
visitor.visit_const(self) visitor.visit_const(self)
} }
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { 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::Allocated(alloc) => alloc.visit(visitor)?,
super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor)?, super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor)?,
super::ty::ConstantKind::Param(_) => {} 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_hir::def::DefKind;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_smir::rustc_internal; use rustc_smir::rustc_internal;
use stable_mir::mir::mono::Instance;
use stable_mir::fold::Foldable; use stable_mir::ty::{RigidTy, TyKind};
use std::assert_matches::assert_matches; use std::assert_matches::assert_matches;
use std::io::Write; use std::io::Write;
use std::ops::ControlFlow; use std::ops::ControlFlow;
@ -119,40 +119,18 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
} }
let monomorphic = get_item(&items, (DefKind::Fn, "monomorphic")).unwrap(); 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 { match &block.terminator.kind {
stable_mir::mir::TerminatorKind::Call { func, .. } => match func { stable_mir::mir::TerminatorKind::Call { func, .. } => {
stable_mir::mir::Operand::Constant(c) => match &c.literal.literal { let TyKind::RigidTy(ty) = func.ty(&body.locals).kind() else { unreachable!() };
stable_mir::ty::ConstantKind::Allocated(alloc) => { let RigidTy::FnDef(def, args) = ty else { unreachable!() };
assert!(alloc.bytes.is_empty()); let next_func = Instance::resolve(def, &args).unwrap();
match c.literal.ty.kind() { match next_func.body().locals[1].ty.kind() {
stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::FnDef( TyKind::RigidTy(RigidTy::Uint(_)) | TyKind::RigidTy(RigidTy::Tuple(_)) => {}
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:?}"),
} }
} }
other => panic!("{other:?}"),
}
}
other => panic!("{other:?}"),
},
other => panic!("{other:?}"),
},
stable_mir::mir::TerminatorKind::Return => {} stable_mir::mir::TerminatorKind::Return => {}
other => panic!("{other:?}"), other => panic!("{other:?}"),
} }