@@ -1716,8 +1716,9 @@ pub(crate) struct Interner(Lock<InternerInner>);
1716
1716
// found that to regress performance up to 2% in some cases. This might be
1717
1717
// revisited after further improvements to `indexmap`.
1718
1718
//
1719
- // This type is private to prevent accidentally constructing more than one `Interner` on the same
1720
- // thread, which makes it easy to mixup `Symbol`s between `Interner`s.
1719
+ // This type is private to prevent accidentally constructing more than one
1720
+ // `Interner` on the same thread, which makes it easy to mixup `Symbol`s
1721
+ // between `Interner`s.
1721
1722
#[ derive( Default ) ]
1722
1723
struct InternerInner {
1723
1724
arena : DroplessArena ,
@@ -1743,14 +1744,20 @@ impl Interner {
1743
1744
1744
1745
let name = Symbol :: new ( inner. strings . len ( ) as u32 ) ;
1745
1746
1746
- // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
1747
- // UTF-8.
1747
+ // SAFETY: we convert from `&str` to `&[u8]`, clone it into the arena,
1748
+ // and immediately convert the clone back to `&[u8], all because there
1749
+ // is no `inner.arena.alloc_str()` method. This is clearly safe.
1748
1750
let string: & str =
1749
1751
unsafe { str:: from_utf8_unchecked ( inner. arena . alloc_slice ( string. as_bytes ( ) ) ) } ;
1750
- // It is safe to extend the arena allocation to `'static` because we only access
1751
- // these while the arena is still alive.
1752
+
1753
+ // SAFETY: we can extend the arena allocation to `'static` because we
1754
+ // only access these while the arena is still alive.
1752
1755
let string: & ' static str = unsafe { & * ( string as * const str ) } ;
1753
1756
inner. strings . push ( string) ;
1757
+
1758
+ // This second hash table lookup can be avoided by using `RawEntryMut`,
1759
+ // but this code path isn't hot enough for it to be worth it. See
1760
+ // #91445 for details.
1754
1761
inner. names . insert ( string, name) ;
1755
1762
name
1756
1763
}
0 commit comments