rustc_query_system/ich/
impls_syntax.rs

1//! This module contains `HashStable` implementations for various data types
2//! from various crates in no particular order.
3
4use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
5use rustc_hir::{self as hir, HashIgnoredAttrId};
6use rustc_span::SourceFile;
7use smallvec::SmallVec;
8
9use crate::ich::StableHashingContext;
10
11impl<'ctx> rustc_abi::HashStableContext for StableHashingContext<'ctx> {}
12impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {}
13
14impl<'a> HashStable<StableHashingContext<'a>> for [hir::Attribute] {
15    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
16        if self.is_empty() {
17            self.len().hash_stable(hcx, hasher);
18            return;
19        }
20
21        // Some attributes are always ignored during hashing.
22        let filtered: SmallVec<[&hir::Attribute; 8]> = self
23            .iter()
24            .filter(|attr| {
25                attr.is_doc_comment().is_none()
26                    // FIXME(jdonszelmann) have a better way to handle ignored attrs
27                    && !attr.ident().is_some_and(|ident| hcx.is_ignored_attr(ident.name))
28            })
29            .collect();
30
31        filtered.len().hash_stable(hcx, hasher);
32        for attr in filtered {
33            attr.hash_stable(hcx, hasher);
34        }
35    }
36}
37
38impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
39    fn hash_attr_id(&mut self, _id: &HashIgnoredAttrId, _hasher: &mut StableHasher) {
40        /* we don't hash HashIgnoredAttrId, we ignore them */
41    }
42}
43
44impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
45    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
46        let SourceFile {
47            name: _, // We hash the smaller stable_id instead of this
48            stable_id,
49            cnum,
50            // Do not hash the source as it is not encoded
51            src: _,
52            ref src_hash,
53            // Already includes src_hash, this is redundant
54            checksum_hash: _,
55            external_src: _,
56            start_pos: _,
57            normalized_source_len: _,
58            unnormalized_source_len: _,
59            lines: _,
60            ref multibyte_chars,
61            ref normalized_pos,
62        } = *self;
63
64        stable_id.hash_stable(hcx, hasher);
65
66        src_hash.hash_stable(hcx, hasher);
67
68        {
69            // We are always in `Lines` form by the time we reach here.
70            assert!(self.lines.read().is_lines());
71            let lines = self.lines();
72            // We only hash the relative position within this source_file
73            lines.len().hash_stable(hcx, hasher);
74            for &line in lines.iter() {
75                line.hash_stable(hcx, hasher);
76            }
77        }
78
79        // We only hash the relative position within this source_file
80        multibyte_chars.len().hash_stable(hcx, hasher);
81        for &char_pos in multibyte_chars.iter() {
82            char_pos.hash_stable(hcx, hasher);
83        }
84
85        normalized_pos.len().hash_stable(hcx, hasher);
86        for &char_pos in normalized_pos.iter() {
87            char_pos.hash_stable(hcx, hasher);
88        }
89
90        cnum.hash_stable(hcx, hasher);
91    }
92}
93
94impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
95    fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
96        // Unfortunately we cannot exhaustively list fields here, since the
97        // struct has private fields (to ensure its invariant is maintained)
98        self.enabled_lang_features().hash_stable(hcx, hasher);
99        self.enabled_lib_features().hash_stable(hcx, hasher);
100    }
101}
102
103impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::EnabledLangFeature {
104    fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
105        let rustc_feature::EnabledLangFeature { gate_name, attr_sp, stable_since } = self;
106        gate_name.hash_stable(hcx, hasher);
107        attr_sp.hash_stable(hcx, hasher);
108        stable_since.hash_stable(hcx, hasher);
109    }
110}
111
112impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::EnabledLibFeature {
113    fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
114        let rustc_feature::EnabledLibFeature { gate_name, attr_sp } = self;
115        gate_name.hash_stable(hcx, hasher);
116        attr_sp.hash_stable(hcx, hasher);
117    }
118}