litho_diagnostics/
lib.rs

1#![deny(missing_docs)]
2//! This crate implements all diagnostics that [Litho](https://litho.dev) (a
3//! GraphQL framework) can emit.
4//!
5//! Within Litho, these diagnostics are emitted by the lexer, parser, type
6//! checker and compiler. Typically, each of those can emit multiple diagnostics
7//! without bailing out after the first diagnostic, but the compiler will only
8//! advance to the next phase if there are no errors in the previous phase.
9//!
10//! All diagnostics are generated by a DSL Macro (see source code), implement
11//! [`DiagnosticInfo<S>`] and are generic with respect to the span that
12//! triggered the diagnostic. Diagnostics consist of an error code, name,
13//! message and zero or more labels. Labels are additional hints that refer to a
14//! separate span in the source code.
15//!
16//! ### Example
17//!
18//! Below is an example of a diagnostic that Litho generates:
19//! [`MissingArgumentsClosingParentheses`]. It starts with the
20//! [`code`](DiagnosticInfo::code) in square brackets, followed by a
21//! [`message`](DiagnosticInfo::message). It shows a snippet of the lines that
22//! caused the diagnostic along with the primary span that starts at
23//! `graphql:6:20`. And finally, it also shows two more spans
24//! ([`first`](MissingArgumentsClosingParentheses::first) and
25//! [`second`](MissingArgumentsClosingParentheses::second)) with additional
26//! hints.
27//!
28//! ```graphql
29//! [E0006] Error: Arguments are missing closing parenthesis.
30//!
31//!    ╭─[graphql:6:20]
32//!    │
33//!  6 │     field(arg: true
34//!    ·          ┬         ┬  
35//!    ·          ╰──────────── This `(` here ...
36//!    ·                    │  
37//!    ·                    ╰── ... should have a matching `)` here.
38//! ───╯
39//! ```
40
41#[macro_use]
42mod dsl;
43
44pub use dsl::DiagnosticInfo;
45
46diagnostics! {
47    E0001 => UnrecognizedTokens @ span {
48        "Syntax error.",
49        "Couldn't recognize these tokens here." @ span
50    },
51    E0002 => MissingOperationDefinitionName @ span {
52        "Operation definition must have a name.",
53        "Expected a name for operation definition here." @ span
54    } @deprecated,
55    E0003 => MissingOperationDefinitionSelectionSet @ span {
56        "Operation definition must have a selection set.",
57        "Expected a selection set for operation definition here." @ span
58    },
59    E0004 => MissingSelectionSetClosingBrace @ second {
60        "Selection set is missing closing curly brace.",
61        "This `{{` here ..." @ first,
62        "... should have a matching `}}` here." @ second
63    },
64    E0005 => MissingFieldName @ span {
65        "Field must have a name.",
66        "Missing name of this field here." @ span
67    },
68    E0006 => MissingArgumentsClosingParentheses @ second {
69        "Arguments are missing closing parenthesis.",
70        "This `(` here ..." @ first,
71        "... should have a matching `)` here." @ second
72    },
73    E0007 => MissingArgumentColon @ span {
74        "Argument is missing colon.",
75        "Argument should have a colon here." @ span
76    },
77    E0008 => MissingArgumentValue @ span {
78        "Argument is missing value.",
79        "Argument should have a value here." @ span
80    },
81    E0009 => MissingInlineFragmentSelectionSet @ span {
82        "Inline fragment is missing selection set.",
83        "Inline fragment here should have a selection set." @ span
84    },
85    E0010 => MissingFragmentName @ span {
86        "Fragment definition must have a name.",
87        "Fragment definition here does not have a name." @ span
88    },
89    E0011 => MissingFragmentTypeCondition @ span {
90        "Fragment definition must have a type condition.",
91        "Fragment definition here does not have a type condition." @ span
92    },
93    E0012 => MissingFragmentSelectionSet @ span {
94        "Fragment definition must have a selection set.",
95        "Fragment definition here does not have a selection set." @ span
96    },
97    E0013 => MissingTypeConditionNamedType @ span {
98        "Type condition must have a named type.",
99        "Type condition here does not have a named type." @ span
100    },
101    E0014 => MissingListValueClosingBracket @ second {
102        "List value must have closing bracket.",
103        "This `[` here ..." @ first,
104        "... should have a matching `]` here." @ second
105    },
106    E0015 => MissingObjectValueClosingBrace @ second {
107        "Object value must have closing brace.",
108        "This `{{` here ..." @ first,
109        "... should have a matching `}}` here." @ second
110    },
111    E0016 => MissingObjectFieldColon @ span {
112        "Object field must have a colon.",
113        "This object field here is missing a colon." @ span
114    },
115    E0017 => MissingObjectFieldValue @ span {
116        "Object field must have a value.",
117        "This object field here is missing a value." @ span
118    },
119    E0018 => MissingVariableDefinitionsClosingParenthesis @ second {
120        "Variable definitions must have a closing parenthesis.",
121        "This `(` here ..." @ first,
122        "... must have a matching `)` here." @ second
123    },
124    E0019 => MissingVariableDefinitionColon @ span {
125        "Variable definition must have a colon.",
126        "This variable definition here is missing a colon." @ span
127    },
128    E0020 => MissingVariableDefinitionType @ span {
129        "Variable definition must have a type.",
130        "This variable definition here is missing a type." @ span
131    },
132    E0021 => MissingDefaultValue @ span {
133        "Default value must have a value.",
134        "This default value here is missing a value." @ span
135    },
136    E0022 => MissingListTypeClosingBracket @ second {
137        "List type must have a closing bracket.",
138        "This `[` here ..." @ first,
139        "... must have a matching `]` here." @ second
140    },
141    E0023 => MissingListTypeWrappedType @ span {
142        "List type must wrap another type.",
143        "This list type here is missing a wrapped type." @ span
144    },
145    E0024 => MissingDirectiveName @ span {
146        "Directive must have a name.",
147        "This directive here is missing a name." @ span
148    },
149    E0025 => MissingRootOperationTypeDefinitions @ span {
150        "Schema definition must define one or more root operation types.",
151        "This schema definition doesn't define any root operation types." @ span
152    },
153    E0026 => MissingRootOperationTypeDefinitionsClosingBrace @ second {
154        "Root operation type definitions must have a closing brace.",
155        "This `{{` here ..." @ first,
156        "... should have a matching `}}` here." @ second
157    },
158    E0027 => MissingRootOperationTypeDefinitionColon @ span {
159        "Root operation type definition must have a colon.",
160        "This root operation type definition here is missing a colon." @ span
161    },
162    E0028 => MissingRootOperationTypeDefinitionNamedType @ span {
163        "Root operation type definition must have a named type.",
164        "This root operation type definition here is missing a named type." @ span
165    },
166    E0029 => MissingScalarTypeDefinitionName @ span {
167        "Scalar type definition must have a name.",
168        "This scalar type definition here is missing a name." @ span
169    },
170    E0030 => MissingScalarTypeExtensionName @ span {
171        "Scalar type extension must have a name.",
172        "This scalar type extension here is missing a name." @ span
173    },
174    E0031 => MissingScalarTypeExtensionDirectives @ span {
175        "Scalar type extension must have one or more directives.",
176        "This scalar type extension here is missing directives." @ span
177    },
178    E0032 => MissingObjectTypeDefinitionName @ span {
179        "Object type definition must have a name.",
180        "This object type definition here is missing a name." @ span
181    },
182    E0033 => MissingFirstImplementsInterface @ span {
183        "Implemented interfaces must not be empty.",
184        "This object type here implements an interface, but its name is missing." @ span
185    },
186    E0034 => MissingSecondImplementsInterface @ span {
187        "Implemented interface name is missing.",
188        "This object type here implements another interface, but its name is missing." @ span
189    },
190    E0035 => MissingFieldsDefinitionClosingBrace @ second {
191        "Fields definition must have a closing brace.",
192        "This `{{` here ..." @ first,
193        "... must have a matching `}}` here." @ second
194    },
195    E0036 => MissingFieldDefinitionColon @ span {
196        "Field definition must have a colon.",
197        "This field definition here is missing a colon." @ span
198    },
199    E0037 => MissingFieldDefinitionType @ span {
200        "Field definition must have a type.",
201        "This field definition here is missing a type." @ span
202    },
203    E0038 => MissingArgumentsDefinitionClosingParenthesis @ second {
204        "Arguments definition must have a closing parenthesis.",
205        "This `(` here ..." @ first,
206        "... must have a matching `)` here." @ second
207    },
208    E0039 => MissingInputValueDefinitionColon @ span {
209        "Input value definition must have a colon.",
210        "This input value definition here is missing a colon." @ span
211    },
212    E0040 => MissingInputValueDefinitionType @ span {
213        "Input value definition must have a type.",
214        "This input value definition here is missing a type." @ span
215    },
216    E0041 => MissingObjectTypeExtensionName @ span {
217        "Object type extension must have a name.",
218        "This object type extension here is missing a name." @ span
219    },
220    E0042 => MissingInterfaceTypeDefinitionName @ span {
221        "Interface type definition must have a name.",
222        "This interface type definition here is missing a name." @ span
223    },
224    E0043 => MissingInterfaceTypeExtensionName @ span {
225        "Interface type extension must have a name.",
226        "This interface type extension here is missing a name." @ span
227    },
228    E0044 => MissingUnionTypeDefinitionName @ span {
229        "Union type definition must have a name.",
230        "This union type definition here is missing a name." @ span
231    },
232    E0045 => MissingFirstUnionMemberType @ span {
233        "Union type definition must have one or more member types.",
234        "This union type definition here is missing a member type." @ span
235    },
236    E0046 => MissingSecondUnionMemberType @ span {
237        "Union member type must have a name.",
238        "This union type definition here defines another member type but its name is missing." @ span
239    },
240    E0047 => MissingUnionTypeExtensionName @ span {
241        "Union type extension must have a name.",
242        "This union type extension here is missing a name." @ span
243    },
244    E0048 => MissingEnumTypeDefinitionName @ span {
245        "Enum type definition must have a name.",
246        "This enum type definition here is missing a name." @ span
247    },
248    E0049 => MissingEnumValuesClosingBrace @ second {
249        "Enum values must have a closing brace.",
250        "This `{{` here ..." @ first,
251        "... must have a matching `}}` here." @ second
252    },
253    E0050 => MissingEnumTypeExtensionName @ span {
254        "Enum type extension must have a name.",
255        "This enum type extension here is missing a name." @ span
256    },
257    E0051 => MissingInputObjectTypeDefinitionName @ span {
258        "Input object type definition must have a name.",
259        "This input object type definition here is missing a name." @ span
260    },
261    E0052 => MissingInputFieldsDefinitionClosingBrace @ second {
262        "Input fields definition must have a closing brace.",
263        "This `{{` here ..." @ first,
264        "... must have a `}}` here." @ second
265    },
266    E0053 => MissingInputObjectTypeExtensionName @ span {
267        "Input object type extension must have a name.",
268        "This input object type extension here is missing a name." @ span
269    },
270    E0054 => MissingDirectiveDefinitionAt @ span {
271        "Directive's name must start with an `@`.",
272        "This directive's name here does not start with an `@`." @ span
273    },
274    E0055 => MissingDirectiveDefinitionName @ span {
275        "Directive definition must have a name.",
276        "This directive definition here is missing a name." @ span
277    },
278    E0056 => MissingDirectiveDefinitionLocations @ span {
279        "Directive definition must have one or more locations.",
280        "This directive definition here is missing locations." @ span
281    },
282    E0057 => MissingFirstDirectiveLocation @ span {
283        "Directive definition must have one or more locations.",
284        "This directive definition here is missing a location." @ span
285    },
286    E0058 => MissingSecondDirectiveLocation @ span {
287        "Directive location must be defined.",
288        "This directive definition here is missing a location." @ span
289    },
290
291    E0100 => UnknownNamedType @ span + name {
292        "Named type must exist.",
293        "Type `{name}` is referenced to here but never defined." @ span
294    },
295    E0101 => EmptyType @ span + name {
296        "Type must define one or more fields.",
297        "Type `{name}` is defined here but the schema doesn't define any fields for it." @ span
298    },
299    E0102 => DuplicateField @ second + field {
300        "Field name must be unique.",
301        "Field `{field}` is first defined here ..." @ first,
302        "... and later defines the same field again here." @ second
303    },
304    E0103 => DuplicateExtendedField @ second + name, field {
305        "Field name must be unique across extended types.",
306        "Type `{name}` first defines field `{field}` here, ..." @ first,
307        "... gets extended here ..." @ extension,
308        "... and later defines the same field again here." @ second
309    },
310    E0104 => ReservedFieldName @ span + name {
311        "Field name must not start with `__`.",
312        "Field `{name}` is defined here and starts with `__`, which is reserved." @ span
313    },
314    E0105 => FieldNotOutputType @ span + name, ty {
315        "Field must be output type.",
316        "Field `{name}` is defined here as type `{ty}`, which is an input type." @ span
317    },
318    E0106 => DuplicateArgumentName @ second + name {
319        "Argument name must be unique.",
320        "Argument `{name}` is first defined here ..." @ first,
321        "... and later defined again here." @ second
322    },
323    E0107 => ReservedInputValueName @ span + name {
324        "Input value name must not start with `__`.",
325        "Input value `{name}` is defined here and starts with `__`, which is reserved." @ span
326    },
327    E0108 => InputValueNotInputType @ span + name, ty {
328        "Input value must be input type.",
329        "Input value `{name}` is defined here as type `{ty}`, which is an output type." @ span
330    },
331    E0109 => DuplicateImplementsInterface @ second + name, interface {
332        "Type must not implement same interface twice.",
333        "Type `{name}` first implements interface `{interface}` here ..." @ first,
334        "... and later implements the same interface again here." @ second
335    },
336    E0110 => ImplementsNonInterfaceType @ span + name, interface {
337        "Implemented type must be interface.",
338        "Type `{name}` implements type `{interface}` here, but `{interface}` is not an interface." @ span
339    },
340    E0111 => MissingInheritedInterface @ span + name, interface, inherited {
341        "Type must also implement inherited interfaces.",
342        "Type `{name}` implements interface `{interface}` here, which requires that `{inherited}` is also implemented." @ span
343    },
344    E0112 => MissingInterfaceField @ span + name, interface, field {
345        "Type must implement field from interface.",
346        "Type `{name}` implements interface `{interface}` here, which requires that field `{field}` is implemented." @ span
347    },
348    E0113 => MissingInterfaceFieldArgument @ span + name, interface, field, argument {
349        "Type must implement field with argument from interface.",
350        "Type `{name}` implements interface `{interface}` here, which requires that field `{field}` has an argument `{argument}`." @ span
351    },
352    E0114 => InvalidInterfaceFieldArgumentType @ span + name, interface, field, argument, expected, ty {
353        "Type must implement field with argument of same type as interface.",
354        "Type `{name}` implements interface `{interface}` here, which requires that field `{field}` has an argument `{argument}` of type `{expected}` instead of `{ty}`." @ span
355    },
356    E0115 => UnexpectedNonNullExtraInterfaceFieldArgument @ span + name, interface, field, argument, ty {
357        "Type must not require extra arguments for fields implementing interface.",
358        "Type `{name}` implements interface `{interface}` here and defines a field `{field}` with required argument `{argument}` of type `{ty}` that matches a field in the interface." @ span
359    },
360    E0116 => NonCovariantInterfaceField @ span + name, interface, field, expected, ty {
361        "Implemented type and type from interface must be covariant.",
362        "Type `{name}` implements interface `{interface}` that defines a field `{field}` of type `{expected}`, but `{field}` is `{ty}` here, which is incompatible." @ span
363    },
364    E0117 => SelfReferentialInterface @ span + name {
365        "Interface must not implement itself.",
366        "Interface `{name}` attempts to implement itself here." @ span
367    },
368    E0118 => MissingUnionMembers @ span + name {
369        "Union must have at least one member type.",
370        "Union `{name}` here doesn't have any member types." @ span
371    },
372    E0119 => DuplicateUnionMember @ second + name {
373        "Union members must be unique.",
374        "Union member type `{name}` first occurs here ..." @ first,
375        "... and later again here." @ second
376    },
377    E0120 => NonObjectUnionMember @ span + name {
378        "Union members must be object types.",
379        "Union member type `{name}` is not an object type." @ span
380    },
381    E0121 => MissingEnumValues @ span + name {
382        "Enum must have at least one value.",
383        "Enum `{name}` here doesn't have any values." @ span
384    },
385    E0122 => DuplicateEnumValue @ second + name {
386        "Enum values must be unique.",
387        "Enum value `{name}` first occurs here ..." @ first,
388        "... and later again here." @ second
389    },
390    E0123 => SelfReferentialInputType @ span + name, field, ty {
391        "Input type must not be self-referential.",
392        "Input type `{name}` references itself here through field `{field}` of type `{ty}`." @ span
393    },
394    E0124 => ReservedDirectiveName @ span + name {
395        "Directive name must not start with `__`.",
396        "Directive `{name}` is defined here, but its name start with `__` which is reserved." @ span
397    },
398    E0125 => SelfReferentialDirective @ span + name, directive {
399        "Directive must not be self-referential.",
400        "Directive `{name}` references itself here through directive `{directive}`." @ span
401    },
402    E0126 => DuplicateTypeName @ second + name {
403        "Type name must be unique.",
404        "Type `{name}` is first defined here ..." @ first,
405        "... and later again here." @ second
406    },
407    E0126 => DuplicateDirectiveName @ second + name {
408        "Directive name must be unique.",
409        "Directive `{name}` is first defined here ..." @ first,
410        "... and later again here." @ second
411    },
412    E0127 => DifferentExtensionType @ second + name, first_type, second_type {
413        "Type extension must extend type of same kind.",
414        "Type `{name}` is first defined as `{first_type}` here ..." @ first,
415        "... and later again as `{second_type}` here." @ second
416    },
417    E0200 => ExpectedNonNullValue @ span + ty {
418        "Expected a non-null value.",
419        "This should be a `{ty}` here." @ span
420    },
421    E0201 => ExpectedListValue @ span + ty {
422        "Expected a list value.",
423        "This should be a `{ty}` here." @ span
424    },
425    E0202 => ExpectedIntValue @ span + ty {
426        "Expected an int value.",
427        "This should be a `{ty}` here." @ span
428    },
429    E0203 => ExpectedFloatValue @ span + ty {
430        "Expected a float value.",
431        "This should be a `{ty}` here." @ span
432    },
433    E0204 => ExpectedStringValue @ span + ty {
434        "Expected a string value.",
435        "This should be a `{ty}` here." @ span
436    },
437    E0205 => ExpectedBooleanValue @ span + ty {
438        "Expected a boolean value.",
439        "This should be a `{ty}` here." @ span
440    },
441    E0206 => ExpectedInputObjectValue @ span + ty {
442        "Expected an input object value.",
443        "This should be a `{ty}` here." @ span
444    },
445    E0207 => MissingInputField @ span + name, ty {
446        "Expected a value for required input field.",
447        "This input object here must have a field `{name}` of type `{ty}`." @ span
448    },
449    E0208 => UnrecognizedInputField @ span + name, ty {
450        "All fields in input object must exist in schema definition.",
451        "Value is provided for field `{name}` here, but type `{ty}` has no such field." @ span
452    },
453    E0209 => UnrecognizedEnumValue @ span + name, value {
454        "Enum values must exist in schema definition.",
455        "Enum value `{value}` here is not a valid value for enum `{name}`." @ span
456    },
457    E0210 => ExpectedEnumValue @ span + ty {
458        "Expected an enum value.",
459        "This should be a `{ty}` here." @ span
460    },
461    E0300 => DuplicateOperationName @ second + name {
462        "Operation definitions must be unique.",
463        "Operation `{name}` is first defined here ..." @ first,
464        "... and later defined again here." @ second
465    },
466    E0301 => LoneAnonymousOperation @ span {
467        "Anonymous operation definitions must be alone.",
468        "Anonymous operation defined here must not coexist with named operation definitions." @ span
469    },
470    E0303 => UndefinedField @ span + ty, field {
471        "Queried field does not exist.",
472        "Type `{ty}` does not have a field named `{field}`." @ span
473    },
474    E0304 => IncompatibleResponseShape @ second + name {
475        "Selection set contains multiple fields of incompatible types with the same name.",
476        "Response key `{name}` is first used here ..." @ first,
477        "... and later again here for a field of a different type." @ second
478    },
479    E0305 => DifferentFieldNames @ second + name {
480        "Selection set contains different fields with the same name.",
481        "Response key `{name}` is first used here ..." @ first,
482        "... and later again here for a different field of the same type." @ second
483    },
484    E0306 => DifferentFieldArguments @ second + name {
485        "Selection set contains fields with the same name but different arguments.",
486        "Response key `{name}` is first used here ..." @ first,
487        "... and later again here with different arguments." @ second
488    },
489    E0307 => IncompatibleResponseFields @ second + name {
490        "Selection set contains multiple fields with the same name with incompatible selection sets.",
491        "Response key `{name}` is first used here ..." @ first,
492        "... and later again here with an incompatible different selection set." @ second
493    },
494    E0308 => MissingSelectionSet @ span + ty, field {
495        "Field of composite type must have selection set.",
496        "Field `{field}` of composite type `{ty}` here must have a selection set." @ span
497    },
498    E0309 => UnexpectedSelectionSet @ span + ty, field {
499        "Field of scalar-like type must not have a selection set.",
500        "Field `{field}` of scalar-like type `{ty}` here must not have a selection set." @ span
501    },
502    E0310 => UndefinedArgument @ span + name {
503        "Argument must exist in schema.",
504        "Argument `{name}` here is not defined in schema." @ span
505    },
506    E0311 => DuplicateArgument @ second + name {
507        "Argument may be provided only once.",
508        "Argument `{name}` is first given here ..." @ first,
509        "... and later again here." @ second
510    },
511    E0312 => MissingRequiredArgument @ span + name, ty {
512        "Missing required argument.",
513        "Argument `{name}` of type `{ty}` is required but not given here." @ span
514    },
515    E0313 => DuplicateFragmentName @ second + name {
516        "Fragment definitions must be unique.",
517        "Fragment `{name}` is first defined here ..." @ first,
518        "... and later defined again here." @ second
519    },
520    E0314 => FragmentOnNonCompositeType @ span + name, ty {
521        "Fragment definitions must target composite type.",
522        "Fragment `{name}` targets non-composite type `{ty}` here." @ span
523    },
524    E0315 => UnusedFragmentDefinition @ span + name {
525        "Fragment definitions must be used.",
526        "Fragment `{name}` is defined here but never used." @ span
527    },
528    E0316 => UndefinedFragment @ span + name {
529        "Fragment definition must be defined.",
530        "Fragment `{name}` is used here but never defined." @ span
531    },
532    E0317 => CyclicFragmentDefinition @ span + name, spread {
533        "Fragment definition must not be cyclic.",
534        "Fragment `{name}` includes fragment `{spread}` here, which causes a cycle." @ span
535    },
536    E0318 => ImpossibleFragmentSpread @ span + ty, scope {
537        "Fragment spread must be possible.",
538        "Fragment assumes type `{ty}`, but scope is type `{scope}`." @ span
539    },
540    E0319 => UndefinedDirective @ span + name {
541        "Directive must be defined.",
542        "Directive `@{name}` is refered to here, but never defined." @ span
543    },
544    E0320 => DirectiveInInvalidLocation @ span + name, location, locations {
545        "Directive must be used in valid location.",
546        "Directive `@{name}` is refered to here in a `{location}` location, but can only be used in `{locations}` location(s)." @ span
547    },
548    E0321 => DuplicateNonRepeatableDirective @ second + name {
549        "Non-repeatable directive must be unique per location.",
550        "Directive `@{name}` is first used here ..." @ first,
551        "... and later again here." @ second
552    },
553    E0322 => DuplicateVariable @ second + name {
554        "Variables must be unique per operation definition.",
555        "Variable `${name}` is first used here ..." @ first,
556        "... and later again here." @ second
557    },
558    E0323 => VariableMustBeInputType @ span + name, ty {
559        "Variables must be input types.",
560        "Variable `${name}` is defined here as type `{ty}`, which is not an input type." @ span
561    },
562    E0324 => UndefinedVariable @ span + name {
563        "Variables must be defined before they can be used.",
564        "Variable `${name}` is used here but never defined." @ span
565    },
566    E0325 => UndefinedVariableInFragment @ span + fragment, name {
567        "Operations must define variables for all transitively included fragments.",
568        "Fragment `{fragment}` is used here, but it requires variable `${name}` to be defined ..." @ span,
569        "... because it is used here." @ usage
570    },
571    E0326 => UnusedVariable @ span + name {
572        "Variables must be used.",
573        "Variable `${name}` is defined here but never used." @ span
574    },
575    E0327 => IncompatibleVariable @ second + name, ty, expected {
576        "Variable must be compatible with usage.",
577        "Variable `${name}` is defined here as type `{ty}` ..." @ first,
578        "... but is expected to be type `{expected}` here." @ second
579    },
580    E0328 => IncompatibleVariableInFragment @ span + fragment, name, ty, expected {
581        "Variable must be compatible with usage.",
582        "Fragment `{fragment}` is used here ..." @ span,
583        "... and it requires variable `${name}` to be type `{expected}` here ..." @ second,
584        "... but variable `${name}` is defined here as type `{ty}`." @ first
585    },
586    E0329 => UnsupportedOperation @ span + name {
587        "Operation must be defined in schema before it can be used.",
588        "Schema doesn't have a `{name}` type. You might be interested in using `@litho(url: \"...\")` to automatically import your existing schema. Learn more at https://litho.dev/docs/operations/import-schemas/." @ span
589    }
590}
591
592#[cfg(feature = "with-ariadne")]
593mod with_ariadne {
594    use ariadne::{Label, Report, ReportKind, Span};
595
596    use super::Diagnostic;
597
598    impl<S> Into<Report<S>> for Diagnostic<S>
599    where
600        S: Copy + Span,
601    {
602        fn into(self) -> Report<S> {
603            let mut builder = Report::build(
604                ReportKind::Error,
605                self.span().source().to_owned(),
606                self.span().start(),
607            )
608            .with_code(self.code())
609            .with_message(self.message());
610            builder.add_labels(
611                self.labels()
612                    .into_iter()
613                    .map(|(span, message)| Label::new(span).with_message(message)),
614            );
615            builder.finish()
616        }
617    }
618}