@@ -344,9 +344,22 @@ impl Decodable for Ident {
344
344
}
345
345
}
346
346
347
- /// A symbol is an interned or gensymed string. The use of `newtype_index!` means
348
- /// that `Option<Symbol>` only takes up 4 bytes, because `newtype_index!` reserves
349
- /// the last 256 values for tagging purposes.
347
+ /// A symbol is an interned or gensymed string. A gensym is a symbol that is
348
+ /// never equal to any other symbol. E.g.:
349
+ /// ```
350
+ /// assert_eq!(Symbol::intern("x"), Symbol::intern("x"))
351
+ /// assert_ne!(Symbol::gensym("x"), Symbol::intern("x"))
352
+ /// assert_ne!(Symbol::gensym("x"), Symbol::gensym("x"))
353
+ /// ```
354
+ /// Conceptually, a gensym can be thought of as a normal symbol with an
355
+ /// invisible unique suffix. Gensyms are useful when creating new identifiers
356
+ /// that must not match any existing identifiers, e.g. during macro expansion
357
+ /// and syntax desugaring.
358
+ ///
359
+ /// Internally, a Symbol is implemented as an index, and all operations
360
+ /// (including hashing, equality, and ordering) operate on that index. The use
361
+ /// of `newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
362
+ /// because `newtype_index!` reserves the last 256 values for tagging purposes.
350
363
///
351
364
/// Note that `Symbol` cannot directly be a `newtype_index!` because it implements
352
365
/// `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
@@ -380,6 +393,7 @@ impl Symbol {
380
393
with_interner ( |interner| interner. gensymed ( self ) )
381
394
}
382
395
396
+ // WARNING: this function is deprecated and will be removed in the future.
383
397
pub fn is_gensymed ( self ) -> bool {
384
398
with_interner ( |interner| interner. is_gensymed ( self ) )
385
399
}
@@ -510,6 +524,8 @@ impl Interner {
510
524
symbol. 0 . as_usize ( ) >= self . strings . len ( )
511
525
}
512
526
527
+ // Get the symbol as a string. `Symbol::as_str()` should be used in
528
+ // preference to this function.
513
529
pub fn get ( & self , symbol : Symbol ) -> & str {
514
530
match self . strings . get ( symbol. 0 . as_usize ( ) ) {
515
531
Some ( string) => string,
@@ -614,11 +630,17 @@ fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
614
630
GLOBALS . with ( |globals| f ( & mut * globals. symbol_interner . lock ( ) ) )
615
631
}
616
632
617
- /// Represents a string stored in the interner. Because the interner outlives any thread
618
- /// which uses this type, we can safely treat `string` which points to interner data,
619
- /// as an immortal string, as long as this type never crosses between threads.
620
- // FIXME: ensure that the interner outlives any thread which uses `LocalInternedString`,
621
- // by creating a new thread right after constructing the interner.
633
+ /// An alternative to `Symbol` and `InternedString`, useful when the chars
634
+ /// within the symbol need to be accessed. It is best used for temporary
635
+ /// values.
636
+ ///
637
+ /// Because the interner outlives any thread which uses this type, we can
638
+ /// safely treat `string` which points to interner data, as an immortal string,
639
+ /// as long as this type never crosses between threads.
640
+ //
641
+ // FIXME: ensure that the interner outlives any thread which uses
642
+ // `LocalInternedString`, by creating a new thread right after constructing the
643
+ // interner.
622
644
#[ derive( Clone , Copy , Hash , PartialOrd , Eq , Ord ) ]
623
645
pub struct LocalInternedString {
624
646
string : & ' static str ,
@@ -711,7 +733,19 @@ impl Encodable for LocalInternedString {
711
733
}
712
734
}
713
735
714
- /// Represents a string stored in the string interner.
736
+ /// An alternative to `Symbol` that is focused on string contents. It has two
737
+ /// main differences to `Symbol`.
738
+ ///
739
+ /// First, its implementations of `Hash`, `PartialOrd` and `Ord` work with the
740
+ /// string chars rather than the symbol integer. This is useful when hash
741
+ /// stability is required across compile sessions, or a guaranteed sort
742
+ /// ordering is required.
743
+ ///
744
+ /// Second, gensym-ness is irrelevant. E.g.:
745
+ /// ```
746
+ /// assert_ne!(Symbol::gensym("x"), Symbol::gensym("x"))
747
+ /// assert_eq!(Symbol::gensym("x").as_interned_str(), Symbol::gensym("x").as_interned_str())
748
+ /// ```
715
749
#[ derive( Clone , Copy , Eq ) ]
716
750
pub struct InternedString {
717
751
symbol : Symbol ,
0 commit comments