@@ -90,12 +90,9 @@ pub struct Definitions {
9090 parent_modules_of_macro_defs : FxHashMap < ExpnId , DefId > ,
9191 /// Item with a given `DefIndex` was defined during macro expansion with ID `ExpnId`.
9292 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 > ,
9996 def_index_to_span : FxHashMap < DefIndex , Span > ,
10097 /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId`
10198 /// we know what parent node that fragment should be attached to thanks to this table.
@@ -107,7 +104,7 @@ pub struct Definitions {
107104/// A unique identifier that we can use to lookup a definition
108105/// precisely. It combines the index of the definition's parent (if
109106/// any) with a `DisambiguatedDefPathData`.
110- #[ derive( Copy , Clone , PartialEq , Debug , RustcEncodable , RustcDecodable ) ]
107+ #[ derive( Copy , Clone , Debug , RustcEncodable , RustcDecodable ) ]
111108pub struct DefKey {
112109 /// The parent path.
113110 pub parent : Option < DefIndex > ,
@@ -158,7 +155,7 @@ impl DefKey {
158155/// between them. This introduces some artificial ordering dependency
159156/// but means that if you have, e.g., two impls for the same type in
160157/// the same module, they do get distinct `DefId`s.
161- #[ derive( Copy , Clone , PartialEq , Debug , RustcEncodable , RustcDecodable ) ]
158+ #[ derive( Copy , Clone , Debug , RustcEncodable , RustcDecodable ) ]
162159pub struct DisambiguatedDefPathData {
163160 pub data : DefPathData ,
164161 pub disambiguator : u32 ,
@@ -261,7 +258,39 @@ impl DefPath {
261258 }
262259}
263260
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 ) ]
265294pub enum DefPathData {
266295 // Root: these should only be used for the root nodes, because
267296 // they are treated specially by the `def_path` function.
@@ -435,14 +464,12 @@ impl Definitions {
435464 ) ;
436465
437466 // The root node must be created with `create_root_def()`.
438- assert ! ( data != DefPathData :: CrateRoot ) ;
467+ assert ! ( ! ( matches! ( data, DefPathData :: CrateRoot ) ) ) ;
439468
440469 // Find the next free disambiguator for this key.
441470 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 ) ;
446473 let disambiguator = * next_disamb;
447474 * next_disamb = next_disamb. checked_add ( 1 ) . expect ( "disambiguator overflow" ) ;
448475 disambiguator
@@ -532,16 +559,20 @@ impl Definitions {
532559}
533560
534561impl 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 {
538563 use self :: DefPathData :: * ;
539564 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 ,
545576 }
546577 }
547578
0 commit comments