macroonz_compiler/descriptor/types.rs
1//! The descriptor home's shared declarations: the names a descriptor grammar spells, the crate bindings a rendered path is rooted at, how a declaration's values refuse, how a helper body is not read, and the composition root.
2//!
3//! Declarations only.
4//! Every road that reaches a private field lives in `type_guard.rs`, this file's own child.
5//!
6//! The three kinds themselves are declared beside their own grammars, in `trial/`, `bench/`, and `mutation/`.
7
8use crate::bounded::NonEmpty;
9use crate::identity::{OwnerFact, OwnerIdentity};
10use crate::token::SpanHandle;
11
12#[path = "type_guard.rs"]
13mod guard;
14
15/// The one alphabet every spelling any grammar here renders in identifier position is admitted by, published from the nucleus every road already reads it through.
16pub use guard::{rendered_identifier, rendered_name};
17
18/// Segments one rendered path may carry after the crate binding it is rooted at.
19///
20/// A path reaching deeper than this has stopped naming an item and started describing a tree, and the repair is a re-export at the address rather than a longer spelling here.
21pub const PATH_SEGMENT_LIMIT: usize = 8;
22
23/// Providers one composition may declare.
24///
25/// The root is a list a reader audits in one sitting, which is the whole reason it is a declaration rather than a scan.
26pub const PROVIDER_LIMIT: usize = 64;
27
28/// The fact a grammar refusal cites as its repair.
29pub const DESCRIPTOR_MEANING_FACT: OwnerFact = OwnerFact {
30 home: "descriptor",
31 name: "a-descriptor-declaration-states-descriptor-meaning-alone",
32};
33
34/// The fact a vocabulary refusal cites as its repair.
35pub const RENDERED_SPELLING_FACT: OwnerFact = OwnerFact {
36 home: "descriptor",
37 name: "a-rendered-spelling-is-one-rust-identifier",
38};
39
40/// The helper attribute one descriptor grammar is written in.
41///
42/// The name is the caller's: a door registers the attribute it wants and hands the same value to the reading, so a refusal names the word an author actually wrote.
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
44pub struct Grammar {
45 /// The attribute's spelling, without its brackets.
46 pub attribute: &'static str,
47}
48
49/// Who emitted a generated table, in the words the emission writes.
50///
51/// Every name these services declare about their own act — the namespace, the producer, and the door — is stated here rather than composed inside a rendering, so an authored declaration cannot sign an act it did not perform.
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
53pub struct Emitter {
54 /// The owner the producer and the door are spelled under.
55 pub namespace: &'static str,
56 /// The producer that emits the table.
57 pub producer: &'static str,
58 /// The door the declaration was authored through.
59 pub door: &'static str,
60}
61
62/// A namespaced name: the owner that declares a spelling, and the spelling.
63///
64/// # Construction
65///
66/// Both parts are refused empty, so a name that names nothing is not a value anybody can hold.
67///
68/// # Ordering
69///
70/// The order is a storage order, over the namespace and then the stem. It ranks nothing.
71#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
72pub struct Name {
73 namespace: String,
74 stem: String,
75}
76
77/// The exported name a consumption target invokes one declaration's carrier by.
78///
79/// The author chooses it and the consumer's own compiler collision-checks it: the physical carrier is exported under a spelling nobody can know before expansion, so a declaration whose carrier nobody can address is a declaration whose rows nobody can run.
80#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
81pub struct SupportName(String);
82
83/// The module a stamped payload is written into, at the target that invokes the carrier.
84#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
85pub struct ModuleName(String);
86
87/// A type a rendered module declares.
88#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
89pub struct TypeName(String);
90
91/// A function a rendered module declares.
92///
93/// One type for every function a stamped module writes, because they all land in ONE namespace: an aggregate seat colliding with a row lens is the same defect as two lenses colliding, and one type is what lets a single pass say so.
94#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
95pub struct FunctionName(String);
96
97/// One physical dependency path a direct descriptor projection is rooted at.
98///
99/// Every segment is an ordinary Rust item name, so a renamed dependency and a facade re-export are both stated through the same shape: `renamed_harness` and `renamed_facade::harness` differ only in how many segments they carry.
100#[derive(Debug, Clone, PartialEq, Eq, Hash)]
101pub struct DirectBinding {
102 segments: NonEmpty<String, PATH_SEGMENT_LIMIT>,
103}
104
105crate::roster! {
106 /// What a declaration was stating when its values refused.
107 ///
108 /// One roster over every bounded and doubled seat the three grammars declare, so a seat admitted later is one row here rather than three rows of a refusal.
109 pub enum Seat {
110 /// A segment of a path rooted at a crate binding.
111 PathSegment = "path-segment",
112 /// An open classification a row carries.
113 Role = "role",
114 /// An open label a row carries beside its roles.
115 Tag = "tag",
116 /// One row of a declared table.
117 Row = "row",
118 /// One aggregate seat's group of rows.
119 SuiteGroup = "suite-group",
120 /// The function an aggregate seat is declared under.
121 Aggregate = "aggregate",
122 /// The function one row is declared under.
123 Lens = "lens",
124 /// One item emitted into a generated target namespace.
125 GeneratedItem = "generated-item",
126 /// One point of a declared input-size axis.
127 AxisSize = "axis-size",
128 /// One byte of a declared work formula.
129 WorkFormulaByte = "work-formula-byte",
130 /// One counted quantity a bench row reads against its formula.
131 WorkObservation = "work-observation",
132 /// One owner fact mapped to the claim that permits pressure on it.
133 FactMapping = "fact-mapping",
134 /// One claim's permission over a roster of operator families.
135 Permission = "permission",
136 /// One operator family a permission names.
137 OperatorFamily = "operator-family",
138 /// One declared alternative at a mutation point.
139 Alternative = "alternative",
140 /// One declared provider of descriptor material.
141 Provider = "provider",
142 }
143}
144
145/// How the values one descriptor declaration states are not a lawful declaration.
146///
147/// Seven shapes over one seat roster rather than one row per seat: what refuses is the SHAPE of the disagreement, and which seat it was about is the other half of the same sentence.
148#[must_use = "a declaration refusal names the seat the declaration did not fill"]
149#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
150pub enum DeclarationError {
151 /// A namespaced name states no owner.
152 NamespaceEmpty,
153 /// A namespaced name states no spelling.
154 StemEmpty,
155 /// A spelling written where the rendering needs an item name cannot be one: not one Rust identifier, or a keyword the language already took.
156 NotAnIdentifier,
157 /// A seat that admits no emptiness was stated empty.
158 Absent {
159 /// What was being stated.
160 seat: Seat,
161 },
162 /// Two of one roster's members carry one spelling.
163 Doubled {
164 /// What was being stated.
165 seat: Seat,
166 },
167 /// A roster states more members than its declared magnitude admits.
168 Unbounded {
169 /// What was being stated.
170 seat: Seat,
171 /// The declared magnitude.
172 bound: u64,
173 /// How many were stated.
174 observed: u64,
175 },
176 /// An input-size axis states too few sizes for a growth class to be read off it.
177 NotACurve {
178 /// How many sizes were stated.
179 observed: u64,
180 },
181}
182
183crate::roster! {
184 /// How one helper body's tokens do not say a declaration its grammar admits.
185 ///
186 /// Dependent checks in a declared order, so exactly one cause is true of any refused body: the attribute is found before its body is read, the body's clauses before their values, and a value's shape before the vocabulary that value states.
187 pub enum CaptureCause {
188 /// The declaration carries the helper more than once.
189 HelperDoubled = "helper-doubled",
190 /// The helper states no parenthesized body.
191 BodyAbsent = "body-absent",
192 /// A clause is not one key and one value.
193 ClauseUnread = "clause-unread",
194 /// A clause's key is not one this grammar declares.
195 ClauseUndeclared = "clause-undeclared",
196 /// One clause is stated twice.
197 ClauseDoubled = "clause-doubled",
198 /// A required clause is absent.
199 ClauseAbsent = "clause-absent",
200 /// A value written where a namespaced reference is required is not one.
201 ReferenceUnread = "reference-unread",
202 /// A value written where a bracketed roster is required is not one.
203 RosterUnread = "roster-unread",
204 /// A value written where a named group is required is not one.
205 GroupUnread = "group-unread",
206 /// A row is not one name and one clause body.
207 RowUnread = "row-unread",
208 /// A mapping is not one fact and one claim.
209 MappingUnread = "mapping-unread",
210 /// A permission is not one claim and one family roster.
211 PermissionUnread = "permission-unread",
212 /// A value written where a declared Rust item path is required is not one.
213 PathUnread = "path-unread",
214 /// The item the helper sits on does not state a declared order this grammar can read.
215 ItemUnread = "item-unread",
216 /// The declared order carries fewer than two members, so no transposition of it exists.
217 OrderUnpressable = "order-unpressable",
218 /// A choice is not one bare name.
219 ChoiceUnread = "choice-unread",
220 /// One name is chosen twice.
221 ChoiceDoubled = "choice-doubled",
222 /// A chosen name is not one the shadow roster covers.
223 NameUnshadowed = "name-unshadowed",
224 /// The declaration chooses no name at all.
225 NothingChosen = "nothing-chosen",
226 /// A fault phrase is not one this grammar reads.
227 PhraseUnread = "phrase-unread",
228 /// A phrase or a link names a node or link the declaration never declared.
229 EndpointUnknown = "endpoint-unknown",
230 /// An authored number outruns the width of the seat it is written for.
231 ///
232 /// Every numeric seat has the width its harness value declares, and the capture parses at exactly that width — because generated code cannot outsource range safety to rustc: the overflowing-literal diagnostic is suppressed inside a foreign macro expansion, and an out-of-range literal wraps silently where source-authored Rust would refuse.
233 NumberBeyondSeat = "number-beyond-seat",
234 /// A declared name is one the language or the generated module already owns.
235 ///
236 /// A Rust keyword, or a name the rendering itself writes beside the authored ones — either would collide in the adopter's build, inside an expansion whose lints rustc has silenced, so the name refuses here at its own token instead.
237 NameReserved = "name-reserved",
238 /// A separator stands where no clause does.
239 ///
240 /// A leading or doubled comma is a phrase the author wrote, and a reader that dropped the empty group it makes would read straight past it — so the dangling separator refuses at its own token. A trailing comma after the last clause is ordinary Rust and stays lawful.
241 SeparatorDangling = "separator-dangling",
242 }
243}
244
245/// Which of the two readings refused, carrying that reading's own answer whole.
246///
247/// Whether the tokens SAY a declaration is the grammar's question; whether the values they say are lawful is the vocabulary's, and each answers in its own words.
248#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
249pub enum CaptureIssue {
250 /// The authored grammar refused.
251 Grammar {
252 /// The established cause.
253 cause: CaptureCause,
254 },
255 /// The vocabulary refused a value the grammar read.
256 Vocabulary {
257 /// The vocabulary's own refusal.
258 refusal: DeclarationError,
259 },
260}
261
262/// How one helper body was not read: which grammar was reading, what it established, and the token.
263///
264/// Shared by every helper grammar this home declares.
265/// The TYPE a refusal travels in is the grammar's own, because a diagnostic's family tag is a fact about the type and two helper readings of one declaration must never derive one related identity.
266#[must_use = "a helper refusal names the grammar, the cause, and the token it was established at"]
267#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
268pub struct HelperRefusal {
269 grammar: Grammar,
270 issue: CaptureIssue,
271 at: SpanHandle,
272}
273
274/// One declared provider of descriptor material.
275///
276/// The owning-home seat is what keeps a composition a declaration rather than a registry: a provider does not stand on its own authority, it stands on the owner fact it derives from.
277#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
278pub struct Provider {
279 /// The provider's own identity.
280 pub identity: OwnerIdentity,
281 /// The owning home whose fact this provider derives from.
282 pub home: OwnerFact,
283 /// The kind it composes, by that kind's declared name.
284 pub composes: &'static str,
285}
286
287/// How a composition fails to be declarable.
288#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
289pub enum CompositionIssue {
290 /// One provider identity is declared more than once.
291 ProviderDoubled {
292 /// The doubled provider.
293 provider: OwnerIdentity,
294 },
295 /// The shared declaration vocabulary refused the provider seat.
296 Declaration {
297 /// The vocabulary's own refusal.
298 refusal: DeclarationError,
299 },
300}
301
302/// How one composition refused, with one required primary issue and every further issue the declaration pass established.
303#[must_use = "a composition refusal carries the issues its declaration pass established"]
304#[derive(Debug, Clone, PartialEq, Eq, Hash)]
305pub struct CompositionError {
306 first: CompositionIssue,
307 further: Vec<CompositionIssue>,
308}
309
310/// The one composition of descriptor-material providers: every provider that participates, named once.
311///
312/// Structurally non-empty — a composition with no provider is not a composition, it is silence — and duplicate-free by construction.
313#[derive(Debug, Clone, PartialEq, Eq, Hash)]
314pub struct Composition {
315 providers: NonEmpty<Provider, PROVIDER_LIMIT>,
316}