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 as rune;
15use crate::alloc::path::PathBuf;
16use crate::alloc::prelude::*;
17use crate::ast::{self, OptionSpanned, Span, Spanned};
18use crate::compile::{ir, Doc, Error, ItemId, ItemMeta, Location, ModId, Result};
19use crate::grammar::{Ignore, Node, NodeAt, NodeId, Tree};
20use crate::hash::Hash;
21use crate::hir;
22use crate::indexing;
23use crate::parse::NonZeroId;
24use crate::runtime::format;
25use crate::runtime::Call;
26
27#[derive(Default, Debug, TryClone, Clone, Copy)]
29#[try_clone(copy)]
30pub(crate) enum Used {
31 Unused,
33 #[default]
35 Used,
36}
37
38impl Used {
39 pub(crate) fn is_unused(self) -> bool {
41 matches!(self, Self::Unused)
42 }
43}
44
45pub(crate) struct Named<'ast> {
47 pub(crate) module: ModId,
49 pub(crate) item: ItemId,
51 pub(crate) trailing: usize,
53 pub(crate) parameters: [Option<(
55 &'ast dyn Spanned,
56 &'ast ast::AngleBracketed<ast::PathSegmentExpr, T![,]>,
57 )>; 2],
58}
59
60impl fmt::Display for Named<'_> {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 fmt::Display::fmt(&self.item, f)
63 }
64}
65
66pub(crate) enum Named2Kind {
67 Full,
69 Ident(ast::Ident),
71 SelfValue(#[allow(unused)] ast::SelfValue),
73}
74
75pub(crate) struct Named2<'a> {
77 pub(crate) module: ModId,
79 pub(crate) kind: Named2Kind,
81 pub(crate) item: ItemId,
83 pub(crate) trailing: usize,
85 pub(crate) parameters: [Option<Node<'a>>; 2],
87}
88
89impl fmt::Display for Named2<'_> {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 fmt::Display::fmt(&self.item, f)
92 }
93}
94
95#[allow(clippy::large_enum_variant)]
97pub(crate) enum BuiltInMacro {
98 Template(BuiltInTemplate),
99 Format(BuiltInFormat),
100 File(BuiltInFile),
101 Line(BuiltInLine),
102}
103
104pub(crate) enum BuiltInMacro2 {
105 File(ast::LitStr),
106 Line(usize),
107 Template(Rc<Tree>, BuiltInLiteral),
108 Format(Rc<Tree>),
109}
110
111#[derive(Spanned)]
113pub(crate) struct BuiltInTemplate {
114 #[rune(span)]
116 pub(crate) span: Span,
117 pub(crate) from_literal: bool,
119 pub(crate) exprs: Vec<ast::Expr>,
121}
122
123#[derive(Spanned)]
125pub(crate) struct BuiltInFormat {
126 #[rune(span)]
127 pub(crate) span: Span,
128 pub(crate) fill: Option<char>,
130 pub(crate) align: Option<format::Alignment>,
132 pub(crate) width: Option<NonZeroUsize>,
134 pub(crate) precision: Option<NonZeroUsize>,
136 pub(crate) flags: Option<format::Flags>,
138 pub(crate) format_type: Option<format::Type>,
140 pub(crate) value: ast::Expr,
142}
143
144#[derive(Debug, TryClone, Clone, Copy, PartialEq, Eq, Spanned)]
146#[try_clone(copy)]
147pub(crate) struct BuiltInFile {
148 pub(crate) value: ast::Lit,
150}
151
152#[derive(Debug, TryClone, Clone, Copy, PartialEq, Eq, Spanned)]
154#[try_clone(copy)]
155pub(crate) struct BuiltInLine {
156 pub(crate) value: ast::Lit,
158}
159
160#[derive(Debug, TryClone)]
161pub(crate) struct Closure<'hir> {
162 pub(crate) hir: &'hir hir::ExprClosure<'hir>,
164 pub(crate) call: Call,
166}
167
168#[derive(Debug, TryClone)]
169pub(crate) struct AsyncBlock<'hir> {
170 pub(crate) hir: &'hir hir::AsyncBlock<'hir>,
172 pub(crate) call: Call,
174}
175
176#[derive(Debug, TryClone)]
178pub(crate) enum SecondaryBuild<'hir> {
179 Closure(Closure<'hir>),
180 AsyncBlock(AsyncBlock<'hir>),
181}
182
183#[derive(Debug, TryClone)]
185pub(crate) struct SecondaryBuildEntry<'hir> {
186 pub(crate) item_meta: ItemMeta,
188 pub(crate) build: SecondaryBuild<'hir>,
190}
191
192#[derive(Debug, TryClone)]
194pub(crate) enum Build {
195 Function(indexing::Function),
196 Unused,
197 Import(indexing::Import),
198 ReExport,
200 Query,
202}
203
204#[derive(Debug, TryClone)]
206pub(crate) struct BuildEntry {
207 pub(crate) item_meta: ItemMeta,
209 pub(crate) build: Build,
211}
212
213pub(crate) enum ImplItemKind {
215 Ast {
216 path: Box<ast::Path>,
218 functions: Vec<ast::ItemFn>,
220 },
221 Node {
222 path: NodeAt,
224 functions: Vec<(NodeId, Attrs)>,
226 },
227}
228
229#[must_use = "must be consumed"]
230#[derive(Default, Debug)]
231pub(crate) struct Attrs {
232 pub(crate) test: Option<Span>,
233 pub(crate) bench: Option<Span>,
234 pub(crate) docs: Vec<Doc>,
235 pub(crate) builtin: Option<(Span, BuiltInLiteral)>,
236}
237
238impl Attrs {
239 pub(crate) fn deny_non_docs(self, cx: &mut dyn Ignore<'_>) -> Result<()> {
240 if let Some(span) = self.test {
241 cx.error(Error::msg(span, "unsupported #[test] attribute"))?;
242 }
243
244 if let Some(span) = self.bench {
245 cx.error(Error::msg(span, "unsupported #[bench] attribute"))?;
246 }
247
248 if let Some((span, _)) = self.builtin {
249 cx.error(Error::msg(span, "unsupported #[builtin] attribute"))?;
250 }
251
252 Ok(())
253 }
254
255 pub(crate) fn deny_any(self, cx: &mut dyn Ignore<'_>) -> Result<()> {
256 if let Some(span) = self.docs.option_span() {
257 cx.error(Error::msg(span, "unsupported documentation"))?;
258 }
259
260 self.deny_non_docs(cx)?;
261 Ok(())
262 }
263}
264
265pub(crate) struct ImplItem {
267 pub(crate) kind: ImplItemKind,
269 pub(crate) location: Location,
271 pub(crate) root: Option<PathBuf>,
273 pub(crate) nested_item: Option<Span>,
275 pub(crate) macro_depth: usize,
277}
278
279#[must_use = "Must be used to report errors"]
281pub(crate) struct ExpandMacroBuiltin {
282 pub(crate) id: NonZeroId,
284 pub(crate) node: NodeAt,
286 pub(crate) location: Location,
288 pub(crate) root: Option<PathBuf>,
290 pub(crate) macro_depth: usize,
292 pub(crate) item: indexing::IndexItem,
294 pub(crate) literal: BuiltInLiteral,
296}
297
298impl ExpandMacroBuiltin {
299 pub(crate) fn finish(self) -> Result<NonZeroId> {
301 if let BuiltInLiteral::Yes(span) = self.literal {
302 return Err(Error::msg(
303 span,
304 "#[builtin(literal)] option is not allowed",
305 ));
306 }
307
308 Ok(self.id)
309 }
310}
311
312#[derive(Default, Debug)]
314pub(crate) enum BuiltInLiteral {
315 Yes(Span),
316 #[default]
317 No,
318}
319
320impl BuiltInLiteral {
321 pub(crate) fn take(&mut self) -> Self {
323 take(self)
324 }
325
326 pub(crate) fn is_yes(&self) -> bool {
328 matches!(self, Self::Yes(_))
329 }
330}
331
332pub(crate) enum DeferEntry {
334 ImplItem(ImplItem),
335 ExpandMacroBuiltin(ExpandMacroBuiltin),
336 ExpandMacroCall(ExpandMacroBuiltin),
337}
338
339pub(crate) struct ConstFn<'hir> {
341 pub(crate) item_meta: ItemMeta,
343 pub(crate) ir_fn: ir::IrFn,
345 #[allow(unused)]
347 pub(crate) hir: hir::ItemFn<'hir>,
348}
349
350pub(crate) enum ExpandedMacro {
352 Builtin(BuiltInMacro2),
354 Tree(Rc<Tree>),
356}
357
358#[derive(Default)]
360pub(crate) struct GenericsParameters {
361 pub(crate) trailing: usize,
362 pub(crate) parameters: [Option<Hash>; 2],
363}
364
365impl GenericsParameters {
366 pub(crate) fn is_empty(&self) -> bool {
367 self.parameters.iter().all(|p| p.is_none())
368 }
369}
370
371impl fmt::Debug for GenericsParameters {
372 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
373 let mut f = f.debug_list();
374
375 for p in &self.parameters[2 - self.trailing..] {
376 f.entry(p);
377 }
378
379 f.finish()
380 }
381}
382
383impl AsRef<GenericsParameters> for GenericsParameters {
384 #[inline]
385 fn as_ref(&self) -> &GenericsParameters {
386 self
387 }
388}