rustc_transmute/layout/
mod.rs
1use std::fmt::{self, Debug};
2use std::hash::Hash;
3
4pub(crate) mod tree;
5pub(crate) use tree::Tree;
6
7pub(crate) mod nfa;
8pub(crate) use nfa::Nfa;
9
10pub(crate) mod dfa;
11pub(crate) use dfa::Dfa;
12
13#[derive(Debug)]
14pub(crate) struct Uninhabited;
15
16#[derive(Hash, Eq, PartialEq, Clone, Copy)]
18pub(crate) enum Byte {
19 Uninit,
20 Init(u8),
21}
22
23impl fmt::Debug for Byte {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 match &self {
26 Self::Uninit => f.write_str("??u8"),
27 Self::Init(b) => write!(f, "{b:#04x}u8"),
28 }
29 }
30}
31
32pub(crate) trait Def: Debug + Hash + Eq + PartialEq + Copy + Clone {
33 fn has_safety_invariants(&self) -> bool;
34}
35pub trait Ref: Debug + Hash + Eq + PartialEq + Copy + Clone {
36 fn min_align(&self) -> usize;
37
38 fn size(&self) -> usize;
39
40 fn is_mutable(&self) -> bool;
41}
42
43impl Def for ! {
44 fn has_safety_invariants(&self) -> bool {
45 unreachable!()
46 }
47}
48
49impl Ref for ! {
50 fn min_align(&self) -> usize {
51 unreachable!()
52 }
53 fn size(&self) -> usize {
54 unreachable!()
55 }
56 fn is_mutable(&self) -> bool {
57 unreachable!()
58 }
59}
60
61#[cfg(feature = "rustc")]
62pub mod rustc {
63 use std::fmt::{self, Write};
64
65 use rustc_abi::Layout;
66 use rustc_middle::mir::Mutability;
67 use rustc_middle::ty::layout::{HasTyCtxt, LayoutCx, LayoutError};
68 use rustc_middle::ty::{self, Ty};
69
70 #[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)]
72 pub struct Ref<'tcx> {
73 pub lifetime: ty::Region<'tcx>,
74 pub ty: Ty<'tcx>,
75 pub mutability: Mutability,
76 pub align: usize,
77 pub size: usize,
78 }
79
80 impl<'tcx> super::Ref for Ref<'tcx> {
81 fn min_align(&self) -> usize {
82 self.align
83 }
84
85 fn size(&self) -> usize {
86 self.size
87 }
88
89 fn is_mutable(&self) -> bool {
90 match self.mutability {
91 Mutability::Mut => true,
92 Mutability::Not => false,
93 }
94 }
95 }
96 impl<'tcx> Ref<'tcx> {}
97
98 impl<'tcx> fmt::Display for Ref<'tcx> {
99 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100 f.write_char('&')?;
101 if self.mutability == Mutability::Mut {
102 f.write_str("mut ")?;
103 }
104 self.ty.fmt(f)
105 }
106 }
107
108 #[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)]
110 pub enum Def<'tcx> {
111 Adt(ty::AdtDef<'tcx>),
112 Variant(&'tcx ty::VariantDef),
113 Field(&'tcx ty::FieldDef),
114 Primitive,
115 }
116
117 impl<'tcx> super::Def for Def<'tcx> {
118 fn has_safety_invariants(&self) -> bool {
119 self != &Self::Primitive
123 }
124 }
125
126 pub(crate) fn layout_of<'tcx>(
127 cx: LayoutCx<'tcx>,
128 ty: Ty<'tcx>,
129 ) -> Result<Layout<'tcx>, &'tcx LayoutError<'tcx>> {
130 use rustc_middle::ty::layout::LayoutOf;
131 let ty = cx.tcx().erase_regions(ty);
132 cx.layout_of(ty).map(|tl| tl.layout)
133 }
134}