1#![allow(rustc::usage_of_qualified_ty)]
4
5use rustc_abi::{ArmCall, CanonAbi, InterruptKind, X86Call};
6use rustc_middle::ty;
7use rustc_public_bridge::Tables;
8use rustc_public_bridge::context::CompilerCtxt;
9use rustc_target::callconv;
10
11use crate::abi::{
12 AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength,
13 IntegerType, Layout, LayoutShape, NumScalableVectors, PassMode, Primitive, ReprFlags,
14 ReprOptions, Scalar, TagEncoding, TyAndLayout, ValueAbi, VariantFields, VariantsShape,
15 WrappingRange,
16};
17use crate::compiler_interface::BridgeTys;
18use crate::target::MachineSize as Size;
19use crate::ty::{Align, VariantIdx};
20use crate::unstable::Stable;
21use crate::{IndexedVal, opaque};
22
23impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx {
24 type T = VariantIdx;
25 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
26 VariantIdx::to_val(self.as_usize())
27 }
28}
29
30impl<'tcx> Stable<'tcx> for rustc_abi::Endian {
31 type T = crate::target::Endian;
32
33 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
34 match self {
35 rustc_abi::Endian::Little => crate::target::Endian::Little,
36 rustc_abi::Endian::Big => crate::target::Endian::Big,
37 }
38 }
39}
40
41impl<'tcx> Stable<'tcx> for rustc_abi::TyAndLayout<'tcx, ty::Ty<'tcx>> {
42 type T = TyAndLayout;
43
44 fn stable<'cx>(
45 &self,
46 tables: &mut Tables<'cx, BridgeTys>,
47 cx: &CompilerCtxt<'cx, BridgeTys>,
48 ) -> Self::T {
49 TyAndLayout { ty: self.ty.stable(tables, cx), layout: self.layout.stable(tables, cx) }
50 }
51}
52
53impl<'tcx> Stable<'tcx> for rustc_abi::Layout<'tcx> {
54 type T = Layout;
55
56 fn stable<'cx>(
57 &self,
58 tables: &mut Tables<'cx, BridgeTys>,
59 cx: &CompilerCtxt<'cx, BridgeTys>,
60 ) -> Self::T {
61 tables.layout_id(cx.lift(*self))
62 }
63}
64
65impl<'tcx> Stable<'tcx> for rustc_abi::LayoutData<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
66 type T = LayoutShape;
67
68 fn stable<'cx>(
69 &self,
70 tables: &mut Tables<'cx, BridgeTys>,
71 cx: &CompilerCtxt<'cx, BridgeTys>,
72 ) -> Self::T {
73 LayoutShape {
74 fields: self.fields.stable(tables, cx),
75 variants: self.variants.stable(tables, cx),
76 abi: self.backend_repr.stable(tables, cx),
77 abi_align: self.align.abi.stable(tables, cx),
78 size: self.size.stable(tables, cx),
79 }
80 }
81}
82
83impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> {
84 type T = FnAbi;
85
86 fn stable<'cx>(
87 &self,
88 tables: &mut Tables<'cx, BridgeTys>,
89 cx: &CompilerCtxt<'cx, BridgeTys>,
90 ) -> Self::T {
91 if !(self.args.len() >= self.fixed_count as usize) {
::core::panicking::panic("assertion failed: self.args.len() >= self.fixed_count as usize")
};assert!(self.args.len() >= self.fixed_count as usize);
92 if !(!self.c_variadic ||
#[allow(non_exhaustive_omitted_patterns)] match self.conv {
CanonAbi::C => true,
_ => false,
}) {
::core::panicking::panic("assertion failed: !self.c_variadic || matches!(self.conv, CanonAbi::C)")
};assert!(!self.c_variadic || matches!(self.conv, CanonAbi::C));
93 FnAbi {
94 args: self.args.as_ref().stable(tables, cx),
95 ret: self.ret.stable(tables, cx),
96 fixed_count: self.fixed_count,
97 conv: self.conv.stable(tables, cx),
98 c_variadic: self.c_variadic,
99 }
100 }
101}
102
103impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> {
104 type T = ArgAbi;
105
106 fn stable<'cx>(
107 &self,
108 tables: &mut Tables<'cx, BridgeTys>,
109 cx: &CompilerCtxt<'cx, BridgeTys>,
110 ) -> Self::T {
111 ArgAbi {
112 ty: self.layout.ty.stable(tables, cx),
113 layout: self.layout.layout.stable(tables, cx),
114 mode: self.mode.stable(tables, cx),
115 }
116 }
117}
118
119impl<'tcx> Stable<'tcx> for CanonAbi {
120 type T = CallConvention;
121
122 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
123 match self {
124 CanonAbi::C => CallConvention::C,
125 CanonAbi::Rust => CallConvention::Rust,
126 CanonAbi::RustCold => CallConvention::Cold,
127 CanonAbi::RustPreserveNone => CallConvention::PreserveNone,
128 CanonAbi::RustTail => CallConvention::Tail,
129 CanonAbi::Custom => CallConvention::Custom,
130 CanonAbi::Swift => CallConvention::Swift,
131 CanonAbi::Arm(arm_call) => match arm_call {
132 ArmCall::Aapcs => CallConvention::ArmAapcs,
133 ArmCall::CCmseNonSecureCall => CallConvention::CCmseNonSecureCall,
134 ArmCall::CCmseNonSecureEntry => CallConvention::CCmseNonSecureEntry,
135 },
136 CanonAbi::GpuKernel => CallConvention::GpuKernel,
137 CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind {
138 InterruptKind::Avr => CallConvention::AvrInterrupt,
139 InterruptKind::AvrNonBlocking => CallConvention::AvrNonBlockingInterrupt,
140 InterruptKind::Msp430 => CallConvention::Msp430Intr,
141 InterruptKind::RiscvMachine | InterruptKind::RiscvSupervisor => {
142 CallConvention::RiscvInterrupt
143 }
144 InterruptKind::X86 => CallConvention::X86Intr,
145 },
146 CanonAbi::X86(x86_call) => match x86_call {
147 X86Call::Fastcall => CallConvention::X86Fastcall,
148 X86Call::Stdcall => CallConvention::X86Stdcall,
149 X86Call::SysV64 => CallConvention::X86_64SysV,
150 X86Call::Thiscall => CallConvention::X86ThisCall,
151 X86Call::Vectorcall => CallConvention::X86VectorCall,
152 X86Call::Win64 => CallConvention::X86_64Win64,
153 },
154 }
155 }
156}
157
158impl<'tcx> Stable<'tcx> for callconv::PassMode {
159 type T = PassMode;
160
161 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
162 match self {
163 callconv::PassMode::Ignore => PassMode::Ignore,
164 callconv::PassMode::Direct(attr) => PassMode::Direct(opaque(attr)),
165 callconv::PassMode::Pair(first, second) => {
166 PassMode::Pair(opaque(first), opaque(second))
167 }
168 callconv::PassMode::Cast { pad_i32, cast } => {
169 PassMode::Cast { pad_i32: *pad_i32, cast: opaque(cast) }
170 }
171 callconv::PassMode::Indirect { attrs, meta_attrs, on_stack } => PassMode::Indirect {
172 attrs: opaque(attrs),
173 meta_attrs: opaque(meta_attrs),
174 on_stack: *on_stack,
175 },
176 }
177 }
178}
179
180impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape<rustc_abi::FieldIdx> {
181 type T = FieldsShape;
182
183 fn stable<'cx>(
184 &self,
185 tables: &mut Tables<'cx, BridgeTys>,
186 cx: &CompilerCtxt<'cx, BridgeTys>,
187 ) -> Self::T {
188 match self {
189 rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive,
190 rustc_abi::FieldsShape::Union(count) => FieldsShape::Union(*count),
191 rustc_abi::FieldsShape::Array { stride, count } => {
192 FieldsShape::Array { stride: stride.stable(tables, cx), count: *count }
193 }
194 rustc_abi::FieldsShape::Arbitrary { offsets, .. } => {
195 FieldsShape::Arbitrary { offsets: offsets.iter().as_slice().stable(tables, cx) }
196 }
197 }
198 }
199}
200
201impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
202 type T = VariantsShape;
203
204 fn stable<'cx>(
205 &self,
206 tables: &mut Tables<'cx, BridgeTys>,
207 cx: &CompilerCtxt<'cx, BridgeTys>,
208 ) -> Self::T {
209 match self {
210 rustc_abi::Variants::Single { index } => {
211 VariantsShape::Single { index: index.stable(tables, cx) }
212 }
213 rustc_abi::Variants::Empty => VariantsShape::Empty,
214 rustc_abi::Variants::Multiple { tag, tag_encoding, tag_field, variants } => {
215 VariantsShape::Multiple {
216 tag: tag.stable(tables, cx),
217 tag_encoding: tag_encoding.stable(tables, cx),
218 tag_field: tag_field.stable(tables, cx),
219 variants: variants
220 .iter()
221 .map(|v| VariantFields {
222 offsets: v.field_offsets.iter().as_slice().stable(tables, cx),
223 })
224 .collect(),
225 }
226 }
227 }
228 }
229}
230
231impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding<rustc_abi::VariantIdx> {
232 type T = TagEncoding;
233
234 fn stable<'cx>(
235 &self,
236 tables: &mut Tables<'cx, BridgeTys>,
237 cx: &CompilerCtxt<'cx, BridgeTys>,
238 ) -> Self::T {
239 match self {
240 rustc_abi::TagEncoding::Direct => TagEncoding::Direct,
241 rustc_abi::TagEncoding::Niche { untagged_variant, niche_variants, niche_start } => {
242 TagEncoding::Niche {
243 untagged_variant: untagged_variant.stable(tables, cx),
244 niche_variants: niche_variants.stable(tables, cx),
245 niche_start: *niche_start,
246 }
247 }
248 }
249 }
250}
251
252impl<'tcx> Stable<'tcx> for rustc_abi::NumScalableVectors {
253 type T = NumScalableVectors;
254
255 fn stable<'cx>(
256 &self,
257 _tables: &mut Tables<'cx, BridgeTys>,
258 _cx: &CompilerCtxt<'cx, BridgeTys>,
259 ) -> Self::T {
260 NumScalableVectors(self.0)
261 }
262}
263
264impl<'tcx> Stable<'tcx> for rustc_abi::BackendLaneCount {
265 type T = u64;
266
267 fn stable<'cx>(
268 &self,
269 _tables: &mut Tables<'cx, BridgeTys>,
270 _cx: &CompilerCtxt<'cx, BridgeTys>,
271 ) -> Self::T {
272 self.as_u64()
273 }
274}
275
276impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
277 type T = ValueAbi;
278
279 fn stable<'cx>(
280 &self,
281 tables: &mut Tables<'cx, BridgeTys>,
282 cx: &CompilerCtxt<'cx, BridgeTys>,
283 ) -> Self::T {
284 match *self {
285 rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables, cx)),
286 rustc_abi::BackendRepr::ScalarPair { a: first, b: second, b_offset: second_offset } => {
287 ValueAbi::ScalarPair {
288 a: first.stable(tables, cx),
289 b: second.stable(tables, cx),
290 b_offset: second_offset.stable(tables, cx),
291 }
292 }
293 rustc_abi::BackendRepr::SimdVector { element, count } => ValueAbi::Vector {
294 element: element.stable(tables, cx),
295 count: count.stable(tables, cx),
296 },
297 rustc_abi::BackendRepr::SimdScalableVector { element, count, number_of_vectors } => {
298 ValueAbi::ScalableVector {
299 element: element.stable(tables, cx),
300 count: count.stable(tables, cx),
301 number_of_vectors: number_of_vectors.stable(tables, cx),
302 }
303 }
304 rustc_abi::BackendRepr::Memory { sized } => ValueAbi::Aggregate { sized },
305 }
306 }
307}
308
309impl<'tcx> Stable<'tcx> for rustc_abi::Size {
310 type T = Size;
311
312 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
313 Size::from_bits(self.bits_usize())
314 }
315}
316
317impl<'tcx> Stable<'tcx> for rustc_abi::Align {
318 type T = Align;
319
320 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
321 self.bytes()
322 }
323}
324
325impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
326 type T = Scalar;
327
328 fn stable<'cx>(
329 &self,
330 tables: &mut Tables<'cx, BridgeTys>,
331 cx: &CompilerCtxt<'cx, BridgeTys>,
332 ) -> Self::T {
333 match self {
334 rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized {
335 value: value.stable(tables, cx),
336 valid_range: valid_range.stable(tables, cx),
337 },
338 rustc_abi::Scalar::Union { value } => Scalar::Union { value: value.stable(tables, cx) },
339 }
340 }
341}
342
343impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
344 type T = Primitive;
345
346 fn stable<'cx>(
347 &self,
348 tables: &mut Tables<'cx, BridgeTys>,
349 cx: &CompilerCtxt<'cx, BridgeTys>,
350 ) -> Self::T {
351 match self {
352 rustc_abi::Primitive::Int(length, signed) => {
353 Primitive::Int { length: length.stable(tables, cx), signed: *signed }
354 }
355 rustc_abi::Primitive::Float(length) => {
356 Primitive::Float { length: length.stable(tables, cx) }
357 }
358 rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables, cx)),
359 }
360 }
361}
362
363impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
364 type T = AddressSpace;
365
366 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
367 AddressSpace(self.0)
368 }
369}
370
371impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
372 type T = IntegerLength;
373
374 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
375 match self {
376 rustc_abi::Integer::I8 => IntegerLength::I8,
377 rustc_abi::Integer::I16 => IntegerLength::I16,
378 rustc_abi::Integer::I32 => IntegerLength::I32,
379 rustc_abi::Integer::I64 => IntegerLength::I64,
380 rustc_abi::Integer::I128 => IntegerLength::I128,
381 }
382 }
383}
384
385impl<'tcx> Stable<'tcx> for rustc_abi::Float {
386 type T = FloatLength;
387
388 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
389 match self {
390 rustc_abi::Float::F16 => FloatLength::F16,
391 rustc_abi::Float::F32 => FloatLength::F32,
392 rustc_abi::Float::F64 => FloatLength::F64,
393 rustc_abi::Float::F128 => FloatLength::F128,
394 }
395 }
396}
397
398impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
399 type T = WrappingRange;
400
401 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
402 WrappingRange { start: self.start, end: self.end }
403 }
404}
405
406impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags {
407 type T = ReprFlags;
408
409 fn stable<'cx>(
410 &self,
411 _tables: &mut Tables<'cx, BridgeTys>,
412 _cx: &CompilerCtxt<'cx, BridgeTys>,
413 ) -> Self::T {
414 ReprFlags {
415 is_simd: self.intersects(Self::IS_SIMD),
416 is_c: self.intersects(Self::IS_C),
417 is_transparent: self.intersects(Self::IS_TRANSPARENT),
418 is_linear: self.intersects(Self::IS_LINEAR),
419 }
420 }
421}
422
423impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType {
424 type T = IntegerType;
425
426 fn stable<'cx>(
427 &self,
428 tables: &mut Tables<'cx, BridgeTys>,
429 cx: &CompilerCtxt<'cx, BridgeTys>,
430 ) -> Self::T {
431 match self {
432 rustc_abi::IntegerType::Pointer(signed) => IntegerType::Pointer { is_signed: *signed },
433 rustc_abi::IntegerType::Fixed(integer, signed) => {
434 IntegerType::Fixed { length: integer.stable(tables, cx), is_signed: *signed }
435 }
436 }
437 }
438}
439
440impl<'tcx> Stable<'tcx> for rustc_abi::ReprOptions {
441 type T = ReprOptions;
442
443 fn stable<'cx>(
444 &self,
445 tables: &mut Tables<'cx, BridgeTys>,
446 cx: &CompilerCtxt<'cx, BridgeTys>,
447 ) -> Self::T {
448 ReprOptions {
449 int: self.int.map(|int| int.stable(tables, cx)),
450 align: self.align.map(|align| align.stable(tables, cx)),
451 pack: self.pack.map(|pack| pack.stable(tables, cx)),
452 flags: self.flags.stable(tables, cx),
453 }
454 }
455}