diff options
Diffstat (limited to 'src/librustc/ich/impls_syntax.rs')
| -rw-r--r-- | src/librustc/ich/impls_syntax.rs | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs new file mode 100644 index 00000000000..26734500001 --- /dev/null +++ b/src/librustc/ich/impls_syntax.rs @@ -0,0 +1,301 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! This module contains `HashStable` implementations for various data types +//! from libsyntax in no particular order. + +use ich::StableHashingContext; + +use std::hash as std_hash; +use std::mem; + +use syntax::ast; +use syntax::parse::token; +use syntax::tokenstream; +use syntax_pos::Span; + +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, + StableHasherResult}; +use rustc_data_structures::accumulate_vec::AccumulateVec; + +impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::syntax::symbol::InternedString { + #[inline] + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'tcx>, + hasher: &mut StableHasher<W>) { + let s: &str = &**self; + s.hash_stable(hcx, hasher); + } +} + +impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ast::Name { + #[inline] + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'tcx>, + hasher: &mut StableHasher<W>) { + self.as_str().hash_stable(hcx, hasher); + } +} + +impl_stable_hash_for!(enum ::syntax::ast::AsmDialect { + Att, + Intel +}); + +impl_stable_hash_for!(enum ::syntax::ext::base::MacroKind { + Bang, + Attr, + Derive +}); + + +impl_stable_hash_for!(enum ::syntax::abi::Abi { + Cdecl, + Stdcall, + Fastcall, + Vectorcall, + Aapcs, + Win64, + SysV64, + PtxKernel, + Msp430Interrupt, + X86Interrupt, + Rust, + C, + System, + RustIntrinsic, + RustCall, + PlatformIntrinsic, + Unadjusted +}); + +impl_stable_hash_for!(struct ::syntax::attr::Deprecation { since, note }); +impl_stable_hash_for!(struct ::syntax::attr::Stability { level, feature, rustc_depr }); + +impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::syntax::attr::StabilityLevel { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'tcx>, + hasher: &mut StableHasher<W>) { + mem::discriminant(self).hash_stable(hcx, hasher); + match *self { + ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue } => { + reason.hash_stable(hcx, hasher); + issue.hash_stable(hcx, hasher); + } + ::syntax::attr::StabilityLevel::Stable { ref since } => { + since.hash_stable(hcx, hasher); + } + } + } +} + +impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason }); + + +impl_stable_hash_for!(enum ::syntax::attr::IntType { + SignedInt(int_ty), + UnsignedInt(uint_ty) +}); + +impl_stable_hash_for!(enum ::syntax::ast::LitIntType { + Signed(int_ty), + Unsigned(int_ty), + Unsuffixed +}); + +impl_stable_hash_for_spanned!(::syntax::ast::LitKind); +impl_stable_hash_for!(enum ::syntax::ast::LitKind { + Str(value, style), + ByteStr(value), + Byte(value), + Char(value), + Int(value, lit_int_type), + Float(value, float_ty), + FloatUnsuffixed(value), + Bool(value) +}); + +impl_stable_hash_for!(enum ::syntax::ast::IntTy { Is, I8, I16, I32, I64, I128 }); +impl_stable_hash_for!(enum ::syntax::ast::UintTy { Us, U8, U16, U32, U64, U128 }); +impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 }); +impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal }); +impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst }); +impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final }); +impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, span, name }); +impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) }); +impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner }); + +impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for [ast::Attribute] { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'tcx>, + hasher: &mut StableHasher<W>) { + // Some attributes are always ignored during hashing. + let filtered: AccumulateVec<[&ast::Attribute; 8]> = self + .iter() + .filter(|attr| { + !attr.is_sugared_doc && + attr.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true) + }) + .collect(); + + filtered.len().hash_stable(hcx, hasher); + for attr in filtered { + attr.hash_stable(hcx, hasher); + } + } +} + +impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ast::Attribute { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'tcx>, + hasher: &mut StableHasher<W>) { + // Make sure that these have been filtered out. + debug_assert!(self.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true)); + debug_assert!(!self.is_sugared_doc); + + let ast::Attribute { + id: _, + style, + ref path, + ref tokens, + is_sugared_doc: _, + span, + } = *self; + + style.hash_stable(hcx, hasher); + path.segments.len().hash_stable(hcx, hasher); + for segment in &path.segments { + segment.identifier.name.hash_stable(hcx, hasher); + } + for tt in tokens.trees() { + tt.hash_stable(hcx, hasher); + } + span.hash_stable(hcx, hasher); + } +} + +impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for tokenstream::TokenTree { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'tcx>, + hasher: &mut StableHasher<W>) { + mem::discriminant(self).hash_stable(hcx, hasher); + match *self { + tokenstream::TokenTree::Token(span, ref token) => { + span.hash_stable(hcx, hasher); + hash_token(token, hcx, hasher, span); + } + tokenstream::TokenTree::Delimited(span, ref delimited) => { + span.hash_stable(hcx, hasher); + std_hash::Hash::hash(&delimited.delim, hasher); + for sub_tt in delimited.stream().trees() { + sub_tt.hash_stable(hcx, hasher); + } + } + } + } +} + +impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for tokenstream::TokenStream { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'tcx>, + hasher: &mut StableHasher<W>) { + for sub_tt in self.trees() { + sub_tt.hash_stable(hcx, hasher); + } + } +} + +fn hash_token<'a, 'tcx, W: StableHasherResult>(token: &token::Token, + hcx: &mut StableHashingContext<'a, 'tcx>, + hasher: &mut StableHasher<W>, + error_reporting_span: Span) { + mem::discriminant(token).hash_stable(hcx, hasher); + match *token { + token::Token::Eq | + token::Token::Lt | + token::Token::Le | + token::Token::EqEq | + token::Token::Ne | + token::Token::Ge | + token::Token::Gt | + token::Token::AndAnd | + token::Token::OrOr | + token::Token::Not | + token::Token::Tilde | + token::Token::At | + token::Token::Dot | + token::Token::DotDot | + token::Token::DotDotDot | + token::Token::Comma | + token::Token::Semi | + token::Token::Colon | + token::Token::ModSep | + token::Token::RArrow | + token::Token::LArrow | + token::Token::FatArrow | + token::Token::Pound | + token::Token::Dollar | + token::Token::Question | + token::Token::Underscore | + token::Token::Whitespace | + token::Token::Comment | + token::Token::Eof => {} + + token::Token::BinOp(bin_op_token) | + token::Token::BinOpEq(bin_op_token) => { + std_hash::Hash::hash(&bin_op_token, hasher); + } + + token::Token::OpenDelim(delim_token) | + token::Token::CloseDelim(delim_token) => { + std_hash::Hash::hash(&delim_token, hasher); + } + token::Token::Literal(ref lit, ref opt_name) => { + mem::discriminant(lit).hash_stable(hcx, hasher); + match *lit { + token::Lit::Byte(val) | + token::Lit::Char(val) | + token::Lit::Integer(val) | + token::Lit::Float(val) | + token::Lit::Str_(val) | + token::Lit::ByteStr(val) => val.hash_stable(hcx, hasher), + token::Lit::StrRaw(val, n) | + token::Lit::ByteStrRaw(val, n) => { + val.hash_stable(hcx, hasher); + n.hash_stable(hcx, hasher); + } + }; + opt_name.hash_stable(hcx, hasher); + } + + token::Token::Ident(ident) | + token::Token::Lifetime(ident) | + token::Token::SubstNt(ident) => ident.name.hash_stable(hcx, hasher), + + token::Token::Interpolated(ref non_terminal) => { + // FIXME(mw): This could be implemented properly. It's just a + // lot of work, since we would need to hash the AST + // in a stable way, in addition to the HIR. + // Since this is hardly used anywhere, just emit a + // warning for now. + if hcx.tcx().sess.opts.debugging_opts.incremental.is_some() { + let msg = format!("Quasi-quoting might make incremental \ + compilation very inefficient: {:?}", + non_terminal); + hcx.tcx().sess.span_warn(error_reporting_span, &msg[..]); + } + + std_hash::Hash::hash(non_terminal, hasher); + } + + token::Token::DocComment(val) | + token::Token::Shebang(val) => val.hash_stable(hcx, hasher), + } +} |
