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