Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DO NOT MERGE] Remove InternedString #65543

Closed
wants to merge 5 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Make Symbol::{PartialOrd,Ord,Hash} use the chars instead of the index.
This makes `Symbol` like `InternedString`.
nnethercote committed Oct 18, 2019
commit 527e7c0fe6417b3f8ec58792ea7dc871f5f42fd1
47 changes: 37 additions & 10 deletions src/libsyntax_pos/symbol.rs
Original file line number Diff line number Diff line change
@@ -871,14 +871,17 @@ impl UseSpecializedDecodable for Ident {

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

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

impl PartialOrd for Symbol {
fn partial_cmp(&self, other: &Symbol) -> Option<Ordering> {
if self == other {
return Some(Ordering::Equal);
}
self.with2(*other, |self_str, other_str| self_str.partial_cmp(other_str))
}
}

impl Ord for Symbol {
fn cmp(&self, other: &Symbol) -> Ordering {
if self == other {
return Ordering::Equal;
}
self.with2(*other, |self_str, other_str| self_str.cmp(other_str))
}
}

impl Hash for Symbol {
fn hash<H: Hasher>(&self, state: &mut H) {
self.with(|str| str.hash(state))
}
}

impl fmt::Debug for Symbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.with(|str| fmt::Debug::fmt(&str, f))
@@ -1028,7 +1055,7 @@ pub mod sym {

impl Symbol {
fn is_used_keyword_2018(self) -> bool {
self >= kw::Async && self <= kw::Dyn
self.0 >= kw::Async.0 && self.0 <= kw::Dyn.0
}

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

/// Used for sanity checking rustdoc keyword sections.
pub fn is_doc_keyword(self) -> bool {
self <= kw::Union
self.0 <= kw::Union.0
}

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

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

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

20 changes: 10 additions & 10 deletions src/test/ui/span/issue-39698.stderr
Original file line number Diff line number Diff line change
@@ -8,16 +8,6 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
| | pattern doesn't bind `a`
| variable not in all patterns

error[E0408]: variable `d` is not bound in all patterns
--> $DIR/issue-39698.rs:10:37
|
LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
| - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d`
| | | |
| | | pattern doesn't bind `d`
| | variable not in all patterns
| variable not in all patterns

error[E0408]: variable `b` is not bound in all patterns
--> $DIR/issue-39698.rs:10:9
|
@@ -38,6 +28,16 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
| | pattern doesn't bind `c`
| pattern doesn't bind `c`

error[E0408]: variable `d` is not bound in all patterns
--> $DIR/issue-39698.rs:10:37
|
LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
| - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d`
| | | |
| | | pattern doesn't bind `d`
| | variable not in all patterns
| variable not in all patterns

error: aborting due to 4 previous errors

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