@@ -15,7 +15,7 @@ use std::fmt;
15
15
use std:: hash:: { Hash , Hasher } ;
16
16
use std:: str;
17
17
18
- use crate :: { Span , DUMMY_SP , GLOBALS } ;
18
+ use crate :: { Span , SyntaxContext , DUMMY_SP , GLOBALS } ;
19
19
20
20
#[ cfg( test) ]
21
21
mod tests;
@@ -803,15 +803,14 @@ impl Ident {
803
803
Ident :: new ( self . name , self . span . modern_and_legacy ( ) )
804
804
}
805
805
806
- /// Transforms an underscore identifier into one with the same name, but
807
- /// gensymed. Leaves non-underscore identifiers unchanged.
808
- pub fn gensym_if_underscore ( self ) -> Ident {
806
+ /// If the name of this ident is "_", then return a new unique identifier.
807
+ /// Otherwise returns `self` unmodified
808
+ #[ inline]
809
+ pub fn unique_if_underscore ( mut self ) -> Ident {
809
810
if self . name == kw:: Underscore {
810
- let name = with_interner ( |interner| interner. gensymed ( self . name ) ) ;
811
- Ident :: new ( name, self . span )
812
- } else {
813
- self
811
+ self . span = self . span . with_ctxt ( SyntaxContext :: unique ( self . span ) ) ;
814
812
}
813
+ self
815
814
}
816
815
817
816
/// Convert the name to a `LocalInternedString`. This is a slowish
@@ -820,8 +819,7 @@ impl Ident {
820
819
self . name . as_str ( )
821
820
}
822
821
823
- /// Convert the name to an `InternedString`. This is a slowish operation
824
- /// because it requires locking the symbol interner.
822
+ /// Convert the name to an `InternedString`.
825
823
pub fn as_interned_str ( self ) -> InternedString {
826
824
self . name . as_interned_str ( )
827
825
}
@@ -876,26 +874,9 @@ impl UseSpecializedDecodable for Ident {
876
874
}
877
875
}
878
876
879
- /// A symbol is an interned or gensymed string. A gensym is a symbol that is
880
- /// never equal to any other symbol.
881
- ///
882
- /// Conceptually, a gensym can be thought of as a normal symbol with an
883
- /// invisible unique suffix. Gensyms are useful when creating new identifiers
884
- /// that must not match any existing identifiers, e.g. during macro expansion
885
- /// and syntax desugaring. Because gensyms should always be identifiers, all
886
- /// gensym operations are on `Ident` rather than `Symbol`. (Indeed, in the
887
- /// future the gensym-ness may be moved from `Symbol` to hygiene data.)
877
+ /// An interned string.
888
878
///
889
- /// Examples:
890
- /// ```
891
- /// assert_eq!(Ident::from_str("_"), Ident::from_str("_"))
892
- /// assert_ne!(Ident::from_str("_").gensym_if_underscore(), Ident::from_str("_"))
893
- /// assert_ne!(
894
- /// Ident::from_str("_").gensym_if_underscore(),
895
- /// Ident::from_str("_").gensym_if_underscore(),
896
- /// )
897
- /// ```
898
- /// Internally, a symbol is implemented as an index, and all operations
879
+ /// Internally, a `Symbol` is implemented as an index, and all operations
899
880
/// (including hashing, equality, and ordering) operate on that index. The use
900
881
/// of `newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
901
882
/// because `newtype_index!` reserves the last 256 values for tagging purposes.
@@ -946,12 +927,9 @@ impl Symbol {
946
927
} )
947
928
}
948
929
949
- /// Convert to an `InternedString`. This is a slowish operation because it
950
- /// requires locking the symbol interner.
930
+ /// Convert to an `InternedString`.
951
931
pub fn as_interned_str ( self ) -> InternedString {
952
- with_interner ( |interner| InternedString {
953
- symbol : interner. interned ( self )
954
- } )
932
+ InternedString { symbol : self }
955
933
}
956
934
957
935
pub fn as_u32 ( self ) -> u32 {
@@ -961,12 +939,7 @@ impl Symbol {
961
939
962
940
impl fmt:: Debug for Symbol {
963
941
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
964
- let is_gensymed = with_interner ( |interner| interner. is_gensymed ( * self ) ) ;
965
- if is_gensymed {
966
- write ! ( f, "{}({:?})" , self , self . 0 )
967
- } else {
968
- write ! ( f, "{}" , self )
969
- }
942
+ fmt:: Display :: fmt ( self , f)
970
943
}
971
944
}
972
945
@@ -989,15 +962,11 @@ impl Decodable for Symbol {
989
962
}
990
963
991
964
// The `&'static str`s in this type actually point into the arena.
992
- //
993
- // Note that normal symbols are indexed upward from 0, and gensyms are indexed
994
- // downward from SymbolIndex::MAX_AS_U32.
995
965
#[ derive( Default ) ]
996
966
pub struct Interner {
997
967
arena : DroplessArena ,
998
968
names : FxHashMap < & ' static str , Symbol > ,
999
969
strings : Vec < & ' static str > ,
1000
- gensyms : Vec < Symbol > ,
1001
970
}
1002
971
1003
972
impl Interner {
@@ -1030,34 +999,10 @@ impl Interner {
1030
999
self . names . insert ( string, name) ;
1031
1000
name
1032
1001
}
1033
-
1034
- fn interned ( & self , symbol : Symbol ) -> Symbol {
1035
- if ( symbol. 0 . as_usize ( ) ) < self . strings . len ( ) {
1036
- symbol
1037
- } else {
1038
- self . gensyms [ ( SymbolIndex :: MAX_AS_U32 - symbol. 0 . as_u32 ( ) ) as usize ]
1039
- }
1040
- }
1041
-
1042
- fn gensymed ( & mut self , symbol : Symbol ) -> Symbol {
1043
- self . gensyms . push ( symbol) ;
1044
- Symbol :: new ( SymbolIndex :: MAX_AS_U32 - self . gensyms . len ( ) as u32 + 1 )
1045
- }
1046
-
1047
- fn is_gensymed ( & mut self , symbol : Symbol ) -> bool {
1048
- symbol. 0 . as_usize ( ) >= self . strings . len ( )
1049
- }
1050
-
1051
1002
// Get the symbol as a string. `Symbol::as_str()` should be used in
1052
1003
// preference to this function.
1053
1004
pub fn get ( & self , symbol : Symbol ) -> & str {
1054
- match self . strings . get ( symbol. 0 . as_usize ( ) ) {
1055
- Some ( string) => string,
1056
- None => {
1057
- let symbol = self . gensyms [ ( SymbolIndex :: MAX_AS_U32 - symbol. 0 . as_u32 ( ) ) as usize ] ;
1058
- self . strings [ symbol. 0 . as_usize ( ) ]
1059
- }
1060
- }
1005
+ self . strings [ symbol. 0 . as_usize ( ) ]
1061
1006
}
1062
1007
}
1063
1008
@@ -1242,19 +1187,12 @@ impl fmt::Display for LocalInternedString {
1242
1187
}
1243
1188
}
1244
1189
1245
- /// An alternative to `Symbol` that is focused on string contents. It has two
1246
- /// main differences to `Symbol`.
1190
+ /// An alternative to `Symbol` that is focused on string contents.
1247
1191
///
1248
- /// First, its implementations of `Hash`, `PartialOrd` and `Ord` work with the
1192
+ /// Its implementations of `Hash`, `PartialOrd` and `Ord` work with the
1249
1193
/// string chars rather than the symbol integer. This is useful when hash
1250
1194
/// stability is required across compile sessions, or a guaranteed sort
1251
1195
/// ordering is required.
1252
- ///
1253
- /// Second, gensym-ness is irrelevant. E.g.:
1254
- /// ```
1255
- /// assert_ne!(Symbol::gensym("x"), Symbol::gensym("x"))
1256
- /// assert_eq!(Symbol::gensym("x").as_interned_str(), Symbol::gensym("x").as_interned_str())
1257
- /// ```
1258
1196
#[ derive( Clone , Copy , PartialEq , Eq ) ]
1259
1197
pub struct InternedString {
1260
1198
symbol : Symbol ,
0 commit comments