about summary refs log tree commit diff
path: root/compiler/stable_mir/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/stable_mir/src')
-rw-r--r--compiler/stable_mir/src/compiler_interface.rs22
-rw-r--r--compiler/stable_mir/src/mir/body.rs10
-rw-r--r--compiler/stable_mir/src/mir/pretty.rs16
-rw-r--r--compiler/stable_mir/src/mir/visit.rs25
-rw-r--r--compiler/stable_mir/src/ty.rs95
-rw-r--r--compiler/stable_mir/src/visitor.rs30
6 files changed, 137 insertions, 61 deletions
diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs
index 858ce5301d8..085dfd9ea89 100644
--- a/compiler/stable_mir/src/compiler_interface.rs
+++ b/compiler/stable_mir/src/compiler_interface.rs
@@ -11,10 +11,10 @@ use crate::mir::mono::{Instance, InstanceDef, StaticDef};
 use crate::mir::{BinOp, Body, Place, UnOp};
 use crate::target::MachineInfo;
 use crate::ty::{
-    AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef,
+    AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef,
     ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, Generics,
-    ImplDef, ImplTrait, IntrinsicDef, LineInfo, PolyFnSig, RigidTy, Span, TraitDecl, TraitDef, Ty,
-    TyKind, UintTy, VariantDef,
+    ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, TraitDecl,
+    TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef,
 };
 use crate::{
     mir, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls, ItemKind,
@@ -109,19 +109,21 @@ pub trait Context {
     fn variant_fields(&self, def: VariantDef) -> Vec<FieldDef>;
 
     /// Evaluate constant as a target usize.
-    fn eval_target_usize(&self, cnst: &Const) -> Result<u64, Error>;
+    fn eval_target_usize(&self, cnst: &MirConst) -> Result<u64, Error>;
+    fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result<u64, Error>;
 
     /// Create a new zero-sized constant.
-    fn try_new_const_zst(&self, ty: Ty) -> Result<Const, Error>;
+    fn try_new_const_zst(&self, ty: Ty) -> Result<MirConst, Error>;
 
     /// Create a new constant that represents the given string value.
-    fn new_const_str(&self, value: &str) -> Const;
+    fn new_const_str(&self, value: &str) -> MirConst;
 
     /// Create a new constant that represents the given boolean value.
-    fn new_const_bool(&self, value: bool) -> Const;
+    fn new_const_bool(&self, value: bool) -> MirConst;
 
     /// Create a new constant that represents the given value.
-    fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<Const, Error>;
+    fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<MirConst, Error>;
+    fn try_new_ty_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<TyConst, Error>;
 
     /// Create a new type from the given kind.
     fn new_rigid_ty(&self, kind: RigidTy) -> Ty;
@@ -136,11 +138,13 @@ pub trait Context {
     fn def_ty_with_args(&self, item: DefId, args: &GenericArgs) -> Ty;
 
     /// Returns literal value of a const as a string.
-    fn const_pretty(&self, cnst: &Const) -> String;
+    fn mir_const_pretty(&self, cnst: &MirConst) -> String;
 
     /// `Span` of an item
     fn span_of_an_item(&self, def_id: DefId) -> Span;
 
+    fn ty_const_pretty(&self, ct: TyConstId) -> String;
+
     /// Obtain the representation of a type.
     fn ty_pretty(&self, ty: Ty) -> String;
 
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 4c779ae96a8..43e4682dc10 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -1,8 +1,8 @@
 use crate::compiler_interface::with;
 use crate::mir::pretty::function_body;
 use crate::ty::{
-    AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, RigidTy, Ty, TyKind,
-    VariantIdx,
+    AdtDef, ClosureDef, CoroutineDef, GenericArgs, MirConst, Movability, Region, RigidTy, Ty,
+    TyConst, TyKind, VariantIdx,
 };
 use crate::{Error, Opaque, Span, Symbol};
 use std::io;
@@ -524,7 +524,7 @@ pub enum Rvalue {
     /// Corresponds to source code like `[x; 32]`.
     ///
     /// [#74836]: https://github.com/rust-lang/rust/issues/74836
-    Repeat(Operand, Const),
+    Repeat(Operand, TyConst),
 
     /// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
     ///
@@ -718,7 +718,7 @@ pub enum VarDebugInfoContents {
 pub struct ConstOperand {
     pub span: Span,
     pub user_ty: Option<UserTypeAnnotationIndex>,
-    pub const_: Const,
+    pub const_: MirConst,
 }
 
 // In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This
@@ -833,7 +833,7 @@ type UserTypeAnnotationIndex = usize;
 pub struct Constant {
     pub span: Span,
     pub user_ty: Option<UserTypeAnnotationIndex>,
-    pub literal: Const,
+    pub literal: MirConst,
 }
 
 /// The possible branch sites of a [TerminatorKind::SwitchInt].
diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs
index 580dc1a2b88..2fb180b84c7 100644
--- a/compiler/stable_mir/src/mir/pretty.rs
+++ b/compiler/stable_mir/src/mir/pretty.rs
@@ -1,5 +1,5 @@
 use crate::mir::{Operand, Place, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents};
-use crate::ty::{Const, IndexedVal, Ty};
+use crate::ty::{IndexedVal, MirConst, Ty, TyConst};
 use crate::{with, Body, Mutability};
 use fmt::{Display, Formatter};
 use std::fmt::Debug;
@@ -46,7 +46,7 @@ pub(crate) fn function_body<W: Write>(writer: &mut W, body: &Body, name: &str) -
             VarDebugInfoContents::Place(place) => {
                 format!("{place:?}")
             }
-            VarDebugInfoContents::Const(constant) => pretty_const(&constant.const_),
+            VarDebugInfoContents::Const(constant) => pretty_mir_const(&constant.const_),
         };
         writeln!(writer, "    debug {} => {};", info.name, content)
     })?;
@@ -310,12 +310,16 @@ fn pretty_operand(operand: &Operand) -> String {
         Operand::Move(mv) => {
             format!("move {:?}", mv)
         }
-        Operand::Constant(cnst) => pretty_const(&cnst.literal),
+        Operand::Constant(cnst) => pretty_mir_const(&cnst.literal),
     }
 }
 
-fn pretty_const(literal: &Const) -> String {
-    with(|cx| cx.const_pretty(literal))
+fn pretty_mir_const(literal: &MirConst) -> String {
+    with(|cx| cx.mir_const_pretty(literal))
+}
+
+fn pretty_ty_const(ct: &TyConst) -> String {
+    with(|cx| cx.ty_const_pretty(ct.id))
 }
 
 fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
@@ -359,7 +363,7 @@ fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
             write!(writer, "{kind}{:?}", place)
         }
         Rvalue::Repeat(op, cnst) => {
-            write!(writer, "{} \" \" {}", &pretty_operand(op), cnst.ty())
+            write!(writer, "{} \" \" {}", &pretty_operand(op), &pretty_ty_const(cnst))
         }
         Rvalue::ShallowInitBox(_, _) => Ok(()),
         Rvalue::ThreadLocalRef(item) => {
diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs
index 24296e9e877..10f30083dc2 100644
--- a/compiler/stable_mir/src/mir/visit.rs
+++ b/compiler/stable_mir/src/mir/visit.rs
@@ -36,7 +36,7 @@
 //! variant argument) that does not require visiting.
 
 use crate::mir::*;
-use crate::ty::{Const, GenericArgs, Region, Ty};
+use crate::ty::{GenericArgs, MirConst, Region, Ty, TyConst};
 use crate::{Error, Opaque, Span};
 
 pub trait MirVisitor {
@@ -112,8 +112,13 @@ pub trait MirVisitor {
         self.super_constant(constant, location)
     }
 
-    fn visit_const(&mut self, constant: &Const, location: Location) {
-        self.super_const(constant, location)
+    fn visit_mir_const(&mut self, constant: &MirConst, location: Location) {
+        self.super_mir_const(constant, location)
+    }
+
+    fn visit_ty_const(&mut self, constant: &TyConst, location: Location) {
+        let _ = location;
+        self.super_ty_const(constant)
     }
 
     fn visit_region(&mut self, region: &Region, location: Location) {
@@ -339,7 +344,7 @@ pub trait MirVisitor {
             }
             Rvalue::Repeat(op, constant) => {
                 self.visit_operand(op, location);
-                self.visit_const(constant, location);
+                self.visit_ty_const(constant, location);
             }
             Rvalue::ShallowInitBox(op, ty) => {
                 self.visit_ty(ty, location);
@@ -378,14 +383,18 @@ pub trait MirVisitor {
     fn super_constant(&mut self, constant: &Constant, location: Location) {
         let Constant { span, user_ty: _, literal } = constant;
         self.visit_span(span);
-        self.visit_const(literal, location);
+        self.visit_mir_const(literal, location);
     }
 
-    fn super_const(&mut self, constant: &Const, location: Location) {
-        let Const { kind: _, ty, id: _ } = constant;
+    fn super_mir_const(&mut self, constant: &MirConst, location: Location) {
+        let MirConst { kind: _, ty, id: _ } = constant;
         self.visit_ty(ty, location);
     }
 
+    fn super_ty_const(&mut self, constant: &TyConst) {
+        let _ = constant;
+    }
+
     fn super_region(&mut self, region: &Region) {
         let _ = region;
     }
@@ -407,7 +416,7 @@ pub trait MirVisitor {
                 self.visit_place(place, PlaceContext::NON_USE, location);
             }
             VarDebugInfoContents::Const(constant) => {
-                self.visit_const(&constant.const_, location);
+                self.visit_mir_const(&constant.const_, location);
             }
         }
     }
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index 50bf0a5d74e..bcbe87f7303 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -28,11 +28,11 @@ impl Ty {
 
     /// Create a new array type.
     pub fn try_new_array(elem_ty: Ty, size: u64) -> Result<Ty, Error> {
-        Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, Const::try_from_target_usize(size)?)))
+        Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, TyConst::try_from_target_usize(size)?)))
     }
 
     /// Create a new array type from Const length.
-    pub fn new_array_with_const_len(elem_ty: Ty, len: Const) -> Ty {
+    pub fn new_array_with_const_len(elem_ty: Ty, len: TyConst) -> Ty {
         Ty::from_rigid_kind(RigidTy::Array(elem_ty, len))
     }
 
@@ -101,24 +101,66 @@ impl Ty {
 /// Represents a pattern in the type system
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub enum Pattern {
-    Range { start: Option<Const>, end: Option<Const>, include_end: bool },
+    Range { start: Option<TyConst>, end: Option<TyConst>, include_end: bool },
 }
 
-/// Represents a constant in MIR or from the Type system.
+/// Represents a constant in the type system
 #[derive(Clone, Debug, Eq, PartialEq)]
-pub struct Const {
+pub struct TyConst {
+    pub(crate) kind: TyConstKind,
+    pub id: TyConstId,
+}
+
+impl TyConst {
+    pub fn new(kind: TyConstKind, id: TyConstId) -> TyConst {
+        Self { kind, id }
+    }
+
+    /// Retrieve the constant kind.
+    pub fn kind(&self) -> &TyConstKind {
+        &self.kind
+    }
+
+    /// Creates an interned usize constant.
+    fn try_from_target_usize(val: u64) -> Result<Self, Error> {
+        with(|cx| cx.try_new_ty_const_uint(val.into(), UintTy::Usize))
+    }
+
+    /// Try to evaluate to a target `usize`.
+    pub fn eval_target_usize(&self) -> Result<u64, Error> {
+        with(|cx| cx.eval_target_usize_ty(self))
+    }
+}
+
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum TyConstKind {
+    Param(ParamConst),
+    Bound(DebruijnIndex, BoundVar),
+    Unevaluated(ConstDef, GenericArgs),
+
+    // FIXME: These should be a valtree
+    Value(Ty, Allocation),
+    ZSTValue(Ty),
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct TyConstId(usize);
+
+/// Represents a constant in MIR
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct MirConst {
     /// The constant kind.
     pub(crate) kind: ConstantKind,
     /// The constant type.
     pub(crate) ty: Ty,
     /// Used for internal tracking of the internal constant.
-    pub id: ConstId,
+    pub id: MirConstId,
 }
 
-impl Const {
+impl MirConst {
     /// 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 }
+    pub fn new(kind: ConstantKind, ty: Ty, id: MirConstId) -> MirConst {
+        MirConst { kind, ty, id }
     }
 
     /// Retrieve the constant kind.
@@ -131,11 +173,6 @@ impl Const {
         self.ty
     }
 
-    /// Creates an interned usize constant.
-    fn try_from_target_usize(val: u64) -> Result<Self, Error> {
-        with(|cx| cx.try_new_const_uint(val.into(), UintTy::Usize))
-    }
-
     /// Try to evaluate to a target `usize`.
     pub fn eval_target_usize(&self) -> Result<u64, Error> {
         with(|cx| cx.eval_target_usize(self))
@@ -143,7 +180,7 @@ impl Const {
 
     /// Create a constant that represents a new zero-sized constant of type T.
     /// Fails if the type is not a ZST or if it doesn't have a known size.
-    pub fn try_new_zero_sized(ty: Ty) -> Result<Const, Error> {
+    pub fn try_new_zero_sized(ty: Ty) -> Result<MirConst, Error> {
         with(|cx| cx.try_new_const_zst(ty))
     }
 
@@ -152,23 +189,23 @@ impl Const {
     /// Note that there is no guarantee today about duplication of the same constant.
     /// I.e.: Calling this function multiple times with the same argument may or may not return
     /// the same allocation.
-    pub fn from_str(value: &str) -> Const {
+    pub fn from_str(value: &str) -> MirConst {
         with(|cx| cx.new_const_str(value))
     }
 
     /// Build a new constant that represents the given boolean value.
-    pub fn from_bool(value: bool) -> Const {
+    pub fn from_bool(value: bool) -> MirConst {
         with(|cx| cx.new_const_bool(value))
     }
 
     /// Build a new constant that represents the given unsigned integer.
-    pub fn try_from_uint(value: u128, uint_ty: UintTy) -> Result<Const, Error> {
+    pub fn try_from_uint(value: u128, uint_ty: UintTy) -> Result<MirConst, Error> {
         with(|cx| cx.try_new_const_uint(value, uint_ty))
     }
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub struct ConstId(usize);
+pub struct MirConstId(usize);
 
 type Ident = Opaque;
 
@@ -484,7 +521,7 @@ pub enum RigidTy {
     Adt(AdtDef, GenericArgs),
     Foreign(ForeignDef),
     Str,
-    Array(Ty, Const),
+    Array(Ty, TyConst),
     Pat(Ty, Pattern),
     Slice(Ty),
     RawPtr(Ty, Mutability),
@@ -866,7 +903,7 @@ impl std::ops::Index<ParamTy> for GenericArgs {
 }
 
 impl std::ops::Index<ParamConst> for GenericArgs {
-    type Output = Const;
+    type Output = TyConst;
 
     fn index(&self, index: ParamConst) -> &Self::Output {
         self.0[index.index as usize].expect_const()
@@ -877,7 +914,7 @@ impl std::ops::Index<ParamConst> for GenericArgs {
 pub enum GenericArgKind {
     Lifetime(Region),
     Type(Ty),
-    Const(Const),
+    Const(TyConst),
 }
 
 impl GenericArgKind {
@@ -894,7 +931,7 @@ impl GenericArgKind {
     /// Panic if this generic argument is not a const, otherwise
     /// return the const.
     #[track_caller]
-    pub fn expect_const(&self) -> &Const {
+    pub fn expect_const(&self) -> &TyConst {
         match self {
             GenericArgKind::Const(c) => c,
             _ => panic!("{self:?}"),
@@ -913,7 +950,7 @@ impl GenericArgKind {
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub enum TermKind {
     Type(Ty),
-    Const(Const),
+    Const(TyConst),
 }
 
 #[derive(Clone, Debug, Eq, PartialEq)]
@@ -1202,6 +1239,7 @@ impl Allocation {
 
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub enum ConstantKind {
+    Ty(TyConst),
     Allocated(Allocation),
     Unevaluated(UnevaluatedConst),
     Param(ParamConst),
@@ -1335,7 +1373,7 @@ pub enum PredicateKind {
     ObjectSafe(TraitDef),
     SubType(SubtypePredicate),
     Coerce(CoercePredicate),
-    ConstEquate(Const, Const),
+    ConstEquate(TyConst, TyConst),
     Ambiguous,
     AliasRelate(TermKind, TermKind, AliasRelationDirection),
 }
@@ -1346,9 +1384,9 @@ pub enum ClauseKind {
     RegionOutlives(RegionOutlivesPredicate),
     TypeOutlives(TypeOutlivesPredicate),
     Projection(ProjectionPredicate),
-    ConstArgHasType(Const, Ty),
+    ConstArgHasType(TyConst, Ty),
     WellFormed(GenericArgKind),
-    ConstEvaluatable(Const),
+    ConstEvaluatable(TyConst),
 }
 
 #[derive(Clone, Debug, Eq, PartialEq)]
@@ -1426,7 +1464,8 @@ macro_rules! index_impl {
     };
 }
 
-index_impl!(ConstId);
+index_impl!(TyConstId);
+index_impl!(MirConstId);
 index_impl!(Ty);
 index_impl!(Span);
 
diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs
index 2d7159f87fe..fc1da8fafe4 100644
--- a/compiler/stable_mir/src/visitor.rs
+++ b/compiler/stable_mir/src/visitor.rs
@@ -1,10 +1,10 @@
 use std::ops::ControlFlow;
 
-use crate::Opaque;
+use crate::{ty::TyConst, Opaque};
 
 use super::ty::{
-    Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
-    Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst,
+    Allocation, Binder, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
+    MirConst, Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst,
 };
 
 pub trait Visitor: Sized {
@@ -12,7 +12,7 @@ pub trait Visitor: Sized {
     fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break> {
         ty.super_visit(self)
     }
-    fn visit_const(&mut self, c: &Const) -> ControlFlow<Self::Break> {
+    fn visit_const(&mut self, c: &TyConst) -> ControlFlow<Self::Break> {
         c.super_visit(self)
     }
     fn visit_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break> {
@@ -42,12 +42,32 @@ impl Visitable for Ty {
     }
 }
 
-impl Visitable for Const {
+impl Visitable for TyConst {
     fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
         visitor.visit_const(self)
     }
     fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        match &self.kind {
+            crate::ty::TyConstKind::Param(_) => {}
+            crate::ty::TyConstKind::Bound(_, _) => {}
+            crate::ty::TyConstKind::Unevaluated(_, args) => args.visit(visitor)?,
+            crate::ty::TyConstKind::Value(ty, alloc) => {
+                alloc.visit(visitor)?;
+                ty.visit(visitor)?;
+            }
+            crate::ty::TyConstKind::ZSTValue(ty) => ty.visit(visitor)?,
+        }
+        ControlFlow::Continue(())
+    }
+}
+
+impl Visitable for MirConst {
+    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        self.super_visit(visitor)
+    }
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
         match &self.kind() {
+            super::ty::ConstantKind::Ty(ct) => ct.visit(visitor)?,
             super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor)?,
             super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor)?,
             super::ty::ConstantKind::Param(_) | super::ty::ConstantKind::ZeroSized => {}