rustc_smir/rustc_smir/convert/
mir.rs1use rustc_middle::mir::interpret::alloc_range;
4use rustc_middle::mir::mono::MonoItem;
5use rustc_middle::{bug, mir};
6use stable_mir::mir::alloc::GlobalAlloc;
7use stable_mir::mir::{ConstOperand, Statement, UserTypeProjection, VarDebugInfoFragment};
8use stable_mir::ty::{Allocation, ConstantKind, MirConst};
9use stable_mir::{Error, opaque};
10
11use crate::rustc_smir::{Stable, Tables, alloc};
12
13impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
14 type T = stable_mir::mir::Body;
15
16 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
17 stable_mir::mir::Body::new(
18 self.basic_blocks
19 .iter()
20 .map(|block| stable_mir::mir::BasicBlock {
21 terminator: block.terminator().stable(tables),
22 statements: block
23 .statements
24 .iter()
25 .map(|statement| statement.stable(tables))
26 .collect(),
27 })
28 .collect(),
29 self.local_decls
30 .iter()
31 .map(|decl| stable_mir::mir::LocalDecl {
32 ty: decl.ty.stable(tables),
33 span: decl.source_info.span.stable(tables),
34 mutability: decl.mutability.stable(tables),
35 })
36 .collect(),
37 self.arg_count,
38 self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
39 self.spread_arg.stable(tables),
40 self.span.stable(tables),
41 )
42 }
43}
44
45impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> {
46 type T = stable_mir::mir::VarDebugInfo;
47 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
48 stable_mir::mir::VarDebugInfo {
49 name: self.name.to_string(),
50 source_info: self.source_info.stable(tables),
51 composite: self.composite.as_ref().map(|composite| composite.stable(tables)),
52 value: self.value.stable(tables),
53 argument_index: self.argument_index,
54 }
55 }
56}
57
58impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
59 type T = stable_mir::mir::Statement;
60 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
61 Statement { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) }
62 }
63}
64
65impl<'tcx> Stable<'tcx> for mir::SourceInfo {
66 type T = stable_mir::mir::SourceInfo;
67 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
68 stable_mir::mir::SourceInfo { span: self.span.stable(tables), scope: self.scope.into() }
69 }
70}
71
72impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> {
73 type T = stable_mir::mir::VarDebugInfoFragment;
74 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
75 VarDebugInfoFragment {
76 ty: self.ty.stable(tables),
77 projection: self.projection.iter().map(|e| e.stable(tables)).collect(),
78 }
79 }
80}
81
82impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> {
83 type T = stable_mir::mir::VarDebugInfoContents;
84 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
85 match self {
86 mir::VarDebugInfoContents::Place(place) => {
87 stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables))
88 }
89 mir::VarDebugInfoContents::Const(const_operand) => {
90 let op = ConstOperand {
91 span: const_operand.span.stable(tables),
92 user_ty: const_operand.user_ty.map(|index| index.as_usize()),
93 const_: const_operand.const_.stable(tables),
94 };
95 stable_mir::mir::VarDebugInfoContents::Const(op)
96 }
97 }
98 }
99}
100
101impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> {
102 type T = stable_mir::mir::StatementKind;
103 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
104 match self {
105 mir::StatementKind::Assign(assign) => stable_mir::mir::StatementKind::Assign(
106 assign.0.stable(tables),
107 assign.1.stable(tables),
108 ),
109 mir::StatementKind::FakeRead(fake_read_place) => {
110 stable_mir::mir::StatementKind::FakeRead(
111 fake_read_place.0.stable(tables),
112 fake_read_place.1.stable(tables),
113 )
114 }
115 mir::StatementKind::SetDiscriminant { place, variant_index } => {
116 stable_mir::mir::StatementKind::SetDiscriminant {
117 place: place.as_ref().stable(tables),
118 variant_index: variant_index.stable(tables),
119 }
120 }
121 mir::StatementKind::Deinit(place) => {
122 stable_mir::mir::StatementKind::Deinit(place.stable(tables))
123 }
124
125 mir::StatementKind::StorageLive(place) => {
126 stable_mir::mir::StatementKind::StorageLive(place.stable(tables))
127 }
128
129 mir::StatementKind::StorageDead(place) => {
130 stable_mir::mir::StatementKind::StorageDead(place.stable(tables))
131 }
132 mir::StatementKind::Retag(retag, place) => {
133 stable_mir::mir::StatementKind::Retag(retag.stable(tables), place.stable(tables))
134 }
135 mir::StatementKind::PlaceMention(place) => {
136 stable_mir::mir::StatementKind::PlaceMention(place.stable(tables))
137 }
138 mir::StatementKind::AscribeUserType(place_projection, variance) => {
139 stable_mir::mir::StatementKind::AscribeUserType {
140 place: place_projection.as_ref().0.stable(tables),
141 projections: place_projection.as_ref().1.stable(tables),
142 variance: variance.stable(tables),
143 }
144 }
145 mir::StatementKind::Coverage(coverage) => {
146 stable_mir::mir::StatementKind::Coverage(opaque(coverage))
147 }
148 mir::StatementKind::Intrinsic(intrinstic) => {
149 stable_mir::mir::StatementKind::Intrinsic(intrinstic.stable(tables))
150 }
151 mir::StatementKind::ConstEvalCounter => {
152 stable_mir::mir::StatementKind::ConstEvalCounter
153 }
154 mir::StatementKind::BackwardIncompatibleDropHint { .. } => {
156 stable_mir::mir::StatementKind::Nop
157 }
158 mir::StatementKind::Nop => stable_mir::mir::StatementKind::Nop,
159 }
160 }
161}
162
163impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
164 type T = stable_mir::mir::Rvalue;
165 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
166 use rustc_middle::mir::Rvalue::*;
167 match self {
168 Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)),
169 Repeat(op, len) => {
170 let len = len.stable(tables);
171 stable_mir::mir::Rvalue::Repeat(op.stable(tables), len)
172 }
173 Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref(
174 region.stable(tables),
175 kind.stable(tables),
176 place.stable(tables),
177 ),
178 ThreadLocalRef(def_id) => {
179 stable_mir::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id))
180 }
181 RawPtr(mutability, place) => {
182 stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables))
183 }
184 Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)),
185 Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast(
186 cast_kind.stable(tables),
187 op.stable(tables),
188 ty.stable(tables),
189 ),
190 BinaryOp(bin_op, ops) => {
191 if let Some(bin_op) = bin_op.overflowing_to_wrapping() {
192 stable_mir::mir::Rvalue::CheckedBinaryOp(
193 bin_op.stable(tables),
194 ops.0.stable(tables),
195 ops.1.stable(tables),
196 )
197 } else {
198 stable_mir::mir::Rvalue::BinaryOp(
199 bin_op.stable(tables),
200 ops.0.stable(tables),
201 ops.1.stable(tables),
202 )
203 }
204 }
205 NullaryOp(null_op, ty) => {
206 stable_mir::mir::Rvalue::NullaryOp(null_op.stable(tables), ty.stable(tables))
207 }
208 UnaryOp(un_op, op) => {
209 stable_mir::mir::Rvalue::UnaryOp(un_op.stable(tables), op.stable(tables))
210 }
211 Discriminant(place) => stable_mir::mir::Rvalue::Discriminant(place.stable(tables)),
212 Aggregate(agg_kind, operands) => {
213 let operands = operands.iter().map(|op| op.stable(tables)).collect();
214 stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables), operands)
215 }
216 ShallowInitBox(op, ty) => {
217 stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), ty.stable(tables))
218 }
219 CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables)),
220 WrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"),
221 }
222 }
223}
224
225impl<'tcx> Stable<'tcx> for mir::Mutability {
226 type T = stable_mir::mir::Mutability;
227 fn stable(&self, _: &mut Tables<'_>) -> Self::T {
228 use rustc_hir::Mutability::*;
229 match *self {
230 Not => stable_mir::mir::Mutability::Not,
231 Mut => stable_mir::mir::Mutability::Mut,
232 }
233 }
234}
235
236impl<'tcx> Stable<'tcx> for mir::RawPtrKind {
237 type T = stable_mir::mir::RawPtrKind;
238 fn stable(&self, _: &mut Tables<'_>) -> Self::T {
239 use mir::RawPtrKind::*;
240 match *self {
241 Const => stable_mir::mir::RawPtrKind::Const,
242 Mut => stable_mir::mir::RawPtrKind::Mut,
243 FakeForPtrMetadata => stable_mir::mir::RawPtrKind::FakeForPtrMetadata,
244 }
245 }
246}
247
248impl<'tcx> Stable<'tcx> for mir::BorrowKind {
249 type T = stable_mir::mir::BorrowKind;
250 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
251 use rustc_middle::mir::BorrowKind::*;
252 match *self {
253 Shared => stable_mir::mir::BorrowKind::Shared,
254 Fake(kind) => stable_mir::mir::BorrowKind::Fake(kind.stable(tables)),
255 Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable(tables) },
256 }
257 }
258}
259
260impl<'tcx> Stable<'tcx> for mir::MutBorrowKind {
261 type T = stable_mir::mir::MutBorrowKind;
262 fn stable(&self, _: &mut Tables<'_>) -> Self::T {
263 use rustc_middle::mir::MutBorrowKind::*;
264 match *self {
265 Default => stable_mir::mir::MutBorrowKind::Default,
266 TwoPhaseBorrow => stable_mir::mir::MutBorrowKind::TwoPhaseBorrow,
267 ClosureCapture => stable_mir::mir::MutBorrowKind::ClosureCapture,
268 }
269 }
270}
271
272impl<'tcx> Stable<'tcx> for mir::FakeBorrowKind {
273 type T = stable_mir::mir::FakeBorrowKind;
274 fn stable(&self, _: &mut Tables<'_>) -> Self::T {
275 use rustc_middle::mir::FakeBorrowKind::*;
276 match *self {
277 Deep => stable_mir::mir::FakeBorrowKind::Deep,
278 Shallow => stable_mir::mir::FakeBorrowKind::Shallow,
279 }
280 }
281}
282
283impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> {
284 type T = stable_mir::mir::NullOp;
285 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
286 use rustc_middle::mir::NullOp::*;
287 match self {
288 SizeOf => stable_mir::mir::NullOp::SizeOf,
289 AlignOf => stable_mir::mir::NullOp::AlignOf,
290 OffsetOf(indices) => stable_mir::mir::NullOp::OffsetOf(
291 indices.iter().map(|idx| idx.stable(tables)).collect(),
292 ),
293 UbChecks => stable_mir::mir::NullOp::UbChecks,
294 ContractChecks => stable_mir::mir::NullOp::ContractChecks,
295 }
296 }
297}
298
299impl<'tcx> Stable<'tcx> for mir::CastKind {
300 type T = stable_mir::mir::CastKind;
301 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
302 use rustc_middle::mir::CastKind::*;
303 use rustc_middle::ty::adjustment::PointerCoercion;
304 match self {
305 PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress,
306 PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance,
307 PointerCoercion(PointerCoercion::DynStar, _) => stable_mir::mir::CastKind::DynStar,
308 PointerCoercion(c, _) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)),
309 IntToInt => stable_mir::mir::CastKind::IntToInt,
310 FloatToInt => stable_mir::mir::CastKind::FloatToInt,
311 FloatToFloat => stable_mir::mir::CastKind::FloatToFloat,
312 IntToFloat => stable_mir::mir::CastKind::IntToFloat,
313 PtrToPtr => stable_mir::mir::CastKind::PtrToPtr,
314 FnPtrToPtr => stable_mir::mir::CastKind::FnPtrToPtr,
315 Transmute => stable_mir::mir::CastKind::Transmute,
316 }
317 }
318}
319
320impl<'tcx> Stable<'tcx> for mir::FakeReadCause {
321 type T = stable_mir::mir::FakeReadCause;
322 fn stable(&self, _: &mut Tables<'_>) -> Self::T {
323 use rustc_middle::mir::FakeReadCause::*;
324 match self {
325 ForMatchGuard => stable_mir::mir::FakeReadCause::ForMatchGuard,
326 ForMatchedPlace(local_def_id) => {
327 stable_mir::mir::FakeReadCause::ForMatchedPlace(opaque(local_def_id))
328 }
329 ForGuardBinding => stable_mir::mir::FakeReadCause::ForGuardBinding,
330 ForLet(local_def_id) => stable_mir::mir::FakeReadCause::ForLet(opaque(local_def_id)),
331 ForIndex => stable_mir::mir::FakeReadCause::ForIndex,
332 }
333 }
334}
335
336impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> {
337 type T = stable_mir::mir::Operand;
338 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
339 use rustc_middle::mir::Operand::*;
340 match self {
341 Copy(place) => stable_mir::mir::Operand::Copy(place.stable(tables)),
342 Move(place) => stable_mir::mir::Operand::Move(place.stable(tables)),
343 Constant(c) => stable_mir::mir::Operand::Constant(c.stable(tables)),
344 }
345 }
346}
347
348impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> {
349 type T = stable_mir::mir::ConstOperand;
350
351 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
352 stable_mir::mir::ConstOperand {
353 span: self.span.stable(tables),
354 user_ty: self.user_ty.map(|u| u.as_usize()).or(None),
355 const_: self.const_.stable(tables),
356 }
357 }
358}
359
360impl<'tcx> Stable<'tcx> for mir::Place<'tcx> {
361 type T = stable_mir::mir::Place;
362 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
363 stable_mir::mir::Place {
364 local: self.local.as_usize(),
365 projection: self.projection.iter().map(|e| e.stable(tables)).collect(),
366 }
367 }
368}
369
370impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
371 type T = stable_mir::mir::ProjectionElem;
372 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
373 use rustc_middle::mir::ProjectionElem::*;
374 match self {
375 Deref => stable_mir::mir::ProjectionElem::Deref,
376 Field(idx, ty) => {
377 stable_mir::mir::ProjectionElem::Field(idx.stable(tables), ty.stable(tables))
378 }
379 Index(local) => stable_mir::mir::ProjectionElem::Index(local.stable(tables)),
380 ConstantIndex { offset, min_length, from_end } => {
381 stable_mir::mir::ProjectionElem::ConstantIndex {
382 offset: *offset,
383 min_length: *min_length,
384 from_end: *from_end,
385 }
386 }
387 Subslice { from, to, from_end } => stable_mir::mir::ProjectionElem::Subslice {
388 from: *from,
389 to: *to,
390 from_end: *from_end,
391 },
392 Downcast(_, idx) => stable_mir::mir::ProjectionElem::Downcast(idx.stable(tables)),
398 OpaqueCast(ty) => stable_mir::mir::ProjectionElem::OpaqueCast(ty.stable(tables)),
399 Subtype(ty) => stable_mir::mir::ProjectionElem::Subtype(ty.stable(tables)),
400 UnwrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"),
401 }
402 }
403}
404
405impl<'tcx> Stable<'tcx> for mir::UserTypeProjection {
406 type T = stable_mir::mir::UserTypeProjection;
407
408 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
409 UserTypeProjection { base: self.base.as_usize(), projection: opaque(&self.projs) }
410 }
411}
412
413impl<'tcx> Stable<'tcx> for mir::Local {
414 type T = stable_mir::mir::Local;
415 fn stable(&self, _: &mut Tables<'_>) -> Self::T {
416 self.as_usize()
417 }
418}
419
420impl<'tcx> Stable<'tcx> for mir::RetagKind {
421 type T = stable_mir::mir::RetagKind;
422 fn stable(&self, _: &mut Tables<'_>) -> Self::T {
423 use rustc_middle::mir::RetagKind;
424 match self {
425 RetagKind::FnEntry => stable_mir::mir::RetagKind::FnEntry,
426 RetagKind::TwoPhase => stable_mir::mir::RetagKind::TwoPhase,
427 RetagKind::Raw => stable_mir::mir::RetagKind::Raw,
428 RetagKind::Default => stable_mir::mir::RetagKind::Default,
429 }
430 }
431}
432
433impl<'tcx> Stable<'tcx> for mir::UnwindAction {
434 type T = stable_mir::mir::UnwindAction;
435 fn stable(&self, _: &mut Tables<'_>) -> Self::T {
436 use rustc_middle::mir::UnwindAction;
437 match self {
438 UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue,
439 UnwindAction::Unreachable => stable_mir::mir::UnwindAction::Unreachable,
440 UnwindAction::Terminate(_) => stable_mir::mir::UnwindAction::Terminate,
441 UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()),
442 }
443 }
444}
445
446impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> {
447 type T = stable_mir::mir::NonDivergingIntrinsic;
448
449 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
450 use rustc_middle::mir::NonDivergingIntrinsic;
451 use stable_mir::mir::CopyNonOverlapping;
452 match self {
453 NonDivergingIntrinsic::Assume(op) => {
454 stable_mir::mir::NonDivergingIntrinsic::Assume(op.stable(tables))
455 }
456 NonDivergingIntrinsic::CopyNonOverlapping(copy_non_overlapping) => {
457 stable_mir::mir::NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping {
458 src: copy_non_overlapping.src.stable(tables),
459 dst: copy_non_overlapping.dst.stable(tables),
460 count: copy_non_overlapping.count.stable(tables),
461 })
462 }
463 }
464 }
465}
466
467impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> {
468 type T = stable_mir::mir::AssertMessage;
469 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
470 use rustc_middle::mir::AssertKind;
471 match self {
472 AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck {
473 len: len.stable(tables),
474 index: index.stable(tables),
475 },
476 AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow(
477 bin_op.stable(tables),
478 op1.stable(tables),
479 op2.stable(tables),
480 ),
481 AssertKind::OverflowNeg(op) => {
482 stable_mir::mir::AssertMessage::OverflowNeg(op.stable(tables))
483 }
484 AssertKind::DivisionByZero(op) => {
485 stable_mir::mir::AssertMessage::DivisionByZero(op.stable(tables))
486 }
487 AssertKind::RemainderByZero(op) => {
488 stable_mir::mir::AssertMessage::RemainderByZero(op.stable(tables))
489 }
490 AssertKind::ResumedAfterReturn(coroutine) => {
491 stable_mir::mir::AssertMessage::ResumedAfterReturn(coroutine.stable(tables))
492 }
493 AssertKind::ResumedAfterPanic(coroutine) => {
494 stable_mir::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables))
495 }
496 AssertKind::MisalignedPointerDereference { required, found } => {
497 stable_mir::mir::AssertMessage::MisalignedPointerDereference {
498 required: required.stable(tables),
499 found: found.stable(tables),
500 }
501 }
502 AssertKind::NullPointerDereference => {
503 stable_mir::mir::AssertMessage::NullPointerDereference
504 }
505 }
506 }
507}
508
509impl<'tcx> Stable<'tcx> for mir::BinOp {
510 type T = stable_mir::mir::BinOp;
511 fn stable(&self, _: &mut Tables<'_>) -> Self::T {
512 use rustc_middle::mir::BinOp;
513 match self {
514 BinOp::Add => stable_mir::mir::BinOp::Add,
515 BinOp::AddUnchecked => stable_mir::mir::BinOp::AddUnchecked,
516 BinOp::AddWithOverflow => bug!("AddWithOverflow should have been translated already"),
517 BinOp::Sub => stable_mir::mir::BinOp::Sub,
518 BinOp::SubUnchecked => stable_mir::mir::BinOp::SubUnchecked,
519 BinOp::SubWithOverflow => bug!("AddWithOverflow should have been translated already"),
520 BinOp::Mul => stable_mir::mir::BinOp::Mul,
521 BinOp::MulUnchecked => stable_mir::mir::BinOp::MulUnchecked,
522 BinOp::MulWithOverflow => bug!("AddWithOverflow should have been translated already"),
523 BinOp::Div => stable_mir::mir::BinOp::Div,
524 BinOp::Rem => stable_mir::mir::BinOp::Rem,
525 BinOp::BitXor => stable_mir::mir::BinOp::BitXor,
526 BinOp::BitAnd => stable_mir::mir::BinOp::BitAnd,
527 BinOp::BitOr => stable_mir::mir::BinOp::BitOr,
528 BinOp::Shl => stable_mir::mir::BinOp::Shl,
529 BinOp::ShlUnchecked => stable_mir::mir::BinOp::ShlUnchecked,
530 BinOp::Shr => stable_mir::mir::BinOp::Shr,
531 BinOp::ShrUnchecked => stable_mir::mir::BinOp::ShrUnchecked,
532 BinOp::Eq => stable_mir::mir::BinOp::Eq,
533 BinOp::Lt => stable_mir::mir::BinOp::Lt,
534 BinOp::Le => stable_mir::mir::BinOp::Le,
535 BinOp::Ne => stable_mir::mir::BinOp::Ne,
536 BinOp::Ge => stable_mir::mir::BinOp::Ge,
537 BinOp::Gt => stable_mir::mir::BinOp::Gt,
538 BinOp::Cmp => stable_mir::mir::BinOp::Cmp,
539 BinOp::Offset => stable_mir::mir::BinOp::Offset,
540 }
541 }
542}
543
544impl<'tcx> Stable<'tcx> for mir::UnOp {
545 type T = stable_mir::mir::UnOp;
546 fn stable(&self, _: &mut Tables<'_>) -> Self::T {
547 use rustc_middle::mir::UnOp;
548 match self {
549 UnOp::Not => stable_mir::mir::UnOp::Not,
550 UnOp::Neg => stable_mir::mir::UnOp::Neg,
551 UnOp::PtrMetadata => stable_mir::mir::UnOp::PtrMetadata,
552 }
553 }
554}
555
556impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
557 type T = stable_mir::mir::AggregateKind;
558 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
559 match self {
560 mir::AggregateKind::Array(ty) => {
561 stable_mir::mir::AggregateKind::Array(ty.stable(tables))
562 }
563 mir::AggregateKind::Tuple => stable_mir::mir::AggregateKind::Tuple,
564 mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => {
565 stable_mir::mir::AggregateKind::Adt(
566 tables.adt_def(*def_id),
567 var_idx.stable(tables),
568 generic_arg.stable(tables),
569 user_ty_index.map(|idx| idx.index()),
570 field_idx.map(|idx| idx.index()),
571 )
572 }
573 mir::AggregateKind::Closure(def_id, generic_arg) => {
574 stable_mir::mir::AggregateKind::Closure(
575 tables.closure_def(*def_id),
576 generic_arg.stable(tables),
577 )
578 }
579 mir::AggregateKind::Coroutine(def_id, generic_arg) => {
580 stable_mir::mir::AggregateKind::Coroutine(
581 tables.coroutine_def(*def_id),
582 generic_arg.stable(tables),
583 tables.tcx.coroutine_movability(*def_id).stable(tables),
584 )
585 }
586 mir::AggregateKind::CoroutineClosure(def_id, generic_args) => {
587 stable_mir::mir::AggregateKind::CoroutineClosure(
588 tables.coroutine_closure_def(*def_id),
589 generic_args.stable(tables),
590 )
591 }
592 mir::AggregateKind::RawPtr(ty, mutability) => {
593 stable_mir::mir::AggregateKind::RawPtr(ty.stable(tables), mutability.stable(tables))
594 }
595 }
596 }
597}
598
599impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> {
600 type T = stable_mir::mir::InlineAsmOperand;
601 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
602 use rustc_middle::mir::InlineAsmOperand;
603
604 let (in_value, out_place) = match self {
605 InlineAsmOperand::In { value, .. } => (Some(value.stable(tables)), None),
606 InlineAsmOperand::Out { place, .. } => (None, place.map(|place| place.stable(tables))),
607 InlineAsmOperand::InOut { in_value, out_place, .. } => {
608 (Some(in_value.stable(tables)), out_place.map(|place| place.stable(tables)))
609 }
610 InlineAsmOperand::Const { .. }
611 | InlineAsmOperand::SymFn { .. }
612 | InlineAsmOperand::SymStatic { .. }
613 | InlineAsmOperand::Label { .. } => (None, None),
614 };
615
616 stable_mir::mir::InlineAsmOperand { in_value, out_place, raw_rpr: format!("{self:?}") }
617 }
618}
619
620impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> {
621 type T = stable_mir::mir::Terminator;
622 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
623 use stable_mir::mir::Terminator;
624 Terminator { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) }
625 }
626}
627
628impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
629 type T = stable_mir::mir::TerminatorKind;
630 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
631 use stable_mir::mir::TerminatorKind;
632 match self {
633 mir::TerminatorKind::Goto { target } => {
634 TerminatorKind::Goto { target: target.as_usize() }
635 }
636 mir::TerminatorKind::SwitchInt { discr, targets } => TerminatorKind::SwitchInt {
637 discr: discr.stable(tables),
638 targets: {
639 let branches = targets.iter().map(|(val, target)| (val, target.as_usize()));
640 stable_mir::mir::SwitchTargets::new(
641 branches.collect(),
642 targets.otherwise().as_usize(),
643 )
644 },
645 },
646 mir::TerminatorKind::UnwindResume => TerminatorKind::Resume,
647 mir::TerminatorKind::UnwindTerminate(_) => TerminatorKind::Abort,
648 mir::TerminatorKind::Return => TerminatorKind::Return,
649 mir::TerminatorKind::Unreachable => TerminatorKind::Unreachable,
650 mir::TerminatorKind::Drop { place, target, unwind, replace: _ } => {
651 TerminatorKind::Drop {
652 place: place.stable(tables),
653 target: target.as_usize(),
654 unwind: unwind.stable(tables),
655 }
656 }
657 mir::TerminatorKind::Call {
658 func,
659 args,
660 destination,
661 target,
662 unwind,
663 call_source: _,
664 fn_span: _,
665 } => TerminatorKind::Call {
666 func: func.stable(tables),
667 args: args.iter().map(|arg| arg.node.stable(tables)).collect(),
668 destination: destination.stable(tables),
669 target: target.map(|t| t.as_usize()),
670 unwind: unwind.stable(tables),
671 },
672 mir::TerminatorKind::TailCall { func: _, args: _, fn_span: _ } => todo!(),
673 mir::TerminatorKind::Assert { cond, expected, msg, target, unwind } => {
674 TerminatorKind::Assert {
675 cond: cond.stable(tables),
676 expected: *expected,
677 msg: msg.stable(tables),
678 target: target.as_usize(),
679 unwind: unwind.stable(tables),
680 }
681 }
682 mir::TerminatorKind::InlineAsm {
683 asm_macro: _,
684 template,
685 operands,
686 options,
687 line_spans,
688 targets,
689 unwind,
690 } => TerminatorKind::InlineAsm {
691 template: format!("{template:?}"),
692 operands: operands.iter().map(|operand| operand.stable(tables)).collect(),
693 options: format!("{options:?}"),
694 line_spans: format!("{line_spans:?}"),
695 destination: targets.first().map(|d| d.as_usize()),
697 unwind: unwind.stable(tables),
698 },
699 mir::TerminatorKind::Yield { .. }
700 | mir::TerminatorKind::CoroutineDrop
701 | mir::TerminatorKind::FalseEdge { .. }
702 | mir::TerminatorKind::FalseUnwind { .. } => unreachable!(),
703 }
704 }
705}
706
707impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> {
708 type T = Allocation;
709
710 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
711 self.inner().stable(tables)
712 }
713}
714
715impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
716 type T = stable_mir::ty::Allocation;
717
718 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
719 alloc::allocation_filter(self, alloc_range(rustc_abi::Size::ZERO, self.size()), tables)
720 }
721}
722
723impl<'tcx> Stable<'tcx> for mir::interpret::AllocId {
724 type T = stable_mir::mir::alloc::AllocId;
725 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
726 tables.create_alloc_id(*self)
727 }
728}
729
730impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> {
731 type T = GlobalAlloc;
732
733 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
734 match self {
735 mir::interpret::GlobalAlloc::Function { instance, .. } => {
736 GlobalAlloc::Function(instance.stable(tables))
737 }
738 mir::interpret::GlobalAlloc::VTable(ty, dyn_ty) => {
739 GlobalAlloc::VTable(ty.stable(tables), dyn_ty.principal().stable(tables))
741 }
742 mir::interpret::GlobalAlloc::Static(def) => {
743 GlobalAlloc::Static(tables.static_def(*def))
744 }
745 mir::interpret::GlobalAlloc::Memory(alloc) => GlobalAlloc::Memory(alloc.stable(tables)),
746 }
747 }
748}
749
750impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
751 type T = stable_mir::ty::MirConst;
752
753 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
754 let id = tables.intern_mir_const(tables.tcx.lift(*self).unwrap());
755 match *self {
756 mir::Const::Ty(ty, c) => MirConst::new(
757 stable_mir::ty::ConstantKind::Ty(c.stable(tables)),
758 ty.stable(tables),
759 id,
760 ),
761 mir::Const::Unevaluated(unev_const, ty) => {
762 let kind =
763 stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
764 def: tables.const_def(unev_const.def),
765 args: unev_const.args.stable(tables),
766 promoted: unev_const.promoted.map(|u| u.as_u32()),
767 });
768 let ty = ty.stable(tables);
769 MirConst::new(kind, ty, id)
770 }
771 mir::Const::Val(mir::ConstValue::ZeroSized, ty) => {
772 let ty = ty.stable(tables);
773 MirConst::new(ConstantKind::ZeroSized, ty, id)
774 }
775 mir::Const::Val(val, ty) => {
776 let ty = tables.tcx.lift(ty).unwrap();
777 let val = tables.tcx.lift(val).unwrap();
778 let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables));
779 let ty = ty.stable(tables);
780 MirConst::new(kind, ty, id)
781 }
782 }
783 }
784}
785
786impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled {
787 type T = Error;
788
789 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
790 Error::new(format!("{self:?}"))
791 }
792}
793
794impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
795 type T = stable_mir::mir::mono::MonoItem;
796
797 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
798 use stable_mir::mir::mono::MonoItem as StableMonoItem;
799 match self {
800 MonoItem::Fn(instance) => StableMonoItem::Fn(instance.stable(tables)),
801 MonoItem::Static(def_id) => StableMonoItem::Static(tables.static_def(*def_id)),
802 MonoItem::GlobalAsm(item_id) => StableMonoItem::GlobalAsm(opaque(item_id)),
803 }
804 }
805}