hax_frontend_exporter/
rustc_utils.rs1use crate::prelude::*;
2use rustc_middle::ty;
3
4#[extension_traits::extension(pub trait SubstBinder)]
5impl<'tcx, T: ty::TypeFoldable<ty::TyCtxt<'tcx>>> ty::Binder<'tcx, T> {
6 fn subst(
7 self,
8 tcx: ty::TyCtxt<'tcx>,
9 generics: &[ty::GenericArg<'tcx>],
10 ) -> ty::Binder<'tcx, T> {
11 ty::EarlyBinder::bind(self).instantiate(tcx, generics)
12 }
13}
14
15#[tracing::instrument(skip(s))]
16pub(crate) fn get_variant_information<'s, S: UnderOwnerState<'s>>(
17 adt_def: &ty::AdtDef<'s>,
18 variant_index: rustc_abi::VariantIdx,
19 s: &S,
20) -> VariantInformations {
21 fn is_named<'s, I: std::iter::Iterator<Item = &'s ty::FieldDef> + Clone>(it: I) -> bool {
22 it.clone()
23 .any(|field| field.name.to_ident_string().parse::<u64>().is_err())
24 }
25 let variant_def = adt_def.variant(variant_index);
26 let variant = variant_def.def_id;
27 let constructs_type: DefId = adt_def.did().sinto(s);
28 let kind = if adt_def.is_struct() {
29 let named = is_named(adt_def.all_fields());
30 VariantKind::Struct { named }
31 } else if adt_def.is_union() {
32 VariantKind::Union
33 } else {
34 let named = is_named(variant_def.fields.iter());
35 let index = variant_index.into();
36 VariantKind::Enum { index, named }
37 };
38 VariantInformations {
39 typ: constructs_type.clone(),
40 variant: variant.sinto(s),
41 kind,
42 type_namespace: match &constructs_type.parent {
43 Some(parent) => parent.clone(),
44 None => {
45 let span = s.base().tcx.def_span(variant);
46 fatal!(
47 s[span],
48 "Type {:#?} appears to have no parent",
49 constructs_type
50 )
51 }
52 },
53 }
54}
55
56#[tracing::instrument(skip(sess))]
57pub fn translate_span(span: rustc_span::Span, sess: &rustc_session::Session) -> Span {
58 let smap: &rustc_span::source_map::SourceMap = sess.psess.source_map();
59 let filename = smap.span_to_filename(span);
60
61 let lo = smap.lookup_char_pos(span.lo());
62 let hi = smap.lookup_char_pos(span.hi());
63
64 Span {
65 lo: lo.into(),
66 hi: hi.into(),
67 filename: filename.sinto(&()),
68 rust_span_data: Some(span.data()),
69 }
70}
71
72pub trait HasParamEnv<'tcx> {
73 fn param_env(&self) -> ty::ParamEnv<'tcx>;
74 fn typing_env(&self) -> ty::TypingEnv<'tcx>;
75}
76
77impl<'tcx, S: UnderOwnerState<'tcx>> HasParamEnv<'tcx> for S {
78 fn param_env(&self) -> ty::ParamEnv<'tcx> {
79 self.base().tcx.param_env(self.owner_id())
80 }
81 fn typing_env(&self) -> ty::TypingEnv<'tcx> {
82 ty::TypingEnv {
83 param_env: self.param_env(),
84 typing_mode: ty::TypingMode::PostAnalysis,
85 }
86 }
87}
88
89#[tracing::instrument(skip(s))]
90pub(crate) fn attribute_from_scope<'tcx, S: ExprState<'tcx>>(
91 s: &S,
92 scope: &rustc_middle::middle::region::Scope,
93) -> (Option<rustc_hir::hir_id::HirId>, Vec<Attribute>) {
94 let owner = s.owner_id();
95 let tcx = s.base().tcx;
96 let scope_tree = tcx.region_scope_tree(owner);
97 let hir_id = scope.hir_id(scope_tree);
98 let tcx = s.base().tcx;
99 let attributes = hir_id
100 .map(|hir_id| tcx.hir_attrs(hir_id).sinto(s))
101 .unwrap_or_default();
102 (hir_id, attributes)
103}
104
105pub fn get_closest_parent_type(
107 tcx: &ty::TyCtxt,
108 id: rustc_span::def_id::DefId,
109) -> rustc_span::def_id::DefId {
110 match tcx.def_kind(id) {
111 rustc_hir::def::DefKind::Union
112 | rustc_hir::def::DefKind::Struct
113 | rustc_hir::def::DefKind::Enum => id,
114 _ => get_closest_parent_type(tcx, tcx.parent(id)),
115 }
116}