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::IndexedVal;
12use crate::abi::{
13 AddressSpace, ArgAbi, ArgAttributes, ArgExtension, CallConvention, CastTarget, FieldsShape,
14 FloatLength, FnAbi, IndirectMode, IntegerLength, IntegerType, Layout, LayoutShape,
15 NumScalableVectors, PassMode, Primitive, Reg, RegKind, ReprFlags, ReprOptions, Scalar,
16 TagEncoding, TyAndLayout, Uniform, ValueRepr, VariantFields, VariantsShape, WrappingRange,
17};
18use crate::compiler_interface::BridgeTys;
19use crate::target::MachineSize as Size;
20use crate::ty::{Align, VariantIdx};
21use crate::unstable::Stable;
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 value_repr: 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::IndirectMode {
159 type T = IndirectMode;
160
161 fn stable<'cx>(
162 &self,
163 _tables: &mut Tables<'cx, BridgeTys>,
164 _cx: &CompilerCtxt<'cx, BridgeTys>,
165 ) -> Self::T {
166 match self {
167 callconv::IndirectMode::Pointer => IndirectMode::Pointer,
168 callconv::IndirectMode::OnStack => IndirectMode::OnStack,
169 callconv::IndirectMode::AmdgpuKernelArg => IndirectMode::AmdgpuKernelArg,
170 }
171 }
172}
173
174impl<'tcx> Stable<'tcx> for callconv::PassMode {
175 type T = PassMode;
176
177 fn stable<'cx>(
178 &self,
179 tables: &mut Tables<'cx, BridgeTys>,
180 cx: &CompilerCtxt<'cx, BridgeTys>,
181 ) -> Self::T {
182 match self {
183 callconv::PassMode::Ignore => PassMode::Ignore,
184 callconv::PassMode::Direct(attr) => PassMode::Direct(attr.stable(tables, cx)),
185 callconv::PassMode::Pair(first, second) => {
186 PassMode::Pair(first.stable(tables, cx), second.stable(tables, cx))
187 }
188 callconv::PassMode::Cast { pad_i32_count, cast } => {
189 PassMode::Cast { pad_i32_count: *pad_i32_count, cast: cast.stable(tables, cx) }
190 }
191 callconv::PassMode::Indirect { attrs, meta_attrs, address_space, mode } => {
192 PassMode::Indirect {
193 attrs: attrs.stable(tables, cx),
194 meta_attrs: meta_attrs.map(|a| a.stable(tables, cx)),
195 address_space: address_space.stable(tables, cx),
196 mode: mode.stable(tables, cx),
197 }
198 }
199 }
200 }
201}
202
203impl<'tcx> Stable<'tcx> for callconv::CastTarget {
204 type T = CastTarget;
205
206 fn stable<'cx>(
207 &self,
208 tables: &mut Tables<'cx, BridgeTys>,
209 cx: &CompilerCtxt<'cx, BridgeTys>,
210 ) -> Self::T {
211 CastTarget {
212 prefix: self.prefix.iter().map(|reg| reg.stable(tables, cx)).collect(),
213 rest_offset: self.rest_offset.map(|offset| Size::from_bits(offset.bits_usize())),
214 rest: self.rest.stable(tables, cx),
215 }
216 }
217}
218
219impl<'tcx> Stable<'tcx> for callconv::Uniform {
220 type T = Uniform;
221
222 fn stable<'cx>(
223 &self,
224 tables: &mut Tables<'cx, BridgeTys>,
225 cx: &CompilerCtxt<'cx, BridgeTys>,
226 ) -> Self::T {
227 Uniform {
228 unit: self.unit.stable(tables, cx),
229 total: Size::from_bits(self.total.bits_usize()),
230 is_consecutive: self.is_consecutive,
231 }
232 }
233}
234
235impl<'tcx> Stable<'tcx> for rustc_abi::Reg {
236 type T = Reg;
237
238 fn stable<'cx>(
239 &self,
240 _: &mut Tables<'cx, BridgeTys>,
241 _: &CompilerCtxt<'cx, BridgeTys>,
242 ) -> Self::T {
243 Reg {
244 kind: match self.kind {
245 rustc_abi::RegKind::Integer => RegKind::Integer,
246 rustc_abi::RegKind::Float => RegKind::Float,
247 rustc_abi::RegKind::Vector { .. } => RegKind::Vector,
248 },
249 size: Size::from_bits(self.size.bits_usize()),
250 }
251 }
252}
253
254impl<'tcx> Stable<'tcx> for callconv::ArgAttributes {
255 type T = ArgAttributes;
256
257 fn stable<'cx>(
258 &self,
259 _: &mut Tables<'cx, BridgeTys>,
260 _: &CompilerCtxt<'cx, BridgeTys>,
261 ) -> Self::T {
262 ArgAttributes {
263 arg_ext: match self.arg_ext {
264 callconv::ArgExtension::None => ArgExtension::None,
265 callconv::ArgExtension::Zext => ArgExtension::Zext,
266 callconv::ArgExtension::Sext => ArgExtension::Sext,
267 },
268 pointee_size: Size::from_bits(self.pointee_size.bits_usize()),
269 pointee_align: self.pointee_align.map(|a| a.bytes()),
270 }
271 }
272}
273
274impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape<rustc_abi::FieldIdx> {
275 type T = FieldsShape;
276
277 fn stable<'cx>(
278 &self,
279 tables: &mut Tables<'cx, BridgeTys>,
280 cx: &CompilerCtxt<'cx, BridgeTys>,
281 ) -> Self::T {
282 match self {
283 rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive,
284 rustc_abi::FieldsShape::Union(count) => FieldsShape::Union(*count),
285 rustc_abi::FieldsShape::Array { stride, count } => {
286 FieldsShape::Array { stride: stride.stable(tables, cx), count: *count }
287 }
288 rustc_abi::FieldsShape::Arbitrary { offsets, .. } => {
289 FieldsShape::Arbitrary { offsets: offsets.iter().as_slice().stable(tables, cx) }
290 }
291 }
292 }
293}
294
295impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
296 type T = VariantsShape;
297
298 fn stable<'cx>(
299 &self,
300 tables: &mut Tables<'cx, BridgeTys>,
301 cx: &CompilerCtxt<'cx, BridgeTys>,
302 ) -> Self::T {
303 match self {
304 rustc_abi::Variants::Single { index } => {
305 VariantsShape::Single { index: index.stable(tables, cx) }
306 }
307 rustc_abi::Variants::Empty => VariantsShape::Empty,
308 rustc_abi::Variants::Multiple { tag, tag_encoding, tag_field, variants } => {
309 VariantsShape::Multiple {
310 tag: tag.stable(tables, cx),
311 tag_encoding: tag_encoding.stable(tables, cx),
312 tag_field: tag_field.stable(tables, cx),
313 variants: variants
314 .iter()
315 .map(|v| VariantFields {
316 offsets: v.field_offsets.iter().as_slice().stable(tables, cx),
317 })
318 .collect(),
319 }
320 }
321 }
322 }
323}
324
325impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding<rustc_abi::VariantIdx> {
326 type T = TagEncoding;
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::TagEncoding::Direct => TagEncoding::Direct,
335 rustc_abi::TagEncoding::Niche { untagged_variant, niche_variants, niche_start } => {
336 TagEncoding::Niche {
337 untagged_variant: untagged_variant.stable(tables, cx),
338 niche_variants: niche_variants.stable(tables, cx),
339 niche_start: *niche_start,
340 }
341 }
342 }
343 }
344}
345
346impl<'tcx> Stable<'tcx> for rustc_abi::NumScalableVectors {
347 type T = NumScalableVectors;
348
349 fn stable<'cx>(
350 &self,
351 _tables: &mut Tables<'cx, BridgeTys>,
352 _cx: &CompilerCtxt<'cx, BridgeTys>,
353 ) -> Self::T {
354 NumScalableVectors(self.0)
355 }
356}
357
358impl<'tcx> Stable<'tcx> for rustc_abi::BackendLaneCount {
359 type T = u64;
360
361 fn stable<'cx>(
362 &self,
363 _tables: &mut Tables<'cx, BridgeTys>,
364 _cx: &CompilerCtxt<'cx, BridgeTys>,
365 ) -> Self::T {
366 self.as_u64()
367 }
368}
369
370impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
371 type T = ValueRepr;
372
373 fn stable<'cx>(
374 &self,
375 tables: &mut Tables<'cx, BridgeTys>,
376 cx: &CompilerCtxt<'cx, BridgeTys>,
377 ) -> Self::T {
378 match *self {
379 rustc_abi::BackendRepr::Scalar(scalar) => ValueRepr::Scalar(scalar.stable(tables, cx)),
380 rustc_abi::BackendRepr::ScalarPair { a: first, b: second, b_offset: second_offset } => {
381 ValueRepr::ScalarPair {
382 a: first.stable(tables, cx),
383 b: second.stable(tables, cx),
384 b_offset: second_offset.stable(tables, cx),
385 }
386 }
387 rustc_abi::BackendRepr::SimdVector { element, count } => ValueRepr::Vector {
388 element: element.stable(tables, cx),
389 count: count.stable(tables, cx),
390 },
391 rustc_abi::BackendRepr::SimdScalableVector { element, count, number_of_vectors } => {
392 ValueRepr::ScalableVector {
393 element: element.stable(tables, cx),
394 count: count.stable(tables, cx),
395 number_of_vectors: number_of_vectors.stable(tables, cx),
396 }
397 }
398 rustc_abi::BackendRepr::Memory { sized } => ValueRepr::Aggregate { sized },
399 }
400 }
401}
402
403impl<'tcx> Stable<'tcx> for rustc_abi::Size {
404 type T = Size;
405
406 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
407 Size::from_bits(self.bits_usize())
408 }
409}
410
411impl<'tcx> Stable<'tcx> for rustc_abi::Align {
412 type T = Align;
413
414 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
415 self.bytes()
416 }
417}
418
419impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
420 type T = Scalar;
421
422 fn stable<'cx>(
423 &self,
424 tables: &mut Tables<'cx, BridgeTys>,
425 cx: &CompilerCtxt<'cx, BridgeTys>,
426 ) -> Self::T {
427 match self {
428 rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized {
429 value: value.stable(tables, cx),
430 valid_range: valid_range.stable(tables, cx),
431 },
432 rustc_abi::Scalar::Union { value } => Scalar::Union { value: value.stable(tables, cx) },
433 }
434 }
435}
436
437impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
438 type T = Primitive;
439
440 fn stable<'cx>(
441 &self,
442 tables: &mut Tables<'cx, BridgeTys>,
443 cx: &CompilerCtxt<'cx, BridgeTys>,
444 ) -> Self::T {
445 match self {
446 rustc_abi::Primitive::Int(length, signed) => {
447 Primitive::Int { length: length.stable(tables, cx), signed: *signed }
448 }
449 rustc_abi::Primitive::Float(length) => {
450 Primitive::Float { length: length.stable(tables, cx) }
451 }
452 rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables, cx)),
453 }
454 }
455}
456
457impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
458 type T = AddressSpace;
459
460 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
461 AddressSpace(self.0)
462 }
463}
464
465impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
466 type T = IntegerLength;
467
468 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
469 match self {
470 rustc_abi::Integer::I8 => IntegerLength::I8,
471 rustc_abi::Integer::I16 => IntegerLength::I16,
472 rustc_abi::Integer::I32 => IntegerLength::I32,
473 rustc_abi::Integer::I64 => IntegerLength::I64,
474 rustc_abi::Integer::I128 => IntegerLength::I128,
475 }
476 }
477}
478
479impl<'tcx> Stable<'tcx> for rustc_abi::Float {
480 type T = FloatLength;
481
482 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
483 match self {
484 rustc_abi::Float::F16 => FloatLength::F16,
485 rustc_abi::Float::F16B => FloatLength::F16B,
486 rustc_abi::Float::F32 => FloatLength::F32,
487 rustc_abi::Float::F64 => FloatLength::F64,
488 rustc_abi::Float::F128 => FloatLength::F128,
489 }
490 }
491}
492
493impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
494 type T = WrappingRange;
495
496 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
497 WrappingRange { start: self.start, end: self.end }
498 }
499}
500
501impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags {
502 type T = ReprFlags;
503
504 fn stable<'cx>(
505 &self,
506 _tables: &mut Tables<'cx, BridgeTys>,
507 _cx: &CompilerCtxt<'cx, BridgeTys>,
508 ) -> Self::T {
509 ReprFlags {
510 is_simd: self.intersects(Self::IS_SIMD),
511 is_c: self.intersects(Self::IS_C),
512 is_transparent: self.intersects(Self::IS_TRANSPARENT),
513 is_linear: self.intersects(Self::IS_LINEAR),
514 }
515 }
516}
517
518impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType {
519 type T = IntegerType;
520
521 fn stable<'cx>(
522 &self,
523 tables: &mut Tables<'cx, BridgeTys>,
524 cx: &CompilerCtxt<'cx, BridgeTys>,
525 ) -> Self::T {
526 match self {
527 rustc_abi::IntegerType::Pointer(signed) => IntegerType::Pointer { is_signed: *signed },
528 rustc_abi::IntegerType::Fixed(integer, signed) => {
529 IntegerType::Fixed { length: integer.stable(tables, cx), is_signed: *signed }
530 }
531 }
532 }
533}
534
535impl<'tcx> Stable<'tcx> for rustc_abi::ReprOptions {
536 type T = ReprOptions;
537
538 fn stable<'cx>(
539 &self,
540 tables: &mut Tables<'cx, BridgeTys>,
541 cx: &CompilerCtxt<'cx, BridgeTys>,
542 ) -> Self::T {
543 ReprOptions {
544 int: self.int.map(|int| int.stable(tables, cx)),
545 align: self.align.map(|align| align.stable(tables, cx)),
546 pack: self.pack.map(|pack| pack.stable(tables, cx)),
547 flags: self.flags.stable(tables, cx),
548 }
549 }
550}