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