Auto merge of #116269 - Veykril:rustc-abi, r=WaffleLapkin
Bring back generic parameters for indices in rustc_abi and make it compile on stable This effectively reverses https://github.com/rust-lang/rust/pull/107163, allowing rust-analyzer to depend on this crate again, It also moves some glob imports / expands them in the first commit because they made it more difficult for me to reason about things.
This commit is contained in:
commit
2c9b0de8ea
9 changed files with 295 additions and 232 deletions
|
@ -1,3 +1,4 @@
|
|||
use rustc_data_structures::intern::Interned;
|
||||
pub use Integer::*;
|
||||
pub use Primitive::*;
|
||||
|
||||
|
@ -18,6 +19,111 @@ impl ToJson for Endian {
|
|||
}
|
||||
}
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
/// The *source-order* index of a field in a variant.
|
||||
///
|
||||
/// This is how most code after type checking refers to fields, rather than
|
||||
/// using names (as names have hygiene complications and more complex lookup).
|
||||
///
|
||||
/// Particularly for `repr(Rust)` types, this may not be the same as *layout* order.
|
||||
/// (It is for `repr(C)` `struct`s, however.)
|
||||
///
|
||||
/// For example, in the following types,
|
||||
/// ```rust
|
||||
/// # enum Never {}
|
||||
/// # #[repr(u16)]
|
||||
/// enum Demo1 {
|
||||
/// Variant0 { a: Never, b: i32 } = 100,
|
||||
/// Variant1 { c: u8, d: u64 } = 10,
|
||||
/// }
|
||||
/// struct Demo2 { e: u8, f: u16, g: u8 }
|
||||
/// ```
|
||||
/// `b` is `FieldIdx(1)` in `VariantIdx(0)`,
|
||||
/// `d` is `FieldIdx(1)` in `VariantIdx(1)`, and
|
||||
/// `f` is `FieldIdx(1)` in `VariantIdx(0)`.
|
||||
#[derive(HashStable_Generic)]
|
||||
pub struct FieldIdx {}
|
||||
}
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
/// The *source-order* index of a variant in a type.
|
||||
///
|
||||
/// For enums, these are always `0..variant_count`, regardless of any
|
||||
/// custom discriminants that may have been defined, and including any
|
||||
/// variants that may end up uninhabited due to field types. (Some of the
|
||||
/// variants may not be present in a monomorphized ABI [`Variants`], but
|
||||
/// those skipped variants are always counted when determining the *index*.)
|
||||
///
|
||||
/// `struct`s, `tuples`, and `unions`s are considered to have a single variant
|
||||
/// with variant index zero, aka [`FIRST_VARIANT`].
|
||||
#[derive(HashStable_Generic)]
|
||||
pub struct VariantIdx {
|
||||
/// Equivalent to `VariantIdx(0)`.
|
||||
const FIRST_VARIANT = 0;
|
||||
}
|
||||
}
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
|
||||
#[rustc_pass_by_value]
|
||||
pub struct Layout<'a>(pub Interned<'a, LayoutS<FieldIdx, VariantIdx>>);
|
||||
|
||||
impl<'a> fmt::Debug for Layout<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// See comment on `<LayoutS as Debug>::fmt` above.
|
||||
self.0.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref for Layout<'a> {
|
||||
type Target = &'a LayoutS<FieldIdx, VariantIdx>;
|
||||
fn deref(&self) -> &&'a LayoutS<FieldIdx, VariantIdx> {
|
||||
&self.0.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Layout<'a> {
|
||||
pub fn fields(self) -> &'a FieldsShape<FieldIdx> {
|
||||
&self.0.0.fields
|
||||
}
|
||||
|
||||
pub fn variants(self) -> &'a Variants<FieldIdx, VariantIdx> {
|
||||
&self.0.0.variants
|
||||
}
|
||||
|
||||
pub fn abi(self) -> Abi {
|
||||
self.0.0.abi
|
||||
}
|
||||
|
||||
pub fn largest_niche(self) -> Option<Niche> {
|
||||
self.0.0.largest_niche
|
||||
}
|
||||
|
||||
pub fn align(self) -> AbiAndPrefAlign {
|
||||
self.0.0.align
|
||||
}
|
||||
|
||||
pub fn size(self) -> Size {
|
||||
self.0.0.size
|
||||
}
|
||||
|
||||
pub fn max_repr_align(self) -> Option<Align> {
|
||||
self.0.0.max_repr_align
|
||||
}
|
||||
|
||||
pub fn unadjusted_abi_align(self) -> Align {
|
||||
self.0.0.unadjusted_abi_align
|
||||
}
|
||||
|
||||
/// Whether the layout is from a type that implements [`std::marker::PointerLike`].
|
||||
///
|
||||
/// Currently, that means that the type is pointer-sized, pointer-aligned,
|
||||
/// and has a scalar ABI.
|
||||
pub fn is_pointer_like(self, data_layout: &TargetDataLayout) -> bool {
|
||||
self.size() == data_layout.pointer_size
|
||||
&& self.align().abi == data_layout.pointer_align.abi
|
||||
&& matches!(self.abi(), Abi::Scalar(..))
|
||||
}
|
||||
}
|
||||
|
||||
/// The layout of a type, alongside the type itself.
|
||||
/// Provides various type traversal APIs (e.g., recursing into fields).
|
||||
///
|
||||
|
@ -42,8 +148,8 @@ impl<'a, Ty: fmt::Display> fmt::Debug for TyAndLayout<'a, Ty> {
|
|||
}
|
||||
|
||||
impl<'a, Ty> Deref for TyAndLayout<'a, Ty> {
|
||||
type Target = &'a LayoutS;
|
||||
fn deref(&self) -> &&'a LayoutS {
|
||||
type Target = &'a LayoutS<FieldIdx, VariantIdx>;
|
||||
fn deref(&self) -> &&'a LayoutS<FieldIdx, VariantIdx> {
|
||||
&self.layout.0.0
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue