Skip to content

Commit 527e7c0

Browse files
committed
Make Symbol::{PartialOrd,Ord,Hash} use the chars instead of the index.
This makes `Symbol` like `InternedString`.
1 parent 3532863 commit 527e7c0

File tree

2 files changed

+47
-20
lines changed

2 files changed

+47
-20
lines changed

src/libsyntax_pos/symbol.rs

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -871,14 +871,17 @@ impl UseSpecializedDecodable for Ident {
871871

872872
/// An interned string.
873873
///
874-
/// Internally, a `Symbol` is implemented as an index, and all operations
875-
/// (including hashing, equality, and ordering) operate on that index. The use
876-
/// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
877-
/// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
874+
/// Internally, a `Symbol` is implemented as an index. Ordering and hashing use
875+
/// the underlying string chars. Equality uses the index, but because of the
876+
/// interning this is equivalent to using the underlying string chars.
877+
///
878+
/// The use of `rustc_index::newtype_index!` means that `Option<Symbol>` only
879+
/// takes up 4 bytes, because `rustc_index::newtype_index!` reserves the last
880+
/// 256 values for tagging purposes.
878881
///
879882
/// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
880883
/// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
881-
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
884+
#[derive(Clone, Copy, PartialEq, Eq)]
882885
pub struct Symbol(SymbolIndex);
883886

884887
rustc_index::newtype_index! {
@@ -932,6 +935,30 @@ impl Symbol {
932935
}
933936
}
934937

938+
impl PartialOrd for Symbol {
939+
fn partial_cmp(&self, other: &Symbol) -> Option<Ordering> {
940+
if self == other {
941+
return Some(Ordering::Equal);
942+
}
943+
self.with2(*other, |self_str, other_str| self_str.partial_cmp(other_str))
944+
}
945+
}
946+
947+
impl Ord for Symbol {
948+
fn cmp(&self, other: &Symbol) -> Ordering {
949+
if self == other {
950+
return Ordering::Equal;
951+
}
952+
self.with2(*other, |self_str, other_str| self_str.cmp(other_str))
953+
}
954+
}
955+
956+
impl Hash for Symbol {
957+
fn hash<H: Hasher>(&self, state: &mut H) {
958+
self.with(|str| str.hash(state))
959+
}
960+
}
961+
935962
impl fmt::Debug for Symbol {
936963
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
937964
self.with(|str| fmt::Debug::fmt(&str, f))
@@ -1028,7 +1055,7 @@ pub mod sym {
10281055

10291056
impl Symbol {
10301057
fn is_used_keyword_2018(self) -> bool {
1031-
self >= kw::Async && self <= kw::Dyn
1058+
self.0 >= kw::Async.0 && self.0 <= kw::Dyn.0
10321059
}
10331060

10341061
fn is_unused_keyword_2018(self) -> bool {
@@ -1037,7 +1064,7 @@ impl Symbol {
10371064

10381065
/// Used for sanity checking rustdoc keyword sections.
10391066
pub fn is_doc_keyword(self) -> bool {
1040-
self <= kw::Union
1067+
self.0 <= kw::Union.0
10411068
}
10421069

10431070
/// A keyword or reserved identifier that can be used as a path segment.
@@ -1065,20 +1092,20 @@ impl Ident {
10651092
// Returns `true` for reserved identifiers used internally for elided lifetimes,
10661093
// unnamed method parameters, crate root module, error recovery etc.
10671094
pub fn is_special(self) -> bool {
1068-
self.name <= kw::Underscore
1095+
self.name.0 <= kw::Underscore.0
10691096
}
10701097

10711098
/// Returns `true` if the token is a keyword used in the language.
10721099
pub fn is_used_keyword(self) -> bool {
10731100
// Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1074-
self.name >= kw::As && self.name <= kw::While ||
1101+
self.name.0 >= kw::As.0 && self.name.0 <= kw::While.0 ||
10751102
self.name.is_used_keyword_2018() && self.span.rust_2018()
10761103
}
10771104

10781105
/// Returns `true` if the token is a keyword reserved for possible future use.
10791106
pub fn is_unused_keyword(self) -> bool {
10801107
// Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1081-
self.name >= kw::Abstract && self.name <= kw::Yield ||
1108+
self.name.0 >= kw::Abstract.0 && self.name.0 <= kw::Yield.0 ||
10821109
self.name.is_unused_keyword_2018() && self.span.rust_2018()
10831110
}
10841111

src/test/ui/span/issue-39698.stderr

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,6 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
88
| | pattern doesn't bind `a`
99
| variable not in all patterns
1010

11-
error[E0408]: variable `d` is not bound in all patterns
12-
--> $DIR/issue-39698.rs:10:37
13-
|
14-
LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
15-
| - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d`
16-
| | | |
17-
| | | pattern doesn't bind `d`
18-
| | variable not in all patterns
19-
| variable not in all patterns
20-
2111
error[E0408]: variable `b` is not bound in all patterns
2212
--> $DIR/issue-39698.rs:10:9
2313
|
@@ -38,6 +28,16 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
3828
| | pattern doesn't bind `c`
3929
| pattern doesn't bind `c`
4030

31+
error[E0408]: variable `d` is not bound in all patterns
32+
--> $DIR/issue-39698.rs:10:37
33+
|
34+
LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
35+
| - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d`
36+
| | | |
37+
| | | pattern doesn't bind `d`
38+
| | variable not in all patterns
39+
| variable not in all patterns
40+
4141
error: aborting due to 4 previous errors
4242

4343
For more information about this error, try `rustc --explain E0408`.

0 commit comments

Comments
 (0)