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