1mod query;
5
6use core::fmt;
7use core::mem::take;
8use core::num::NonZeroUsize;
9
10use rust_alloc::rc::Rc;
11
12pub(crate) use self::query::{Query, QueryInner, QuerySource};
13
14use crate::alloc::prelude::*;
15use crate::ast::{self, OptionSpanned, Span, Spanned};
16use crate::compile::{ir, Doc, Error, ItemId, ItemMeta, Location, ModId, Result};
17use crate::grammar::{Ignore, Node, NodeAt, NodeId, Tree};
18use crate::hash::Hash;
19use crate::hir;
20use crate::indexing;
21use crate::parse::NonZeroId;
22use crate::runtime::format;
23use crate::runtime::Call;
24use crate::{self as rune, SourceId};
25
26#[derive(Default, Debug, TryClone, Clone, Copy)]
28#[try_clone(copy)]
29pub(crate) enum Used {
30 Unused,
32 #[default]
34 Used,
35}
36
37impl Used {
38 pub(crate) fn is_unused(self) -> bool {
40 matches!(self, Self::Unused)
41 }
42}
43
44pub(crate) struct Named<'ast> {
46 pub(crate) module: ModId,
48 pub(crate) item: ItemId,
50 pub(crate) trailing: usize,
52 pub(crate) parameters: [Option<(
54 &'ast dyn Spanned,
55 &'ast ast::AngleBracketed<ast::PathSegmentExpr, T![,]>,
56 )>; 2],
57}
58
59impl fmt::Display for Named<'_> {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 fmt::Display::fmt(&self.item, f)
62 }
63}
64
65pub(crate) enum Named2Kind {
66 Full,
68 Ident(ast::Ident),
70 SelfValue(#[allow(unused)] ast::SelfValue),
72}
73
74pub(crate) struct Named2<'a> {
76 pub(crate) module: ModId,
78 pub(crate) kind: Named2Kind,
80 pub(crate) item: ItemId,
82 pub(crate) trailing: usize,
84 pub(crate) parameters: [Option<Node<'a>>; 2],
86}
87
88impl fmt::Display for Named2<'_> {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 fmt::Display::fmt(&self.item, f)
91 }
92}
93
94#[allow(clippy::large_enum_variant)]
96pub(crate) enum BuiltInMacro {
97 Template(BuiltInTemplate),
98 Format(BuiltInFormat),
99 File(BuiltInFile),
100 Line(BuiltInLine),
101}
102
103pub(crate) enum BuiltInMacro2 {
104 File(ast::LitStr),
105 Line(usize),
106 Template(Rc<Tree>, BuiltInLiteral),
107 Format(Rc<Tree>),
108}
109
110#[derive(Spanned)]
112pub(crate) struct BuiltInTemplate {
113 #[rune(span)]
115 pub(crate) span: Span,
116 pub(crate) from_literal: bool,
118 pub(crate) exprs: Vec<ast::Expr>,
120}
121
122#[derive(Spanned)]
124pub(crate) struct BuiltInFormat {
125 #[rune(span)]
126 pub(crate) span: Span,
127 pub(crate) fill: Option<char>,
129 pub(crate) align: Option<format::Alignment>,
131 pub(crate) width: Option<NonZeroUsize>,
133 pub(crate) precision: Option<NonZeroUsize>,
135 pub(crate) flags: Option<format::Flags>,
137 pub(crate) format_type: Option<format::Type>,
139 pub(crate) value: ast::Expr,
141}
142
143#[derive(Debug, TryClone, Clone, Copy, PartialEq, Eq, Spanned)]
145#[try_clone(copy)]
146pub(crate) struct BuiltInFile {
147 pub(crate) value: ast::Lit,
149}
150
151#[derive(Debug, TryClone, Clone, Copy, PartialEq, Eq, Spanned)]
153#[try_clone(copy)]
154pub(crate) struct BuiltInLine {
155 pub(crate) value: ast::Lit,
157}
158
159#[derive(Debug, TryClone)]
160pub(crate) struct Closure<'hir> {
161 pub(crate) hir: &'hir hir::ExprClosure<'hir>,
163 pub(crate) call: Call,
165}
166
167#[derive(Debug, TryClone)]
168pub(crate) struct AsyncBlock<'hir> {
169 pub(crate) hir: &'hir hir::AsyncBlock<'hir>,
171 pub(crate) call: Call,
173}
174
175#[derive(Debug, TryClone)]
177pub(crate) enum SecondaryBuild<'hir> {
178 Closure(Closure<'hir>),
179 AsyncBlock(AsyncBlock<'hir>),
180}
181
182#[derive(Debug, TryClone)]
184pub(crate) struct SecondaryBuildEntry<'hir> {
185 pub(crate) item_meta: ItemMeta,
187 pub(crate) build: SecondaryBuild<'hir>,
189}
190
191#[derive(Debug, TryClone)]
193pub(crate) enum Build {
194 Function(indexing::Function),
195 Unused,
196 Import(indexing::Import),
197 ReExport,
199 Query,
201}
202
203#[derive(Debug, TryClone)]
205pub(crate) struct BuildEntry {
206 pub(crate) item_meta: ItemMeta,
208 pub(crate) build: Build,
210}
211
212pub(crate) enum ImplItemKind {
214 Ast {
215 path: Box<ast::Path>,
217 functions: Vec<ast::ItemFn>,
219 },
220 Node {
221 path: NodeAt,
223 functions: Vec<(NodeId, Attrs)>,
225 },
226}
227
228#[must_use = "must be consumed"]
229#[derive(Default, Debug)]
230pub(crate) struct Attrs {
231 pub(crate) test: Option<Span>,
232 pub(crate) bench: Option<Span>,
233 pub(crate) docs: Vec<Doc>,
234 pub(crate) builtin: Option<(Span, BuiltInLiteral)>,
235}
236
237impl Attrs {
238 pub(crate) fn deny_non_docs(self, cx: &mut dyn Ignore<'_>) -> Result<()> {
239 if let Some(span) = self.test {
240 cx.error(Error::msg(span, "unsupported #[test] attribute"))?;
241 }
242
243 if let Some(span) = self.bench {
244 cx.error(Error::msg(span, "unsupported #[bench] attribute"))?;
245 }
246
247 if let Some((span, _)) = self.builtin {
248 cx.error(Error::msg(span, "unsupported #[builtin] attribute"))?;
249 }
250
251 Ok(())
252 }
253
254 pub(crate) fn deny_any(self, cx: &mut dyn Ignore<'_>) -> Result<()> {
255 if let Some(span) = self.docs.option_span() {
256 cx.error(Error::msg(span, "unsupported documentation"))?;
257 }
258
259 self.deny_non_docs(cx)?;
260 Ok(())
261 }
262}
263
264pub(crate) struct ImplItem {
266 pub(crate) kind: ImplItemKind,
268 pub(crate) location: Location,
270 pub(crate) root: Option<SourceId>,
272 pub(crate) nested_item: Option<Span>,
274 pub(crate) macro_depth: usize,
276}
277
278#[must_use = "Must be used to report errors"]
280pub(crate) struct ExpandMacroBuiltin {
281 pub(crate) id: NonZeroId,
283 pub(crate) node: NodeAt,
285 pub(crate) location: Location,
287 pub(crate) root: Option<SourceId>,
289 pub(crate) macro_depth: usize,
291 pub(crate) item: indexing::IndexItem,
293 pub(crate) literal: BuiltInLiteral,
295}
296
297impl ExpandMacroBuiltin {
298 pub(crate) fn finish(self) -> Result<NonZeroId> {
300 if let BuiltInLiteral::Yes(span) = self.literal {
301 return Err(Error::msg(
302 span,
303 "#[builtin(literal)] option is not allowed",
304 ));
305 }
306
307 Ok(self.id)
308 }
309}
310
311#[derive(Default, Debug)]
313pub(crate) enum BuiltInLiteral {
314 Yes(Span),
315 #[default]
316 No,
317}
318
319impl BuiltInLiteral {
320 pub(crate) fn take(&mut self) -> Self {
322 take(self)
323 }
324
325 pub(crate) fn is_yes(&self) -> bool {
327 matches!(self, Self::Yes(_))
328 }
329}
330
331pub(crate) enum DeferEntry {
333 ImplItem(ImplItem),
334 ExpandMacroBuiltin(ExpandMacroBuiltin),
335 ExpandMacroCall(ExpandMacroBuiltin),
336}
337
338pub(crate) struct ConstFn<'hir> {
340 pub(crate) item_meta: ItemMeta,
342 pub(crate) ir_fn: ir::IrFn,
344 #[allow(unused)]
346 pub(crate) hir: hir::ItemFn<'hir>,
347}
348
349pub(crate) enum ExpandedMacro {
351 Builtin(BuiltInMacro2),
353 Tree(Rc<Tree>),
355}
356
357#[derive(Default)]
359pub(crate) struct GenericsParameters {
360 pub(crate) trailing: usize,
361 pub(crate) parameters: [Option<Hash>; 2],
362}
363
364impl GenericsParameters {
365 pub(crate) fn is_empty(&self) -> bool {
366 self.parameters.iter().all(|p| p.is_none())
367 }
368}
369
370impl fmt::Debug for GenericsParameters {
371 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
372 let mut f = f.debug_list();
373
374 for p in &self.parameters[2 - self.trailing..] {
375 f.entry(p);
376 }
377
378 f.finish()
379 }
380}
381
382impl AsRef<GenericsParameters> for GenericsParameters {
383 #[inline]
384 fn as_ref(&self) -> &GenericsParameters {
385 self
386 }
387}