@@ -344,9 +344,22 @@ impl Decodable for Ident {
344344 }
345345}
346346
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.
350363///
351364/// Note that `Symbol` cannot directly be a `newtype_index!` because it implements
352365/// `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
@@ -380,6 +393,7 @@ impl Symbol {
380393 with_interner ( |interner| interner. gensymed ( self ) )
381394 }
382395
396+ // WARNING: this function is deprecated and will be removed in the future.
383397 pub fn is_gensymed ( self ) -> bool {
384398 with_interner ( |interner| interner. is_gensymed ( self ) )
385399 }
@@ -510,6 +524,8 @@ impl Interner {
510524 symbol. 0 . as_usize ( ) >= self . strings . len ( )
511525 }
512526
527+ // Get the symbol as a string. `Symbol::as_str()` should be used in
528+ // preference to this function.
513529 pub fn get ( & self , symbol : Symbol ) -> & str {
514530 match self . strings . get ( symbol. 0 . as_usize ( ) ) {
515531 Some ( string) => string,
@@ -614,11 +630,17 @@ fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
614630 GLOBALS . with ( |globals| f ( & mut * globals. symbol_interner . lock ( ) ) )
615631}
616632
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.
622644#[ derive( Clone , Copy , Hash , PartialOrd , Eq , Ord ) ]
623645pub struct LocalInternedString {
624646 string : & ' static str ,
@@ -711,7 +733,19 @@ impl Encodable for LocalInternedString {
711733 }
712734}
713735
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+ /// ```
715749#[ derive( Clone , Copy , Eq ) ]
716750pub struct InternedString {
717751 symbol : Symbol ,
0 commit comments