diff options
| author | bors <bors@rust-lang.org> | 2023-10-25 13:19:54 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-10-25 13:19:54 +0000 |
| commit | b66fe58f68d84cf422ff50c362ac5ad245cd9ce7 (patch) | |
| tree | cae4b569811a1a0e347954cd044af681b2185b80 | |
| parent | eb03d40a9c946bbf57c655ed7d26dc44416ca4ad (diff) | |
| parent | 17f6df9c63695d8206f30e7a23e56d676b95c392 (diff) | |
| download | rust-b66fe58f68d84cf422ff50c362ac5ad245cd9ce7.tar.gz rust-b66fe58f68d84cf422ff50c362ac5ad245cd9ce7.zip | |
Auto merge of #117113 - celinval:smir-stable-ty, r=oli-obk
Remove fold code and add `Const::internal()` to StableMIR We are not planning to support user generated constant in the foreseeable future, so we are cleaning up the fold logic and user created type for now. Users should use `Instance::resolve` in order to trigger monomorphization. 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.
| -rw-r--r-- | compiler/rustc_smir/src/lib.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_smir/src/rustc_internal/internal.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_smir/src/rustc_internal/mod.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_smir/src/rustc_smir/mod.rs | 186 | ||||
| -rw-r--r-- | compiler/stable_mir/src/fold.rs | 245 | ||||
| -rw-r--r-- | compiler/stable_mir/src/lib.rs | 4 | ||||
| -rw-r--r-- | compiler/stable_mir/src/mir/body.rs | 2 | ||||
| -rw-r--r-- | compiler/stable_mir/src/ty.rs | 63 | ||||
| -rw-r--r-- | compiler/stable_mir/src/visitor.rs | 4 | ||||
| -rw-r--r-- | tests/ui-fulldeps/stable-mir/crate-info.rs | 46 |
10 files changed, 155 insertions, 421 deletions
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<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,18 +252,18 @@ 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: IndexMap<Ty<'tcx>, stable_mir::ty::Ty>, pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>, + pub(crate) constants: IndexMap<mir::Const<'tcx>, 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<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(), - }) - } -} 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,18 +21,37 @@ 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 } } -} -#[derive(Debug, Clone)] -pub struct Const { - pub literal: ConstantKind, - pub ty: Ty, + /// Retrieve the constant kind. + pub fn kind(&self) -> &ConstantKind { + &self.kind + } + + /// Get the constant type. + pub fn ty(&self) -> Ty { + self.ty + } } +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct ConstId(pub usize); + type Ident = Opaque; #[derive(Debug, Clone)] @@ -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<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) } } 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:?}"), } |
