]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_syntax.rs
Refactor away `inferred_obligations` from the trait selector
[rust.git] / src / librustc / ich / impls_syntax.rs
1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! This module contains `HashStable` implementations for various data types
12 //! from libsyntax in no particular order.
13
14 use ich::StableHashingContext;
15
16 use std::hash as std_hash;
17 use std::mem;
18
19 use syntax::ast;
20 use syntax::parse::token;
21 use syntax::symbol::InternedString;
22 use syntax::tokenstream;
23 use syntax_pos::FileMap;
24
25 use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
26
27 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
28                                            StableHasher, StableHasherResult};
29 use rustc_data_structures::accumulate_vec::AccumulateVec;
30
31 impl<'gcx> HashStable<StableHashingContext<'gcx>> for InternedString {
32     #[inline]
33     fn hash_stable<W: StableHasherResult>(&self,
34                                           hcx: &mut StableHashingContext<'gcx>,
35                                           hasher: &mut StableHasher<W>) {
36         let s: &str = &**self;
37         s.hash_stable(hcx, hasher);
38     }
39 }
40
41 impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for InternedString {
42     type KeyType = InternedString;
43
44     #[inline]
45     fn to_stable_hash_key(&self,
46                           _: &StableHashingContext<'gcx>)
47                           -> InternedString {
48         self.clone()
49     }
50 }
51
52 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ast::Name {
53     #[inline]
54     fn hash_stable<W: StableHasherResult>(&self,
55                                           hcx: &mut StableHashingContext<'gcx>,
56                                           hasher: &mut StableHasher<W>) {
57         self.as_str().hash_stable(hcx, hasher);
58     }
59 }
60
61 impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for ast::Name {
62     type KeyType = InternedString;
63
64     #[inline]
65     fn to_stable_hash_key(&self,
66                           _: &StableHashingContext<'gcx>)
67                           -> InternedString {
68         self.as_str()
69     }
70 }
71
72 impl_stable_hash_for!(enum ::syntax::ast::AsmDialect {
73     Att,
74     Intel
75 });
76
77 impl_stable_hash_for!(enum ::syntax::ext::base::MacroKind {
78     Bang,
79     Attr,
80     Derive
81 });
82
83
84 impl_stable_hash_for!(enum ::syntax::abi::Abi {
85     Cdecl,
86     Stdcall,
87     Fastcall,
88     Vectorcall,
89     Thiscall,
90     Aapcs,
91     Win64,
92     SysV64,
93     PtxKernel,
94     Msp430Interrupt,
95     X86Interrupt,
96     Rust,
97     C,
98     System,
99     RustIntrinsic,
100     RustCall,
101     PlatformIntrinsic,
102     Unadjusted
103 });
104
105 impl_stable_hash_for!(struct ::syntax::attr::Deprecation { since, note });
106 impl_stable_hash_for!(struct ::syntax::attr::Stability {
107     level,
108     feature,
109     rustc_depr,
110     rustc_const_unstable
111 });
112
113 impl<'gcx> HashStable<StableHashingContext<'gcx>>
114 for ::syntax::attr::StabilityLevel {
115     fn hash_stable<W: StableHasherResult>(&self,
116                                           hcx: &mut StableHashingContext<'gcx>,
117                                           hasher: &mut StableHasher<W>) {
118         mem::discriminant(self).hash_stable(hcx, hasher);
119         match *self {
120             ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue } => {
121                 reason.hash_stable(hcx, hasher);
122                 issue.hash_stable(hcx, hasher);
123             }
124             ::syntax::attr::StabilityLevel::Stable { ref since } => {
125                 since.hash_stable(hcx, hasher);
126             }
127         }
128     }
129 }
130
131 impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason });
132 impl_stable_hash_for!(struct ::syntax::attr::RustcConstUnstable { feature });
133
134
135 impl_stable_hash_for!(enum ::syntax::attr::IntType {
136     SignedInt(int_ty),
137     UnsignedInt(uint_ty)
138 });
139
140 impl_stable_hash_for!(enum ::syntax::ast::LitIntType {
141     Signed(int_ty),
142     Unsigned(int_ty),
143     Unsuffixed
144 });
145
146 impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
147 impl_stable_hash_for!(enum ::syntax::ast::LitKind {
148     Str(value, style),
149     ByteStr(value),
150     Byte(value),
151     Char(value),
152     Int(value, lit_int_type),
153     Float(value, float_ty),
154     FloatUnsuffixed(value),
155     Bool(value)
156 });
157
158 impl_stable_hash_for!(enum ::syntax::ast::IntTy { Isize, I8, I16, I32, I64, I128 });
159 impl_stable_hash_for!(enum ::syntax::ast::UintTy { Usize, U8, U16, U32, U64, U128 });
160 impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 });
161 impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal });
162 impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst });
163 impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final });
164 impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, span, ident });
165 impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) });
166 impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner });
167
168 impl<'gcx> HashStable<StableHashingContext<'gcx>> for [ast::Attribute] {
169     fn hash_stable<W: StableHasherResult>(&self,
170                                           hcx: &mut StableHashingContext<'gcx>,
171                                           hasher: &mut StableHasher<W>) {
172         if self.len() == 0 {
173             self.len().hash_stable(hcx, hasher);
174             return
175         }
176
177         // Some attributes are always ignored during hashing.
178         let filtered: AccumulateVec<[&ast::Attribute; 8]> = self
179             .iter()
180             .filter(|attr| {
181                 !attr.is_sugared_doc &&
182                 attr.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true)
183             })
184             .collect();
185
186         filtered.len().hash_stable(hcx, hasher);
187         for attr in filtered {
188             attr.hash_stable(hcx, hasher);
189         }
190     }
191 }
192
193 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ast::Attribute {
194     fn hash_stable<W: StableHasherResult>(&self,
195                                           hcx: &mut StableHashingContext<'gcx>,
196                                           hasher: &mut StableHasher<W>) {
197         // Make sure that these have been filtered out.
198         debug_assert!(self.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true));
199         debug_assert!(!self.is_sugared_doc);
200
201         let ast::Attribute {
202             id: _,
203             style,
204             ref path,
205             ref tokens,
206             is_sugared_doc: _,
207             span,
208         } = *self;
209
210         style.hash_stable(hcx, hasher);
211         path.segments.len().hash_stable(hcx, hasher);
212         for segment in &path.segments {
213             segment.identifier.name.hash_stable(hcx, hasher);
214         }
215         for tt in tokens.trees() {
216             tt.hash_stable(hcx, hasher);
217         }
218         span.hash_stable(hcx, hasher);
219     }
220 }
221
222 impl<'gcx> HashStable<StableHashingContext<'gcx>>
223 for tokenstream::TokenTree {
224     fn hash_stable<W: StableHasherResult>(&self,
225                                           hcx: &mut StableHashingContext<'gcx>,
226                                           hasher: &mut StableHasher<W>) {
227         mem::discriminant(self).hash_stable(hcx, hasher);
228         match *self {
229             tokenstream::TokenTree::Token(span, ref token) => {
230                 span.hash_stable(hcx, hasher);
231                 hash_token(token, hcx, hasher);
232             }
233             tokenstream::TokenTree::Delimited(span, ref delimited) => {
234                 span.hash_stable(hcx, hasher);
235                 std_hash::Hash::hash(&delimited.delim, hasher);
236                 for sub_tt in delimited.stream().trees() {
237                     sub_tt.hash_stable(hcx, hasher);
238                 }
239             }
240         }
241     }
242 }
243
244 impl<'gcx> HashStable<StableHashingContext<'gcx>>
245 for tokenstream::TokenStream {
246     fn hash_stable<W: StableHasherResult>(&self,
247                                           hcx: &mut StableHashingContext<'gcx>,
248                                           hasher: &mut StableHasher<W>) {
249         for sub_tt in self.trees() {
250             sub_tt.hash_stable(hcx, hasher);
251         }
252     }
253 }
254
255 fn hash_token<'gcx, W: StableHasherResult>(token: &token::Token,
256                                            hcx: &mut StableHashingContext<'gcx>,
257                                            hasher: &mut StableHasher<W>) {
258     mem::discriminant(token).hash_stable(hcx, hasher);
259     match *token {
260         token::Token::Eq |
261         token::Token::Lt |
262         token::Token::Le |
263         token::Token::EqEq |
264         token::Token::Ne |
265         token::Token::Ge |
266         token::Token::Gt |
267         token::Token::AndAnd |
268         token::Token::OrOr |
269         token::Token::Not |
270         token::Token::Tilde |
271         token::Token::At |
272         token::Token::Dot |
273         token::Token::DotDot |
274         token::Token::DotDotDot |
275         token::Token::DotDotEq |
276         token::Token::DotEq |
277         token::Token::Comma |
278         token::Token::Semi |
279         token::Token::Colon |
280         token::Token::ModSep |
281         token::Token::RArrow |
282         token::Token::LArrow |
283         token::Token::FatArrow |
284         token::Token::Pound |
285         token::Token::Dollar |
286         token::Token::Question |
287         token::Token::Underscore |
288         token::Token::Whitespace |
289         token::Token::Comment |
290         token::Token::Eof => {}
291
292         token::Token::BinOp(bin_op_token) |
293         token::Token::BinOpEq(bin_op_token) => {
294             std_hash::Hash::hash(&bin_op_token, hasher);
295         }
296
297         token::Token::OpenDelim(delim_token) |
298         token::Token::CloseDelim(delim_token) => {
299             std_hash::Hash::hash(&delim_token, hasher);
300         }
301         token::Token::Literal(ref lit, ref opt_name) => {
302             mem::discriminant(lit).hash_stable(hcx, hasher);
303             match *lit {
304                 token::Lit::Byte(val) |
305                 token::Lit::Char(val) |
306                 token::Lit::Integer(val) |
307                 token::Lit::Float(val) |
308                 token::Lit::Str_(val) |
309                 token::Lit::ByteStr(val) => val.hash_stable(hcx, hasher),
310                 token::Lit::StrRaw(val, n) |
311                 token::Lit::ByteStrRaw(val, n) => {
312                     val.hash_stable(hcx, hasher);
313                     n.hash_stable(hcx, hasher);
314                 }
315             };
316             opt_name.hash_stable(hcx, hasher);
317         }
318
319         token::Token::Ident(ident) |
320         token::Token::Lifetime(ident) => ident.name.hash_stable(hcx, hasher),
321
322         token::Token::Interpolated(_) => {
323             bug!("interpolated tokens should not be present in the HIR")
324         }
325
326         token::Token::DocComment(val) |
327         token::Token::Shebang(val) => val.hash_stable(hcx, hasher),
328     }
329 }
330
331 impl_stable_hash_for_spanned!(::syntax::ast::NestedMetaItemKind);
332
333 impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItemKind {
334     MetaItem(meta_item),
335     Literal(lit)
336 });
337
338 impl_stable_hash_for!(struct ::syntax::ast::MetaItem {
339     name,
340     node,
341     span
342 });
343
344 impl_stable_hash_for!(enum ::syntax::ast::MetaItemKind {
345     Word,
346     List(nested_items),
347     NameValue(lit)
348 });
349
350 impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo {
351     call_site,
352     callee
353 });
354
355 impl_stable_hash_for!(struct ::syntax_pos::hygiene::NameAndSpan {
356     format,
357     allow_internal_unstable,
358     allow_internal_unsafe,
359     span
360 });
361
362 impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnFormat {
363     MacroAttribute(sym),
364     MacroBang(sym),
365     CompilerDesugaring(kind)
366 });
367
368 impl_stable_hash_for!(enum ::syntax_pos::hygiene::CompilerDesugaringKind {
369     BackArrow,
370     DotFill,
371     QuestionMark
372 });
373
374 impl_stable_hash_for!(enum ::syntax_pos::FileName {
375     Real(pb),
376     Macros(s),
377     QuoteExpansion,
378     Anon,
379     MacroExpansion,
380     ProcMacroSourceCode,
381     CfgSpec,
382     Custom(s)
383 });
384
385 impl<'gcx> HashStable<StableHashingContext<'gcx>> for FileMap {
386     fn hash_stable<W: StableHasherResult>(&self,
387                                           hcx: &mut StableHashingContext<'gcx>,
388                                           hasher: &mut StableHasher<W>) {
389         let FileMap {
390             name: _, // We hash the smaller name_hash instead of this
391             name_hash,
392             name_was_remapped,
393             unmapped_path: _,
394             crate_of_origin,
395             // Do not hash the source as it is not encoded
396             src: _,
397             src_hash,
398             external_src: _,
399             start_pos,
400             end_pos: _,
401             ref lines,
402             ref multibyte_chars,
403             ref non_narrow_chars,
404         } = *self;
405
406         (name_hash as u64).hash_stable(hcx, hasher);
407         name_was_remapped.hash_stable(hcx, hasher);
408
409         DefId {
410             krate: CrateNum::from_u32(crate_of_origin),
411             index: CRATE_DEF_INDEX,
412         }.hash_stable(hcx, hasher);
413
414         src_hash.hash_stable(hcx, hasher);
415
416         // We only hash the relative position within this filemap
417         let lines = lines.borrow();
418         lines.len().hash_stable(hcx, hasher);
419         for &line in lines.iter() {
420             stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
421         }
422
423         // We only hash the relative position within this filemap
424         let multibyte_chars = multibyte_chars.borrow();
425         multibyte_chars.len().hash_stable(hcx, hasher);
426         for &char_pos in multibyte_chars.iter() {
427             stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher);
428         }
429
430         let non_narrow_chars = non_narrow_chars.borrow();
431         non_narrow_chars.len().hash_stable(hcx, hasher);
432         for &char_pos in non_narrow_chars.iter() {
433             stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher);
434         }
435     }
436 }
437
438 fn stable_byte_pos(pos: ::syntax_pos::BytePos,
439                    filemap_start: ::syntax_pos::BytePos)
440                    -> u32 {
441     pos.0 - filemap_start.0
442 }
443
444 fn stable_multibyte_char(mbc: ::syntax_pos::MultiByteChar,
445                          filemap_start: ::syntax_pos::BytePos)
446                          -> (u32, u32) {
447     let ::syntax_pos::MultiByteChar {
448         pos,
449         bytes,
450     } = mbc;
451
452     (pos.0 - filemap_start.0, bytes as u32)
453 }
454
455 fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar,
456                           filemap_start: ::syntax_pos::BytePos)
457                           -> (u32, u32) {
458     let pos = swc.pos();
459     let width = swc.width();
460
461     (pos.0 - filemap_start.0, width as u32)
462 }