rustc_smir/rustc_smir/convert/
abi.rs1#![allow(rustc::usage_of_qualified_ty)]
4
5use rustc_middle::ty;
6use rustc_target::callconv::{self, Conv};
7use stable_mir::abi::{
8 AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength, Layout,
9 LayoutShape, PassMode, Primitive, Scalar, TagEncoding, TyAndLayout, ValueAbi, VariantsShape,
10 WrappingRange,
11};
12use stable_mir::opaque;
13use stable_mir::target::MachineSize as Size;
14use stable_mir::ty::{Align, IndexedVal, VariantIdx};
15
16use crate::rustc_smir::{Stable, Tables};
17
18impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx {
19 type T = VariantIdx;
20 fn stable(&self, _: &mut Tables<'_>) -> Self::T {
21 VariantIdx::to_val(self.as_usize())
22 }
23}
24
25impl<'tcx> Stable<'tcx> for rustc_abi::Endian {
26 type T = stable_mir::target::Endian;
27
28 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
29 match self {
30 rustc_abi::Endian::Little => stable_mir::target::Endian::Little,
31 rustc_abi::Endian::Big => stable_mir::target::Endian::Big,
32 }
33 }
34}
35
36impl<'tcx> Stable<'tcx> for rustc_abi::TyAndLayout<'tcx, ty::Ty<'tcx>> {
37 type T = TyAndLayout;
38
39 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
40 TyAndLayout { ty: self.ty.stable(tables), layout: self.layout.stable(tables) }
41 }
42}
43
44impl<'tcx> Stable<'tcx> for rustc_abi::Layout<'tcx> {
45 type T = Layout;
46
47 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
48 tables.layout_id(tables.tcx.lift(*self).unwrap())
49 }
50}
51
52impl<'tcx> Stable<'tcx> for rustc_abi::LayoutData<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
53 type T = LayoutShape;
54
55 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
56 LayoutShape {
57 fields: self.fields.stable(tables),
58 variants: self.variants.stable(tables),
59 abi: self.backend_repr.stable(tables),
60 abi_align: self.align.abi.stable(tables),
61 size: self.size.stable(tables),
62 }
63 }
64}
65
66impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> {
67 type T = FnAbi;
68
69 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
70 assert!(self.args.len() >= self.fixed_count as usize);
71 assert!(!self.c_variadic || matches!(self.conv, Conv::C));
72 FnAbi {
73 args: self.args.as_ref().stable(tables),
74 ret: self.ret.stable(tables),
75 fixed_count: self.fixed_count,
76 conv: self.conv.stable(tables),
77 c_variadic: self.c_variadic,
78 }
79 }
80}
81
82impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> {
83 type T = ArgAbi;
84
85 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
86 ArgAbi {
87 ty: self.layout.ty.stable(tables),
88 layout: self.layout.layout.stable(tables),
89 mode: self.mode.stable(tables),
90 }
91 }
92}
93
94impl<'tcx> Stable<'tcx> for callconv::Conv {
95 type T = CallConvention;
96
97 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
98 match self {
99 Conv::C => CallConvention::C,
100 Conv::Rust => CallConvention::Rust,
101 Conv::Cold => CallConvention::Cold,
102 Conv::PreserveMost => CallConvention::PreserveMost,
103 Conv::PreserveAll => CallConvention::PreserveAll,
104 Conv::ArmAapcs => CallConvention::ArmAapcs,
105 Conv::CCmseNonSecureCall => CallConvention::CCmseNonSecureCall,
106 Conv::CCmseNonSecureEntry => CallConvention::CCmseNonSecureEntry,
107 Conv::Msp430Intr => CallConvention::Msp430Intr,
108 Conv::X86Fastcall => CallConvention::X86Fastcall,
109 Conv::X86Intr => CallConvention::X86Intr,
110 Conv::X86Stdcall => CallConvention::X86Stdcall,
111 Conv::X86ThisCall => CallConvention::X86ThisCall,
112 Conv::X86VectorCall => CallConvention::X86VectorCall,
113 Conv::X86_64SysV => CallConvention::X86_64SysV,
114 Conv::X86_64Win64 => CallConvention::X86_64Win64,
115 Conv::GpuKernel => CallConvention::GpuKernel,
116 Conv::AvrInterrupt => CallConvention::AvrInterrupt,
117 Conv::AvrNonBlockingInterrupt => CallConvention::AvrNonBlockingInterrupt,
118 Conv::RiscvInterrupt { .. } => CallConvention::RiscvInterrupt,
119 }
120 }
121}
122
123impl<'tcx> Stable<'tcx> for callconv::PassMode {
124 type T = PassMode;
125
126 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
127 match self {
128 callconv::PassMode::Ignore => PassMode::Ignore,
129 callconv::PassMode::Direct(attr) => PassMode::Direct(opaque(attr)),
130 callconv::PassMode::Pair(first, second) => {
131 PassMode::Pair(opaque(first), opaque(second))
132 }
133 callconv::PassMode::Cast { pad_i32, cast } => {
134 PassMode::Cast { pad_i32: *pad_i32, cast: opaque(cast) }
135 }
136 callconv::PassMode::Indirect { attrs, meta_attrs, on_stack } => PassMode::Indirect {
137 attrs: opaque(attrs),
138 meta_attrs: opaque(meta_attrs),
139 on_stack: *on_stack,
140 },
141 }
142 }
143}
144
145impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape<rustc_abi::FieldIdx> {
146 type T = FieldsShape;
147
148 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
149 match self {
150 rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive,
151 rustc_abi::FieldsShape::Union(count) => FieldsShape::Union(*count),
152 rustc_abi::FieldsShape::Array { stride, count } => {
153 FieldsShape::Array { stride: stride.stable(tables), count: *count }
154 }
155 rustc_abi::FieldsShape::Arbitrary { offsets, .. } => {
156 FieldsShape::Arbitrary { offsets: offsets.iter().as_slice().stable(tables) }
157 }
158 }
159 }
160}
161
162impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
163 type T = VariantsShape;
164
165 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
166 match self {
167 rustc_abi::Variants::Single { index } => {
168 VariantsShape::Single { index: index.stable(tables) }
169 }
170 rustc_abi::Variants::Empty => VariantsShape::Empty,
171 rustc_abi::Variants::Multiple { tag, tag_encoding, tag_field, variants } => {
172 VariantsShape::Multiple {
173 tag: tag.stable(tables),
174 tag_encoding: tag_encoding.stable(tables),
175 tag_field: *tag_field,
176 variants: variants.iter().as_slice().stable(tables),
177 }
178 }
179 }
180 }
181}
182
183impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding<rustc_abi::VariantIdx> {
184 type T = TagEncoding;
185
186 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
187 match self {
188 rustc_abi::TagEncoding::Direct => TagEncoding::Direct,
189 rustc_abi::TagEncoding::Niche { untagged_variant, niche_variants, niche_start } => {
190 TagEncoding::Niche {
191 untagged_variant: untagged_variant.stable(tables),
192 niche_variants: niche_variants.stable(tables),
193 niche_start: *niche_start,
194 }
195 }
196 }
197 }
198}
199
200impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
201 type T = ValueAbi;
202
203 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
204 match *self {
205 rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables)),
206 rustc_abi::BackendRepr::ScalarPair(first, second) => {
207 ValueAbi::ScalarPair(first.stable(tables), second.stable(tables))
208 }
209 rustc_abi::BackendRepr::SimdVector { element, count } => {
210 ValueAbi::Vector { element: element.stable(tables), count }
211 }
212 rustc_abi::BackendRepr::Memory { sized } => ValueAbi::Aggregate { sized },
213 }
214 }
215}
216
217impl<'tcx> Stable<'tcx> for rustc_abi::Size {
218 type T = Size;
219
220 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
221 Size::from_bits(self.bits_usize())
222 }
223}
224
225impl<'tcx> Stable<'tcx> for rustc_abi::Align {
226 type T = Align;
227
228 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
229 self.bytes()
230 }
231}
232
233impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
234 type T = Scalar;
235
236 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
237 match self {
238 rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized {
239 value: value.stable(tables),
240 valid_range: valid_range.stable(tables),
241 },
242 rustc_abi::Scalar::Union { value } => Scalar::Union { value: value.stable(tables) },
243 }
244 }
245}
246
247impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
248 type T = Primitive;
249
250 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
251 match self {
252 rustc_abi::Primitive::Int(length, signed) => {
253 Primitive::Int { length: length.stable(tables), signed: *signed }
254 }
255 rustc_abi::Primitive::Float(length) => {
256 Primitive::Float { length: length.stable(tables) }
257 }
258 rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables)),
259 }
260 }
261}
262
263impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
264 type T = AddressSpace;
265
266 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
267 AddressSpace(self.0)
268 }
269}
270
271impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
272 type T = IntegerLength;
273
274 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
275 match self {
276 rustc_abi::Integer::I8 => IntegerLength::I8,
277 rustc_abi::Integer::I16 => IntegerLength::I16,
278 rustc_abi::Integer::I32 => IntegerLength::I32,
279 rustc_abi::Integer::I64 => IntegerLength::I64,
280 rustc_abi::Integer::I128 => IntegerLength::I128,
281 }
282 }
283}
284
285impl<'tcx> Stable<'tcx> for rustc_abi::Float {
286 type T = FloatLength;
287
288 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
289 match self {
290 rustc_abi::Float::F16 => FloatLength::F16,
291 rustc_abi::Float::F32 => FloatLength::F32,
292 rustc_abi::Float::F64 => FloatLength::F64,
293 rustc_abi::Float::F128 => FloatLength::F128,
294 }
295 }
296}
297
298impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
299 type T = WrappingRange;
300
301 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
302 WrappingRange { start: self.start, end: self.end }
303 }
304}