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::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::Custom => CallConvention::Custom,
129            CanonAbi::Swift => CallConvention::Swift,
130            CanonAbi::Arm(arm_call) => match arm_call {
131                ArmCall::Aapcs => CallConvention::ArmAapcs,
132                ArmCall::CCmseNonSecureCall => CallConvention::CCmseNonSecureCall,
133                ArmCall::CCmseNonSecureEntry => CallConvention::CCmseNonSecureEntry,
134            },
135            CanonAbi::GpuKernel => CallConvention::GpuKernel,
136            CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind {
137                InterruptKind::Avr => CallConvention::AvrInterrupt,
138                InterruptKind::AvrNonBlocking => CallConvention::AvrNonBlockingInterrupt,
139                InterruptKind::Msp430 => CallConvention::Msp430Intr,
140                InterruptKind::RiscvMachine | InterruptKind::RiscvSupervisor => {
141                    CallConvention::RiscvInterrupt
142                }
143                InterruptKind::X86 => CallConvention::X86Intr,
144            },
145            CanonAbi::X86(x86_call) => match x86_call {
146                X86Call::Fastcall => CallConvention::X86Fastcall,
147                X86Call::Stdcall => CallConvention::X86Stdcall,
148                X86Call::SysV64 => CallConvention::X86_64SysV,
149                X86Call::Thiscall => CallConvention::X86ThisCall,
150                X86Call::Vectorcall => CallConvention::X86VectorCall,
151                X86Call::Win64 => CallConvention::X86_64Win64,
152            },
153        }
154    }
155}
156
157impl<'tcx> Stable<'tcx> for callconv::PassMode {
158    type T = PassMode;
159
160    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
161        match self {
162            callconv::PassMode::Ignore => PassMode::Ignore,
163            callconv::PassMode::Direct(attr) => PassMode::Direct(opaque(attr)),
164            callconv::PassMode::Pair(first, second) => {
165                PassMode::Pair(opaque(first), opaque(second))
166            }
167            callconv::PassMode::Cast { pad_i32, cast } => {
168                PassMode::Cast { pad_i32: *pad_i32, cast: opaque(cast) }
169            }
170            callconv::PassMode::Indirect { attrs, meta_attrs, on_stack } => PassMode::Indirect {
171                attrs: opaque(attrs),
172                meta_attrs: opaque(meta_attrs),
173                on_stack: *on_stack,
174            },
175        }
176    }
177}
178
179impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape<rustc_abi::FieldIdx> {
180    type T = FieldsShape;
181
182    fn stable<'cx>(
183        &self,
184        tables: &mut Tables<'cx, BridgeTys>,
185        cx: &CompilerCtxt<'cx, BridgeTys>,
186    ) -> Self::T {
187        match self {
188            rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive,
189            rustc_abi::FieldsShape::Union(count) => FieldsShape::Union(*count),
190            rustc_abi::FieldsShape::Array { stride, count } => {
191                FieldsShape::Array { stride: stride.stable(tables, cx), count: *count }
192            }
193            rustc_abi::FieldsShape::Arbitrary { offsets, .. } => {
194                FieldsShape::Arbitrary { offsets: offsets.iter().as_slice().stable(tables, cx) }
195            }
196        }
197    }
198}
199
200impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
201    type T = VariantsShape;
202
203    fn stable<'cx>(
204        &self,
205        tables: &mut Tables<'cx, BridgeTys>,
206        cx: &CompilerCtxt<'cx, BridgeTys>,
207    ) -> Self::T {
208        match self {
209            rustc_abi::Variants::Single { index } => {
210                VariantsShape::Single { index: index.stable(tables, cx) }
211            }
212            rustc_abi::Variants::Empty => VariantsShape::Empty,
213            rustc_abi::Variants::Multiple { tag, tag_encoding, tag_field, variants } => {
214                VariantsShape::Multiple {
215                    tag: tag.stable(tables, cx),
216                    tag_encoding: tag_encoding.stable(tables, cx),
217                    tag_field: tag_field.stable(tables, cx),
218                    variants: variants
219                        .iter()
220                        .map(|v| match &v.fields {
221                            rustc_abi::FieldsShape::Arbitrary { offsets, .. } => VariantFields {
222                                offsets: offsets.iter().as_slice().stable(tables, cx),
223                            },
224                            _ => {
    ::core::panicking::panic_fmt(format_args!("variant layout should be Arbitrary"));
}panic!("variant layout should be Arbitrary"),
225                        })
226                        .collect(),
227                }
228            }
229        }
230    }
231}
232
233impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding<rustc_abi::VariantIdx> {
234    type T = TagEncoding;
235
236    fn stable<'cx>(
237        &self,
238        tables: &mut Tables<'cx, BridgeTys>,
239        cx: &CompilerCtxt<'cx, BridgeTys>,
240    ) -> Self::T {
241        match self {
242            rustc_abi::TagEncoding::Direct => TagEncoding::Direct,
243            rustc_abi::TagEncoding::Niche { untagged_variant, niche_variants, niche_start } => {
244                TagEncoding::Niche {
245                    untagged_variant: untagged_variant.stable(tables, cx),
246                    niche_variants: niche_variants.stable(tables, cx),
247                    niche_start: *niche_start,
248                }
249            }
250        }
251    }
252}
253
254impl<'tcx> Stable<'tcx> for rustc_abi::NumScalableVectors {
255    type T = NumScalableVectors;
256
257    fn stable<'cx>(
258        &self,
259        _tables: &mut Tables<'cx, BridgeTys>,
260        _cx: &CompilerCtxt<'cx, BridgeTys>,
261    ) -> Self::T {
262        NumScalableVectors(self.0)
263    }
264}
265
266impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
267    type T = ValueAbi;
268
269    fn stable<'cx>(
270        &self,
271        tables: &mut Tables<'cx, BridgeTys>,
272        cx: &CompilerCtxt<'cx, BridgeTys>,
273    ) -> Self::T {
274        match *self {
275            rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables, cx)),
276            rustc_abi::BackendRepr::ScalarPair(first, second) => {
277                ValueAbi::ScalarPair(first.stable(tables, cx), second.stable(tables, cx))
278            }
279            rustc_abi::BackendRepr::SimdVector { element, count } => {
280                ValueAbi::Vector { element: element.stable(tables, cx), count }
281            }
282            rustc_abi::BackendRepr::SimdScalableVector { element, count, number_of_vectors } => {
283                ValueAbi::ScalableVector {
284                    element: element.stable(tables, cx),
285                    count,
286                    number_of_vectors: number_of_vectors.stable(tables, cx),
287                }
288            }
289            rustc_abi::BackendRepr::Memory { sized } => ValueAbi::Aggregate { sized },
290        }
291    }
292}
293
294impl<'tcx> Stable<'tcx> for rustc_abi::Size {
295    type T = Size;
296
297    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
298        Size::from_bits(self.bits_usize())
299    }
300}
301
302impl<'tcx> Stable<'tcx> for rustc_abi::Align {
303    type T = Align;
304
305    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
306        self.bytes()
307    }
308}
309
310impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
311    type T = Scalar;
312
313    fn stable<'cx>(
314        &self,
315        tables: &mut Tables<'cx, BridgeTys>,
316        cx: &CompilerCtxt<'cx, BridgeTys>,
317    ) -> Self::T {
318        match self {
319            rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized {
320                value: value.stable(tables, cx),
321                valid_range: valid_range.stable(tables, cx),
322            },
323            rustc_abi::Scalar::Union { value } => Scalar::Union { value: value.stable(tables, cx) },
324        }
325    }
326}
327
328impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
329    type T = Primitive;
330
331    fn stable<'cx>(
332        &self,
333        tables: &mut Tables<'cx, BridgeTys>,
334        cx: &CompilerCtxt<'cx, BridgeTys>,
335    ) -> Self::T {
336        match self {
337            rustc_abi::Primitive::Int(length, signed) => {
338                Primitive::Int { length: length.stable(tables, cx), signed: *signed }
339            }
340            rustc_abi::Primitive::Float(length) => {
341                Primitive::Float { length: length.stable(tables, cx) }
342            }
343            rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables, cx)),
344        }
345    }
346}
347
348impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
349    type T = AddressSpace;
350
351    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
352        AddressSpace(self.0)
353    }
354}
355
356impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
357    type T = IntegerLength;
358
359    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
360        match self {
361            rustc_abi::Integer::I8 => IntegerLength::I8,
362            rustc_abi::Integer::I16 => IntegerLength::I16,
363            rustc_abi::Integer::I32 => IntegerLength::I32,
364            rustc_abi::Integer::I64 => IntegerLength::I64,
365            rustc_abi::Integer::I128 => IntegerLength::I128,
366        }
367    }
368}
369
370impl<'tcx> Stable<'tcx> for rustc_abi::Float {
371    type T = FloatLength;
372
373    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
374        match self {
375            rustc_abi::Float::F16 => FloatLength::F16,
376            rustc_abi::Float::F32 => FloatLength::F32,
377            rustc_abi::Float::F64 => FloatLength::F64,
378            rustc_abi::Float::F128 => FloatLength::F128,
379        }
380    }
381}
382
383impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
384    type T = WrappingRange;
385
386    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
387        WrappingRange { start: self.start, end: self.end }
388    }
389}
390
391impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags {
392    type T = ReprFlags;
393
394    fn stable<'cx>(
395        &self,
396        _tables: &mut Tables<'cx, BridgeTys>,
397        _cx: &CompilerCtxt<'cx, BridgeTys>,
398    ) -> Self::T {
399        ReprFlags {
400            is_simd: self.intersects(Self::IS_SIMD),
401            is_c: self.intersects(Self::IS_C),
402            is_transparent: self.intersects(Self::IS_TRANSPARENT),
403            is_linear: self.intersects(Self::IS_LINEAR),
404        }
405    }
406}
407
408impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType {
409    type T = IntegerType;
410
411    fn stable<'cx>(
412        &self,
413        tables: &mut Tables<'cx, BridgeTys>,
414        cx: &CompilerCtxt<'cx, BridgeTys>,
415    ) -> Self::T {
416        match self {
417            rustc_abi::IntegerType::Pointer(signed) => IntegerType::Pointer { is_signed: *signed },
418            rustc_abi::IntegerType::Fixed(integer, signed) => {
419                IntegerType::Fixed { length: integer.stable(tables, cx), is_signed: *signed }
420            }
421        }
422    }
423}
424
425impl<'tcx> Stable<'tcx> for rustc_abi::ReprOptions {
426    type T = ReprOptions;
427
428    fn stable<'cx>(
429        &self,
430        tables: &mut Tables<'cx, BridgeTys>,
431        cx: &CompilerCtxt<'cx, BridgeTys>,
432    ) -> Self::T {
433        ReprOptions {
434            int: self.int.map(|int| int.stable(tables, cx)),
435            align: self.align.map(|align| align.stable(tables, cx)),
436            pack: self.pack.map(|pack| pack.stable(tables, cx)),
437            flags: self.flags.stable(tables, cx),
438        }
439    }
440}