//! Common utilities shared by both `rustc_ast` and `rustc_type_ir`. //! //! Don't depend on this crate directly; both of those crates should re-export //! the functionality. Additionally, if you're in scope of `rustc_middle`, then //! prefer imports via that too, to avoid needing to directly depend on (e.g.) //! `rustc_type_ir` for a single import. // tidy-alphabetical-start #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(never_type))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] // tidy-alphabetical-end use std::fmt; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; #[cfg(feature = "nightly")] use rustc_span::{Symbol, sym}; pub mod visit; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] pub enum IntTy { Isize, I8, I16, I32, I64, I128, } impl IntTy { pub fn name_str(&self) -> &'static str { match *self { IntTy::Isize => "isize", IntTy::I8 => "i8", IntTy::I16 => "i16", IntTy::I32 => "i32", IntTy::I64 => "i64", IntTy::I128 => "i128", } } #[cfg(feature = "nightly")] pub fn name(self) -> Symbol { match self { IntTy::Isize => sym::isize, IntTy::I8 => sym::i8, IntTy::I16 => sym::i16, IntTy::I32 => sym::i32, IntTy::I64 => sym::i64, IntTy::I128 => sym::i128, } } pub fn bit_width(&self) -> Option { Some(match *self { IntTy::Isize => return None, IntTy::I8 => 8, IntTy::I16 => 16, IntTy::I32 => 32, IntTy::I64 => 64, IntTy::I128 => 128, }) } pub fn normalize(&self, target_width: u16) -> Self { match self { IntTy::Isize => match target_width { 16 => IntTy::I16, 32 => IntTy::I32, 64 => IntTy::I64, _ => unreachable!(), }, _ => *self, } } pub fn to_unsigned(self) -> UintTy { match self { IntTy::Isize => UintTy::Usize, IntTy::I8 => UintTy::U8, IntTy::I16 => UintTy::U16, IntTy::I32 => UintTy::U32, IntTy::I64 => UintTy::U64, IntTy::I128 => UintTy::U128, } } } impl fmt::Debug for IntTy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.name_str()) } } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] pub enum UintTy { Usize, U8, U16, U32, U64, U128, } impl UintTy { pub fn name_str(&self) -> &'static str { match *self { UintTy::Usize => "usize", UintTy::U8 => "u8", UintTy::U16 => "u16", UintTy::U32 => "u32", UintTy::U64 => "u64", UintTy::U128 => "u128", } } #[cfg(feature = "nightly")] pub fn name(self) -> Symbol { match self { UintTy::Usize => sym::usize, UintTy::U8 => sym::u8, UintTy::U16 => sym::u16, UintTy::U32 => sym::u32, UintTy::U64 => sym::u64, UintTy::U128 => sym::u128, } } pub fn bit_width(&self) -> Option { Some(match *self { UintTy::Usize => return None, UintTy::U8 => 8, UintTy::U16 => 16, UintTy::U32 => 32, UintTy::U64 => 64, UintTy::U128 => 128, }) } pub fn normalize(&self, target_width: u16) -> Self { match self { UintTy::Usize => match target_width { 16 => UintTy::U16, 32 => UintTy::U32, 64 => UintTy::U64, _ => unreachable!(), }, _ => *self, } } pub fn to_signed(self) -> IntTy { match self { UintTy::Usize => IntTy::Isize, UintTy::U8 => IntTy::I8, UintTy::U16 => IntTy::I16, UintTy::U32 => IntTy::I32, UintTy::U64 => IntTy::I64, UintTy::U128 => IntTy::I128, } } } impl fmt::Debug for UintTy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.name_str()) } } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] pub enum FloatTy { F16, F32, F64, F128, } impl FloatTy { pub fn name_str(self) -> &'static str { match self { FloatTy::F16 => "f16", FloatTy::F32 => "f32", FloatTy::F64 => "f64", FloatTy::F128 => "f128", } } #[cfg(feature = "nightly")] pub fn name(self) -> Symbol { match self { FloatTy::F16 => sym::f16, FloatTy::F32 => sym::f32, FloatTy::F64 => sym::f64, FloatTy::F128 => sym::f128, } } pub fn bit_width(self) -> u64 { match self { FloatTy::F16 => 16, FloatTy::F32 => 32, FloatTy::F64 => 64, FloatTy::F128 => 128, } } } impl fmt::Debug for FloatTy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.name_str()) } } /// The movability of a coroutine / closure literal: /// whether a coroutine contains self-references, causing it to be `!Unpin`. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] pub enum Movability { /// May contain self-references, `!Unpin`. Static, /// Must not contain self-references, `Unpin`. Movable, } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] pub enum Mutability { // N.B. Order is deliberate, so that Not < Mut Not, Mut, } impl Mutability { pub fn invert(self) -> Self { match self { Mutability::Mut => Mutability::Not, Mutability::Not => Mutability::Mut, } } /// Returns `""` (empty string) or `"mut "` depending on the mutability. pub fn prefix_str(self) -> &'static str { match self { Mutability::Mut => "mut ", Mutability::Not => "", } } /// Returns `"&"` or `"&mut "` depending on the mutability. pub fn ref_prefix_str(self) -> &'static str { match self { Mutability::Not => "&", Mutability::Mut => "&mut ", } } /// Returns `"const"` or `"mut"` depending on the mutability. pub fn ptr_str(self) -> &'static str { match self { Mutability::Not => "const", Mutability::Mut => "mut", } } /// Returns `""` (empty string) or `"mutably "` depending on the mutability. pub fn mutably_str(self) -> &'static str { match self { Mutability::Not => "", Mutability::Mut => "mutably ", } } /// Return `true` if self is mutable pub fn is_mut(self) -> bool { matches!(self, Self::Mut) } /// Return `true` if self is **not** mutable pub fn is_not(self) -> bool { matches!(self, Self::Not) } } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] pub enum Pinnedness { Not, Pinned, }