Skip to main content

rustc_query_system/ich/
hcx.rs

1use rustc_data_structures::stable_hasher::HashingControls;
2use rustc_hir::def_id::{DefId, LocalDefId};
3use rustc_hir::definitions::DefPathHash;
4use rustc_session::Session;
5use rustc_session::cstore::Untracked;
6use rustc_span::source_map::SourceMap;
7use rustc_span::{BytePos, CachingSourceMapView, DUMMY_SP, SourceFile, Span, SpanData};
8
9// Very often, we are hashing something that does not need the `CachingSourceMapView`, so we
10// initialize it lazily.
11#[derive(#[automatically_derived]
impl<'a> ::core::clone::Clone for CachingSourceMap<'a> {
    #[inline]
    fn clone(&self) -> CachingSourceMap<'a> {
        match self {
            CachingSourceMap::Unused(__self_0) =>
                CachingSourceMap::Unused(::core::clone::Clone::clone(__self_0)),
            CachingSourceMap::InUse(__self_0) =>
                CachingSourceMap::InUse(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone)]
12enum CachingSourceMap<'a> {
13    Unused(&'a SourceMap),
14    InUse(CachingSourceMapView<'a>),
15}
16
17/// This is the context state available during incr. comp. hashing. It contains
18/// enough information to transform `DefId`s and `HirId`s into stable `DefPath`s (i.e.,
19/// a reference to the `TyCtxt`) and it holds a few caches for speeding up various
20/// things (e.g., each `DefId`/`DefPath` is only hashed once).
21#[derive(#[automatically_derived]
impl<'a> ::core::clone::Clone for StableHashingContext<'a> {
    #[inline]
    fn clone(&self) -> StableHashingContext<'a> {
        StableHashingContext {
            untracked: ::core::clone::Clone::clone(&self.untracked),
            incremental_ignore_spans: ::core::clone::Clone::clone(&self.incremental_ignore_spans),
            caching_source_map: ::core::clone::Clone::clone(&self.caching_source_map),
            hashing_controls: ::core::clone::Clone::clone(&self.hashing_controls),
        }
    }
}Clone)]
22pub struct StableHashingContext<'a> {
23    untracked: &'a Untracked,
24    // The value of `-Z incremental-ignore-spans`.
25    // This field should only be used by `unstable_opts_incremental_ignore_span`
26    incremental_ignore_spans: bool,
27    caching_source_map: CachingSourceMap<'a>,
28    hashing_controls: HashingControls,
29}
30
31impl<'a> StableHashingContext<'a> {
32    #[inline]
33    pub fn new(sess: &'a Session, untracked: &'a Untracked) -> Self {
34        let hash_spans_initial = !sess.opts.unstable_opts.incremental_ignore_spans;
35
36        StableHashingContext {
37            untracked,
38            incremental_ignore_spans: sess.opts.unstable_opts.incremental_ignore_spans,
39            caching_source_map: CachingSourceMap::Unused(sess.source_map()),
40            hashing_controls: HashingControls { hash_spans: hash_spans_initial },
41        }
42    }
43
44    #[inline]
45    pub fn while_hashing_spans<F: FnOnce(&mut Self)>(&mut self, hash_spans: bool, f: F) {
46        let prev_hash_spans = self.hashing_controls.hash_spans;
47        self.hashing_controls.hash_spans = hash_spans;
48        f(self);
49        self.hashing_controls.hash_spans = prev_hash_spans;
50    }
51
52    #[inline]
53    fn source_map(&mut self) -> &mut CachingSourceMapView<'a> {
54        match self.caching_source_map {
55            CachingSourceMap::InUse(ref mut sm) => sm,
56            CachingSourceMap::Unused(sm) => {
57                self.caching_source_map = CachingSourceMap::InUse(CachingSourceMapView::new(sm));
58                self.source_map() // this recursive call will hit the `InUse` case
59            }
60        }
61    }
62
63    #[inline]
64    pub fn hashing_controls(&self) -> HashingControls {
65        self.hashing_controls
66    }
67}
68
69impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
70    #[inline]
71    fn unstable_opts_incremental_ignore_spans(&self) -> bool {
72        self.incremental_ignore_spans
73    }
74
75    #[inline]
76    fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
77        if let Some(def_id) = def_id.as_local() {
78            self.untracked.definitions.read().def_path_hash(def_id)
79        } else {
80            self.untracked.cstore.read().def_path_hash(def_id)
81        }
82    }
83
84    #[inline]
85    fn def_span(&self, def_id: LocalDefId) -> Span {
86        self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
87    }
88
89    #[inline]
90    fn span_data_to_lines_and_cols(
91        &mut self,
92        span: &SpanData,
93    ) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)> {
94        self.source_map().span_data_to_lines_and_cols(span)
95    }
96
97    #[inline]
98    fn hashing_controls(&self) -> HashingControls {
99        self.hashing_controls
100    }
101}
102
103impl<'a> rustc_abi::HashStableContext for StableHashingContext<'a> {}
104impl<'a> rustc_ast::HashStableContext for StableHashingContext<'a> {}
105impl<'a> rustc_hir::HashStableContext for StableHashingContext<'a> {}
106impl<'a> rustc_session::HashStableContext for StableHashingContext<'a> {}