mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-02 10:04:23 +00:00
Add method to get type of an Rvalue in StableMIR
This commit is contained in:
parent
7a34091eed
commit
281b65aad9
@ -250,6 +250,13 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||
tables.tcx.mk_ty_from_kind(internal_kind).stable(&mut *tables)
|
||||
}
|
||||
|
||||
#[allow(rustc::usage_of_qualified_ty)]
|
||||
fn new_box_ty(&self, ty: stable_mir::ty::Ty) -> stable_mir::ty::Ty {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let inner = ty.internal(&mut *tables);
|
||||
ty::Ty::new_box(tables.tcx, inner).stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn def_ty(&self, item: stable_mir::DefId) -> stable_mir::ty::Ty {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
tables.tcx.type_of(item.internal(&mut *tables)).instantiate_identity().stable(&mut *tables)
|
||||
@ -276,6 +283,13 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||
tables.types[ty].kind().stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> stable_mir::ty::Ty {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let internal_kind = ty.internal(&mut *tables);
|
||||
let internal_ty = tables.tcx.mk_ty_from_kind(internal_kind);
|
||||
internal_ty.discriminant_ty(tables.tcx).stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn instance_body(&self, def: InstanceDef) -> Option<Body> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let instance = tables.instances[def];
|
||||
|
@ -87,6 +87,9 @@ pub trait Context {
|
||||
/// Create a new type from the given kind.
|
||||
fn new_rigid_ty(&self, kind: RigidTy) -> Ty;
|
||||
|
||||
/// Create a new box type, `Box<T>`, for the given inner type `T`.
|
||||
fn new_box_ty(&self, ty: Ty) -> Ty;
|
||||
|
||||
/// Returns the type of given crate item.
|
||||
fn def_ty(&self, item: DefId) -> Ty;
|
||||
|
||||
@ -102,6 +105,9 @@ pub trait Context {
|
||||
/// Obtain the representation of a type.
|
||||
fn ty_kind(&self, ty: Ty) -> TyKind;
|
||||
|
||||
// Get the discriminant Ty for this Ty if there's one.
|
||||
fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> Ty;
|
||||
|
||||
/// Get the body of an Instance which is already monomorphized.
|
||||
fn instance_body(&self, instance: InstanceDef) -> Option<Body>;
|
||||
|
||||
|
@ -274,6 +274,32 @@ pub enum BinOp {
|
||||
Offset,
|
||||
}
|
||||
|
||||
impl BinOp {
|
||||
/// Return the type of this operation for the given input Ty.
|
||||
/// This function does not perform type checking, and it currently doesn't handle SIMD.
|
||||
pub fn ty(&self, lhs_ty: Ty, _rhs_ty: Ty) -> Ty {
|
||||
match self {
|
||||
BinOp::Add
|
||||
| BinOp::AddUnchecked
|
||||
| BinOp::Sub
|
||||
| BinOp::SubUnchecked
|
||||
| BinOp::Mul
|
||||
| BinOp::MulUnchecked
|
||||
| BinOp::Div
|
||||
| BinOp::Rem
|
||||
| BinOp::BitXor
|
||||
| BinOp::BitAnd
|
||||
| BinOp::BitOr
|
||||
| BinOp::Shl
|
||||
| BinOp::ShlUnchecked
|
||||
| BinOp::Shr
|
||||
| BinOp::ShrUnchecked
|
||||
| BinOp::Offset => lhs_ty,
|
||||
BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => Ty::bool_ty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum UnOp {
|
||||
Not,
|
||||
@ -475,6 +501,63 @@ pub enum Rvalue {
|
||||
Use(Operand),
|
||||
}
|
||||
|
||||
impl Rvalue {
|
||||
pub fn ty(&self, locals: &[LocalDecl]) -> Result<Ty, Error> {
|
||||
match self {
|
||||
Rvalue::Use(operand) => operand.ty(locals),
|
||||
Rvalue::Repeat(operand, count) => {
|
||||
Ok(Ty::new_array_with_const_len(operand.ty(locals)?, count.clone()))
|
||||
}
|
||||
Rvalue::ThreadLocalRef(did) => Ok(did.ty()),
|
||||
Rvalue::Ref(reg, bk, place) => {
|
||||
let place_ty = place.ty(locals)?;
|
||||
Ok(Ty::new_ref(reg.clone(), place_ty, bk.to_mutable_lossy()))
|
||||
}
|
||||
Rvalue::AddressOf(mutability, place) => {
|
||||
let place_ty = place.ty(locals)?;
|
||||
Ok(Ty::new_ptr(place_ty, *mutability))
|
||||
}
|
||||
Rvalue::Len(..) => Ok(Ty::usize_ty()),
|
||||
Rvalue::Cast(.., ty) => Ok(*ty),
|
||||
Rvalue::BinaryOp(op, lhs, rhs) => {
|
||||
let lhs_ty = lhs.ty(locals)?;
|
||||
let rhs_ty = rhs.ty(locals)?;
|
||||
Ok(op.ty(lhs_ty, rhs_ty))
|
||||
}
|
||||
Rvalue::CheckedBinaryOp(op, lhs, rhs) => {
|
||||
let lhs_ty = lhs.ty(locals)?;
|
||||
let rhs_ty = rhs.ty(locals)?;
|
||||
let ty = op.ty(lhs_ty, rhs_ty);
|
||||
Ok(Ty::new_tuple(&[ty, Ty::bool_ty()]))
|
||||
}
|
||||
Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, operand) => operand.ty(locals),
|
||||
Rvalue::Discriminant(place) => {
|
||||
let place_ty = place.ty(locals)?;
|
||||
place_ty
|
||||
.kind()
|
||||
.discriminant_ty()
|
||||
.ok_or_else(|| error!("Expected a `RigidTy` but found: {place_ty:?}"))
|
||||
}
|
||||
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
|
||||
Ok(Ty::usize_ty())
|
||||
}
|
||||
Rvalue::Aggregate(ak, ops) => match *ak {
|
||||
AggregateKind::Array(ty) => Ty::try_new_array(ty, ops.len() as u64),
|
||||
AggregateKind::Tuple => Ok(Ty::new_tuple(
|
||||
&ops.iter().map(|op| op.ty(locals)).collect::<Result<Vec<_>, _>>()?,
|
||||
)),
|
||||
AggregateKind::Adt(def, _, ref args, _, _) => Ok(def.ty_with_args(args)),
|
||||
AggregateKind::Closure(def, ref args) => Ok(Ty::new_closure(def, args.clone())),
|
||||
AggregateKind::Coroutine(def, ref args, mov) => {
|
||||
Ok(Ty::new_coroutine(def, args.clone(), mov))
|
||||
}
|
||||
},
|
||||
Rvalue::ShallowInitBox(_, ty) => Ok(Ty::new_box(*ty)),
|
||||
Rvalue::CopyForDeref(place) => place.ty(locals),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum AggregateKind {
|
||||
Array(Ty),
|
||||
@ -725,6 +808,17 @@ pub enum BorrowKind {
|
||||
},
|
||||
}
|
||||
|
||||
impl BorrowKind {
|
||||
pub fn to_mutable_lossy(self) -> Mutability {
|
||||
match self {
|
||||
BorrowKind::Mut { .. } => Mutability::Mut,
|
||||
BorrowKind::Shared => Mutability::Not,
|
||||
// There's no type corresponding to a shallow borrow, so use `&` as an approximation.
|
||||
BorrowKind::Fake => Mutability::Not,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum MutBorrowKind {
|
||||
Default,
|
||||
|
@ -212,6 +212,21 @@ impl TryFrom<CrateItem> for StaticDef {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Instance> for StaticDef {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(value: Instance) -> Result<Self, Self::Error> {
|
||||
StaticDef::try_from(CrateItem::try_from(value)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StaticDef> for Instance {
|
||||
fn from(value: StaticDef) -> Self {
|
||||
// A static definition should always be convertible to an instance.
|
||||
Instance::try_from(CrateItem::from(value)).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl StaticDef {
|
||||
/// Return the type of this static definition.
|
||||
pub fn ty(&self) -> Ty {
|
||||
|
@ -31,15 +31,50 @@ impl Ty {
|
||||
Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, Const::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 {
|
||||
Ty::from_rigid_kind(RigidTy::Array(elem_ty, len))
|
||||
}
|
||||
|
||||
/// Create a new pointer type.
|
||||
pub fn new_ptr(pointee_ty: Ty, mutability: Mutability) -> Ty {
|
||||
Ty::from_rigid_kind(RigidTy::RawPtr(pointee_ty, mutability))
|
||||
}
|
||||
|
||||
/// Create a new reference type.
|
||||
pub fn new_ref(reg: Region, pointee_ty: Ty, mutability: Mutability) -> Ty {
|
||||
Ty::from_rigid_kind(RigidTy::Ref(reg, pointee_ty, mutability))
|
||||
}
|
||||
|
||||
/// Create a new pointer type.
|
||||
pub fn new_tuple(tys: &[Ty]) -> Ty {
|
||||
Ty::from_rigid_kind(RigidTy::Tuple(Vec::from(tys)))
|
||||
}
|
||||
|
||||
/// Create a new closure type.
|
||||
pub fn new_closure(def: ClosureDef, args: GenericArgs) -> Ty {
|
||||
Ty::from_rigid_kind(RigidTy::Closure(def, args))
|
||||
}
|
||||
|
||||
/// Create a new coroutine type.
|
||||
pub fn new_coroutine(def: CoroutineDef, args: GenericArgs, mov: Movability) -> Ty {
|
||||
Ty::from_rigid_kind(RigidTy::Coroutine(def, args, mov))
|
||||
}
|
||||
|
||||
/// Create a new box type that represents `Box<T>`, for the given inner type `T`.
|
||||
pub fn new_box(inner_ty: Ty) -> Ty {
|
||||
with(|cx| cx.new_box_ty(inner_ty))
|
||||
}
|
||||
|
||||
/// Create a type representing `usize`.
|
||||
pub fn usize_ty() -> Ty {
|
||||
Ty::from_rigid_kind(RigidTy::Uint(UintTy::Usize))
|
||||
}
|
||||
|
||||
/// Create a type representing `bool`.
|
||||
pub fn bool_ty() -> Ty {
|
||||
Ty::from_rigid_kind(RigidTy::Bool)
|
||||
}
|
||||
}
|
||||
|
||||
impl Ty {
|
||||
@ -251,6 +286,7 @@ impl TyKind {
|
||||
}
|
||||
|
||||
/// Get the function signature for function like types (Fn, FnPtr, Closure, Coroutine)
|
||||
/// FIXME(closure)
|
||||
pub fn fn_sig(&self) -> Option<PolyFnSig> {
|
||||
match self {
|
||||
TyKind::RigidTy(RigidTy::FnDef(def, args)) => Some(with(|cx| cx.fn_sig(*def, args))),
|
||||
@ -258,6 +294,11 @@ impl TyKind {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the discriminant type for this type.
|
||||
pub fn discriminant_ty(&self) -> Option<Ty> {
|
||||
self.rigid().map(|ty| with(|cx| cx.rigid_ty_discriminant_ty(ty)))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TypeAndMut {
|
||||
@ -289,6 +330,13 @@ pub enum RigidTy {
|
||||
CoroutineWitness(CoroutineWitnessDef, GenericArgs),
|
||||
}
|
||||
|
||||
impl RigidTy {
|
||||
/// Get the discriminant type for this type.
|
||||
pub fn discriminant_ty(&self) -> Ty {
|
||||
with(|cx| cx.rigid_ty_discriminant_ty(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RigidTy> for TyKind {
|
||||
fn from(value: RigidTy) -> Self {
|
||||
TyKind::RigidTy(value)
|
||||
|
Loading…
Reference in New Issue
Block a user