Skip to main content

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_span::{SourceFile, Symbol, sym};
6use smallvec::SmallVec;
7use {rustc_ast as ast, rustc_hir as hir};
8
9use crate::ich::StableHashingContext;
10
11impl<'a> HashStable<StableHashingContext<'a>> for ast::NodeId {
12    #[inline]
13    fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) {
14        {
    ::core::panicking::panic_fmt(format_args!("Node IDs should not appear in incremental state"));
};panic!("Node IDs should not appear in incremental state");
15    }
16}
17
18impl<'a> HashStable<StableHashingContext<'a>> for [hir::Attribute] {
19    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
20        if self.is_empty() {
21            self.len().hash_stable(hcx, hasher);
22            return;
23        }
24
25        // Some attributes are always ignored during hashing.
26        let filtered: SmallVec<[&hir::Attribute; 8]> = self
27            .iter()
28            .filter(|attr| {
29                attr.is_doc_comment().is_none()
30                    // FIXME(jdonszelmann) have a better way to handle ignored attrs
31                    && !attr.name().is_some_and(|ident| is_ignored_attr(ident))
32            })
33            .collect();
34
35        filtered.len().hash_stable(hcx, hasher);
36        for attr in filtered {
37            attr.hash_stable(hcx, hasher);
38        }
39    }
40}
41
42#[inline]
43fn is_ignored_attr(name: Symbol) -> bool {
44    const IGNORED_ATTRIBUTES: &[Symbol] = &[
45        sym::cfg_trace, // FIXME(#138844) should this really be ignored?
46        sym::rustc_if_this_changed,
47        sym::rustc_then_this_would_need,
48        sym::rustc_clean,
49        sym::rustc_partition_reused,
50        sym::rustc_partition_codegened,
51        sym::rustc_expected_cgu_reuse,
52    ];
53    IGNORED_ATTRIBUTES.contains(&name)
54}
55
56impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
57    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
58        let SourceFile {
59            name: _, // We hash the smaller stable_id instead of this
60            stable_id,
61            cnum,
62            // Do not hash the source as it is not encoded
63            src: _,
64            ref src_hash,
65            // Already includes src_hash, this is redundant
66            checksum_hash: _,
67            external_src: _,
68            start_pos: _,
69            normalized_source_len: _,
70            unnormalized_source_len: _,
71            lines: _,
72            ref multibyte_chars,
73            ref normalized_pos,
74        } = *self;
75
76        stable_id.hash_stable(hcx, hasher);
77
78        src_hash.hash_stable(hcx, hasher);
79
80        {
81            // We are always in `Lines` form by the time we reach here.
82            if !self.lines.read().is_lines() {
    ::core::panicking::panic("assertion failed: self.lines.read().is_lines()")
};assert!(self.lines.read().is_lines());
83            let lines = self.lines();
84            // We only hash the relative position within this source_file
85            lines.len().hash_stable(hcx, hasher);
86            for &line in lines.iter() {
87                line.hash_stable(hcx, hasher);
88            }
89        }
90
91        // We only hash the relative position within this source_file
92        multibyte_chars.len().hash_stable(hcx, hasher);
93        for &char_pos in multibyte_chars.iter() {
94            char_pos.hash_stable(hcx, hasher);
95        }
96
97        normalized_pos.len().hash_stable(hcx, hasher);
98        for &char_pos in normalized_pos.iter() {
99            char_pos.hash_stable(hcx, hasher);
100        }
101
102        cnum.hash_stable(hcx, hasher);
103    }
104}
105
106impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
107    fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
108        // Unfortunately we cannot exhaustively list fields here, since the
109        // struct has private fields (to ensure its invariant is maintained)
110        self.enabled_lang_features().hash_stable(hcx, hasher);
111        self.enabled_lib_features().hash_stable(hcx, hasher);
112    }
113}
114
115impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::EnabledLangFeature {
116    fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
117        let rustc_feature::EnabledLangFeature { gate_name, attr_sp, stable_since } = self;
118        gate_name.hash_stable(hcx, hasher);
119        attr_sp.hash_stable(hcx, hasher);
120        stable_since.hash_stable(hcx, hasher);
121    }
122}
123
124impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::EnabledLibFeature {
125    fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
126        let rustc_feature::EnabledLibFeature { gate_name, attr_sp } = self;
127        gate_name.hash_stable(hcx, hasher);
128        attr_sp.hash_stable(hcx, hasher);
129    }
130}