diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index c24b9efe865..dcf6b904077 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -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; diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index f42a9739320..78144524ac5 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -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] + } +} + +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] } } diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index d3ea8cdc699..4d2a518226d 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -167,8 +167,9 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) { def_ids: IndexMap::default(), alloc_ids: IndexMap::default(), spans: IndexMap::default(), - types: vec![], + types: IndexMap::default(), instances: IndexMap::default(), + constants: IndexMap::default(), })); stable_mir::run(&tables, || init(&tables, f)); } diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 2253dc57010..e772ae942fa 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -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].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 { - Stable(S), - Rustc(R), -} - -impl<'tcx, S, R> MaybeStable { - 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 PartialEq for MaybeStable { - fn eq(&self, other: &R) -> bool { - match self { - MaybeStable::Stable(_) => false, - MaybeStable::Rustc(r) => r == other, - } - } -} - pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell>); pub struct Tables<'tcx> { @@ -286,18 +252,18 @@ pub struct Tables<'tcx> { pub(crate) def_ids: IndexMap, pub(crate) alloc_ids: IndexMap, pub(crate) spans: IndexMap, - pub(crate) types: Vec>>, + pub(crate) types: IndexMap, stable_mir::ty::Ty>, pub(crate) instances: IndexMap, InstanceDef>, + pub(crate) constants: IndexMap, ConstId>, } impl<'tcx> Tables<'tcx> { fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::Ty { - if let Some(id) = self.types.iter().position(|t| *t == ty) { - return stable_mir::ty::Ty(id); - } - let id = self.types.len(); - self.types.push(MaybeStable::Rustc(ty)); - stable_mir::ty::Ty(id) + self.types.create_or_fetch(ty) + } + + fn intern_const(&mut self, constant: mir::Const<'tcx>) -> ConstId { + self.constants.create_or_fetch(constant) } } @@ -338,7 +304,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 +402,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 +415,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 +426,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 +570,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 +851,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 +1019,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 +1065,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 +1203,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 +1225,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 +1260,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 +1281,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 +1391,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) + } } } } @@ -1562,7 +1532,7 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> { ClauseKind::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), )) } @@ -1571,7 +1541,7 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> { } ClauseKind::ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType( const_.stable(tables), - tables.intern_ty(ty), + ty.stable(tables), ), ClauseKind::WellFormed(generic_arg) => { stable_mir::ty::ClauseKind::WellFormed(generic_arg.unpack().stable(tables)) @@ -1601,7 +1571,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) } } } @@ -1610,7 +1580,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) } } } diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs deleted file mode 100644 index ca6ea92c4a1..00000000000 --- a/compiler/stable_mir/src/fold.rs +++ /dev/null @@ -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 { - ty.super_fold(self) - } - fn fold_const(&mut self, c: &Const) -> ControlFlow { - c.super_fold(self) - } - fn fold_reg(&mut self, reg: &Region) -> ControlFlow { - reg.super_fold(self) - } -} - -pub trait Foldable: Sized + Clone { - fn fold(&self, folder: &mut V) -> ControlFlow { - self.super_fold(folder) - } - fn super_fold(&self, folder: &mut V) -> ControlFlow; -} - -impl Foldable for Ty { - fn fold(&self, folder: &mut V) -> ControlFlow { - folder.fold_ty(self) - } - fn super_fold(&self, folder: &mut V) -> ControlFlow { - 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(&self, folder: &mut V) -> ControlFlow { - folder.fold_const(self) - } - fn super_fold(&self, folder: &mut V) -> ControlFlow { - 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(&self, _folder: &mut V) -> ControlFlow { - ControlFlow::Continue(self.clone()) - } -} - -impl Foldable for Allocation { - fn super_fold(&self, _folder: &mut V) -> ControlFlow { - ControlFlow::Continue(self.clone()) - } -} - -impl Foldable for UnevaluatedConst { - fn super_fold(&self, folder: &mut V) -> ControlFlow { - 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(&self, _folder: &mut V) -> ControlFlow { - ControlFlow::Continue(*self) - } -} - -impl Foldable for Option { - fn super_fold(&self, folder: &mut V) -> ControlFlow { - ControlFlow::Continue(match self { - Some(val) => Some(val.fold(folder)?), - None => None, - }) - } -} - -impl Foldable for Promoted { - fn super_fold(&self, _folder: &mut V) -> ControlFlow { - ControlFlow::Continue(*self) - } -} - -impl Foldable for GenericArgs { - fn super_fold(&self, folder: &mut V) -> ControlFlow { - ControlFlow::Continue(GenericArgs(self.0.fold(folder)?)) - } -} - -impl Foldable for Region { - fn fold(&self, folder: &mut V) -> ControlFlow { - folder.fold_reg(self) - } - fn super_fold(&self, _: &mut V) -> ControlFlow { - ControlFlow::Continue(self.clone()) - } -} - -impl Foldable for GenericArgKind { - fn super_fold(&self, folder: &mut V) -> ControlFlow { - 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(&self, folder: &mut V) -> ControlFlow { - 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 Foldable for Vec { - fn super_fold(&self, folder: &mut V) -> ControlFlow { - let mut this = self.clone(); - for arg in &mut this { - *arg = arg.fold(folder)?; - } - ControlFlow::Continue(this) - } -} - -impl Foldable for Binder { - fn super_fold(&self, folder: &mut V) -> ControlFlow { - ControlFlow::Continue(Self { - value: self.value.fold(folder)?, - bound_vars: self.bound_vars.clone(), - }) - } -} - -impl Foldable for ExistentialPredicate { - fn super_fold(&self, folder: &mut V) -> ControlFlow { - 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(&self, folder: &mut V) -> ControlFlow { - 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(&self, folder: &mut V) -> ControlFlow { - 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 { - ControlFlow::Continue(match ty.kind() { - TyKind::Param(p) => self[p], - _ => *ty, - }) - } - - fn fold_const(&mut self, c: &Const) -> ControlFlow { - ControlFlow::Continue(match &c.literal { - ConstantKind::Param(p) => self[p.clone()].clone(), - _ => c.clone(), - }) - } -} diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 8cacbdbda48..38915afaa0c 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -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; diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 5eee1ec00df..fc617513aee 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -477,7 +477,7 @@ impl Operand { impl Constant { pub fn ty(&self) -> Ty { - self.literal.ty + self.literal.ty() } } diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index 8f7f8bd4e38..0dbf6fe23aa 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -6,7 +6,7 @@ use super::{ use crate::{Filename, Opaque}; use std::fmt::{self, Debug, Formatter}; -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Eq, PartialEq, Hash)] pub struct Ty(pub usize); impl Debug for Ty { @@ -21,17 +21,36 @@ impl Ty { } } -impl From 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); type Ident = Opaque; @@ -108,15 +127,6 @@ pub struct LineInfo { pub end_col: usize, } -impl IndexedVal for Span { - fn to_val(index: usize) -> Self { - Span(index) - } - fn to_index(&self) -> usize { - self.0 - } -} - #[derive(Clone, Debug)] pub enum TyKind { RigidTy(RigidTy), @@ -603,3 +613,20 @@ pub trait IndexedVal { fn to_index(&self) -> usize; } + +macro_rules! index_impl { + ($name:ident) => { + impl IndexedVal for $name { + fn to_val(index: usize) -> Self { + $name(index) + } + fn to_index(&self) -> usize { + self.0 + } + } + }; +} + +index_impl!(ConstId); +index_impl!(Ty); +index_impl!(Span); diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs index a6020cc5bd9..c337f5b68d3 100644 --- a/compiler/stable_mir/src/visitor.rs +++ b/compiler/stable_mir/src/visitor.rs @@ -47,12 +47,12 @@ impl Visitable for Const { visitor.visit_const(self) } fn super_visit(&self, visitor: &mut V) -> ControlFlow { - 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) } } diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index 3cb71b5a025..60c6053d295 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -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:?}"), }