Skip to main content

rustc_public/unstable/convert/stable/
abi.rs

1//! Conversion of internal Rust compiler `rustc_target` and `rustc_abi` items to stable ones.
2
3#![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}