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, PassMode, Primitive, ReprFlags, ReprOptions, Scalar,
14    TagEncoding, TyAndLayout, ValueAbi, VariantsShape, WrappingRange,
15};
16use crate::compiler_interface::BridgeTys;
17use crate::target::MachineSize as Size;
18use crate::ty::{Align, VariantIdx};
19use crate::unstable::Stable;
20use crate::{IndexedVal, opaque};
21
22impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx {
23    type T = VariantIdx;
24    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
25        VariantIdx::to_val(self.as_usize())
26    }
27}
28
29impl<'tcx> Stable<'tcx> for rustc_abi::Endian {
30    type T = crate::target::Endian;
31
32    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
33        match self {
34            rustc_abi::Endian::Little => crate::target::Endian::Little,
35            rustc_abi::Endian::Big => crate::target::Endian::Big,
36        }
37    }
38}
39
40impl<'tcx> Stable<'tcx> for rustc_abi::TyAndLayout<'tcx, ty::Ty<'tcx>> {
41    type T = TyAndLayout;
42
43    fn stable<'cx>(
44        &self,
45        tables: &mut Tables<'cx, BridgeTys>,
46        cx: &CompilerCtxt<'cx, BridgeTys>,
47    ) -> Self::T {
48        TyAndLayout { ty: self.ty.stable(tables, cx), layout: self.layout.stable(tables, cx) }
49    }
50}
51
52impl<'tcx> Stable<'tcx> for rustc_abi::Layout<'tcx> {
53    type T = Layout;
54
55    fn stable<'cx>(
56        &self,
57        tables: &mut Tables<'cx, BridgeTys>,
58        cx: &CompilerCtxt<'cx, BridgeTys>,
59    ) -> Self::T {
60        tables.layout_id(cx.lift(*self).unwrap())
61    }
62}
63
64impl<'tcx> Stable<'tcx> for rustc_abi::LayoutData<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
65    type T = LayoutShape;
66
67    fn stable<'cx>(
68        &self,
69        tables: &mut Tables<'cx, BridgeTys>,
70        cx: &CompilerCtxt<'cx, BridgeTys>,
71    ) -> Self::T {
72        LayoutShape {
73            fields: self.fields.stable(tables, cx),
74            variants: self.variants.stable(tables, cx),
75            abi: self.backend_repr.stable(tables, cx),
76            abi_align: self.align.abi.stable(tables, cx),
77            size: self.size.stable(tables, cx),
78        }
79    }
80}
81
82impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> {
83    type T = FnAbi;
84
85    fn stable<'cx>(
86        &self,
87        tables: &mut Tables<'cx, BridgeTys>,
88        cx: &CompilerCtxt<'cx, BridgeTys>,
89    ) -> Self::T {
90        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);
91        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));
92        FnAbi {
93            args: self.args.as_ref().stable(tables, cx),
94            ret: self.ret.stable(tables, cx),
95            fixed_count: self.fixed_count,
96            conv: self.conv.stable(tables, cx),
97            c_variadic: self.c_variadic,
98        }
99    }
100}
101
102impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> {
103    type T = ArgAbi;
104
105    fn stable<'cx>(
106        &self,
107        tables: &mut Tables<'cx, BridgeTys>,
108        cx: &CompilerCtxt<'cx, BridgeTys>,
109    ) -> Self::T {
110        ArgAbi {
111            ty: self.layout.ty.stable(tables, cx),
112            layout: self.layout.layout.stable(tables, cx),
113            mode: self.mode.stable(tables, cx),
114        }
115    }
116}
117
118impl<'tcx> Stable<'tcx> for CanonAbi {
119    type T = CallConvention;
120
121    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
122        match self {
123            CanonAbi::C => CallConvention::C,
124            CanonAbi::Rust => CallConvention::Rust,
125            CanonAbi::RustCold => CallConvention::Cold,
126            CanonAbi::Custom => CallConvention::Custom,
127            CanonAbi::Arm(arm_call) => match arm_call {
128                ArmCall::Aapcs => CallConvention::ArmAapcs,
129                ArmCall::CCmseNonSecureCall => CallConvention::CCmseNonSecureCall,
130                ArmCall::CCmseNonSecureEntry => CallConvention::CCmseNonSecureEntry,
131            },
132            CanonAbi::GpuKernel => CallConvention::GpuKernel,
133            CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind {
134                InterruptKind::Avr => CallConvention::AvrInterrupt,
135                InterruptKind::AvrNonBlocking => CallConvention::AvrNonBlockingInterrupt,
136                InterruptKind::Msp430 => CallConvention::Msp430Intr,
137                InterruptKind::RiscvMachine | InterruptKind::RiscvSupervisor => {
138                    CallConvention::RiscvInterrupt
139                }
140                InterruptKind::X86 => CallConvention::X86Intr,
141            },
142            CanonAbi::X86(x86_call) => match x86_call {
143                X86Call::Fastcall => CallConvention::X86Fastcall,
144                X86Call::Stdcall => CallConvention::X86Stdcall,
145                X86Call::SysV64 => CallConvention::X86_64SysV,
146                X86Call::Thiscall => CallConvention::X86ThisCall,
147                X86Call::Vectorcall => CallConvention::X86VectorCall,
148                X86Call::Win64 => CallConvention::X86_64Win64,
149            },
150        }
151    }
152}
153
154impl<'tcx> Stable<'tcx> for callconv::PassMode {
155    type T = PassMode;
156
157    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
158        match self {
159            callconv::PassMode::Ignore => PassMode::Ignore,
160            callconv::PassMode::Direct(attr) => PassMode::Direct(opaque(attr)),
161            callconv::PassMode::Pair(first, second) => {
162                PassMode::Pair(opaque(first), opaque(second))
163            }
164            callconv::PassMode::Cast { pad_i32, cast } => {
165                PassMode::Cast { pad_i32: *pad_i32, cast: opaque(cast) }
166            }
167            callconv::PassMode::Indirect { attrs, meta_attrs, on_stack } => PassMode::Indirect {
168                attrs: opaque(attrs),
169                meta_attrs: opaque(meta_attrs),
170                on_stack: *on_stack,
171            },
172        }
173    }
174}
175
176impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape<rustc_abi::FieldIdx> {
177    type T = FieldsShape;
178
179    fn stable<'cx>(
180        &self,
181        tables: &mut Tables<'cx, BridgeTys>,
182        cx: &CompilerCtxt<'cx, BridgeTys>,
183    ) -> Self::T {
184        match self {
185            rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive,
186            rustc_abi::FieldsShape::Union(count) => FieldsShape::Union(*count),
187            rustc_abi::FieldsShape::Array { stride, count } => {
188                FieldsShape::Array { stride: stride.stable(tables, cx), count: *count }
189            }
190            rustc_abi::FieldsShape::Arbitrary { offsets, .. } => {
191                FieldsShape::Arbitrary { offsets: offsets.iter().as_slice().stable(tables, cx) }
192            }
193        }
194    }
195}
196
197impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
198    type T = VariantsShape;
199
200    fn stable<'cx>(
201        &self,
202        tables: &mut Tables<'cx, BridgeTys>,
203        cx: &CompilerCtxt<'cx, BridgeTys>,
204    ) -> Self::T {
205        match self {
206            rustc_abi::Variants::Single { index } => {
207                VariantsShape::Single { index: index.stable(tables, cx) }
208            }
209            rustc_abi::Variants::Empty => VariantsShape::Empty,
210            rustc_abi::Variants::Multiple { tag, tag_encoding, tag_field, variants } => {
211                VariantsShape::Multiple {
212                    tag: tag.stable(tables, cx),
213                    tag_encoding: tag_encoding.stable(tables, cx),
214                    tag_field: tag_field.stable(tables, cx),
215                    variants: variants.iter().as_slice().stable(tables, cx),
216                }
217            }
218        }
219    }
220}
221
222impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding<rustc_abi::VariantIdx> {
223    type T = TagEncoding;
224
225    fn stable<'cx>(
226        &self,
227        tables: &mut Tables<'cx, BridgeTys>,
228        cx: &CompilerCtxt<'cx, BridgeTys>,
229    ) -> Self::T {
230        match self {
231            rustc_abi::TagEncoding::Direct => TagEncoding::Direct,
232            rustc_abi::TagEncoding::Niche { untagged_variant, niche_variants, niche_start } => {
233                TagEncoding::Niche {
234                    untagged_variant: untagged_variant.stable(tables, cx),
235                    niche_variants: niche_variants.stable(tables, cx),
236                    niche_start: *niche_start,
237                }
238            }
239        }
240    }
241}
242
243impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
244    type T = ValueAbi;
245
246    fn stable<'cx>(
247        &self,
248        tables: &mut Tables<'cx, BridgeTys>,
249        cx: &CompilerCtxt<'cx, BridgeTys>,
250    ) -> Self::T {
251        match *self {
252            rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables, cx)),
253            rustc_abi::BackendRepr::ScalarPair(first, second) => {
254                ValueAbi::ScalarPair(first.stable(tables, cx), second.stable(tables, cx))
255            }
256            rustc_abi::BackendRepr::SimdVector { element, count } => {
257                ValueAbi::Vector { element: element.stable(tables, cx), count }
258            }
259            rustc_abi::BackendRepr::ScalableVector { element, count } => {
260                ValueAbi::ScalableVector { element: element.stable(tables, cx), count }
261            }
262            rustc_abi::BackendRepr::Memory { sized } => ValueAbi::Aggregate { sized },
263        }
264    }
265}
266
267impl<'tcx> Stable<'tcx> for rustc_abi::Size {
268    type T = Size;
269
270    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
271        Size::from_bits(self.bits_usize())
272    }
273}
274
275impl<'tcx> Stable<'tcx> for rustc_abi::Align {
276    type T = Align;
277
278    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
279        self.bytes()
280    }
281}
282
283impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
284    type T = Scalar;
285
286    fn stable<'cx>(
287        &self,
288        tables: &mut Tables<'cx, BridgeTys>,
289        cx: &CompilerCtxt<'cx, BridgeTys>,
290    ) -> Self::T {
291        match self {
292            rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized {
293                value: value.stable(tables, cx),
294                valid_range: valid_range.stable(tables, cx),
295            },
296            rustc_abi::Scalar::Union { value } => Scalar::Union { value: value.stable(tables, cx) },
297        }
298    }
299}
300
301impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
302    type T = Primitive;
303
304    fn stable<'cx>(
305        &self,
306        tables: &mut Tables<'cx, BridgeTys>,
307        cx: &CompilerCtxt<'cx, BridgeTys>,
308    ) -> Self::T {
309        match self {
310            rustc_abi::Primitive::Int(length, signed) => {
311                Primitive::Int { length: length.stable(tables, cx), signed: *signed }
312            }
313            rustc_abi::Primitive::Float(length) => {
314                Primitive::Float { length: length.stable(tables, cx) }
315            }
316            rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables, cx)),
317        }
318    }
319}
320
321impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
322    type T = AddressSpace;
323
324    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
325        AddressSpace(self.0)
326    }
327}
328
329impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
330    type T = IntegerLength;
331
332    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
333        match self {
334            rustc_abi::Integer::I8 => IntegerLength::I8,
335            rustc_abi::Integer::I16 => IntegerLength::I16,
336            rustc_abi::Integer::I32 => IntegerLength::I32,
337            rustc_abi::Integer::I64 => IntegerLength::I64,
338            rustc_abi::Integer::I128 => IntegerLength::I128,
339        }
340    }
341}
342
343impl<'tcx> Stable<'tcx> for rustc_abi::Float {
344    type T = FloatLength;
345
346    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
347        match self {
348            rustc_abi::Float::F16 => FloatLength::F16,
349            rustc_abi::Float::F32 => FloatLength::F32,
350            rustc_abi::Float::F64 => FloatLength::F64,
351            rustc_abi::Float::F128 => FloatLength::F128,
352        }
353    }
354}
355
356impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
357    type T = WrappingRange;
358
359    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
360        WrappingRange { start: self.start, end: self.end }
361    }
362}
363
364impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags {
365    type T = ReprFlags;
366
367    fn stable<'cx>(
368        &self,
369        _tables: &mut Tables<'cx, BridgeTys>,
370        _cx: &CompilerCtxt<'cx, BridgeTys>,
371    ) -> Self::T {
372        ReprFlags {
373            is_simd: self.intersects(Self::IS_SIMD),
374            is_c: self.intersects(Self::IS_C),
375            is_transparent: self.intersects(Self::IS_TRANSPARENT),
376            is_linear: self.intersects(Self::IS_LINEAR),
377        }
378    }
379}
380
381impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType {
382    type T = IntegerType;
383
384    fn stable<'cx>(
385        &self,
386        tables: &mut Tables<'cx, BridgeTys>,
387        cx: &CompilerCtxt<'cx, BridgeTys>,
388    ) -> Self::T {
389        match self {
390            rustc_abi::IntegerType::Pointer(signed) => IntegerType::Pointer { is_signed: *signed },
391            rustc_abi::IntegerType::Fixed(integer, signed) => {
392                IntegerType::Fixed { length: integer.stable(tables, cx), is_signed: *signed }
393            }
394        }
395    }
396}
397
398impl<'tcx> Stable<'tcx> for rustc_abi::ReprOptions {
399    type T = ReprOptions;
400
401    fn stable<'cx>(
402        &self,
403        tables: &mut Tables<'cx, BridgeTys>,
404        cx: &CompilerCtxt<'cx, BridgeTys>,
405    ) -> Self::T {
406        ReprOptions {
407            int: self.int.map(|int| int.stable(tables, cx)),
408            align: self.align.map(|align| align.stable(tables, cx)),
409            pack: self.pack.map(|pack| pack.stable(tables, cx)),
410            flags: self.flags.stable(tables, cx),
411        }
412    }
413}