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

Use proc-macro to derive HashStable everywhere #66279

Merged
merged 16 commits into from
Nov 25, 2019
Merged
Show file tree
Hide file tree
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
58 changes: 9 additions & 49 deletions src/librustc/ich/impls_syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ use std::mem;
use syntax::ast;
use syntax::feature_gate;
use syntax::token;
use syntax::tokenstream;
use syntax_pos::SourceFile;

use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};

use smallvec::SmallVec;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};

impl<'ctx> syntax::StableHashingContextLike for StableHashingContext<'ctx> {}
impl<'ctx> rustc_target::StableHashingContextLike for StableHashingContext<'ctx> {}

impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
Expand Down Expand Up @@ -47,11 +45,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
}
}

impl_stable_hash_for!(struct ::syntax::ast::AttrItem {
path,
tokens,
});

impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
// Make sure that these have been filtered out.
Expand All @@ -69,38 +62,10 @@ impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
}
}

impl<'a> HashStable<StableHashingContext<'a>>
for tokenstream::TokenTree {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
tokenstream::TokenTree::Token(ref token) => {
token.hash_stable(hcx, hasher);
}
tokenstream::TokenTree::Delimited(span, delim, ref tts) => {
span.hash_stable(hcx, hasher);
std_hash::Hash::hash(&delim, hasher);
for sub_tt in tts.trees() {
sub_tt.hash_stable(hcx, hasher);
}
}
}
}
}

impl<'a> HashStable<StableHashingContext<'a>>
for tokenstream::TokenStream {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
for sub_tt in self.trees() {
sub_tt.hash_stable(hcx, hasher);
}
}
}

impl<'a> HashStable<StableHashingContext<'a>> for token::TokenKind {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
impl<'ctx> syntax::StableHashingContextLike for StableHashingContext<'ctx> {
fn hash_stable_tokenkind(&mut self, tokenkind: &token::TokenKind, hasher: &mut StableHasher) {
mem::discriminant(tokenkind).hash_stable(self, hasher);
match *tokenkind {
token::Eq |
token::Lt |
token::Le |
Expand Down Expand Up @@ -141,30 +106,25 @@ impl<'a> HashStable<StableHashingContext<'a>> for token::TokenKind {
token::CloseDelim(delim_token) => {
std_hash::Hash::hash(&delim_token, hasher);
}
token::Literal(lit) => lit.hash_stable(hcx, hasher),
token::Literal(lit) => lit.hash_stable(self, hasher),

token::Ident(name, is_raw) => {
name.hash_stable(hcx, hasher);
is_raw.hash_stable(hcx, hasher);
name.hash_stable(self, hasher);
is_raw.hash_stable(self, hasher);
}
token::Lifetime(name) => name.hash_stable(hcx, hasher),
token::Lifetime(name) => name.hash_stable(self, hasher),

token::Interpolated(_) => {
bug!("interpolated tokens should not be present in the HIR")
Zoxc marked this conversation as resolved.
Show resolved Hide resolved
}

token::DocComment(val) |
token::Shebang(val) |
token::Unknown(val) => val.hash_stable(hcx, hasher),
token::Unknown(val) => val.hash_stable(self, hasher),
}
}
}

impl_stable_hash_for!(struct token::Token {
kind,
span
});

impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItem {
MetaItem(meta_item),
Literal(lit)
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2276,7 +2276,7 @@ impl rustc_serialize::Decodable for AttrId {
}
}

#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
pub struct AttrItem {
pub path: Path,
pub tokens: TokenStream,
Expand Down
5 changes: 4 additions & 1 deletion src/libsyntax/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#![recursion_limit="256"]

pub use errors;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::Lock;
use rustc_index::bit_set::GrowableBitSet;
pub use rustc_data_structures::thin_vec::ThinVec;
Expand Down Expand Up @@ -114,4 +115,6 @@ pub mod early_buffered_lints;
/// Requirements for a `StableHashingContext` to be used in this crate.
/// This is a hack to allow using the `HashStable_Generic` derive macro
/// instead of implementing everything in librustc.
pub trait StableHashingContextLike: syntax_pos::StableHashingContextLike {}
pub trait StableHashingContextLike: syntax_pos::StableHashingContextLike {
fn hash_stable_tokenkind(&mut self, tokenkind: &token::TokenKind, hasher: &mut StableHasher);
}
11 changes: 10 additions & 1 deletion src/libsyntax/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use syntax_pos::{self, Span, DUMMY_SP};

use std::fmt;
use std::mem;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
use rustc_macros::HashStable_Generic;

Expand Down Expand Up @@ -262,7 +263,15 @@ pub enum TokenKind {
#[cfg(target_arch = "x86_64")]
rustc_data_structures::static_assert_size!(TokenKind, 16);

#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
impl<CTX> HashStable<CTX> for TokenKind
where CTX: crate::StableHashingContextLike
{
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
hcx.hash_stable_tokenkind(self, hasher)
}
}

#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
pub struct Token {
pub kind: TokenKind,
pub span: Span,
Expand Down
31 changes: 31 additions & 0 deletions src/libsyntax/tokenstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use crate::token::{self, DelimToken, Token, TokenKind};

use syntax_pos::{Span, DUMMY_SP};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
use smallvec::{SmallVec, smallvec};

Expand Down Expand Up @@ -51,6 +52,26 @@ where
TokenStream: Send + Sync,
{}

impl<CTX> HashStable<CTX> for TokenTree
cjgillot marked this conversation as resolved.
Show resolved Hide resolved
where CTX: crate::StableHashingContextLike
{
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
TokenTree::Token(ref token) => {
token.hash_stable(hcx, hasher);
}
TokenTree::Delimited(span, delim, ref tts) => {
span.hash_stable(hcx, hasher);
std::hash::Hash::hash(&delim, hasher);
for sub_tt in tts.trees() {
sub_tt.hash_stable(hcx, hasher);
}
}
}
}
}

impl TokenTree {
/// Checks if this TokenTree is equal to the other, regardless of span information.
pub fn eq_unspanned(&self, other: &TokenTree) -> bool {
Expand Down Expand Up @@ -115,6 +136,16 @@ impl TokenTree {
}
}

impl<CTX> HashStable<CTX> for TokenStream
where CTX: crate::StableHashingContextLike
{
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
for sub_tt in self.trees() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nnethercote It seems like this iterator does a bunch of Lrc clones. Is there some reason this can't just hash the Vec<TreeAndJoint>? It also doesn't hash IsJoint, which seems questionable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@petrochenkov Do you know why this ignores IsJoint?

sub_tt.hash_stable(hcx, hasher);
}
}
}

/// A `TokenStream` is an abstract sequence of tokens, organized into `TokenTree`s.
///
/// The goal is for procedural macros to work with `TokenStream`s and `TokenTree`s
Expand Down