From 7a4fb11c6d242894cbde99fc3adff98f3049e4ed Mon Sep 17 00:00:00 2001 From: Artem Agvanian Date: Mon, 15 Jul 2024 14:11:47 -0700 Subject: [PATCH 1/2] Implement `RustcInternal` for `StableBody` --- Cargo.lock | 1 + compiler/rustc_smir/Cargo.toml | 1 + .../rustc_smir/src/rustc_internal/internal.rs | 676 +++++++++++++++++- compiler/stable_mir/src/mir/body.rs | 4 + 4 files changed, 681 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 2d3bc59dddb21..61bc0c0ba0c6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4741,6 +4741,7 @@ dependencies = [ "rustc_ast_pretty", "rustc_data_structures", "rustc_hir", + "rustc_index", "rustc_middle", "rustc_session", "rustc_span", diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index 1230667ee910a..92934d6e9bcf0 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -10,6 +10,7 @@ rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_hir = { path = "../rustc_hir" } +rustc_index = { path = "../rustc_index" } rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index 854295dc04818..2580d57aece1c 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -11,7 +11,13 @@ use rustc_span::Symbol; use stable_mir::abi::Layout; use stable_mir::mir::alloc::AllocId; use stable_mir::mir::mono::{Instance, MonoItem, StaticDef}; -use stable_mir::mir::{BinOp, Mutability, Place, ProjectionElem, Safety, UnOp}; +use stable_mir::mir::{ + AggregateKind, AssertMessage, BinOp, Body, BorrowKind, CastKind, ConstOperand, + CopyNonOverlapping, CoroutineDesugaring, CoroutineKind, CoroutineSource, FakeBorrowKind, + FakeReadCause, LocalDecl, MutBorrowKind, Mutability, NonDivergingIntrinsic, NullOp, Operand, + Place, PointerCoercion, ProjectionElem, RetagKind, Rvalue, Safety, Statement, StatementKind, + SwitchTargets, Terminator, TerminatorKind, UnOp, UnwindAction, UserTypeProjection, Variance, +}; use stable_mir::ty::{ Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, DynKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig, @@ -592,6 +598,674 @@ impl RustcInternal for UnOp { } } +impl RustcInternal for AggregateKind { + type T<'tcx> = rustc_middle::mir::AggregateKind<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + AggregateKind::Array(ty) => { + rustc_middle::mir::AggregateKind::Array(ty.internal(tables, tcx).into()) + } + AggregateKind::Tuple => rustc_middle::mir::AggregateKind::Tuple, + AggregateKind::Adt( + adt_def, + variant_idx, + generic_args, + maybe_user_type_annotation_index, + maybe_field_idx, + ) => rustc_middle::mir::AggregateKind::Adt( + adt_def.0.internal(tables, tcx).into(), + variant_idx.internal(tables, tcx).into(), + generic_args.internal(tables, tcx).into(), + maybe_user_type_annotation_index + .map(|idx| rustc_middle::ty::UserTypeAnnotationIndex::from_usize(idx)), + maybe_field_idx.map(|idx| rustc_target::abi::FieldIdx::from_usize(idx)), + ), + AggregateKind::Closure(closure_def, generic_args) => { + rustc_middle::mir::AggregateKind::Closure( + closure_def.0.internal(tables, tcx).into(), + generic_args.internal(tables, tcx).into(), + ) + } + AggregateKind::Coroutine(coroutine_def, generic_args, _) => { + rustc_middle::mir::AggregateKind::Coroutine( + coroutine_def.0.internal(tables, tcx).into(), + generic_args.internal(tables, tcx).into(), + ) + } + AggregateKind::RawPtr(ty, mutability) => rustc_middle::mir::AggregateKind::RawPtr( + ty.internal(tables, tcx).into(), + mutability.internal(tables, tcx).into(), + ), + } + } +} + +impl RustcInternal for ConstOperand { + type T<'tcx> = rustc_middle::mir::ConstOperand<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + rustc_middle::mir::ConstOperand { + span: self.span.internal(tables, tcx).into(), + user_ty: self.user_ty.map(|idx| rustc_ty::UserTypeAnnotationIndex::from_usize(idx)), + const_: self.const_.internal(tables, tcx).into(), + } + } +} + +impl RustcInternal for Operand { + type T<'tcx> = rustc_middle::mir::Operand<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + Operand::Copy(place) => { + rustc_middle::mir::Operand::Copy(place.internal(tables, tcx).into()) + } + Operand::Move(place) => { + rustc_middle::mir::Operand::Move(place.internal(tables, tcx).into()) + } + Operand::Constant(const_operand) => rustc_middle::mir::Operand::Constant(Box::new( + const_operand.internal(tables, tcx).into(), + )), + } + } +} + +impl RustcInternal for PointerCoercion { + type T<'tcx> = rustc_middle::ty::adjustment::PointerCoercion; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + PointerCoercion::ReifyFnPointer => { + rustc_middle::ty::adjustment::PointerCoercion::ReifyFnPointer + } + PointerCoercion::UnsafeFnPointer => { + rustc_middle::ty::adjustment::PointerCoercion::UnsafeFnPointer + } + PointerCoercion::ClosureFnPointer(safety) => { + rustc_middle::ty::adjustment::PointerCoercion::ClosureFnPointer( + safety.internal(tables, tcx).into(), + ) + } + PointerCoercion::MutToConstPointer => { + rustc_middle::ty::adjustment::PointerCoercion::MutToConstPointer + } + PointerCoercion::ArrayToPointer => { + rustc_middle::ty::adjustment::PointerCoercion::ArrayToPointer + } + PointerCoercion::Unsize => rustc_middle::ty::adjustment::PointerCoercion::Unsize, + } + } +} + +impl RustcInternal for CastKind { + type T<'tcx> = rustc_middle::mir::CastKind; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + CastKind::PointerExposeAddress => rustc_middle::mir::CastKind::PointerExposeProvenance, + CastKind::PointerWithExposedProvenance => { + rustc_middle::mir::CastKind::PointerWithExposedProvenance + } + CastKind::PointerCoercion(ptr_coercion) => { + rustc_middle::mir::CastKind::PointerCoercion( + ptr_coercion.internal(tables, tcx).into(), + ) + } + CastKind::DynStar => rustc_middle::mir::CastKind::DynStar, + CastKind::IntToInt => rustc_middle::mir::CastKind::IntToInt, + CastKind::FloatToInt => rustc_middle::mir::CastKind::FloatToInt, + CastKind::FloatToFloat => rustc_middle::mir::CastKind::FloatToFloat, + CastKind::IntToFloat => rustc_middle::mir::CastKind::IntToFloat, + CastKind::PtrToPtr => rustc_middle::mir::CastKind::PtrToPtr, + CastKind::FnPtrToPtr => rustc_middle::mir::CastKind::FnPtrToPtr, + CastKind::Transmute => rustc_middle::mir::CastKind::Transmute, + } + } +} + +impl RustcInternal for FakeBorrowKind { + type T<'tcx> = rustc_middle::mir::FakeBorrowKind; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + FakeBorrowKind::Deep => rustc_middle::mir::FakeBorrowKind::Deep, + FakeBorrowKind::Shallow => rustc_middle::mir::FakeBorrowKind::Shallow, + } + } +} + +impl RustcInternal for MutBorrowKind { + type T<'tcx> = rustc_middle::mir::MutBorrowKind; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + MutBorrowKind::Default => rustc_middle::mir::MutBorrowKind::Default, + MutBorrowKind::TwoPhaseBorrow => rustc_middle::mir::MutBorrowKind::TwoPhaseBorrow, + MutBorrowKind::ClosureCapture => rustc_middle::mir::MutBorrowKind::ClosureCapture, + } + } +} + +impl RustcInternal for BorrowKind { + type T<'tcx> = rustc_middle::mir::BorrowKind; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + BorrowKind::Shared => rustc_middle::mir::BorrowKind::Shared, + BorrowKind::Fake(fake_borrow_kind) => { + rustc_middle::mir::BorrowKind::Fake(fake_borrow_kind.internal(tables, tcx).into()) + } + BorrowKind::Mut { kind } => { + rustc_middle::mir::BorrowKind::Mut { kind: kind.internal(tables, tcx).into() } + } + } + } +} + +impl RustcInternal for NullOp { + type T<'tcx> = rustc_middle::mir::NullOp<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + NullOp::SizeOf => rustc_middle::mir::NullOp::SizeOf, + NullOp::AlignOf => rustc_middle::mir::NullOp::AlignOf, + NullOp::OffsetOf(offsets) => rustc_middle::mir::NullOp::OffsetOf( + tcx.mk_offset_of( + offsets + .iter() + .map(|(variant_idx, field_idx)| { + ( + variant_idx.internal(tables, tcx), + rustc_target::abi::FieldIdx::from_usize(*field_idx), + ) + }) + .collect::>() + .as_slice(), + ), + ), + NullOp::UbChecks => rustc_middle::mir::NullOp::UbChecks, + } + } +} + +impl RustcInternal for Rvalue { + type T<'tcx> = rustc_middle::mir::Rvalue<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + Rvalue::AddressOf(mutability, place) => rustc_middle::mir::Rvalue::AddressOf( + mutability.internal(tables, tcx).into(), + place.internal(tables, tcx).into(), + ), + Rvalue::Aggregate(aggregate_kind, operands) => rustc_middle::mir::Rvalue::Aggregate( + Box::new(aggregate_kind.internal(tables, tcx).into()), + rustc_index::IndexVec::from_raw( + operands.iter().map(|operand| operand.internal(tables, tcx).into()).collect(), + ), + ), + Rvalue::BinaryOp(bin_op, left_operand, right_operand) + | Rvalue::CheckedBinaryOp(bin_op, left_operand, right_operand) => { + rustc_middle::mir::Rvalue::BinaryOp( + bin_op.internal(tables, tcx).into(), + Box::new(( + left_operand.internal(tables, tcx).into(), + right_operand.internal(tables, tcx).into(), + )), + ) + } + Rvalue::Cast(cast_kind, operand, ty) => rustc_middle::mir::Rvalue::Cast( + cast_kind.internal(tables, tcx).into(), + operand.internal(tables, tcx).into(), + ty.internal(tables, tcx).into(), + ), + Rvalue::CopyForDeref(place) => { + rustc_middle::mir::Rvalue::CopyForDeref(place.internal(tables, tcx).into()) + } + Rvalue::Discriminant(place) => { + rustc_middle::mir::Rvalue::Discriminant(place.internal(tables, tcx).into()) + } + Rvalue::Len(place) => { + rustc_middle::mir::Rvalue::Len(place.internal(tables, tcx).into()) + } + Rvalue::Ref(region, borrow_kind, place) => rustc_middle::mir::Rvalue::Ref( + region.internal(tables, tcx).into(), + borrow_kind.internal(tables, tcx).into(), + place.internal(tables, tcx).into(), + ), + Rvalue::Repeat(operand, ty_const) => rustc_middle::mir::Rvalue::Repeat( + operand.internal(tables, tcx).into(), + ty_const.internal(tables, tcx).into(), + ), + Rvalue::ShallowInitBox(operand, ty) => rustc_middle::mir::Rvalue::ShallowInitBox( + operand.internal(tables, tcx).into(), + ty.internal(tables, tcx).into(), + ), + Rvalue::ThreadLocalRef(crate_item) => { + rustc_middle::mir::Rvalue::ThreadLocalRef(crate_item.0.internal(tables, tcx).into()) + } + Rvalue::NullaryOp(null_op, ty) => rustc_middle::mir::Rvalue::NullaryOp( + null_op.internal(tables, tcx).into(), + ty.internal(tables, tcx).into(), + ), + Rvalue::UnaryOp(un_op, operand) => rustc_middle::mir::Rvalue::UnaryOp( + un_op.internal(tables, tcx).into(), + operand.internal(tables, tcx).into(), + ), + Rvalue::Use(operand) => { + rustc_middle::mir::Rvalue::Use(operand.internal(tables, tcx).into()) + } + } + } +} + +impl RustcInternal for FakeReadCause { + type T<'tcx> = rustc_middle::mir::FakeReadCause; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + FakeReadCause::ForMatchGuard => rustc_middle::mir::FakeReadCause::ForMatchGuard, + FakeReadCause::ForMatchedPlace(_opaque) => { + unimplemented!("cannot convert back from an opaque field") + } + FakeReadCause::ForGuardBinding => rustc_middle::mir::FakeReadCause::ForGuardBinding, + FakeReadCause::ForLet(_opaque) => { + unimplemented!("cannot convert back from an opaque field") + } + FakeReadCause::ForIndex => rustc_middle::mir::FakeReadCause::ForIndex, + } + } +} + +impl RustcInternal for RetagKind { + type T<'tcx> = rustc_middle::mir::RetagKind; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + RetagKind::FnEntry => rustc_middle::mir::RetagKind::FnEntry, + RetagKind::TwoPhase => rustc_middle::mir::RetagKind::TwoPhase, + RetagKind::Raw => rustc_middle::mir::RetagKind::Raw, + RetagKind::Default => rustc_middle::mir::RetagKind::Default, + } + } +} + +impl RustcInternal for UserTypeProjection { + type T<'tcx> = rustc_middle::mir::UserTypeProjection; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + unimplemented!("cannot convert back from an opaque field") + } +} + +impl RustcInternal for Variance { + type T<'tcx> = rustc_middle::ty::Variance; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + Variance::Covariant => rustc_middle::ty::Variance::Covariant, + Variance::Invariant => rustc_middle::ty::Variance::Invariant, + Variance::Contravariant => rustc_middle::ty::Variance::Contravariant, + Variance::Bivariant => rustc_middle::ty::Variance::Bivariant, + } + } +} + +impl RustcInternal for CopyNonOverlapping { + type T<'tcx> = rustc_middle::mir::CopyNonOverlapping<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + rustc_middle::mir::CopyNonOverlapping { + src: self.src.internal(tables, tcx).into(), + dst: self.dst.internal(tables, tcx).into(), + count: self.count.internal(tables, tcx).into(), + } + } +} + +impl RustcInternal for NonDivergingIntrinsic { + type T<'tcx> = rustc_middle::mir::NonDivergingIntrinsic<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + NonDivergingIntrinsic::Assume(operand) => { + rustc_middle::mir::NonDivergingIntrinsic::Assume( + operand.internal(tables, tcx).into(), + ) + } + NonDivergingIntrinsic::CopyNonOverlapping(copy_non_overlapping) => { + rustc_middle::mir::NonDivergingIntrinsic::CopyNonOverlapping( + copy_non_overlapping.internal(tables, tcx).into(), + ) + } + } + } +} + +impl RustcInternal for StatementKind { + type T<'tcx> = rustc_middle::mir::StatementKind<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + StatementKind::Assign(place, rvalue) => rustc_middle::mir::StatementKind::Assign( + Box::new((place.internal(tables, tcx).into(), rvalue.internal(tables, tcx).into())), + ), + StatementKind::FakeRead(fake_read_cause, place) => { + rustc_middle::mir::StatementKind::FakeRead(Box::new(( + fake_read_cause.internal(tables, tcx).into(), + place.internal(tables, tcx).into(), + ))) + } + StatementKind::SetDiscriminant { place, variant_index } => { + rustc_middle::mir::StatementKind::SetDiscriminant { + place: place.internal(tables, tcx).into(), + variant_index: variant_index.internal(tables, tcx).into(), + } + } + StatementKind::Deinit(place) => { + rustc_middle::mir::StatementKind::Deinit(place.internal(tables, tcx).into()) + } + StatementKind::StorageLive(local) => rustc_middle::mir::StatementKind::StorageLive( + rustc_middle::mir::Local::from_usize(*local), + ), + StatementKind::StorageDead(local) => rustc_middle::mir::StatementKind::StorageDead( + rustc_middle::mir::Local::from_usize(*local), + ), + StatementKind::Retag(retag_kind, place) => rustc_middle::mir::StatementKind::Retag( + retag_kind.internal(tables, tcx).into(), + place.internal(tables, tcx).into(), + ), + StatementKind::PlaceMention(place) => rustc_middle::mir::StatementKind::PlaceMention( + Box::new(place.internal(tables, tcx).into()), + ), + StatementKind::AscribeUserType { place, projections, variance } => { + rustc_middle::mir::StatementKind::AscribeUserType( + Box::new(( + place.internal(tables, tcx).into(), + projections.internal(tables, tcx).into(), + )), + variance.internal(tables, tcx).into(), + ) + } + StatementKind::Coverage(_coverage_kind) => { + unimplemented!("cannot convert back from an opaque field") + } + StatementKind::Intrinsic(non_diverging_intrinsic) => { + rustc_middle::mir::StatementKind::Intrinsic( + non_diverging_intrinsic.internal(tables, tcx).into(), + ) + } + StatementKind::ConstEvalCounter => rustc_middle::mir::StatementKind::ConstEvalCounter, + StatementKind::Nop => rustc_middle::mir::StatementKind::Nop, + } + } +} + +impl RustcInternal for Statement { + type T<'tcx> = rustc_middle::mir::Statement<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + rustc_middle::mir::Statement { + source_info: rustc_middle::mir::SourceInfo::outermost( + // TODO: is this a good default value? + self.span.internal(tables, tcx).into(), + ), + kind: self.kind.internal(tables, tcx).into(), + } + } +} + +impl RustcInternal for UnwindAction { + type T<'tcx> = rustc_middle::mir::UnwindAction; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + UnwindAction::Continue => rustc_middle::mir::UnwindAction::Continue, + UnwindAction::Unreachable => rustc_middle::mir::UnwindAction::Unreachable, + UnwindAction::Terminate => rustc_middle::mir::UnwindAction::Terminate( + rustc_middle::mir::UnwindTerminateReason::Abi, // TODO: is this a good default value? + ), + UnwindAction::Cleanup(basic_block_idx) => rustc_middle::mir::UnwindAction::Cleanup( + rustc_middle::mir::BasicBlock::from_usize(*basic_block_idx), + ), + } + } +} + +impl RustcInternal for SwitchTargets { + type T<'tcx> = rustc_middle::mir::SwitchTargets; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + rustc_middle::mir::SwitchTargets::new( + self.branches().map(|(value, basic_block_idx)| { + (value, rustc_middle::mir::BasicBlock::from_usize(basic_block_idx)) + }), + rustc_middle::mir::BasicBlock::from_usize(self.otherwise()), + ) + } +} + +impl RustcInternal for CoroutineDesugaring { + type T<'tcx> = rustc_hir::CoroutineDesugaring; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + CoroutineDesugaring::Async => rustc_hir::CoroutineDesugaring::Async, + CoroutineDesugaring::Gen => rustc_hir::CoroutineDesugaring::Gen, + CoroutineDesugaring::AsyncGen => rustc_hir::CoroutineDesugaring::AsyncGen, + } + } +} + +impl RustcInternal for CoroutineSource { + type T<'tcx> = rustc_hir::CoroutineSource; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + CoroutineSource::Block => rustc_hir::CoroutineSource::Block, + CoroutineSource::Closure => rustc_hir::CoroutineSource::Closure, + CoroutineSource::Fn => rustc_hir::CoroutineSource::Fn, + } + } +} + +impl RustcInternal for CoroutineKind { + type T<'tcx> = rustc_hir::CoroutineKind; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + CoroutineKind::Desugared(coroutine_desugaring, coroutine_source) => { + rustc_hir::CoroutineKind::Desugared( + coroutine_desugaring.internal(tables, tcx).into(), + coroutine_source.internal(tables, tcx).into(), + ) + } + CoroutineKind::Coroutine(movability) => { + rustc_hir::CoroutineKind::Coroutine(movability.internal(tables, tcx).into()) + } + } + } +} + +impl RustcInternal for AssertMessage { + type T<'tcx> = rustc_middle::mir::AssertMessage<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + AssertMessage::BoundsCheck { len, index } => { + rustc_middle::mir::AssertMessage::BoundsCheck { + len: len.internal(tables, tcx).into(), + index: index.internal(tables, tcx).into(), + } + } + AssertMessage::Overflow(bin_op, left_operand, right_operand) => { + rustc_middle::mir::AssertMessage::Overflow( + bin_op.internal(tables, tcx).into(), + left_operand.internal(tables, tcx).into(), + right_operand.internal(tables, tcx).into(), + ) + } + AssertMessage::OverflowNeg(operand) => { + rustc_middle::mir::AssertMessage::OverflowNeg(operand.internal(tables, tcx).into()) + } + AssertMessage::DivisionByZero(operand) => { + rustc_middle::mir::AssertMessage::DivisionByZero( + operand.internal(tables, tcx).into(), + ) + } + AssertMessage::RemainderByZero(operand) => { + rustc_middle::mir::AssertMessage::RemainderByZero( + operand.internal(tables, tcx).into(), + ) + } + AssertMessage::ResumedAfterReturn(coroutine_kind) => { + rustc_middle::mir::AssertMessage::ResumedAfterReturn( + coroutine_kind.internal(tables, tcx).into(), + ) + } + AssertMessage::ResumedAfterPanic(coroutine_kind) => { + rustc_middle::mir::AssertMessage::ResumedAfterPanic( + coroutine_kind.internal(tables, tcx).into(), + ) + } + AssertMessage::MisalignedPointerDereference { required, found } => { + rustc_middle::mir::AssertMessage::MisalignedPointerDereference { + required: required.internal(tables, tcx).into(), + found: found.internal(tables, tcx).into(), + } + } + } + } +} + +impl RustcInternal for TerminatorKind { + type T<'tcx> = rustc_middle::mir::TerminatorKind<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + TerminatorKind::Goto { target } => rustc_middle::mir::TerminatorKind::Goto { + target: rustc_middle::mir::BasicBlock::from_usize(*target), + }, + TerminatorKind::SwitchInt { discr, targets } => { + rustc_middle::mir::TerminatorKind::SwitchInt { + discr: discr.internal(tables, tcx).into(), + targets: targets.internal(tables, tcx).into(), + } + } + TerminatorKind::Resume => rustc_middle::mir::TerminatorKind::UnwindResume, + TerminatorKind::Abort => rustc_middle::mir::TerminatorKind::UnwindTerminate( + rustc_middle::mir::UnwindTerminateReason::Abi, + ), + TerminatorKind::Return => rustc_middle::mir::TerminatorKind::Return, + TerminatorKind::Unreachable => rustc_middle::mir::TerminatorKind::Unreachable, + TerminatorKind::Drop { place, target, unwind } => { + rustc_middle::mir::TerminatorKind::Drop { + place: place.internal(tables, tcx).into(), + target: rustc_middle::mir::BasicBlock::from_usize(*target), + unwind: unwind.internal(tables, tcx).into(), + replace: false, // TODO: is this a good default value? + } + } + TerminatorKind::Call { func, args, destination, target, unwind } => { + rustc_middle::mir::TerminatorKind::Call { + func: func.internal(tables, tcx).into(), + args: Box::from_iter(args.iter().map(|arg| { + rustc_span::source_map::dummy_spanned(arg.internal(tables, tcx).into()) + })), + destination: destination.internal(tables, tcx).into(), + target: target.map(|basic_block_idx| { + rustc_middle::mir::BasicBlock::from_usize(basic_block_idx) + }), + unwind: unwind.internal(tables, tcx).into(), + call_source: rustc_middle::mir::CallSource::Misc, // TODO: is this a good default value? + fn_span: rustc_span::DUMMY_SP, // TODO: is this a good default value? + } + } + TerminatorKind::Assert { cond, expected, msg, target, unwind } => { + rustc_middle::mir::TerminatorKind::Assert { + cond: cond.internal(tables, tcx).into(), + expected: *expected, + msg: Box::new(msg.internal(tables, tcx).into()), + target: rustc_middle::mir::BasicBlock::from_usize(*target), + unwind: unwind.internal(tables, tcx).into(), + } + } + TerminatorKind::InlineAsm { .. } => todo!(), + } + } +} + +impl RustcInternal for Terminator { + type T<'tcx> = rustc_middle::mir::Terminator<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + rustc_middle::mir::Terminator { + source_info: rustc_middle::mir::SourceInfo::outermost( + self.span.internal(tables, tcx).into(), + ), + kind: self.kind.internal(tables, tcx).into(), + } + } +} + +impl RustcInternal for LocalDecl { + type T<'tcx> = rustc_middle::mir::LocalDecl<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + rustc_middle::mir::LocalDecl { + mutability: self.mutability.internal(tables, tcx).into(), + local_info: rustc_middle::mir::ClearCrossCrate::Set(Box::new( + rustc_middle::mir::LocalInfo::Boring, + )), + ty: self.ty.internal(tables, tcx).into(), + user_ty: None, // TODO: is this a good default value? + source_info: rustc_middle::mir::SourceInfo::outermost( + self.span.internal(tables, tcx).into(), + ), + } + } +} + +impl RustcInternal for Body { + type T<'tcx> = rustc_middle::mir::Body<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + let internal_basic_blocks = rustc_index::IndexVec::from_raw( + self.blocks + .iter() + .map(|stable_basic_block| rustc_middle::mir::BasicBlockData { + statements: stable_basic_block + .statements + .iter() + .map(|statement| statement.internal(tables, tcx).into()) + .collect(), + terminator: Some(stable_basic_block.terminator.internal(tables, tcx).into()), + is_cleanup: false, + }) + .collect(), + ); + let local_decls = rustc_index::IndexVec::from_raw( + self.locals() + .iter() + .map(|local_decl| local_decl.internal(tables, tcx).into()) + .collect(), + ); + // TODO: this is lossy, I wonder how should we signal this to the user. + rustc_middle::mir::Body::new( + rustc_middle::mir::MirSource::item(rustc_hir::def_id::CRATE_DEF_ID.to_def_id()), + internal_basic_blocks, + rustc_index::IndexVec::new(), + local_decls, + rustc_index::IndexVec::new(), + self.arg_count(), + Vec::new(), + rustc_span::DUMMY_SP, + None, + None, + ) + } +} + impl RustcInternal for &T where T: RustcInternal, diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index e0f9e7ae67a0f..f0ab9df2d18ea 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -100,6 +100,10 @@ impl Body { pub fn spread_arg(&self) -> Option { self.spread_arg } + + pub fn arg_count(&self) -> usize { + self.arg_count + } } type LocalDecls = Vec; From d08c4f4b862f5a9b9c9c63a91761a0b2f1306391 Mon Sep 17 00:00:00 2001 From: Artem Agvanian Date: Tue, 16 Jul 2024 08:44:31 -0700 Subject: [PATCH 2/2] Pull all `RustcInternal` impls for MIR items into its own file --- .../{internal.rs => internal/mir.rs} | 473 +---------------- .../src/rustc_internal/internal/mod.rs | 477 ++++++++++++++++++ 2 files changed, 478 insertions(+), 472 deletions(-) rename compiler/rustc_smir/src/rustc_internal/{internal.rs => internal/mir.rs} (65%) create mode 100644 compiler/rustc_smir/src/rustc_internal/internal/mod.rs diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal/mir.rs similarity index 65% rename from compiler/rustc_smir/src/rustc_internal/internal.rs rename to compiler/rustc_smir/src/rustc_internal/internal/mir.rs index 2580d57aece1c..a2caacf3f5050 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal/mir.rs @@ -1,14 +1,5 @@ -//! Module containing the translation from stable mir constructs to the rustc counterpart. -//! -//! This module will only include a few constructs to allow users to invoke internal rustc APIs -//! due to incomplete stable coverage. - -// Prefer importing stable_mir over internal rustc constructs to make this file more readable. - use crate::rustc_smir::Tables; -use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy, TyCtxt}; -use rustc_span::Symbol; -use stable_mir::abi::Layout; +use rustc_middle::ty::{self as rustc_ty, TyCtxt}; use stable_mir::mir::alloc::AllocId; use stable_mir::mir::mono::{Instance, MonoItem, StaticDef}; use stable_mir::mir::{ @@ -18,191 +9,9 @@ use stable_mir::mir::{ Place, PointerCoercion, ProjectionElem, RetagKind, Rvalue, Safety, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, UnOp, UnwindAction, UserTypeProjection, Variance, }; -use stable_mir::ty::{ - Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, DynKind, - ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig, - GenericArgKind, GenericArgs, IndexedVal, IntTy, MirConst, Movability, Pattern, Region, RigidTy, - Span, TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx, -}; -use stable_mir::{CrateItem, CrateNum, DefId}; use super::RustcInternal; -impl RustcInternal for CrateItem { - type T<'tcx> = rustc_span::def_id::DefId; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - self.0.internal(tables, tcx) - } -} - -impl RustcInternal for CrateNum { - type T<'tcx> = rustc_span::def_id::CrateNum; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - rustc_span::def_id::CrateNum::from_usize(*self) - } -} - -impl RustcInternal for DefId { - type T<'tcx> = rustc_span::def_id::DefId; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.lift(tables.def_ids[*self]).unwrap() - } -} - -impl RustcInternal for GenericArgs { - type T<'tcx> = rustc_ty::GenericArgsRef<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.mk_args_from_iter(self.0.iter().map(|arg| arg.internal(tables, tcx))) - } -} - -impl RustcInternal for GenericArgKind { - type T<'tcx> = rustc_ty::GenericArg<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - let arg: rustc_ty::GenericArg<'tcx> = match self { - GenericArgKind::Lifetime(reg) => reg.internal(tables, tcx).into(), - GenericArgKind::Type(ty) => ty.internal(tables, tcx).into(), - GenericArgKind::Const(cnst) => cnst.internal(tables, tcx).into(), - }; - tcx.lift(arg).unwrap() - } -} - -impl RustcInternal for Region { - type T<'tcx> = rustc_ty::Region<'tcx>; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - // Cannot recover region. Use erased for now. - tcx.lifetimes.re_erased - } -} - -impl RustcInternal for Ty { - type T<'tcx> = InternalTy<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.lift(tables.types[*self]).unwrap() - } -} - -impl RustcInternal for TyConst { - type T<'tcx> = InternalConst<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.lift(tables.ty_consts[self.id]).unwrap() - } -} - -impl RustcInternal for Pattern { - type T<'tcx> = rustc_ty::Pattern<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.mk_pat(match self { - Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range { - start: start.as_ref().map(|c| c.internal(tables, tcx)), - end: end.as_ref().map(|c| c.internal(tables, tcx)), - include_end: *include_end, - }, - }) - } -} - -impl RustcInternal for RigidTy { - type T<'tcx> = rustc_ty::TyKind<'tcx>; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - match self { - RigidTy::Bool => rustc_ty::TyKind::Bool, - RigidTy::Char => rustc_ty::TyKind::Char, - RigidTy::Int(int_ty) => rustc_ty::TyKind::Int(int_ty.internal(tables, tcx)), - RigidTy::Uint(uint_ty) => rustc_ty::TyKind::Uint(uint_ty.internal(tables, tcx)), - RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables, tcx)), - RigidTy::Never => rustc_ty::TyKind::Never, - RigidTy::Array(ty, cnst) => { - rustc_ty::TyKind::Array(ty.internal(tables, tcx), cnst.internal(tables, tcx)) - } - RigidTy::Pat(ty, pat) => { - rustc_ty::TyKind::Pat(ty.internal(tables, tcx), pat.internal(tables, tcx)) - } - RigidTy::Adt(def, args) => { - rustc_ty::TyKind::Adt(def.internal(tables, tcx), args.internal(tables, tcx)) - } - RigidTy::Str => rustc_ty::TyKind::Str, - RigidTy::Slice(ty) => rustc_ty::TyKind::Slice(ty.internal(tables, tcx)), - RigidTy::RawPtr(ty, mutability) => { - rustc_ty::TyKind::RawPtr(ty.internal(tables, tcx), mutability.internal(tables, tcx)) - } - RigidTy::Ref(region, ty, mutability) => rustc_ty::TyKind::Ref( - region.internal(tables, tcx), - ty.internal(tables, tcx), - mutability.internal(tables, tcx), - ), - RigidTy::Foreign(def) => rustc_ty::TyKind::Foreign(def.0.internal(tables, tcx)), - RigidTy::FnDef(def, args) => { - rustc_ty::TyKind::FnDef(def.0.internal(tables, tcx), args.internal(tables, tcx)) - } - RigidTy::FnPtr(sig) => rustc_ty::TyKind::FnPtr(sig.internal(tables, tcx)), - RigidTy::Closure(def, args) => { - rustc_ty::TyKind::Closure(def.0.internal(tables, tcx), args.internal(tables, tcx)) - } - RigidTy::Coroutine(def, args, _mov) => { - rustc_ty::TyKind::Coroutine(def.0.internal(tables, tcx), args.internal(tables, tcx)) - } - RigidTy::CoroutineWitness(def, args) => rustc_ty::TyKind::CoroutineWitness( - def.0.internal(tables, tcx), - args.internal(tables, tcx), - ), - RigidTy::Dynamic(predicate, region, dyn_kind) => rustc_ty::TyKind::Dynamic( - tcx.mk_poly_existential_predicates(&predicate.internal(tables, tcx)), - region.internal(tables, tcx), - dyn_kind.internal(tables, tcx), - ), - RigidTy::Tuple(tys) => { - rustc_ty::TyKind::Tuple(tcx.mk_type_list(&tys.internal(tables, tcx))) - } - } - } -} - -impl RustcInternal for IntTy { - type T<'tcx> = rustc_ty::IntTy; - - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - match self { - IntTy::Isize => rustc_ty::IntTy::Isize, - IntTy::I8 => rustc_ty::IntTy::I8, - IntTy::I16 => rustc_ty::IntTy::I16, - IntTy::I32 => rustc_ty::IntTy::I32, - IntTy::I64 => rustc_ty::IntTy::I64, - IntTy::I128 => rustc_ty::IntTy::I128, - } - } -} - -impl RustcInternal for UintTy { - type T<'tcx> = rustc_ty::UintTy; - - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - match self { - UintTy::Usize => rustc_ty::UintTy::Usize, - UintTy::U8 => rustc_ty::UintTy::U8, - UintTy::U16 => rustc_ty::UintTy::U16, - UintTy::U32 => rustc_ty::UintTy::U32, - UintTy::U64 => rustc_ty::UintTy::U64, - UintTy::U128 => rustc_ty::UintTy::U128, - } - } -} - -impl RustcInternal for FloatTy { - type T<'tcx> = rustc_ty::FloatTy; - - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - match self { - FloatTy::F16 => rustc_ty::FloatTy::F16, - FloatTy::F32 => rustc_ty::FloatTy::F32, - FloatTy::F64 => rustc_ty::FloatTy::F64, - FloatTy::F128 => rustc_ty::FloatTy::F128, - } - } -} - impl RustcInternal for Mutability { type T<'tcx> = rustc_ty::Mutability; @@ -214,68 +23,6 @@ impl RustcInternal for Mutability { } } -impl RustcInternal for Movability { - type T<'tcx> = rustc_ty::Movability; - - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - match self { - Movability::Static => rustc_ty::Movability::Static, - Movability::Movable => rustc_ty::Movability::Movable, - } - } -} - -impl RustcInternal for FnSig { - type T<'tcx> = rustc_ty::FnSig<'tcx>; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.lift(rustc_ty::FnSig { - inputs_and_output: tcx.mk_type_list(&self.inputs_and_output.internal(tables, tcx)), - c_variadic: self.c_variadic, - safety: self.safety.internal(tables, tcx), - abi: self.abi.internal(tables, tcx), - }) - .unwrap() - } -} - -impl RustcInternal for VariantIdx { - type T<'tcx> = rustc_target::abi::VariantIdx; - - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - rustc_target::abi::VariantIdx::from(self.to_index()) - } -} - -impl RustcInternal for VariantDef { - type T<'tcx> = &'tcx rustc_ty::VariantDef; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - self.adt_def.internal(tables, tcx).variant(self.idx.internal(tables, tcx)) - } -} - -impl RustcInternal for MirConst { - type T<'tcx> = rustc_middle::mir::Const<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - let constant = tables.mir_consts[self.id]; - match constant { - rustc_middle::mir::Const::Ty(ty, ct) => { - rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap(), tcx.lift(ct).unwrap()) - } - rustc_middle::mir::Const::Unevaluated(uneval, ty) => { - rustc_middle::mir::Const::Unevaluated( - tcx.lift(uneval).unwrap(), - tcx.lift(ty).unwrap(), - ) - } - rustc_middle::mir::Const::Val(const_val, ty) => { - rustc_middle::mir::Const::Val(tcx.lift(const_val).unwrap(), tcx.lift(ty).unwrap()) - } - } - } -} - impl RustcInternal for MonoItem { type T<'tcx> = rustc_middle::mir::mono::MonoItem<'tcx>; @@ -307,124 +54,6 @@ impl RustcInternal for StaticDef { } } -#[allow(rustc::usage_of_qualified_ty)] -impl RustcInternal for Binder -where - T: RustcInternal, - for<'tcx> T::T<'tcx>: rustc_ty::TypeVisitable>, -{ - type T<'tcx> = rustc_ty::Binder<'tcx, T::T<'tcx>>; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - rustc_ty::Binder::bind_with_vars( - self.value.internal(tables, tcx), - tcx.mk_bound_variable_kinds_from_iter( - self.bound_vars.iter().map(|bound| bound.internal(tables, tcx)), - ), - ) - } -} - -impl RustcInternal for BoundVariableKind { - type T<'tcx> = rustc_ty::BoundVariableKind; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - match self { - BoundVariableKind::Ty(kind) => rustc_ty::BoundVariableKind::Ty(match kind { - BoundTyKind::Anon => rustc_ty::BoundTyKind::Anon, - BoundTyKind::Param(def, symbol) => rustc_ty::BoundTyKind::Param( - def.0.internal(tables, tcx), - Symbol::intern(symbol), - ), - }), - BoundVariableKind::Region(kind) => rustc_ty::BoundVariableKind::Region(match kind { - BoundRegionKind::BrAnon => rustc_ty::BoundRegionKind::BrAnon, - BoundRegionKind::BrNamed(def, symbol) => rustc_ty::BoundRegionKind::BrNamed( - def.0.internal(tables, tcx), - Symbol::intern(symbol), - ), - BoundRegionKind::BrEnv => rustc_ty::BoundRegionKind::BrEnv, - }), - BoundVariableKind::Const => rustc_ty::BoundVariableKind::Const, - } - } -} - -impl RustcInternal for DynKind { - type T<'tcx> = rustc_ty::DynKind; - - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - match self { - DynKind::Dyn => rustc_ty::DynKind::Dyn, - DynKind::DynStar => rustc_ty::DynKind::DynStar, - } - } -} - -impl RustcInternal for ExistentialPredicate { - type T<'tcx> = rustc_ty::ExistentialPredicate<'tcx>; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - match self { - ExistentialPredicate::Trait(trait_ref) => { - rustc_ty::ExistentialPredicate::Trait(trait_ref.internal(tables, tcx)) - } - ExistentialPredicate::Projection(proj) => { - rustc_ty::ExistentialPredicate::Projection(proj.internal(tables, tcx)) - } - ExistentialPredicate::AutoTrait(trait_def) => { - rustc_ty::ExistentialPredicate::AutoTrait(trait_def.0.internal(tables, tcx)) - } - } - } -} - -impl RustcInternal for ExistentialProjection { - type T<'tcx> = rustc_ty::ExistentialProjection<'tcx>; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - rustc_ty::ExistentialProjection { - def_id: self.def_id.0.internal(tables, tcx), - args: self.generic_args.internal(tables, tcx), - term: self.term.internal(tables, tcx), - } - } -} - -impl RustcInternal for TermKind { - type T<'tcx> = rustc_ty::Term<'tcx>; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - match self { - TermKind::Type(ty) => ty.internal(tables, tcx).into(), - TermKind::Const(cnst) => cnst.internal(tables, tcx).into(), - } - } -} - -impl RustcInternal for ExistentialTraitRef { - type T<'tcx> = rustc_ty::ExistentialTraitRef<'tcx>; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - rustc_ty::ExistentialTraitRef { - def_id: self.def_id.0.internal(tables, tcx), - args: self.generic_args.internal(tables, tcx), - } - } -} - -impl RustcInternal for TraitRef { - type T<'tcx> = rustc_ty::TraitRef<'tcx>; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - rustc_ty::TraitRef::new_from_args( - tcx, - self.def_id.0.internal(tables, tcx), - self.args().internal(tables, tcx), - ) - } -} - impl RustcInternal for AllocId { type T<'tcx> = rustc_middle::mir::interpret::AllocId; fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { @@ -432,58 +61,6 @@ impl RustcInternal for AllocId { } } -impl RustcInternal for ClosureKind { - type T<'tcx> = rustc_ty::ClosureKind; - - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - match self { - ClosureKind::Fn => rustc_ty::ClosureKind::Fn, - ClosureKind::FnMut => rustc_ty::ClosureKind::FnMut, - ClosureKind::FnOnce => rustc_ty::ClosureKind::FnOnce, - } - } -} - -impl RustcInternal for AdtDef { - type T<'tcx> = rustc_ty::AdtDef<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.adt_def(self.0.internal(tables, tcx)) - } -} - -impl RustcInternal for Abi { - type T<'tcx> = rustc_target::spec::abi::Abi; - - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - match *self { - Abi::Rust => rustc_target::spec::abi::Abi::Rust, - Abi::C { unwind } => rustc_target::spec::abi::Abi::C { unwind }, - Abi::Cdecl { unwind } => rustc_target::spec::abi::Abi::Cdecl { unwind }, - Abi::Stdcall { unwind } => rustc_target::spec::abi::Abi::Stdcall { unwind }, - Abi::Fastcall { unwind } => rustc_target::spec::abi::Abi::Fastcall { unwind }, - Abi::Vectorcall { unwind } => rustc_target::spec::abi::Abi::Vectorcall { unwind }, - Abi::Thiscall { unwind } => rustc_target::spec::abi::Abi::Thiscall { unwind }, - Abi::Aapcs { unwind } => rustc_target::spec::abi::Abi::Aapcs { unwind }, - Abi::Win64 { unwind } => rustc_target::spec::abi::Abi::Win64 { unwind }, - Abi::SysV64 { unwind } => rustc_target::spec::abi::Abi::SysV64 { unwind }, - Abi::PtxKernel => rustc_target::spec::abi::Abi::PtxKernel, - Abi::Msp430Interrupt => rustc_target::spec::abi::Abi::Msp430Interrupt, - Abi::X86Interrupt => rustc_target::spec::abi::Abi::X86Interrupt, - Abi::EfiApi => rustc_target::spec::abi::Abi::EfiApi, - Abi::AvrInterrupt => rustc_target::spec::abi::Abi::AvrInterrupt, - Abi::AvrNonBlockingInterrupt => rustc_target::spec::abi::Abi::AvrNonBlockingInterrupt, - Abi::CCmseNonSecureCall => rustc_target::spec::abi::Abi::CCmseNonSecureCall, - Abi::System { unwind } => rustc_target::spec::abi::Abi::System { unwind }, - Abi::RustIntrinsic => rustc_target::spec::abi::Abi::RustIntrinsic, - Abi::RustCall => rustc_target::spec::abi::Abi::RustCall, - Abi::Unadjusted => rustc_target::spec::abi::Abi::Unadjusted, - Abi::RustCold => rustc_target::spec::abi::Abi::RustCold, - Abi::RiscvInterruptM => rustc_target::spec::abi::Abi::RiscvInterruptM, - Abi::RiscvInterruptS => rustc_target::spec::abi::Abi::RiscvInterruptS, - } - } -} - impl RustcInternal for Safety { type T<'tcx> = rustc_hir::Safety; @@ -494,21 +71,6 @@ impl RustcInternal for Safety { } } } -impl RustcInternal for Span { - type T<'tcx> = rustc_span::Span; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tables[*self] - } -} - -impl RustcInternal for Layout { - type T<'tcx> = rustc_target::abi::Layout<'tcx>; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.lift(tables.layouts[*self]).unwrap() - } -} impl RustcInternal for Place { type T<'tcx> = rustc_middle::mir::Place<'tcx>; @@ -1265,36 +827,3 @@ impl RustcInternal for Body { ) } } - -impl RustcInternal for &T -where - T: RustcInternal, -{ - type T<'tcx> = T::T<'tcx>; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - (*self).internal(tables, tcx) - } -} - -impl RustcInternal for Option -where - T: RustcInternal, -{ - type T<'tcx> = Option>; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - self.as_ref().map(|inner| inner.internal(tables, tcx)) - } -} - -impl RustcInternal for Vec -where - T: RustcInternal, -{ - type T<'tcx> = Vec>; - - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - self.iter().map(|e| e.internal(tables, tcx)).collect() - } -} diff --git a/compiler/rustc_smir/src/rustc_internal/internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/internal/mod.rs new file mode 100644 index 0000000000000..339887688ffee --- /dev/null +++ b/compiler/rustc_smir/src/rustc_internal/internal/mod.rs @@ -0,0 +1,477 @@ +//! Module containing the translation from stable mir constructs to the rustc counterpart. +//! +//! This module will only include a few constructs to allow users to invoke internal rustc APIs +//! due to incomplete stable coverage. + +// Prefer importing stable_mir over internal rustc constructs to make this file more readable. +use crate::rustc_smir::Tables; +use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy, TyCtxt}; +use rustc_span::Symbol; +use stable_mir::abi::Layout; +use stable_mir::ty::{ + Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, DynKind, + ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig, + GenericArgKind, GenericArgs, IndexedVal, IntTy, MirConst, Movability, Pattern, Region, RigidTy, + Span, TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx, +}; +use stable_mir::{CrateItem, CrateNum, DefId}; + +use super::RustcInternal; + +pub mod mir; + +impl RustcInternal for CrateItem { + type T<'tcx> = rustc_span::def_id::DefId; + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + self.0.internal(tables, tcx) + } +} + +impl RustcInternal for CrateNum { + type T<'tcx> = rustc_span::def_id::CrateNum; + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + rustc_span::def_id::CrateNum::from_usize(*self) + } +} + +impl RustcInternal for DefId { + type T<'tcx> = rustc_span::def_id::DefId; + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + tcx.lift(tables.def_ids[*self]).unwrap() + } +} + +impl RustcInternal for GenericArgs { + type T<'tcx> = rustc_ty::GenericArgsRef<'tcx>; + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + tcx.mk_args_from_iter(self.0.iter().map(|arg| arg.internal(tables, tcx))) + } +} + +impl RustcInternal for GenericArgKind { + type T<'tcx> = rustc_ty::GenericArg<'tcx>; + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + let arg: rustc_ty::GenericArg<'tcx> = match self { + GenericArgKind::Lifetime(reg) => reg.internal(tables, tcx).into(), + GenericArgKind::Type(ty) => ty.internal(tables, tcx).into(), + GenericArgKind::Const(cnst) => cnst.internal(tables, tcx).into(), + }; + tcx.lift(arg).unwrap() + } +} + +impl RustcInternal for Region { + type T<'tcx> = rustc_ty::Region<'tcx>; + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + // Cannot recover region. Use erased for now. + tcx.lifetimes.re_erased + } +} + +impl RustcInternal for Ty { + type T<'tcx> = InternalTy<'tcx>; + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + tcx.lift(tables.types[*self]).unwrap() + } +} + +impl RustcInternal for TyConst { + type T<'tcx> = InternalConst<'tcx>; + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + tcx.lift(tables.ty_consts[self.id]).unwrap() + } +} + +impl RustcInternal for Pattern { + type T<'tcx> = rustc_ty::Pattern<'tcx>; + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + tcx.mk_pat(match self { + Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range { + start: start.as_ref().map(|c| c.internal(tables, tcx)), + end: end.as_ref().map(|c| c.internal(tables, tcx)), + include_end: *include_end, + }, + }) + } +} + +impl RustcInternal for RigidTy { + type T<'tcx> = rustc_ty::TyKind<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + RigidTy::Bool => rustc_ty::TyKind::Bool, + RigidTy::Char => rustc_ty::TyKind::Char, + RigidTy::Int(int_ty) => rustc_ty::TyKind::Int(int_ty.internal(tables, tcx)), + RigidTy::Uint(uint_ty) => rustc_ty::TyKind::Uint(uint_ty.internal(tables, tcx)), + RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables, tcx)), + RigidTy::Never => rustc_ty::TyKind::Never, + RigidTy::Array(ty, cnst) => { + rustc_ty::TyKind::Array(ty.internal(tables, tcx), cnst.internal(tables, tcx)) + } + RigidTy::Pat(ty, pat) => { + rustc_ty::TyKind::Pat(ty.internal(tables, tcx), pat.internal(tables, tcx)) + } + RigidTy::Adt(def, args) => { + rustc_ty::TyKind::Adt(def.internal(tables, tcx), args.internal(tables, tcx)) + } + RigidTy::Str => rustc_ty::TyKind::Str, + RigidTy::Slice(ty) => rustc_ty::TyKind::Slice(ty.internal(tables, tcx)), + RigidTy::RawPtr(ty, mutability) => { + rustc_ty::TyKind::RawPtr(ty.internal(tables, tcx), mutability.internal(tables, tcx)) + } + RigidTy::Ref(region, ty, mutability) => rustc_ty::TyKind::Ref( + region.internal(tables, tcx), + ty.internal(tables, tcx), + mutability.internal(tables, tcx), + ), + RigidTy::Foreign(def) => rustc_ty::TyKind::Foreign(def.0.internal(tables, tcx)), + RigidTy::FnDef(def, args) => { + rustc_ty::TyKind::FnDef(def.0.internal(tables, tcx), args.internal(tables, tcx)) + } + RigidTy::FnPtr(sig) => rustc_ty::TyKind::FnPtr(sig.internal(tables, tcx)), + RigidTy::Closure(def, args) => { + rustc_ty::TyKind::Closure(def.0.internal(tables, tcx), args.internal(tables, tcx)) + } + RigidTy::Coroutine(def, args, _mov) => { + rustc_ty::TyKind::Coroutine(def.0.internal(tables, tcx), args.internal(tables, tcx)) + } + RigidTy::CoroutineWitness(def, args) => rustc_ty::TyKind::CoroutineWitness( + def.0.internal(tables, tcx), + args.internal(tables, tcx), + ), + RigidTy::Dynamic(predicate, region, dyn_kind) => rustc_ty::TyKind::Dynamic( + tcx.mk_poly_existential_predicates(&predicate.internal(tables, tcx)), + region.internal(tables, tcx), + dyn_kind.internal(tables, tcx), + ), + RigidTy::Tuple(tys) => { + rustc_ty::TyKind::Tuple(tcx.mk_type_list(&tys.internal(tables, tcx))) + } + } + } +} + +impl RustcInternal for IntTy { + type T<'tcx> = rustc_ty::IntTy; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + IntTy::Isize => rustc_ty::IntTy::Isize, + IntTy::I8 => rustc_ty::IntTy::I8, + IntTy::I16 => rustc_ty::IntTy::I16, + IntTy::I32 => rustc_ty::IntTy::I32, + IntTy::I64 => rustc_ty::IntTy::I64, + IntTy::I128 => rustc_ty::IntTy::I128, + } + } +} + +impl RustcInternal for UintTy { + type T<'tcx> = rustc_ty::UintTy; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + UintTy::Usize => rustc_ty::UintTy::Usize, + UintTy::U8 => rustc_ty::UintTy::U8, + UintTy::U16 => rustc_ty::UintTy::U16, + UintTy::U32 => rustc_ty::UintTy::U32, + UintTy::U64 => rustc_ty::UintTy::U64, + UintTy::U128 => rustc_ty::UintTy::U128, + } + } +} + +impl RustcInternal for FloatTy { + type T<'tcx> = rustc_ty::FloatTy; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + FloatTy::F16 => rustc_ty::FloatTy::F16, + FloatTy::F32 => rustc_ty::FloatTy::F32, + FloatTy::F64 => rustc_ty::FloatTy::F64, + FloatTy::F128 => rustc_ty::FloatTy::F128, + } + } +} + +impl RustcInternal for Movability { + type T<'tcx> = rustc_ty::Movability; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + Movability::Static => rustc_ty::Movability::Static, + Movability::Movable => rustc_ty::Movability::Movable, + } + } +} + +impl RustcInternal for FnSig { + type T<'tcx> = rustc_ty::FnSig<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + tcx.lift(rustc_ty::FnSig { + inputs_and_output: tcx.mk_type_list(&self.inputs_and_output.internal(tables, tcx)), + c_variadic: self.c_variadic, + safety: self.safety.internal(tables, tcx), + abi: self.abi.internal(tables, tcx), + }) + .unwrap() + } +} + +impl RustcInternal for VariantIdx { + type T<'tcx> = rustc_target::abi::VariantIdx; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + rustc_target::abi::VariantIdx::from(self.to_index()) + } +} + +impl RustcInternal for VariantDef { + type T<'tcx> = &'tcx rustc_ty::VariantDef; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + self.adt_def.internal(tables, tcx).variant(self.idx.internal(tables, tcx)) + } +} + +impl RustcInternal for MirConst { + type T<'tcx> = rustc_middle::mir::Const<'tcx>; + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + let constant = tables.mir_consts[self.id]; + match constant { + rustc_middle::mir::Const::Ty(ty, ct) => { + rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap(), tcx.lift(ct).unwrap()) + } + rustc_middle::mir::Const::Unevaluated(uneval, ty) => { + rustc_middle::mir::Const::Unevaluated( + tcx.lift(uneval).unwrap(), + tcx.lift(ty).unwrap(), + ) + } + rustc_middle::mir::Const::Val(const_val, ty) => { + rustc_middle::mir::Const::Val(tcx.lift(const_val).unwrap(), tcx.lift(ty).unwrap()) + } + } + } +} + +#[allow(rustc::usage_of_qualified_ty)] +impl RustcInternal for Binder +where + T: RustcInternal, + for<'tcx> T::T<'tcx>: rustc_ty::TypeVisitable>, +{ + type T<'tcx> = rustc_ty::Binder<'tcx, T::T<'tcx>>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + rustc_ty::Binder::bind_with_vars( + self.value.internal(tables, tcx), + tcx.mk_bound_variable_kinds_from_iter( + self.bound_vars.iter().map(|bound| bound.internal(tables, tcx)), + ), + ) + } +} + +impl RustcInternal for BoundVariableKind { + type T<'tcx> = rustc_ty::BoundVariableKind; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + BoundVariableKind::Ty(kind) => rustc_ty::BoundVariableKind::Ty(match kind { + BoundTyKind::Anon => rustc_ty::BoundTyKind::Anon, + BoundTyKind::Param(def, symbol) => rustc_ty::BoundTyKind::Param( + def.0.internal(tables, tcx), + Symbol::intern(symbol), + ), + }), + BoundVariableKind::Region(kind) => rustc_ty::BoundVariableKind::Region(match kind { + BoundRegionKind::BrAnon => rustc_ty::BoundRegionKind::BrAnon, + BoundRegionKind::BrNamed(def, symbol) => rustc_ty::BoundRegionKind::BrNamed( + def.0.internal(tables, tcx), + Symbol::intern(symbol), + ), + BoundRegionKind::BrEnv => rustc_ty::BoundRegionKind::BrEnv, + }), + BoundVariableKind::Const => rustc_ty::BoundVariableKind::Const, + } + } +} + +impl RustcInternal for DynKind { + type T<'tcx> = rustc_ty::DynKind; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + DynKind::Dyn => rustc_ty::DynKind::Dyn, + DynKind::DynStar => rustc_ty::DynKind::DynStar, + } + } +} + +impl RustcInternal for ExistentialPredicate { + type T<'tcx> = rustc_ty::ExistentialPredicate<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + ExistentialPredicate::Trait(trait_ref) => { + rustc_ty::ExistentialPredicate::Trait(trait_ref.internal(tables, tcx)) + } + ExistentialPredicate::Projection(proj) => { + rustc_ty::ExistentialPredicate::Projection(proj.internal(tables, tcx)) + } + ExistentialPredicate::AutoTrait(trait_def) => { + rustc_ty::ExistentialPredicate::AutoTrait(trait_def.0.internal(tables, tcx)) + } + } + } +} + +impl RustcInternal for ExistentialProjection { + type T<'tcx> = rustc_ty::ExistentialProjection<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + rustc_ty::ExistentialProjection { + def_id: self.def_id.0.internal(tables, tcx), + args: self.generic_args.internal(tables, tcx), + term: self.term.internal(tables, tcx), + } + } +} + +impl RustcInternal for TermKind { + type T<'tcx> = rustc_ty::Term<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + TermKind::Type(ty) => ty.internal(tables, tcx).into(), + TermKind::Const(cnst) => cnst.internal(tables, tcx).into(), + } + } +} + +impl RustcInternal for ExistentialTraitRef { + type T<'tcx> = rustc_ty::ExistentialTraitRef<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + rustc_ty::ExistentialTraitRef { + def_id: self.def_id.0.internal(tables, tcx), + args: self.generic_args.internal(tables, tcx), + } + } +} + +impl RustcInternal for TraitRef { + type T<'tcx> = rustc_ty::TraitRef<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + rustc_ty::TraitRef::new_from_args( + tcx, + self.def_id.0.internal(tables, tcx), + self.args().internal(tables, tcx), + ) + } +} + +impl RustcInternal for ClosureKind { + type T<'tcx> = rustc_ty::ClosureKind; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match self { + ClosureKind::Fn => rustc_ty::ClosureKind::Fn, + ClosureKind::FnMut => rustc_ty::ClosureKind::FnMut, + ClosureKind::FnOnce => rustc_ty::ClosureKind::FnOnce, + } + } +} + +impl RustcInternal for AdtDef { + type T<'tcx> = rustc_ty::AdtDef<'tcx>; + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + tcx.adt_def(self.0.internal(tables, tcx)) + } +} + +impl RustcInternal for Abi { + type T<'tcx> = rustc_target::spec::abi::Abi; + + fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + match *self { + Abi::Rust => rustc_target::spec::abi::Abi::Rust, + Abi::C { unwind } => rustc_target::spec::abi::Abi::C { unwind }, + Abi::Cdecl { unwind } => rustc_target::spec::abi::Abi::Cdecl { unwind }, + Abi::Stdcall { unwind } => rustc_target::spec::abi::Abi::Stdcall { unwind }, + Abi::Fastcall { unwind } => rustc_target::spec::abi::Abi::Fastcall { unwind }, + Abi::Vectorcall { unwind } => rustc_target::spec::abi::Abi::Vectorcall { unwind }, + Abi::Thiscall { unwind } => rustc_target::spec::abi::Abi::Thiscall { unwind }, + Abi::Aapcs { unwind } => rustc_target::spec::abi::Abi::Aapcs { unwind }, + Abi::Win64 { unwind } => rustc_target::spec::abi::Abi::Win64 { unwind }, + Abi::SysV64 { unwind } => rustc_target::spec::abi::Abi::SysV64 { unwind }, + Abi::PtxKernel => rustc_target::spec::abi::Abi::PtxKernel, + Abi::Msp430Interrupt => rustc_target::spec::abi::Abi::Msp430Interrupt, + Abi::X86Interrupt => rustc_target::spec::abi::Abi::X86Interrupt, + Abi::EfiApi => rustc_target::spec::abi::Abi::EfiApi, + Abi::AvrInterrupt => rustc_target::spec::abi::Abi::AvrInterrupt, + Abi::AvrNonBlockingInterrupt => rustc_target::spec::abi::Abi::AvrNonBlockingInterrupt, + Abi::CCmseNonSecureCall => rustc_target::spec::abi::Abi::CCmseNonSecureCall, + Abi::System { unwind } => rustc_target::spec::abi::Abi::System { unwind }, + Abi::RustIntrinsic => rustc_target::spec::abi::Abi::RustIntrinsic, + Abi::RustCall => rustc_target::spec::abi::Abi::RustCall, + Abi::Unadjusted => rustc_target::spec::abi::Abi::Unadjusted, + Abi::RustCold => rustc_target::spec::abi::Abi::RustCold, + Abi::RiscvInterruptM => rustc_target::spec::abi::Abi::RiscvInterruptM, + Abi::RiscvInterruptS => rustc_target::spec::abi::Abi::RiscvInterruptS, + } + } +} + +impl RustcInternal for Span { + type T<'tcx> = rustc_span::Span; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + tables[*self] + } +} + +impl RustcInternal for Layout { + type T<'tcx> = rustc_target::abi::Layout<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + tcx.lift(tables.layouts[*self]).unwrap() + } +} + +impl RustcInternal for &T +where + T: RustcInternal, +{ + type T<'tcx> = T::T<'tcx>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + (*self).internal(tables, tcx) + } +} + +impl RustcInternal for Option +where + T: RustcInternal, +{ + type T<'tcx> = Option>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + self.as_ref().map(|inner| inner.internal(tables, tcx)) + } +} + +impl RustcInternal for Vec +where + T: RustcInternal, +{ + type T<'tcx> = Vec>; + + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + self.iter().map(|e| e.internal(tables, tcx)).collect() + } +}