-
Notifications
You must be signed in to change notification settings - Fork 48
/
error.rs
365 lines (257 loc) · 11.5 KB
/
error.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
use miette::Diagnostic;
use thiserror::Error;
use crate::{
constants::Span,
inputs::ParsingError,
lexer::TokenKind,
parser::types::{AttributeKind, TyKind},
};
pub type Result<T> = std::result::Result<T, Error>;
/// An error in noname.
#[derive(Diagnostic, Debug, Error)]
#[error("Looks like something went wrong in {label}")]
pub struct Error {
/// A hint as to where the error happened (e.g. type-checker, parser, lexer, etc.)
pub label: &'static str,
/// The type of error.
#[help]
pub kind: ErrorKind,
/// Indicate where the error occurred in the source code.
#[label("here")]
pub span: Span,
}
impl Error {
/// Creates a new [Error] from an [ErrorKind].
pub fn new(label: &'static str, kind: ErrorKind, span: Span) -> Self {
Self { label, kind, span }
}
}
/// The type of error.
#[derive(Error, Diagnostic, Debug)]
pub enum ErrorKind {
#[error(
"Unexpected error: {0}. Please report this error on https://github.com/mimoo/noname/issues"
)]
UnexpectedError(&'static str),
#[error("variable is not mutable. You must set the `mut` keyword to make it mutable")]
AssignmentToImmutableVariable,
#[error("the {0} of assert_eq must be of type Field or BigInt. It was of type {1}")]
AssertTypeMismatch(&'static str, TyKind),
#[error(
"the dependency `{0}` does not appear to be listed in your manifest file `Noname.toml`"
)]
UnknownDependency(String),
#[error("the function `{1}` does not exist in the module `{0}`")]
UnknownExternalFn(String, String),
#[error("the struct `{1}` does not exist in the module `{0}`")]
UnknownExternalStruct(String, String),
#[error("you cannot have a function called `main` in a library")]
MainFunctionInLib,
#[error("you cannot call your function `{0}`, as it already exists as a builtin function (try renaming your function)")]
ShadowingBuiltIn(String),
#[error(transparent)]
ParsingError(#[from] ParsingError),
#[error("the `const` attribute cannot be used for arguments of the main function")]
ConstArgumentNotForMain,
#[error("a field access or a method call can only be applied on a field of another struct, a struct, or an array access")]
InvalidFieldAccessExpression,
#[error("the method called is not a static method")]
NotAStaticMethod,
#[error("{0} arguments are passed when {1} were expected")]
MismatchFunctionArguments(usize, usize),
#[error("constants must be declared before any structs or functions")]
OrderOfConstDeclaration,
#[error(
"the `use` keyword must be used before anything else (consts, structs, functions, etc.)"
)]
OrderOfUseDeclaration,
#[error("cannot chain arithmetic operations without using parenthesis")]
MissingParenthesis,
#[error("the `pub` keyword is reserved for arguments of the main function")]
PubArgumentOutsideMain,
#[error("the function main is not recursive")]
RecursiveMain,
#[error("invalid token")]
InvalidToken,
#[error("missing type")]
MissingType,
#[error("missing token")]
MissingToken,
#[error("invalid token, expected: {0}")]
ExpectedToken(TokenKind),
#[error("invalid path: {0}")]
InvalidPath(&'static str),
#[error("invalid end of line")]
InvalidEndOfLine,
#[error("invalid function signature: {0}")]
InvalidFunctionSignature(&'static str),
#[error("invalid function name")]
InvalidFunctionName,
#[error("invalid type name")]
InvalidTypeName,
#[error("invalid type, expected an array or a type name (starting with an uppercase letter, and only containing alphanumeric characters)")]
InvalidType,
#[error("the custom type name used: `{0}` is a reserved type name")]
ReservedType(String),
#[error("invalid array size, expected [_; x] with x in [0,2^32]")]
InvalidArraySize,
#[error("Invalid expression in symbolic size")]
InvalidSymbolicSize,
#[error("invalid generic parameter, expected single uppercase letter, such as N, M, etc.")]
InvalidGenericParameter,
#[error("missing generic value: `{0}`")]
GenericValueExpected(String),
#[error("conflict generic values during binding for `{0}`: `{1}` and `{2}`")]
ConflictGenericValue(String, String, String),
#[error("unexpected generic parameter: `{0}`")]
UnexpectedGenericParameter(String),
#[error("calling generic functions in for loop is not allowed")]
GenericInForLoop,
#[error("variable `{0}` is forbidden to be accessed in the for loop, likely due to a generic function call")]
VarAccessForbiddenInForLoop(String),
#[error("the value passed could not be converted to a field element")]
InvalidField(String),
#[error("invalid range size, expected x..y with x and y integers in [0,2^32]")]
InvalidRangeSize,
#[error("invalid iterator type, expected an array but found {0}")]
InvalidIteratorType(TyKind),
#[error("invalid statement")]
InvalidStatement,
#[error("missing expression")]
MissingExpression,
#[error("invalid expression")]
InvalidExpression,
#[error("invalid identifier `{0}`, expected lowercase alphanumeric string (including underscore `_`) and starting with a letter")]
InvalidIdentifier(String),
#[error("invalid function call: {0}")]
InvalidFnCall(&'static str),
#[error("imports via `use` keyword must appear before anything else")]
UseAfterFn,
#[error("argument `{arg_name}` of function {fn_name} was passed a type {observed_ty} when it expected a {expected_ty}")]
WrongArgumentType {
fn_name: String,
arg_name: String,
expected_ty: String,
observed_ty: String,
},
#[error("cannot compute the expression")]
CannotComputeExpression,
#[error("type '{0}' and '{1}' are not compatible")]
MismatchType(TyKind, TyKind),
#[error("variable used is not defined anywhere")]
UndefinedVariable,
#[error("unexpected argument type in function call. Expected: {0} and got {1}")]
ArgumentTypeMismatch(TyKind, TyKind),
#[error("the function `{0}` return value must be used")]
FunctionReturnsType(String),
#[error("you need to pass the following public argument: `{0}`")]
MissingPublicArg(String),
#[error("you need to pass the following private argument: `{0}`")]
MissingPrivateArg(String),
#[error("cannot convert `{0}` to field element")]
CannotConvertToField(String),
#[error("cannot convert `{0}` to {1}")]
CannotConvertFromField(String, String),
#[error("a return value was expected by the function signature")]
MissingReturn,
#[error("no return value was expected as part of this function signature")]
NoReturnExpected,
#[error("the `self` argument cannot have attributes")]
SelfHasAttribute,
#[error("the return type observed (`{0}`) doesn't match what the function expected as return type (`{1}`)")]
ReturnTypeMismatch(TyKind, TyKind),
#[error("missing return type in the function signature")]
UnexpectedReturn,
#[error("error while importing std path: {0}")]
StdImport(String),
#[error("tried to import the same module `{0}` twice")]
DuplicateModule(String),
#[error("`{0}` is a reserved argument name")]
PublicOutputReserved(String),
#[error("function `{0}` not present in scope (did you misspell it?)")]
UndefinedFunction(String),
#[error("hint function `{0}` signature is missing its corresponding builtin function")]
MissingHintMapping(String),
#[error("function name `{0}` is already in use by a variable present in the scope")]
FunctionNameInUsebyVariable(String),
#[error("module `{0}` not present in scope (are you sure you imported it?)")]
UndefinedModule(String),
#[error("attribute not recognized: `{0:?}`")]
InvalidAttribute(AttributeKind),
#[error("unsafe attribute is needed to call a hint function. eg: `unsafe fn foo()`")]
ExpectedUnsafeAttribute,
#[error("unsafe attribute should only be applied to hint function calls")]
UnexpectedUnsafeAttribute,
#[error("A return value is not used")]
UnusedReturnValue,
#[error("array accessed at index {0} is out of bounds (max allowed index is {1})")]
ArrayIndexOutOfBounds(usize, usize),
#[error(
"one-letter variables or types are not allowed. Best practice is to use descriptive names"
)]
NoOneLetterVariable,
#[error("array indexes must be constants in circuits")]
ExpectedConstant,
#[error("kimchi setup: {0}")]
KimchiSetup(#[from] kimchi::error::SetupError),
#[error("kimchi prover: {0}")]
KimchiProver(#[from] kimchi::error::ProverError),
#[error("kimchi verifier: {0}")]
KimchiVerifier(#[from] kimchi::error::VerifyError),
#[error("the program did not run to completion with the given private and/or public inputs (row {0} of the witness failed to verify)")]
InvalidWitness(usize),
#[error("user provided input `{0}` is not defined in the main function's arguments")]
UnusedInput(String),
#[error("private input not used in the circuit")]
PrivateInputNotUsed,
#[error("the variable `{0}` is declared twice")]
DuplicateDefinition(String),
#[error("only variables and arrays can be mutated")]
InvalidAssignmentExpression,
#[error("unexpected assignment type. Expected: {0} and got {1}")]
AssignmentTypeMismatch(TyKind, TyKind),
#[error("the main function must have at least one argument")]
NoArgsInMain,
#[error("local variable `{0}` couldn't be found")]
LocalVariableNotFound(String),
#[error("the public output cannot contain constants")]
ConstantInOutput,
#[error("incorrect number of fields declared for the `{0}` struct declaration")]
MismatchStructFields(String),
#[error("invalid field, expected `{0}` and got `{1}`")]
InvalidStructField(String, String),
#[error("invalid type for the field, expected `{0}` and got `{1}`")]
InvalidStructFieldType(TyKind, TyKind),
#[error("method call can only be applied on custom structs")]
MethodCallOnNonCustomStruct,
#[error("field access can only be applied on custom structs")]
FieldAccessOnNonCustomStruct,
#[error("array access can only be performed on arrays")]
ArrayAccessOnNonArray,
#[error("struct `{0}` does not exist (are you sure it is defined?)")]
UndefinedStruct(String),
#[error("struct `{0}` does not have a method called `{1}`")]
UndefinedMethod(String, String),
#[error("struct `{0}` does not have a field called `{1}`")]
UndefinedField(String, String),
#[error("this assertion failed")]
AssertionFailed,
#[error("constants can only have a literal decimal value")]
InvalidConstType,
#[error("cannot compile a module without a main function")]
NoMainFunction,
#[error("invalid hexadecimal literal `${0}`")]
InvalidHexLiteral(String),
#[error("if-else condition is expected to be a boolean, but has type `{0}`")]
IfElseInvalidConditionType(TyKind),
#[error("`if` branch must be a variable, a field access, or an array access. It can't be logic that creates constraints.")]
IfElseInvalidIfBranch(),
#[error("`else` branch must be a variable, a field access, or an array access. It can't be logic that creates constraints.")]
IfElseInvalidElseBranch(),
#[error("`if` branch and `else` branch must have matching types")]
IfElseMismatchingBranchesTypes(),
#[error("invalid range, the end value can't be smaller than the start value")]
InvalidRange,
#[error("division by zero")]
DivisionByZero,
}