Coverage Report

Created: 2026-04-29 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/dhall-0.13.0/src/ctxt.rs
Line
Count
Source
1
use elsa::vec::FrozenVec;
2
use once_cell::sync::OnceCell;
3
use std::marker::PhantomData;
4
use std::ops::{Deref, Index};
5
6
use crate::semantics::{Import, ImportLocation, ImportNode};
7
use crate::syntax::Span;
8
use crate::Typed;
9
10
/////////////////////////////////////////////////////////////////////////////////////////////////////
11
// Ctxt
12
13
/// Implementation detail. Made public for the `Index` instances.
14
#[derive(Default)]
15
pub struct CtxtS<'cx> {
16
    imports: FrozenVec<Box<StoredImport<'cx>>>,
17
    import_alternatives: FrozenVec<Box<StoredImportAlternative<'cx>>>,
18
    import_results: FrozenVec<Box<StoredImportResult<'cx>>>,
19
}
20
21
/// Context for the dhall compiler. Stores various global maps.
22
/// Access the relevant value using `cx[id]`.
23
#[derive(Copy, Clone)]
24
pub struct Ctxt<'cx>(&'cx CtxtS<'cx>);
25
26
impl Ctxt<'_> {
27
0
    pub fn with_new<T>(f: impl for<'cx> FnOnce(Ctxt<'cx>) -> T) -> T {
28
0
        let cx = CtxtS::default();
29
0
        let cx = Ctxt(&cx);
30
0
        f(cx)
31
0
    }
Unexecuted instantiation: <dhall::ctxt::Ctxt>::with_new::<core::result::Result<core::result::Result<serde_dhall::value::Value, serde_dhall::error::Error>, dhall::error::Error>, <serde_dhall::options::de::Deserializer<serde_dhall::options::StaticAnnot>>::_parse<anise::structure::location::Location>::{closure#0}>
Unexecuted instantiation: <dhall::ctxt::Ctxt>::with_new::<core::result::Result<core::result::Result<serde_dhall::value::Value, serde_dhall::error::Error>, dhall::error::Error>, <serde_dhall::options::de::Deserializer<serde_dhall::options::StaticAnnot>>::_parse<anise::almanac::metaload::metaalmanac::MetaAlmanac>::{closure#0}>
Unexecuted instantiation: <dhall::ctxt::Ctxt>::with_new::<core::result::Result<core::result::Result<serde_dhall::value::Value, serde_dhall::error::Error>, dhall::error::Error>, <serde_dhall::options::de::Deserializer<serde_dhall::options::StaticAnnot>>::_parse<anise::structure::dataset::location_dhall::LocationDhallSet>::{closure#0}>
Unexecuted instantiation: <dhall::ctxt::Ctxt>::with_new::<core::result::Result<core::result::Result<serde_dhall::value::Value, serde_dhall::error::Error>, dhall::error::Error>, <serde_dhall::options::de::Deserializer<serde_dhall::options::NoAnnot>>::_parse<anise::almanac::metaload::metaalmanac::MetaAlmanac>::{closure#0}>
Unexecuted instantiation: <dhall::ctxt::Ctxt>::with_new::<core::result::Result<dhall::syntax::ast::expr::Expr, serde_dhall::error::Error>, <serde_dhall::value::SimpleValue>::to_expr::{closure#0}>
Unexecuted instantiation: <dhall::ctxt::Ctxt>::with_new::<dhall::syntax::ast::expr::Expr, <serde_dhall::value::SimpleType>::to_expr::{closure#0}>
Unexecuted instantiation: <dhall::ctxt::Ctxt>::with_new::<_, _>
32
}
33
impl<'cx> Deref for Ctxt<'cx> {
34
    type Target = &'cx CtxtS<'cx>;
35
0
    fn deref(&self) -> &&'cx CtxtS<'cx> {
36
0
        &self.0
37
0
    }
38
}
39
impl<'a, 'cx, T> Index<&'a T> for CtxtS<'cx>
40
where
41
    Self: Index<T>,
42
    T: Copy,
43
{
44
    type Output = <Self as Index<T>>::Output;
45
0
    fn index(&self, id: &'a T) -> &Self::Output {
46
0
        &self[*id]
47
0
    }
Unexecuted instantiation: <dhall::ctxt::CtxtS as core::ops::index::Index<&dhall::ctxt::ImportAlternativeId>>::index
Unexecuted instantiation: <dhall::ctxt::CtxtS as core::ops::index::Index<&dhall::ctxt::ImportId>>::index
48
}
49
50
/// Empty impl, because `FrozenVec` does not implement `Debug` and I can't be bothered to do it
51
/// myself.
52
impl<'cx> std::fmt::Debug for Ctxt<'cx> {
53
0
    fn fmt(&self, _: &mut std::fmt::Formatter) -> std::fmt::Result {
54
0
        Ok(())
55
0
    }
56
}
57
58
/////////////////////////////////////////////////////////////////////////////////////////////////////
59
// Imports
60
61
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
62
pub struct ImportId<'cx>(usize, PhantomData<&'cx ()>);
63
64
/// What's stored for each `ImportId`. Allows getting and setting a result for this import.
65
pub struct StoredImport<'cx> {
66
    cx: Ctxt<'cx>,
67
    pub base_location: ImportLocation,
68
    pub import: Import,
69
    pub span: Span,
70
    result: OnceCell<ImportResultId<'cx>>,
71
}
72
73
impl<'cx> StoredImport<'cx> {
74
    /// Get the id of the result of fetching this import. Returns `None` if the result has not yet
75
    /// been fetched.
76
0
    pub fn get_resultid(&self) -> Option<ImportResultId<'cx>> {
77
0
        self.result.get().copied()
78
0
    }
79
    /// Store the result of fetching this import.
80
0
    pub fn set_resultid(&self, res: ImportResultId<'cx>) {
81
0
        let _ = self.result.set(res);
82
0
    }
83
    /// Get the result of fetching this import. Returns `None` if the result has not yet been
84
    /// fetched.
85
0
    pub fn get_result(&self) -> Option<&'cx StoredImportResult<'cx>> {
86
0
        let res = self.get_resultid()?;
87
0
        Some(&self.cx[res])
88
0
    }
89
    /// Get the result of fetching this import. Panicx if the result has not yet been
90
    /// fetched.
91
0
    pub fn unwrap_result(&self) -> &'cx StoredImportResult<'cx> {
92
0
        self.get_result()
93
0
            .expect("imports should all have been resolved at this stage")
94
0
    }
95
    /// Store the result of fetching this import.
96
0
    pub fn set_result(
97
0
        &self,
98
0
        res: StoredImportResult<'cx>,
99
0
    ) -> ImportResultId<'cx> {
100
0
        let res = self.cx.push_import_result(res);
101
0
        self.set_resultid(res);
102
0
        res
103
0
    }
104
}
105
impl<'cx> Ctxt<'cx> {
106
    /// Store an import and the location relative to which it must be resolved.
107
0
    pub fn push_import(
108
0
        self,
109
0
        base_location: ImportLocation,
110
0
        import: Import,
111
0
        span: Span,
112
0
    ) -> ImportId<'cx> {
113
0
        let stored = StoredImport {
114
0
            cx: self,
115
0
            base_location,
116
0
            import,
117
0
            span,
118
0
            result: OnceCell::new(),
119
0
        };
120
0
        let id = self.0.imports.len();
121
0
        self.0.imports.push(Box::new(stored));
122
0
        ImportId(id, PhantomData)
123
0
    }
124
}
125
impl<'cx> Index<ImportId<'cx>> for CtxtS<'cx> {
126
    type Output = StoredImport<'cx>;
127
0
    fn index(&self, id: ImportId<'cx>) -> &StoredImport<'cx> {
128
0
        &self.imports[id.0]
129
0
    }
130
}
131
132
/////////////////////////////////////////////////////////////////////////////////////////////////////
133
// Import alternatives
134
135
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
136
pub struct ImportAlternativeId<'cx>(usize, PhantomData<&'cx ()>);
137
138
/// What's stored for each `ImportAlternativeId`.
139
pub struct StoredImportAlternative<'cx> {
140
    pub left_imports: Box<[ImportNode<'cx>]>,
141
    pub right_imports: Box<[ImportNode<'cx>]>,
142
    /// `true` for left, `false` for right.
143
    selected: OnceCell<bool>,
144
}
145
146
impl<'cx> StoredImportAlternative<'cx> {
147
    /// Get which alternative got selected. `true` for left, `false` for right.
148
0
    pub fn get_selected(&self) -> Option<bool> {
149
0
        self.selected.get().copied()
150
0
    }
151
    /// Get which alternative got selected. `true` for left, `false` for right.
152
0
    pub fn unwrap_selected(&self) -> bool {
153
0
        self.get_selected()
154
0
            .expect("imports should all have been resolved at this stage")
155
0
    }
156
    /// Set which alternative got selected. `true` for left, `false` for right.
157
0
    pub fn set_selected(&self, selected: bool) {
158
0
        let _ = self.selected.set(selected);
159
0
    }
160
}
161
impl<'cx> Ctxt<'cx> {
162
0
    pub fn push_import_alternative(
163
0
        self,
164
0
        left_imports: Box<[ImportNode<'cx>]>,
165
0
        right_imports: Box<[ImportNode<'cx>]>,
166
0
    ) -> ImportAlternativeId<'cx> {
167
0
        let stored = StoredImportAlternative {
168
0
            left_imports,
169
0
            right_imports,
170
0
            selected: OnceCell::new(),
171
0
        };
172
0
        let id = self.0.import_alternatives.len();
173
0
        self.0.import_alternatives.push(Box::new(stored));
174
0
        ImportAlternativeId(id, PhantomData)
175
0
    }
176
}
177
impl<'cx> Index<ImportAlternativeId<'cx>> for CtxtS<'cx> {
178
    type Output = StoredImportAlternative<'cx>;
179
0
    fn index(
180
0
        &self,
181
0
        id: ImportAlternativeId<'cx>,
182
0
    ) -> &StoredImportAlternative<'cx> {
183
0
        &self.import_alternatives[id.0]
184
0
    }
185
}
186
187
/////////////////////////////////////////////////////////////////////////////////////////////////////
188
// Import results
189
190
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
191
pub struct ImportResultId<'cx>(usize, PhantomData<&'cx ()>);
192
193
type StoredImportResult<'cx> = Typed<'cx>;
194
195
impl<'cx> Ctxt<'cx> {
196
    /// Store the result of fetching an import.
197
0
    pub fn push_import_result(
198
0
        self,
199
0
        res: StoredImportResult<'cx>,
200
0
    ) -> ImportResultId<'cx> {
201
0
        let id = self.0.import_results.len();
202
0
        self.0.import_results.push(Box::new(res));
203
0
        ImportResultId(id, PhantomData)
204
0
    }
205
}
206
impl<'cx> Index<ImportResultId<'cx>> for CtxtS<'cx> {
207
    type Output = StoredImportResult<'cx>;
208
0
    fn index(&self, id: ImportResultId<'cx>) -> &StoredImportResult<'cx> {
209
0
        &self.import_results[id.0]
210
0
    }
211
}