@@ -18,7 +18,7 @@ use crate::prelude::*;
18
18
use crate :: { AdtInto , JsonSchema } ;
19
19
20
20
#[ cfg( feature = "rustc" ) ]
21
- use { rustc_hir as hir, rustc_span :: def_id:: DefId as RDefId } ;
21
+ use { rustc_hir as hir, rustc_hir :: def_id:: DefId as RDefId , rustc_middle :: ty } ;
22
22
23
23
pub type Symbol = String ;
24
24
@@ -72,10 +72,29 @@ pub enum MacroKind {
72
72
Derive ,
73
73
}
74
74
75
+ /// The id of a promoted MIR constant.
76
+ ///
77
+ /// Reflects [`rustc_middle::mir::Promoted`].
78
+ #[ derive_group( Serializers ) ]
79
+ #[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
80
+ #[ cfg_attr( not( feature = "extract_names_mode" ) , derive( JsonSchema , AdtInto ) ) ]
81
+ #[ cfg_attr( not( feature = "extract_names_mode" ) , args( <S >, from: rustc_middle:: mir:: Promoted , state: S as _s) ) ]
82
+ pub struct PromotedId {
83
+ #[ cfg_attr( not( feature = "extract_names_mode" ) , value( self . as_u32( ) ) ) ]
84
+ pub id : u32 ,
85
+ }
86
+
87
+ #[ cfg( feature = "rustc" ) ]
88
+ impl PromotedId {
89
+ pub fn as_rust_promoted_id ( & self ) -> rustc_middle:: mir:: Promoted {
90
+ rustc_middle:: mir:: Promoted :: from_u32 ( self . id )
91
+ }
92
+ }
93
+
75
94
/// Reflects [`rustc_hir::def::DefKind`]
76
95
#[ derive_group( Serializers ) ]
77
96
#[ cfg_attr( not( feature = "extract_names_mode" ) , derive( JsonSchema , AdtInto ) ) ]
78
- #[ cfg_attr( not( feature = "extract_names_mode" ) , args( <S >, from: rustc_hir:: def:: DefKind , state: S as tcx) ) ]
97
+ #[ cfg_attr( not( feature = "extract_names_mode" ) , args( <S >, from: rustc_hir:: def:: DefKind , state: S as tcx) ) ]
79
98
#[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
80
99
pub enum DefKind {
81
100
Mod ,
@@ -106,6 +125,9 @@ pub enum DefKind {
106
125
ForeignMod ,
107
126
AnonConst ,
108
127
InlineConst ,
128
+ #[ cfg_attr( not( feature = "extract_names_mode" ) , disable_mapping) ]
129
+ /// Added by hax: promoted constants don't have def_ids in rustc but they do in hax.
130
+ PromotedConst ,
109
131
OpaqueTy ,
110
132
Field ,
111
133
LifetimeParam ,
@@ -117,7 +139,8 @@ pub enum DefKind {
117
139
SyntheticCoroutineBody ,
118
140
}
119
141
120
- /// Reflects [`rustc_hir::def_id::DefId`]
142
+ /// Reflects [`rustc_hir::def_id::DefId`], augmented to also give ids to promoted constants (which
143
+ /// have their own ad-hoc numbering scheme in rustc for now).
121
144
#[ derive_group( Serializers ) ]
122
145
#[ derive( Clone , PartialEq , Eq , PartialOrd , Ord ) ]
123
146
#[ cfg_attr( not( feature = "extract_names_mode" ) , derive( JsonSchema ) ) ]
@@ -132,30 +155,52 @@ pub struct DefIdContents {
132
155
pub krate : String ,
133
156
pub path : Vec < DisambiguatedDefPathItem > ,
134
157
pub parent : Option < DefId > ,
135
- /// Rustc 's `CrateNum` and `DefIndex ` raw indexes . This can be
136
- /// useful if one needs to convert a [`DefId`] into a
137
- /// [`rustc_hir::def_id::DefId`]; there is a `From` instance for
138
- /// that purpose .
158
+ /// Stores rustc 's `CrateNum`, `DefIndex` and `Promoted ` raw indices . This can be useful if one
159
+ /// needs to convert a [`DefId`] into a [`rustc_hir::def_id::DefId`]. If the promoted id is
160
+ /// `Some`, then this `DefId` indicates the nth promoted constant associated with the item,
161
+ /// which doesn't have a real `rustc::DefId` .
139
162
///
140
- /// **Warning: this `index` field might not be safe to use**. They are
141
- /// valid only for one Rustc sesssion. Please do not rely on those
142
- /// indexes unless you cannot do otherwise.
143
- pub index : ( u32 , u32 ) ,
163
+ /// **Warning: this `index` field might not be safe to use**. They are valid only for one Rustc
164
+ /// sesssion. Please do not rely on those indices unless you cannot do otherwise.
165
+ pub index : ( u32 , u32 , Option < PromotedId > ) ,
144
166
pub is_local : bool ,
145
167
146
168
/// The kind of definition this `DefId` points to.
147
169
pub kind : crate :: DefKind ,
148
170
}
149
171
172
+ #[ cfg( feature = "rustc" ) ]
173
+ impl DefIdContents {
174
+ pub fn make_def_id < ' tcx , S : BaseState < ' tcx > > ( self , s : & S ) -> DefId {
175
+ let contents =
176
+ s. with_global_cache ( |cache| id_table:: Node :: new ( self , & mut cache. id_table_session ) ) ;
177
+ DefId { contents }
178
+ }
179
+ }
180
+
150
181
#[ cfg( feature = "rustc" ) ]
151
182
impl DefId {
152
- pub fn to_rust_def_id ( & self ) -> RDefId {
153
- let ( krate, index) = self . index ;
183
+ /// The rustc def_id corresponding to this item, if there is one. Promoted constants don't have
184
+ /// a rustc def_id.
185
+ pub fn as_rust_def_id ( & self ) -> Option < RDefId > {
186
+ let ( _, _, promoted) = self . index ;
187
+ match promoted {
188
+ None => Some ( self . underlying_rust_def_id ( ) ) ,
189
+ Some ( _) => None ,
190
+ }
191
+ }
192
+ /// The def_id of this item or its parent if this is a promoted constant.
193
+ pub fn underlying_rust_def_id ( & self ) -> RDefId {
194
+ let ( krate, index, _) = self . index ;
154
195
RDefId {
155
196
krate : rustc_hir:: def_id:: CrateNum :: from_u32 ( krate) ,
156
197
index : rustc_hir:: def_id:: DefIndex :: from_u32 ( index) ,
157
198
}
158
199
}
200
+ pub fn promoted_id ( & self ) -> Option < PromotedId > {
201
+ let ( _, _, promoted) = self . index ;
202
+ promoted
203
+ }
159
204
160
205
/// Iterate over this element and its parents.
161
206
pub fn ancestry ( & self ) -> impl Iterator < Item = & Self > {
@@ -174,6 +219,31 @@ impl DefId {
174
219
} ,
175
220
} )
176
221
}
222
+
223
+ /// Construct a hax `DefId` for the nth promoted constant of the current item. That `DefId` has
224
+ /// no corresponding rustc `DefId`.
225
+ pub fn make_promoted_child < ' tcx , S : BaseState < ' tcx > > (
226
+ & self ,
227
+ s : & S ,
228
+ promoted_id : PromotedId ,
229
+ ) -> Self {
230
+ let mut path = self . path . clone ( ) ;
231
+ path. push ( DisambiguatedDefPathItem {
232
+ data : DefPathItem :: PromotedConst ,
233
+ // Reuse the promoted id as disambiguator, like for inline consts.
234
+ disambiguator : promoted_id. id ,
235
+ } ) ;
236
+ let ( krate, index, _) = self . index ;
237
+ let contents = DefIdContents {
238
+ krate : self . krate . clone ( ) ,
239
+ path,
240
+ parent : Some ( self . clone ( ) ) ,
241
+ is_local : self . is_local ,
242
+ index : ( krate, index, Some ( promoted_id) ) ,
243
+ kind : DefKind :: PromotedConst ,
244
+ } ;
245
+ contents. make_def_id ( s)
246
+ }
177
247
}
178
248
179
249
impl std:: ops:: Deref for DefId {
@@ -197,7 +267,11 @@ impl std::fmt::Debug for DefId {
197
267
impl std:: fmt:: Debug for DefId {
198
268
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
199
269
// Use the more legible rustc debug implementation.
200
- write ! ( f, "{:?}" , rustc_span:: def_id:: DefId :: from( self ) )
270
+ write ! ( f, "{:?}" , self . underlying_rust_def_id( ) ) ?;
271
+ if let Some ( promoted) = self . promoted_id ( ) {
272
+ write ! ( f, "::promoted#{}" , promoted. id) ?;
273
+ }
274
+ Ok ( ( ) )
201
275
}
202
276
}
203
277
@@ -210,6 +284,18 @@ impl std::hash::Hash for DefId {
210
284
}
211
285
}
212
286
287
+ /// Gets the kind of the definition. Can't use `def_kind` directly because this crashes on the
288
+ /// crate root.
289
+ #[ cfg( feature = "rustc" ) ]
290
+ pub ( crate ) fn get_def_kind < ' tcx > ( tcx : ty:: TyCtxt < ' tcx > , def_id : RDefId ) -> hir:: def:: DefKind {
291
+ if def_id == rustc_span:: def_id:: CRATE_DEF_ID . to_def_id ( ) {
292
+ // Horrible hack: without this, `def_kind` crashes on the crate root. Presumably some table
293
+ // isn't properly initialized otherwise.
294
+ let _ = tcx. def_span ( def_id) ;
295
+ } ;
296
+ tcx. def_kind ( def_id)
297
+ }
298
+
213
299
#[ cfg( feature = "rustc" ) ]
214
300
pub ( crate ) fn translate_def_id < ' tcx , S : BaseState < ' tcx > > ( s : & S , def_id : RDefId ) -> DefId {
215
301
let tcx = s. base ( ) . tcx ;
@@ -229,13 +315,12 @@ pub(crate) fn translate_def_id<'tcx, S: BaseState<'tcx>>(s: &S, def_id: RDefId)
229
315
index : (
230
316
rustc_hir:: def_id:: CrateNum :: as_u32 ( def_id. krate ) ,
231
317
rustc_hir:: def_id:: DefIndex :: as_u32 ( def_id. index ) ,
318
+ None ,
232
319
) ,
233
320
is_local : def_id. is_local ( ) ,
234
- kind : tcx . def_kind ( def_id) . sinto ( s) ,
321
+ kind : get_def_kind ( tcx , def_id) . sinto ( s) ,
235
322
} ;
236
- let contents =
237
- s. with_global_cache ( |cache| id_table:: Node :: new ( contents, & mut cache. id_table_session ) ) ;
238
- DefId { contents }
323
+ contents. make_def_id ( s)
239
324
}
240
325
241
326
#[ cfg( all( not( feature = "extract_names_mode" ) , feature = "rustc" ) ) ]
@@ -250,21 +335,6 @@ impl<'s, S: BaseState<'s>> SInto<S, DefId> for RDefId {
250
335
}
251
336
}
252
337
253
- #[ cfg( feature = "rustc" ) ]
254
- impl From < & DefId > for RDefId {
255
- fn from < ' tcx > ( def_id : & DefId ) -> Self {
256
- def_id. to_rust_def_id ( )
257
- }
258
- }
259
-
260
- // Impl to be able to use hax's `DefId` for many rustc queries.
261
- #[ cfg( feature = "rustc" ) ]
262
- impl rustc_middle:: query:: IntoQueryParam < RDefId > for & DefId {
263
- fn into_query_param ( self ) -> RDefId {
264
- self . into ( )
265
- }
266
- }
267
-
268
338
#[ cfg( not( feature = "extract_names_mode" ) ) ]
269
339
pub type Path = Vec < String > ;
270
340
@@ -315,6 +385,8 @@ pub enum DefPathItem {
315
385
Closure ,
316
386
Ctor ,
317
387
AnonConst ,
388
+ #[ cfg_attr( not( feature = "extract_names_mode" ) , disable_mapping) ]
389
+ PromotedConst ,
318
390
OpaqueTy ,
319
391
}
320
392
0 commit comments