stable_mir/unstable/
mod.rs

1//! Module that collects the things that have no stability guarantees.
2//!
3//! We want to keep StableMIR definitions and logic separate from
4//! any sort of conversion and usage of internal rustc code. So we
5//! restrict the usage of internal items to be inside this module.
6
7use std::marker::PointeeSized;
8
9use rustc_hir::def::DefKind;
10use rustc_middle::ty::{List, Ty, TyCtxt};
11use rustc_middle::{mir, ty};
12use rustc_smir::Tables;
13use rustc_smir::context::SmirCtxt;
14
15use super::compiler_interface::BridgeTys;
16use crate::{CtorKind, ItemKind};
17
18pub(crate) mod convert;
19mod internal_cx;
20
21/// Trait that defines the methods that are fine to call from [`RustcInternal`].
22///
23/// This trait is only for [`RustcInternal`]. Any other other access to rustc's internals
24/// should go through [`rustc_smir::context::SmirCtxt`].
25pub trait InternalCx<'tcx>: Copy + Clone {
26    fn tcx(self) -> TyCtxt<'tcx>;
27
28    fn lift<T: ty::Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted>;
29
30    fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
31    where
32        I: Iterator<Item = T>,
33        T: ty::CollectAndApply<ty::GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>;
34
35    fn mk_pat(self, v: ty::PatternKind<'tcx>) -> ty::Pattern<'tcx>;
36
37    fn mk_poly_existential_predicates(
38        self,
39        eps: &[ty::PolyExistentialPredicate<'tcx>],
40    ) -> &'tcx List<ty::PolyExistentialPredicate<'tcx>>;
41
42    fn mk_type_list(self, v: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>>;
43
44    fn lifetimes_re_erased(self) -> ty::Region<'tcx>;
45
46    fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
47    where
48        I: Iterator<Item = T>,
49        T: ty::CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>;
50
51    fn mk_place_elems(self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List<mir::PlaceElem<'tcx>>;
52
53    fn adt_def(self, def_id: rustc_hir::def_id::DefId) -> ty::AdtDef<'tcx>;
54}
55
56/// Trait used to convert between an internal MIR type to a Stable MIR type.
57///
58/// This trait is currently exposed to users so they can have interoperability between internal MIR
59/// and StableMIR constructs. However, they should be used seldom and they have no influence
60/// in this crate semver.
61#[doc(hidden)]
62pub trait Stable<'tcx>: PointeeSized {
63    /// The stable representation of the type implementing Stable.
64    type T;
65    /// Converts an object to the equivalent Stable MIR representation.
66    fn stable<'cx>(
67        &self,
68        tables: &mut Tables<'cx, BridgeTys>,
69        cx: &SmirCtxt<'cx, BridgeTys>,
70    ) -> Self::T;
71}
72
73/// Trait used to translate a stable construct to its rustc counterpart.
74///
75/// This is basically a mirror of [Stable].
76///
77/// This trait is currently exposed to users so they can have interoperability between internal MIR
78/// and StableMIR constructs. They should be used seldom as they have no stability guarantees.
79#[doc(hidden)]
80pub trait RustcInternal {
81    type T<'tcx>;
82    fn internal<'tcx>(
83        &self,
84        tables: &mut Tables<'_, BridgeTys>,
85        tcx: impl InternalCx<'tcx>,
86    ) -> Self::T<'tcx>;
87}
88
89pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind {
90    match kind {
91        DefKind::Mod
92        | DefKind::Struct
93        | DefKind::Union
94        | DefKind::Enum
95        | DefKind::Variant
96        | DefKind::Trait
97        | DefKind::TyAlias
98        | DefKind::ForeignTy
99        | DefKind::TraitAlias
100        | DefKind::AssocTy
101        | DefKind::TyParam
102        | DefKind::ConstParam
103        | DefKind::Macro(_)
104        | DefKind::ExternCrate
105        | DefKind::Use
106        | DefKind::ForeignMod
107        | DefKind::OpaqueTy
108        | DefKind::Field
109        | DefKind::LifetimeParam
110        | DefKind::Impl { .. }
111        | DefKind::GlobalAsm => {
112            unreachable!("Not a valid item kind: {kind:?}");
113        }
114        DefKind::Closure | DefKind::AssocFn | DefKind::Fn | DefKind::SyntheticCoroutineBody => {
115            ItemKind::Fn
116        }
117        DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => {
118            ItemKind::Const
119        }
120        DefKind::Static { .. } => ItemKind::Static,
121        DefKind::Ctor(_, rustc_hir::def::CtorKind::Const) => ItemKind::Ctor(CtorKind::Const),
122        DefKind::Ctor(_, rustc_hir::def::CtorKind::Fn) => ItemKind::Ctor(CtorKind::Fn),
123    }
124}