/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 | | } |