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, ArgAttributeFlags, ArgAttributes, ArgExtension, CallConvention,
14 CastTarget, FieldsShape, FloatLength, FnAbi, IndirectMode, IntegerLength, IntegerType, Layout,
15 LayoutShape, NumScalableVectors, PassMode, Primitive, Reg, RegKind, ReprFlags, ReprOptions,
16 Scalar, TagEncoding, TyAndLayout, Uniform, ValueRepr, VariantFields, VariantsShape,
17 WrappingRange,
18};
19use crate::compiler_interface::BridgeTys;
20use crate::target::MachineSize as Size;
21use crate::ty::{Align, VariantIdx};
22use crate::unstable::Stable;
23
24impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx {
25 type T = VariantIdx;
26 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
27 VariantIdx::to_val(self.as_usize())
28 }
29}
30
31impl<'tcx> Stable<'tcx> for rustc_abi::Endian {
32 type T = crate::target::Endian;
33
34 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
35 match self {
36 rustc_abi::Endian::Little => crate::target::Endian::Little,
37 rustc_abi::Endian::Big => crate::target::Endian::Big,
38 }
39 }
40}
41
42impl<'tcx> Stable<'tcx> for rustc_abi::TyAndLayout<'tcx, ty::Ty<'tcx>> {
43 type T = TyAndLayout;
44
45 fn stable<'cx>(
46 &self,
47 tables: &mut Tables<'cx, BridgeTys>,
48 cx: &CompilerCtxt<'cx, BridgeTys>,
49 ) -> Self::T {
50 TyAndLayout { ty: self.ty.stable(tables, cx), layout: self.layout.stable(tables, cx) }
51 }
52}
53
54impl<'tcx> Stable<'tcx> for rustc_abi::Layout<'tcx> {
55 type T = Layout;
56
57 fn stable<'cx>(
58 &self,
59 tables: &mut Tables<'cx, BridgeTys>,
60 cx: &CompilerCtxt<'cx, BridgeTys>,
61 ) -> Self::T {
62 tables.layout_id(cx.lift(*self))
63 }
64}
65
66impl<'tcx> Stable<'tcx> for rustc_abi::LayoutData<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
67 type T = LayoutShape;
68
69 fn stable<'cx>(
70 &self,
71 tables: &mut Tables<'cx, BridgeTys>,
72 cx: &CompilerCtxt<'cx, BridgeTys>,
73 ) -> Self::T {
74 LayoutShape {
75 fields: self.fields.stable(tables, cx),
76 variants: self.variants.stable(tables, cx),
77 value_repr: self.backend_repr.stable(tables, cx),
78 abi_align: self.align.abi.stable(tables, cx),
79 size: self.size.stable(tables, cx),
80 }
81 }
82}
83
84impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> {
85 type T = FnAbi;
86
87 fn stable<'cx>(
88 &self,
89 tables: &mut Tables<'cx, BridgeTys>,
90 cx: &CompilerCtxt<'cx, BridgeTys>,
91 ) -> Self::T {
92 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);
93 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));
94 FnAbi {
95 args: self.args.as_ref().stable(tables, cx),
96 ret: self.ret.stable(tables, cx),
97 fixed_count: self.fixed_count,
98 conv: self.conv.stable(tables, cx),
99 c_variadic: self.c_variadic,
100 }
101 }
102}
103
104impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> {
105 type T = ArgAbi;
106
107 fn stable<'cx>(
108 &self,
109 tables: &mut Tables<'cx, BridgeTys>,
110 cx: &CompilerCtxt<'cx, BridgeTys>,
111 ) -> Self::T {
112 ArgAbi {
113 ty: self.layout.ty.stable(tables, cx),
114 layout: self.layout.layout.stable(tables, cx),
115 mode: self.mode.stable(tables, cx),
116 }
117 }
118}
119
120impl<'tcx> Stable<'tcx> for CanonAbi {
121 type T = CallConvention;
122
123 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
124 match self {
125 CanonAbi::C => CallConvention::C,
126 CanonAbi::Rust => CallConvention::Rust,
127 CanonAbi::RustCold => CallConvention::Cold,
128 CanonAbi::RustPreserveNone => CallConvention::PreserveNone,
129 CanonAbi::RustTail => CallConvention::Tail,
130 CanonAbi::Custom => CallConvention::Custom,
131 CanonAbi::Swift => CallConvention::Swift,
132 CanonAbi::Arm(arm_call) => match arm_call {
133 ArmCall::Aapcs => CallConvention::ArmAapcs,
134 ArmCall::CCmseNonSecureCall => CallConvention::CCmseNonSecureCall,
135 ArmCall::CCmseNonSecureEntry => CallConvention::CCmseNonSecureEntry,
136 },
137 CanonAbi::GpuKernel => CallConvention::GpuKernel,
138 CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind {
139 InterruptKind::Avr => CallConvention::AvrInterrupt,
140 InterruptKind::AvrNonBlocking => CallConvention::AvrNonBlockingInterrupt,
141 InterruptKind::Msp430 => CallConvention::Msp430Intr,
142 InterruptKind::RiscvMachine | InterruptKind::RiscvSupervisor => {
143 CallConvention::RiscvInterrupt
144 }
145 InterruptKind::X86 => CallConvention::X86Intr,
146 },
147 CanonAbi::X86(x86_call) => match x86_call {
148 X86Call::Fastcall => CallConvention::X86Fastcall,
149 X86Call::Stdcall => CallConvention::X86Stdcall,
150 X86Call::SysV64 => CallConvention::X86_64SysV,
151 X86Call::Thiscall => CallConvention::X86ThisCall,
152 X86Call::Vectorcall => CallConvention::X86VectorCall,
153 X86Call::Win64 => CallConvention::X86_64Win64,
154 },
155 }
156 }
157}
158
159impl<'tcx> Stable<'tcx> for callconv::IndirectMode {
160 type T = IndirectMode;
161
162 fn stable<'cx>(
163 &self,
164 _tables: &mut Tables<'cx, BridgeTys>,
165 _cx: &CompilerCtxt<'cx, BridgeTys>,
166 ) -> Self::T {
167 match self {
168 callconv::IndirectMode::Pointer => IndirectMode::Pointer,
169 callconv::IndirectMode::OnStack => IndirectMode::OnStack,
170 callconv::IndirectMode::AmdgpuKernelArg => IndirectMode::AmdgpuKernelArg,
171 }
172 }
173}
174
175impl<'tcx> Stable<'tcx> for callconv::PassMode {
176 type T = PassMode;
177
178 fn stable<'cx>(
179 &self,
180 tables: &mut Tables<'cx, BridgeTys>,
181 cx: &CompilerCtxt<'cx, BridgeTys>,
182 ) -> Self::T {
183 match self {
184 callconv::PassMode::Ignore => PassMode::Ignore,
185 callconv::PassMode::Direct(attr) => PassMode::Direct(attr.stable(tables, cx)),
186 callconv::PassMode::Pair(first, second) => {
187 PassMode::Pair(first.stable(tables, cx), second.stable(tables, cx))
188 }
189 callconv::PassMode::Cast { pad_i32_count, cast } => {
190 PassMode::Cast { pad_i32_count: *pad_i32_count, cast: cast.stable(tables, cx) }
191 }
192 callconv::PassMode::Indirect { attrs, address_space, mode } => PassMode::Indirect {
193 attrs: attrs.stable(tables, cx),
194 address_space: address_space.stable(tables, cx),
195 mode: mode.stable(tables, cx),
196 },
197 callconv::PassMode::IndirectUnsized { attrs, meta_attrs } => {
198 PassMode::IndirectUnsized {
199 attrs: attrs.stable(tables, cx),
200 meta_attrs: meta_attrs.stable(tables, cx),
201 }
202 }
203 }
204 }
205}
206
207impl<'tcx> Stable<'tcx> for callconv::CastTarget {
208 type T = CastTarget;
209
210 fn stable<'cx>(
211 &self,
212 tables: &mut Tables<'cx, BridgeTys>,
213 cx: &CompilerCtxt<'cx, BridgeTys>,
214 ) -> Self::T {
215 CastTarget {
216 prefix: self.prefix.iter().map(|reg| reg.stable(tables, cx)).collect(),
217 rest_offset: self.rest_offset.map(|offset| Size::from_bits(offset.bits_usize())),
218 rest: self.rest.stable(tables, cx),
219 }
220 }
221}
222
223impl<'tcx> Stable<'tcx> for callconv::Uniform {
224 type T = Uniform;
225
226 fn stable<'cx>(
227 &self,
228 tables: &mut Tables<'cx, BridgeTys>,
229 cx: &CompilerCtxt<'cx, BridgeTys>,
230 ) -> Self::T {
231 Uniform {
232 unit: self.unit.stable(tables, cx),
233 total: Size::from_bits(self.total.bits_usize()),
234 is_consecutive: self.is_consecutive,
235 }
236 }
237}
238
239impl<'tcx> Stable<'tcx> for rustc_abi::Reg {
240 type T = Reg;
241
242 fn stable<'cx>(
243 &self,
244 _: &mut Tables<'cx, BridgeTys>,
245 _: &CompilerCtxt<'cx, BridgeTys>,
246 ) -> Self::T {
247 Reg {
248 kind: match self.kind {
249 rustc_abi::RegKind::Integer => RegKind::Integer,
250 rustc_abi::RegKind::Float => RegKind::Float,
251 rustc_abi::RegKind::PpcF128 => RegKind::Float,
252 rustc_abi::RegKind::Vector { .. } => RegKind::Vector,
253 },
254 size: Size::from_bits(self.size.bits_usize()),
255 }
256 }
257}
258
259impl<'tcx> Stable<'tcx> for callconv::ArgAttributes {
260 type T = ArgAttributes;
261
262 fn stable<'cx>(
263 &self,
264 _: &mut Tables<'cx, BridgeTys>,
265 _: &CompilerCtxt<'cx, BridgeTys>,
266 ) -> Self::T {
267 ArgAttributes {
268 regular: ArgAttributeFlags {
269 captures_none: self.regular.contains(callconv::ArgAttribute::CapturesNone),
270 captures_address: self.regular.contains(callconv::ArgAttribute::CapturesAddress),
271 captures_read_only: self.regular.contains(callconv::ArgAttribute::CapturesReadOnly),
272 no_alias: self.regular.contains(callconv::ArgAttribute::NoAlias),
273 non_null: self.regular.contains(callconv::ArgAttribute::NonNull),
274 read_only: self.regular.contains(callconv::ArgAttribute::ReadOnly),
275 in_reg: self.regular.contains(callconv::ArgAttribute::InReg),
276 no_undef: self.regular.contains(callconv::ArgAttribute::NoUndef),
277 writable: self.regular.contains(callconv::ArgAttribute::Writable),
278 no_free: self.regular.contains(callconv::ArgAttribute::NoFree),
279 },
280 arg_ext: match self.arg_ext {
281 callconv::ArgExtension::None => ArgExtension::None,
282 callconv::ArgExtension::Zext => ArgExtension::Zext,
283 callconv::ArgExtension::Sext => ArgExtension::Sext,
284 },
285 pointee_size: Size::from_bits(self.pointee_size.bits_usize()),
286 pointee_align: self.pointee_align.map(|a| a.bytes()),
287 }
288 }
289}
290
291impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape<rustc_abi::FieldIdx> {
292 type T = FieldsShape;
293
294 fn stable<'cx>(
295 &self,
296 tables: &mut Tables<'cx, BridgeTys>,
297 cx: &CompilerCtxt<'cx, BridgeTys>,
298 ) -> Self::T {
299 match self {
300 rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive,
301 rustc_abi::FieldsShape::Union(count) => FieldsShape::Union(*count),
302 rustc_abi::FieldsShape::Array { stride, count } => {
303 FieldsShape::Array { stride: stride.stable(tables, cx), count: *count }
304 }
305 rustc_abi::FieldsShape::Arbitrary { offsets, .. } => {
306 FieldsShape::Arbitrary { offsets: offsets.iter().as_slice().stable(tables, cx) }
307 }
308 }
309 }
310}
311
312impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
313 type T = VariantsShape;
314
315 fn stable<'cx>(
316 &self,
317 tables: &mut Tables<'cx, BridgeTys>,
318 cx: &CompilerCtxt<'cx, BridgeTys>,
319 ) -> Self::T {
320 match self {
321 rustc_abi::Variants::Single { index } => {
322 VariantsShape::Single { index: index.stable(tables, cx) }
323 }
324 rustc_abi::Variants::Empty => VariantsShape::Empty,
325 rustc_abi::Variants::Multiple { tag, tag_encoding, tag_field, variants } => {
326 VariantsShape::Multiple {
327 tag: tag.stable(tables, cx),
328 tag_encoding: tag_encoding.stable(tables, cx),
329 tag_field: tag_field.stable(tables, cx),
330 variants: variants
331 .iter()
332 .map(|v| VariantFields {
333 offsets: v.field_offsets.iter().as_slice().stable(tables, cx),
334 })
335 .collect(),
336 }
337 }
338 }
339 }
340}
341
342impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding<rustc_abi::VariantIdx> {
343 type T = TagEncoding;
344
345 fn stable<'cx>(
346 &self,
347 tables: &mut Tables<'cx, BridgeTys>,
348 cx: &CompilerCtxt<'cx, BridgeTys>,
349 ) -> Self::T {
350 match self {
351 rustc_abi::TagEncoding::Direct => TagEncoding::Direct,
352 rustc_abi::TagEncoding::Niche { untagged_variant, niche_variants, niche_start } => {
353 TagEncoding::Niche {
354 untagged_variant: untagged_variant.stable(tables, cx),
355 niche_variants: niche_variants.stable(tables, cx),
356 niche_start: *niche_start,
357 }
358 }
359 }
360 }
361}
362
363impl<'tcx> Stable<'tcx> for rustc_abi::NumScalableVectors {
364 type T = NumScalableVectors;
365
366 fn stable<'cx>(
367 &self,
368 _tables: &mut Tables<'cx, BridgeTys>,
369 _cx: &CompilerCtxt<'cx, BridgeTys>,
370 ) -> Self::T {
371 NumScalableVectors(self.0)
372 }
373}
374
375impl<'tcx> Stable<'tcx> for rustc_abi::BackendLaneCount {
376 type T = u64;
377
378 fn stable<'cx>(
379 &self,
380 _tables: &mut Tables<'cx, BridgeTys>,
381 _cx: &CompilerCtxt<'cx, BridgeTys>,
382 ) -> Self::T {
383 self.as_u64()
384 }
385}
386
387impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
388 type T = ValueRepr;
389
390 fn stable<'cx>(
391 &self,
392 tables: &mut Tables<'cx, BridgeTys>,
393 cx: &CompilerCtxt<'cx, BridgeTys>,
394 ) -> Self::T {
395 match *self {
396 rustc_abi::BackendRepr::Scalar(scalar) => ValueRepr::Scalar(scalar.stable(tables, cx)),
397 rustc_abi::BackendRepr::ScalarPair { a: first, b: second, b_offset: second_offset } => {
398 ValueRepr::ScalarPair {
399 a: first.stable(tables, cx),
400 b: second.stable(tables, cx),
401 b_offset: second_offset.stable(tables, cx),
402 }
403 }
404 rustc_abi::BackendRepr::SimdVector { element, count } => ValueRepr::Vector {
405 element: element.stable(tables, cx),
406 count: count.stable(tables, cx),
407 },
408 rustc_abi::BackendRepr::SimdScalableVector { element, count, number_of_vectors } => {
409 ValueRepr::ScalableVector {
410 element: element.stable(tables, cx),
411 count: count.stable(tables, cx),
412 number_of_vectors: number_of_vectors.stable(tables, cx),
413 }
414 }
415 rustc_abi::BackendRepr::Memory { sized } => ValueRepr::Aggregate { sized },
416 }
417 }
418}
419
420impl<'tcx> Stable<'tcx> for rustc_abi::Size {
421 type T = Size;
422
423 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
424 Size::from_bits(self.bits_usize())
425 }
426}
427
428impl<'tcx> Stable<'tcx> for rustc_abi::Align {
429 type T = Align;
430
431 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
432 self.bytes()
433 }
434}
435
436impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
437 type T = Scalar;
438
439 fn stable<'cx>(
440 &self,
441 tables: &mut Tables<'cx, BridgeTys>,
442 cx: &CompilerCtxt<'cx, BridgeTys>,
443 ) -> Self::T {
444 match self {
445 rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized {
446 value: value.stable(tables, cx),
447 valid_range: valid_range.stable(tables, cx),
448 },
449 rustc_abi::Scalar::Union { value } => Scalar::Union { value: value.stable(tables, cx) },
450 }
451 }
452}
453
454impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
455 type T = Primitive;
456
457 fn stable<'cx>(
458 &self,
459 tables: &mut Tables<'cx, BridgeTys>,
460 cx: &CompilerCtxt<'cx, BridgeTys>,
461 ) -> Self::T {
462 match self {
463 rustc_abi::Primitive::Int(length, signed) => {
464 Primitive::Int { length: length.stable(tables, cx), signed: *signed }
465 }
466 rustc_abi::Primitive::Float(length) => {
467 Primitive::Float { length: length.stable(tables, cx) }
468 }
469 rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables, cx)),
470 }
471 }
472}
473
474impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
475 type T = AddressSpace;
476
477 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
478 AddressSpace(self.0)
479 }
480}
481
482impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
483 type T = IntegerLength;
484
485 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
486 match self {
487 rustc_abi::Integer::I8 => IntegerLength::I8,
488 rustc_abi::Integer::I16 => IntegerLength::I16,
489 rustc_abi::Integer::I32 => IntegerLength::I32,
490 rustc_abi::Integer::I64 => IntegerLength::I64,
491 rustc_abi::Integer::I128 => IntegerLength::I128,
492 }
493 }
494}
495
496impl<'tcx> Stable<'tcx> for rustc_abi::Float {
497 type T = FloatLength;
498
499 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
500 match self {
501 rustc_abi::Float::F16 => FloatLength::F16,
502 rustc_abi::Float::F16B => FloatLength::F16B,
503 rustc_abi::Float::F32 => FloatLength::F32,
504 rustc_abi::Float::F64 => FloatLength::F64,
505 rustc_abi::Float::F128 => FloatLength::F128,
506 rustc_abi::Float::PpcF128 => FloatLength::PpcF128,
507 }
508 }
509}
510
511impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
512 type T = WrappingRange;
513
514 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
515 WrappingRange { start: self.start, end: self.end }
516 }
517}
518
519impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags {
520 type T = ReprFlags;
521
522 fn stable<'cx>(
523 &self,
524 _tables: &mut Tables<'cx, BridgeTys>,
525 _cx: &CompilerCtxt<'cx, BridgeTys>,
526 ) -> Self::T {
527 ReprFlags {
528 is_simd: self.intersects(Self::IS_SIMD),
529 is_c: self.intersects(Self::IS_C),
530 is_transparent: self.intersects(Self::IS_TRANSPARENT),
531 is_linear: self.intersects(Self::IS_LINEAR),
532 }
533 }
534}
535
536impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType {
537 type T = IntegerType;
538
539 fn stable<'cx>(
540 &self,
541 tables: &mut Tables<'cx, BridgeTys>,
542 cx: &CompilerCtxt<'cx, BridgeTys>,
543 ) -> Self::T {
544 match self {
545 rustc_abi::IntegerType::Pointer(signed) => IntegerType::Pointer { is_signed: *signed },
546 rustc_abi::IntegerType::Fixed(integer, signed) => {
547 IntegerType::Fixed { length: integer.stable(tables, cx), is_signed: *signed }
548 }
549 }
550 }
551}
552
553impl<'tcx> Stable<'tcx> for rustc_abi::ReprOptions {
554 type T = ReprOptions;
555
556 fn stable<'cx>(
557 &self,
558 tables: &mut Tables<'cx, BridgeTys>,
559 cx: &CompilerCtxt<'cx, BridgeTys>,
560 ) -> Self::T {
561 ReprOptions {
562 int: self.int.map(|int| int.stable(tables, cx)),
563 align: self.align.map(|align| align.stable(tables, cx)),
564 pack: self.pack.map(|pack| pack.stable(tables, cx)),
565 flags: self.flags.stable(tables, cx),
566 }
567 }
568}