@@ -90,12 +90,9 @@ pub struct Definitions {
90
90
parent_modules_of_macro_defs : FxHashMap < ExpnId , DefId > ,
91
91
/// Item with a given `DefIndex` was defined during macro expansion with ID `ExpnId`.
92
92
expansions_that_defined : FxHashMap < DefIndex , ExpnId > ,
93
- // Keeps track of the current disambiguator for a given (DefIndex, DefPathData)
94
- // Note that we replace any `Spans` (e.g. in `Ident`) with `DUMMY_SP` before
95
- // inserting a `DefPathData`. This ensures that we create a new disambiguator
96
- // for definitions that have the same name, but different spans (e.g. definitions
97
- // created by a macro invocation).
98
- next_disambiguator : FxHashMap < ( DefIndex , DefPathData ) , u32 > ,
93
+ // We use a `PlainDefPathData` instead of `DefPathData` so that we don't
94
+ // consider `Span`s (from `Ident`) when hashing or comparing
95
+ next_disambiguator : FxHashMap < ( DefIndex , PlainDefPathData ) , u32 > ,
99
96
def_index_to_span : FxHashMap < DefIndex , Span > ,
100
97
/// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId`
101
98
/// we know what parent node that fragment should be attached to thanks to this table.
@@ -107,7 +104,7 @@ pub struct Definitions {
107
104
/// A unique identifier that we can use to lookup a definition
108
105
/// precisely. It combines the index of the definition's parent (if
109
106
/// any) with a `DisambiguatedDefPathData`.
110
- #[ derive( Copy , Clone , PartialEq , Debug , RustcEncodable , RustcDecodable ) ]
107
+ #[ derive( Copy , Clone , Debug , RustcEncodable , RustcDecodable ) ]
111
108
pub struct DefKey {
112
109
/// The parent path.
113
110
pub parent : Option < DefIndex > ,
@@ -158,7 +155,7 @@ impl DefKey {
158
155
/// between them. This introduces some artificial ordering dependency
159
156
/// but means that if you have, e.g., two impls for the same type in
160
157
/// the same module, they do get distinct `DefId`s.
161
- #[ derive( Copy , Clone , PartialEq , Debug , RustcEncodable , RustcDecodable ) ]
158
+ #[ derive( Copy , Clone , Debug , RustcEncodable , RustcDecodable ) ]
162
159
pub struct DisambiguatedDefPathData {
163
160
pub data : DefPathData ,
164
161
pub disambiguator : u32 ,
@@ -261,7 +258,39 @@ impl DefPath {
261
258
}
262
259
}
263
260
264
- #[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
261
+ // A copy of `DefPathData`, but with `Symbol` substituted for `Ident`.
262
+ // We want to implement `Hash`, `Eq`, and `PartialEq` for this struct,
263
+ // but not for `DefPathData`. This prevents us from doing something like
264
+ // ```enum BaseDefPathData<T> { ... }, type DefPathData = BaseDefPathData<Ident>```
265
+ //, as `DefPathData` would end up implementing `Hash`, `Eq`, and `PartialEq` due to
266
+ // the `#[derive] macros we would need to place on `BaseDefPathData`.
267
+ //
268
+ // This could be fixed by switching to the `derivative` crate, which allows
269
+ // custom bounds to be applied to parameters in the generated impls.
270
+ // This would allow us to write `trait IsSymbol {}; impl IsSymbol for Symbol {}`.
271
+ // and add a `T: IsSymbol` bound to the `derivative` impls on `PlainDefPathData`.
272
+ //
273
+ // For now, this small amount of duplication (which is invisible outside of this module)
274
+ // isn't worth pulling in an extra dependency.
275
+ #[ derive( Eq , PartialEq , Hash , Clone , Copy ) ]
276
+ enum PlainDefPathData {
277
+ CrateRoot ,
278
+ Misc ,
279
+ Impl ,
280
+ TypeNs ( Symbol ) ,
281
+ ValueNs ( Symbol ) ,
282
+ MacroNs ( Symbol ) ,
283
+ LifetimeNs ( Symbol ) ,
284
+ ClosureExpr ,
285
+ Ctor ,
286
+ AnonConst ,
287
+ ImplTrait ,
288
+ }
289
+
290
+ // We intentionally do *not* derive `Eq`, `PartialEq`, and `Hash`:
291
+ // this would cause us to hash/compare using the `Span` from the `Ident`,
292
+ // which is almost never correct.
293
+ #[ derive( Copy , Clone , Debug , RustcEncodable , RustcDecodable ) ]
265
294
pub enum DefPathData {
266
295
// Root: these should only be used for the root nodes, because
267
296
// they are treated specially by the `def_path` function.
@@ -435,14 +464,12 @@ impl Definitions {
435
464
) ;
436
465
437
466
// The root node must be created with `create_root_def()`.
438
- assert ! ( data != DefPathData :: CrateRoot ) ;
467
+ assert ! ( ! ( matches! ( data, DefPathData :: CrateRoot ) ) ) ;
439
468
440
469
// Find the next free disambiguator for this key.
441
470
let disambiguator = {
442
- // Replace any span with `DUMMY_SP` - two definitions which differ
443
- // only in their spans still need to be disambiguated.
444
- let data_dummy_span = data. with_dummy_span ( ) ;
445
- let next_disamb = self . next_disambiguator . entry ( ( parent, data_dummy_span) ) . or_insert ( 0 ) ;
471
+ let plain_data = data. to_plain ( ) ;
472
+ let next_disamb = self . next_disambiguator . entry ( ( parent, plain_data) ) . or_insert ( 0 ) ;
446
473
let disambiguator = * next_disamb;
447
474
* next_disamb = next_disamb. checked_add ( 1 ) . expect ( "disambiguator overflow" ) ;
448
475
disambiguator
@@ -532,16 +559,20 @@ impl Definitions {
532
559
}
533
560
534
561
impl DefPathData {
535
- /// Replaces any `Spans` contains in this `DefPathData` with `DUMMY_SP`.
536
- /// Useful when using a `DefPathData` as a cache key.
537
- pub fn with_dummy_span ( & self ) -> DefPathData {
562
+ fn to_plain ( & self ) -> PlainDefPathData {
538
563
use self :: DefPathData :: * ;
539
564
match * self {
540
- TypeNs ( name) => TypeNs ( Ident :: with_dummy_span ( name. name ) ) ,
541
- ValueNs ( name) => ValueNs ( Ident :: with_dummy_span ( name. name ) ) ,
542
- MacroNs ( name) => MacroNs ( Ident :: with_dummy_span ( name. name ) ) ,
543
- LifetimeNs ( name) => LifetimeNs ( Ident :: with_dummy_span ( name. name ) ) ,
544
- CrateRoot | Misc | Impl | ClosureExpr | Ctor | AnonConst | ImplTrait => * self ,
565
+ TypeNs ( name) => PlainDefPathData :: TypeNs ( name. name ) ,
566
+ ValueNs ( name) => PlainDefPathData :: ValueNs ( name. name ) ,
567
+ MacroNs ( name) => PlainDefPathData :: MacroNs ( name. name ) ,
568
+ LifetimeNs ( name) => PlainDefPathData :: LifetimeNs ( name. name ) ,
569
+ CrateRoot => PlainDefPathData :: CrateRoot ,
570
+ Misc => PlainDefPathData :: Misc ,
571
+ Impl => PlainDefPathData :: Impl ,
572
+ ClosureExpr => PlainDefPathData :: ClosureExpr ,
573
+ Ctor => PlainDefPathData :: Ctor ,
574
+ AnonConst => PlainDefPathData :: AnonConst ,
575
+ ImplTrait => PlainDefPathData :: ImplTrait ,
545
576
}
546
577
}
547
578
0 commit comments