From c8b44141ebb44ac99d55171688964973b9934e22 Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Mon, 18 Apr 2022 11:33:43 -0700 Subject: [PATCH 1/4] fix some span and input parsing issues --- .../ast/src/reducer/reconstructing_reducer.rs | 2 +- compiler/parser/src/parser/context.rs | 2 +- compiler/parser/src/parser/file.rs | 4 +-- compiler/parser/src/parser/input.rs | 2 +- compiler/parser/src/parser/statement.rs | 4 +-- compiler/parser/src/parser/type_.rs | 32 +++++++++++-------- compiler/parser/src/tokenizer/mod.rs | 4 +-- 7 files changed, 27 insertions(+), 23 deletions(-) diff --git a/compiler/ast/src/reducer/reconstructing_reducer.rs b/compiler/ast/src/reducer/reconstructing_reducer.rs index 9d0bc2e46d..308fb36ec7 100644 --- a/compiler/ast/src/reducer/reconstructing_reducer.rs +++ b/compiler/ast/src/reducer/reconstructing_reducer.rs @@ -154,7 +154,7 @@ pub trait ReconstructingReducer { value: Expression, ) -> Result { Ok(DefinitionStatement { - declaration_type: definition.declaration_type.clone(), + declaration_type: definition.declaration_type, variable_names, type_, value, diff --git a/compiler/parser/src/parser/context.rs b/compiler/parser/src/parser/context.rs index 1b82207c1a..e4123a94a5 100644 --- a/compiler/parser/src/parser/context.rs +++ b/compiler/parser/src/parser/context.rs @@ -114,7 +114,7 @@ impl<'a> ParserContext<'a> { Some(idx) => idx, }; - looker(self.tokens.get(idx).unwrap_or_else(|| &self.dummy_eof)) + looker(self.tokens.get(idx).unwrap_or(&self.dummy_eof)) } /// Emit the error `err`. diff --git a/compiler/parser/src/parser/file.rs b/compiler/parser/src/parser/file.rs index d925079b9b..bcf9104534 100644 --- a/compiler/parser/src/parser/file.rs +++ b/compiler/parser/src/parser/file.rs @@ -100,7 +100,7 @@ impl ParserContext<'_> { } self.expect(&Token::Colon)?; - let type_ = self.parse_type()?.0; + let type_ = self.parse_all_types()?.0; Ok(FunctionInput::Variable(FunctionInputVariable::new( name.clone(), mode, @@ -124,7 +124,7 @@ impl ParserContext<'_> { // Parse return type. let output = if self.eat(&Token::Arrow) { - Some(self.parse_type()?.0) + Some(self.parse_all_types()?.0) } else { None }; diff --git a/compiler/parser/src/parser/input.rs b/compiler/parser/src/parser/input.rs index 16252416b4..05dba6eda1 100644 --- a/compiler/parser/src/parser/input.rs +++ b/compiler/parser/src/parser/input.rs @@ -65,7 +65,7 @@ impl ParserContext<'_> { let name = self.expect_ident()?; self.expect(&Token::Colon)?; - let (type_, span) = self.parse_type()?; + let (type_, span) = self.parse_non_ident_types()?; self.expect(&Token::Assign)?; let value = self.parse_primary_expression()?; self.expect(&Token::Semicolon)?; diff --git a/compiler/parser/src/parser/statement.rs b/compiler/parser/src/parser/statement.rs index bfdc238a2e..df33528786 100644 --- a/compiler/parser/src/parser/statement.rs +++ b/compiler/parser/src/parser/statement.rs @@ -252,8 +252,6 @@ impl ParserContext<'_> { Token::Const => Declare::Const, _ => unreachable!("parse_definition_statement_ shouldn't produce this"), }; - dbg!(); - // Parse variable names. let variable_names = if self.peek_is_left_par() { let vars = self @@ -272,7 +270,7 @@ impl ParserContext<'_> { // Parse an optional type ascription. let type_ = self .eat(&Token::Colon) - .then(|| self.parse_type().map(|t| t.0)) + .then(|| self.parse_all_types().map(|t| t.0)) .transpose()?; self.expect(&Token::Assign)?; diff --git a/compiler/parser/src/parser/type_.rs b/compiler/parser/src/parser/type_.rs index 7d4fc5c0dc..fc560e9b4e 100644 --- a/compiler/parser/src/parser/type_.rs +++ b/compiler/parser/src/parser/type_.rs @@ -57,23 +57,29 @@ impl ParserContext<'_> { /// Returns a [`(Type, Span)`] tuple of AST nodes if the next token represents a type. /// Also returns the span of the parsed token. - pub fn parse_type(&mut self) -> Result<(Type, Span)> { + pub fn parse_non_ident_types(&mut self) -> Result<(Type, Span)> { + let span = self.expect_any(TYPE_TOKENS)?; + Ok(( + match &self.prev_token.token { + Token::Field => Type::Field, + Token::Group => Type::Group, + Token::Address => Type::Address, + Token::Bool => Type::Boolean, + Token::Char => Type::Char, + x => Type::IntegerType(Self::token_to_int_type(x).expect("invalid int type")), + }, + span, + )) + } + + /// Returns a [`(Type, Span)`] tuple of AST nodes if the next token represents a type. + /// Also returns the span of the parsed token. + pub fn parse_all_types(&mut self) -> Result<(Type, Span)> { Ok(if let Some(ident) = self.eat_identifier() { let span = ident.span.clone(); (Type::Identifier(ident), span) } else { - let span = self.expect_any(TYPE_TOKENS)?; - ( - match &self.prev_token.token { - Token::Field => Type::Field, - Token::Group => Type::Group, - Token::Address => Type::Address, - Token::Bool => Type::Boolean, - Token::Char => Type::Char, - x => Type::IntegerType(Self::token_to_int_type(x).expect("invalid int type")), - }, - span, - ) + self.parse_non_ident_types()? }) } } diff --git a/compiler/parser/src/tokenizer/mod.rs b/compiler/parser/src/tokenizer/mod.rs index 0d97f13ea3..4829268689 100644 --- a/compiler/parser/src/tokenizer/mod.rs +++ b/compiler/parser/src/tokenizer/mod.rs @@ -46,7 +46,7 @@ pub(crate) fn tokenize_iter<'a>(path: &'a str, input: &'a str) -> impl 'a + Iter iter::from_fn(move || { while input.len() > index { let token = match Token::eat(&input[index..]) { - Err(e) => return Some(Err(e.into())), + Err(e) => return Some(Err(e)), Ok(t) => t, }; @@ -56,7 +56,7 @@ pub(crate) fn tokenize_iter<'a>(path: &'a str, input: &'a str) -> impl 'a + Iter if bytes[index] == 0x000D && matches!(bytes.get(index + 1), Some(0x000A)) { // Check carriage return followed by newline. line_no += 1; - line_start = index + token_len; + line_start = index + token_len + 1; index += token_len; } else if matches!(bytes[index], 0x000A | 0x000D) { // Check new-line or carriage-return From 54c936cc6142d7eaf7c80ed656d3c7f536303419 Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Mon, 18 Apr 2022 14:06:28 -0700 Subject: [PATCH 2/4] leo warnings, disable unused errors for now --- compiler/parser/src/parser/context.rs | 7 +- compiler/parser/src/parser/file.rs | 4 +- compiler/parser/src/test.rs | 2 +- leo/errors/src/common/backtraced.rs | 63 ++-- leo/errors/src/common/formatted.rs | 52 ++-- leo/errors/src/common/macros.rs | 87 +++--- leo/errors/src/common/traits.rs | 18 +- leo/errors/src/emitter/mod.rs | 58 +++- leo/errors/src/{ => errors}/asg/asg_errors.rs | 0 leo/errors/src/{ => errors}/asg/mod.rs | 0 leo/errors/src/{ => errors}/ast/ast_errors.rs | 8 +- leo/errors/src/{ => errors}/ast/mod.rs | 0 leo/errors/src/{ => errors}/cli/cli_errors.rs | 8 +- leo/errors/src/{ => errors}/cli/mod.rs | 0 .../{ => errors}/compiler/compiler_errors.rs | 8 +- leo/errors/src/{ => errors}/compiler/mod.rs | 0 .../src/{ => errors}/import/import_errors.rs | 0 leo/errors/src/{ => errors}/import/mod.rs | 0 .../src/{ => errors}/input/input_errors.rs | 8 +- leo/errors/src/{ => errors}/input/mod.rs | 0 leo/errors/src/errors/mod.rs | 99 +++++++ leo/errors/src/{ => errors}/package/mod.rs | 0 .../{ => errors}/package/package_errors.rs | 8 +- leo/errors/src/{ => errors}/parser/mod.rs | 0 .../src/{ => errors}/parser/parser_errors.rs | 30 +- leo/errors/src/{ => errors}/snarkvm/mod.rs | 0 .../{ => errors}/snarkvm/snarkvm_errors.rs | 0 leo/errors/src/{ => errors}/state/mod.rs | 0 .../src/{ => errors}/state/state_errors.rs | 0 leo/errors/src/lib.rs | 139 +-------- leo/errors/src/warnings/mod.rs | 43 +++ leo/errors/src/warnings/parser/mod.rs | 19 ++ .../src/warnings/parser/parser_warning.rs | 32 ++ .../parser/functions/const_input.leo.out | 75 +++++ .../parser/functions/const_input_fail.leo.out | 2 +- .../functions/const_input_kw_fail.leo.out | 5 + .../functions/const_public_param_fail.leo.out | 2 +- .../functions/public_const_param_fail.leo.out | 2 +- .../parser/parser/inputs/input_const.leo.out | 274 +++++++++++++++++- tests/parser/functions/const_input.leo | 8 + ...input_fail.leo => const_input_kw_fail.leo} | 0 tests/parser/inputs/input_const.leo | 2 +- tests/test-framework/src/bin/errcov.rs | 52 +--- 43 files changed, 805 insertions(+), 310 deletions(-) rename leo/errors/src/{ => errors}/asg/asg_errors.rs (100%) rename leo/errors/src/{ => errors}/asg/mod.rs (100%) rename leo/errors/src/{ => errors}/ast/ast_errors.rs (97%) rename leo/errors/src/{ => errors}/ast/mod.rs (100%) rename leo/errors/src/{ => errors}/cli/cli_errors.rs (99%) rename leo/errors/src/{ => errors}/cli/mod.rs (100%) rename leo/errors/src/{ => errors}/compiler/compiler_errors.rs (99%) rename leo/errors/src/{ => errors}/compiler/mod.rs (100%) rename leo/errors/src/{ => errors}/import/import_errors.rs (100%) rename leo/errors/src/{ => errors}/import/mod.rs (100%) rename leo/errors/src/{ => errors}/input/input_errors.rs (96%) rename leo/errors/src/{ => errors}/input/mod.rs (100%) create mode 100644 leo/errors/src/errors/mod.rs rename leo/errors/src/{ => errors}/package/mod.rs (100%) rename leo/errors/src/{ => errors}/package/package_errors.rs (99%) rename leo/errors/src/{ => errors}/parser/mod.rs (100%) rename leo/errors/src/{ => errors}/parser/parser_errors.rs (94%) rename leo/errors/src/{ => errors}/snarkvm/mod.rs (100%) rename leo/errors/src/{ => errors}/snarkvm/snarkvm_errors.rs (100%) rename leo/errors/src/{ => errors}/state/mod.rs (100%) rename leo/errors/src/{ => errors}/state/state_errors.rs (100%) create mode 100644 leo/errors/src/warnings/mod.rs create mode 100644 leo/errors/src/warnings/parser/mod.rs create mode 100644 leo/errors/src/warnings/parser/parser_warning.rs create mode 100644 tests/expectations/parser/parser/functions/const_input.leo.out create mode 100644 tests/expectations/parser/parser/functions/const_input_kw_fail.leo.out create mode 100644 tests/parser/functions/const_input.leo rename tests/parser/functions/{const_input_fail.leo => const_input_kw_fail.leo} (100%) diff --git a/compiler/parser/src/parser/context.rs b/compiler/parser/src/parser/context.rs index e4123a94a5..95c40c9afc 100644 --- a/compiler/parser/src/parser/context.rs +++ b/compiler/parser/src/parser/context.rs @@ -18,7 +18,7 @@ use crate::{assert_no_whitespace, tokenizer::*, Token, KEYWORD_TOKENS}; use leo_ast::*; use leo_errors::emitter::Handler; -use leo_errors::{ParserError, Result}; +use leo_errors::{ParserError, ParserWarning, Result}; use leo_span::{Span, Symbol}; use std::fmt::Display; @@ -122,6 +122,11 @@ impl<'a> ParserContext<'a> { self.handler.emit_err(err.into()); } + /// Emit the error `err`. + pub(crate) fn emit_warning(&self, warning: ParserWarning) { + self.handler.emit_warning(warning.into()); + } + /// Returns true if the next token exists. pub fn has_next(&self) -> bool { !matches!(self.token.token, Token::Eof) diff --git a/compiler/parser/src/parser/file.rs b/compiler/parser/src/parser/file.rs index bcf9104534..6f363d0e80 100644 --- a/compiler/parser/src/parser/file.rs +++ b/compiler/parser/src/parser/file.rs @@ -16,7 +16,7 @@ use super::*; -use leo_errors::{ParserError, Result}; +use leo_errors::{ParserError, ParserWarning, Result}; use leo_span::sym; impl ParserContext<'_> { @@ -69,7 +69,7 @@ impl ParserContext<'_> { let const_ = self.eat(&Token::Const).then(|| self.prev_token.span.clone()); if let Some(span) = &const_ { - self.emit_err(ParserError::const_parameter_or_input(span)); + self.emit_warning(ParserWarning::const_parameter_or_input(span)); } match (public, constant, const_) { diff --git a/compiler/parser/src/test.rs b/compiler/parser/src/test.rs index 64ac57385e..abe1d50c21 100644 --- a/compiler/parser/src/test.rs +++ b/compiler/parser/src/test.rs @@ -71,7 +71,7 @@ fn with_handler( let mut tokens = ParserContext::new(&handler, tokens); let parsed = handler .extend_if_error(logic(&mut tokens)) - .map_err(|_| buf.extract().to_string())?; + .map_err(|_| buf.extract_errs().to_string())?; not_fully_consumed(&mut tokens)?; Ok(parsed) } diff --git a/leo/errors/src/common/backtraced.rs b/leo/errors/src/common/backtraced.rs index b98b4e1275..a9bda2768d 100644 --- a/leo/errors/src/common/backtraced.rs +++ b/leo/errors/src/common/backtraced.rs @@ -24,37 +24,40 @@ use derivative::Derivative; /// The indent for an error message. pub(crate) const INDENT: &str = " "; -/// Backtraced compiler error type +/// Backtraced compiler ouput type /// undefined value `x` /// --> file.leo: 2:8 /// = help: Initialize a variable `x` first. #[derive(Derivative)] #[derivative(Clone, Debug, Default, Hash, PartialEq)] -pub struct BacktracedError { +pub struct Backtraced { /// The error message. pub message: String, /// The error help message if it exists. pub help: Option, /// The error exit code. - pub exit_code: i32, + pub code: i32, /// The error leading digits identifier. pub code_identifier: i8, /// The characters representing the type of error. - pub error_type: String, + pub type_: String, + /// Is this Backtrace a warning or error? + pub error: bool, #[derivative(PartialEq = "ignore")] #[derivative(Hash = "ignore")] /// The backtrace representing where the error occured in Leo. pub backtrace: Backtrace, } -impl BacktracedError { +impl Backtraced { /// Creates a backtraced error from a backtrace. pub fn new_from_backtrace( message: S, help: Option, - exit_code: i32, + code: i32, code_identifier: i8, - error_type: String, + type_: String, + error: bool, backtrace: Backtrace, ) -> Self where @@ -63,14 +66,15 @@ impl BacktracedError { Self { message: message.to_string(), help, - exit_code, + code, code_identifier, - error_type, + type_, + error, backtrace, } } - /// Gets the backtraced error error code. + /// Gets the backtraced error exit code. pub fn exit_code(&self) -> i32 { let mut code: i32; if self.code_identifier > 99 { @@ -80,7 +84,7 @@ impl BacktracedError { } else { code = self.code_identifier as i32 * 1_000; } - code += self.exit_code; + code += self.code; code } @@ -89,20 +93,31 @@ impl BacktracedError { pub fn error_code(&self) -> String { format!( "E{error_type}{code_identifier:0>3}{exit_code:0>4}", - error_type = self.error_type, + error_type = self.type_, code_identifier = self.code_identifier, - exit_code = self.exit_code, + exit_code = self.code, + ) + } + + /// Gets a unique warning identifier. + pub fn warning_code(&self) -> String { + format!( + "W{error_type}{code_identifier:0>3}{exit_code:0>4}", + error_type = self.type_, + code_identifier = self.code_identifier, + exit_code = self.code, ) } } -impl fmt::Display for BacktracedError { +impl fmt::Display for Backtraced { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let error_message = format!( - "Error [{error_code}]: {message}", - error_code = self.error_code(), - message = self.message, - ); + let (kind, code) = if self.error { + ("Error", self.error_code()) + } else { + ("Warning", self.warning_code()) + }; + let message = format!("{kind} [{code}]: {message}", message = self.message,); // To avoid the color enabling characters for comparison with test expectations. if std::env::var("LEO_TESTFRAMEWORK") @@ -111,9 +126,13 @@ impl fmt::Display for BacktracedError { .to_owned() .is_empty() { - write!(f, "{}", error_message.bold().red())?; + if self.error { + write!(f, "{}", message.bold().red())?; + } else { + write!(f, "{}", message.bold().yellow())?; + } } else { - write!(f, "{}", error_message)?; + write!(f, "{}", message)?; }; if let Some(help) = &self.help { @@ -151,7 +170,7 @@ impl fmt::Display for BacktracedError { } } -impl std::error::Error for BacktracedError { +impl std::error::Error for Backtraced { fn description(&self) -> &str { &self.message } diff --git a/leo/errors/src/common/formatted.rs b/leo/errors/src/common/formatted.rs index 3e4cc5dc4c..37ee87cde7 100644 --- a/leo/errors/src/common/formatted.rs +++ b/leo/errors/src/common/formatted.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{BacktracedError, INDENT}; +use crate::{Backtraced, INDENT}; use leo_span::Span; @@ -33,21 +33,23 @@ use std::fmt; /// = help: Initialize a variable `x` first. /// Makes use of the same fields as a BacktracedError. #[derive(Clone, Debug, Default, Hash, PartialEq)] -pub struct FormattedError { +pub struct Formatted { /// The formatted error span information. pub span: Span, /// The backtrace to track where the Leo error originated. - pub backtrace: BacktracedError, + pub backtrace: Backtraced, } -impl FormattedError { +impl Formatted { /// Creates a backtraced error from a span and a backtrace. + #[allow(clippy::too_many_arguments)] pub fn new_from_span( message: S, help: Option, - exit_code: i32, + code: i32, code_identifier: i8, - error_type: String, + type_: String, + error: bool, span: &Span, backtrace: Backtrace, ) -> Self @@ -56,18 +58,19 @@ impl FormattedError { { Self { span: span.clone(), - backtrace: BacktracedError::new_from_backtrace( + backtrace: Backtraced::new_from_backtrace( message.to_string(), help, - exit_code, + code, code_identifier, - error_type, + type_, + error, backtrace, ), } } - /// Calls the backtraces error code. + /// Calls the backtraces error exit code. pub fn exit_code(&self) -> i32 { self.backtrace.exit_code() } @@ -76,9 +79,14 @@ impl FormattedError { pub fn error_code(&self) -> String { self.backtrace.error_code() } + + /// Returns an warning identifier. + pub fn warning_code(&self) -> String { + self.backtrace.warning_code() + } } -impl fmt::Display for FormattedError { +impl fmt::Display for Formatted { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let underline = |mut start: usize, mut end: usize| -> String { if start > end { @@ -101,11 +109,13 @@ impl fmt::Display for FormattedError { let underlined = underline(self.span.col_start, self.span.col_stop); - let error_message = format!( - "Error [{error_code}]: {message}", - error_code = self.error_code(), - message = self.backtrace.message, - ); + let (kind, code) = if self.backtrace.error { + ("Error", self.error_code()) + } else { + ("Warning", self.warning_code()) + }; + + let message = format!("{kind} [{code}]: {message}", message = self.backtrace.message,); // To avoid the color enabling characters for comparison with test expectations. if std::env::var("LEO_TESTFRAMEWORK") @@ -114,9 +124,13 @@ impl fmt::Display for FormattedError { .to_owned() .is_empty() { - write!(f, "{}", error_message.bold().red())?; + if self.backtrace.error { + write!(f, "{}", message.bold().red())?; + } else { + write!(f, "{}", message.bold().yellow())?; + } } else { - write!(f, "{}", error_message)?; + write!(f, "{}", message)?; }; write!( @@ -183,7 +197,7 @@ impl fmt::Display for FormattedError { } } -impl std::error::Error for FormattedError { +impl std::error::Error for Formatted { fn description(&self) -> &str { &self.backtrace.message } diff --git a/leo/errors/src/common/macros.rs b/leo/errors/src/common/macros.rs index f284845e4c..e353922bfb 100644 --- a/leo/errors/src/common/macros.rs +++ b/leo/errors/src/common/macros.rs @@ -18,7 +18,7 @@ /// and error methods generated through a DSL creates and generates errors /// with a unique error code. #[macro_export] -macro_rules! create_errors { +macro_rules! create_messages { (@step $code:expr,) => { #[inline(always)] // Returns the number of unique exit codes that this error type can take on. @@ -26,71 +26,85 @@ macro_rules! create_errors { $code } }; - ($(#[$error_type_docs:meta])* $error_type:ident, exit_code_mask: $exit_code_mask:expr, error_code_prefix: $error_code_prefix:expr, $($(#[$docs:meta])* @$formatted_or_backtraced_list:ident $names:ident { args: ($($arg_names:ident: $arg_types:ty$(,)?)*), msg: $messages:expr, help: $helps:expr, })*) => { + ($(#[$error_type_docs:meta])* $type_:ident, code_mask: $code_mask:expr, code_prefix: $code_prefix:expr, $($(#[$docs:meta])* @$formatted_or_backtraced_list:ident $names:ident { args: ($($arg_names:ident: $arg_types:ty$(,)?)*), msg: $messages:expr, help: $helps:expr, })*) => { #[allow(unused_imports)] // Allow unused for errors that only use formatted or backtraced errors. - use crate::{BacktracedError, FormattedError, LeoErrorCode}; + use crate::{Backtraced, Formatted, LeoMessageCode}; use backtrace::Backtrace; // Generates the enum and implements from FormattedError and BacktracedErrors. #[derive(Debug, Error)] $(#[$error_type_docs])* - pub enum $error_type { + pub enum $type_ { #[error(transparent)] - FormattedError(#[from] FormattedError), + Formatted(#[from] Formatted), #[error(transparent)] - BacktracedError(#[from] BacktracedError), + Backtraced(#[from] Backtraced), } /// Implements the trait for LeoError Codes. - impl LeoErrorCode for $error_type { + impl LeoMessageCode for $type_ { #[inline(always)] fn exit_code(&self) -> i32 { match self { - Self::FormattedError(formatted) => formatted.exit_code(), - Self::BacktracedError(backtraced) => backtraced.exit_code() + Self::Formatted(formatted) => formatted.exit_code(), + Self::Backtraced(backtraced) => backtraced.exit_code() } } #[inline(always)] fn error_code(&self) -> String { match self { - Self::FormattedError(formatted) => formatted.error_code(), - Self::BacktracedError(backtraced) => backtraced.error_code() + Self::Formatted(formatted) => formatted.error_code(), + Self::Backtraced(backtraced) => backtraced.error_code() } } #[inline(always)] - fn exit_code_mask() -> i32 { - $exit_code_mask + fn warning_code(&self) -> String { + match self { + Self::Formatted(formatted) => formatted.warning_code(), + Self::Backtraced(backtraced) => backtraced.warning_code() + } } #[inline(always)] - fn error_type() -> String { - $error_code_prefix.to_string() + fn code_mask() -> i32 { + $code_mask + } + + #[inline(always)] + fn message_type() -> String { + $code_prefix.to_string() + } + + #[inline(always)] + fn is_error() -> bool { + stringify!($type_).contains("Error") } } - // Steps over the list of functions with an initial error code of 0. - impl $error_type { - create_errors!(@step 0i32, $(($(#[$docs])* $formatted_or_backtraced_list, $names($($arg_names: $arg_types,)*), $messages, $helps),)*); + // Steps over the list of functions with an initial code of 0. + impl $type_ { + create_messages!(@step 0i32, $(($(#[$docs])* $formatted_or_backtraced_list, $names($($arg_names: $arg_types,)*), $messages, $helps),)*); } }; - // Matches the function if it is a formatted error. - (@step $code:expr, ($(#[$error_func_docs:meta])* formatted, $error_name:ident($($arg_names:ident: $arg_types:ty,)*), $message:expr, $help:expr), $(($(#[$docs:meta])* $formatted_or_backtraced_tail:ident, $names:ident($($tail_arg_names:ident: $tail_arg_types:ty,)*), $messages:expr, $helps:expr),)*) => { + // Matches the function if it is a formatted message. + (@step $code:expr, ($(#[$error_func_docs:meta])* formatted, $name:ident($($arg_names:ident: $arg_types:ty,)*), $message:expr, $help:expr), $(($(#[$docs:meta])* $formatted_or_backtraced_tail:ident, $names:ident($($tail_arg_names:ident: $tail_arg_types:ty,)*), $messages:expr, $helps:expr),)*) => { // Formatted errors always takes a span. $(#[$error_func_docs])* // Expands additional arguments for the error defining function. - pub fn $error_name($($arg_names: $arg_types,)* span: &leo_span::Span) -> Self { - Self::FormattedError( - FormattedError::new_from_span( + pub fn $name($($arg_names: $arg_types,)* span: &leo_span::Span) -> Self { + Self::Formatted( + Formatted::new_from_span( $message, $help, - $code + Self::exit_code_mask(), + $code + Self::code_mask(), Self::code_identifier(), - Self::error_type(), + Self::message_type(), + Self::is_error(), span, // Each function always generates its own backtrace for backtrace clarity to originate from the error function. Backtrace::new(), @@ -98,28 +112,29 @@ macro_rules! create_errors { ) } - // Steps the error code value by one and calls on the rest of the functions. - create_errors!(@step $code + 1i32, $(($(#[$docs])* $formatted_or_backtraced_tail, $names($($tail_arg_names: $tail_arg_types,)*), $messages, $helps),)*); + // Steps the code value by one and calls on the rest of the functions. + create_messages!(@step $code + 1i32, $(($(#[$docs])* $formatted_or_backtraced_tail, $names($($tail_arg_names: $tail_arg_types,)*), $messages, $helps),)*); }; - // matches the function if it is a backtraced error. - (@step $code:expr, ($(#[$error_func_docs:meta])* backtraced, $error_name:ident($($arg_names:ident: $arg_types:ty,)*), $message:expr, $help:expr), $(($(#[$docs:meta])* $formatted_or_backtraced_tail:ident, $names:ident($($tail_arg_names:ident: $tail_arg_types:ty,)*), $messages:expr, $helps:expr),)*) => { + // matches the function if it is a backtraced message. + (@step $code:expr, ($(#[$error_func_docs:meta])* backtraced, $name:ident($($arg_names:ident: $arg_types:ty,)*), $message:expr, $help:expr), $(($(#[$docs:meta])* $formatted_or_backtraced_tail:ident, $names:ident($($tail_arg_names:ident: $tail_arg_types:ty,)*), $messages:expr, $helps:expr),)*) => { $(#[$error_func_docs])* // Expands additional arguments for the error defining function. - pub fn $error_name($($arg_names: $arg_types,)*) -> Self { - Self::BacktracedError( - BacktracedError::new_from_backtrace( + pub fn $name($($arg_names: $arg_types,)*) -> Self { + Self::Backtraced( + Backtraced::new_from_backtrace( $message, $help, - $code + Self::exit_code_mask(), + $code + Self::code_mask(), Self::code_identifier(), - Self::error_type(), + Self::message_type(), + Self::is_error(), // Each function always generates its own backtrace for backtrace clarity to originate from the error function. Backtrace::new(), ) ) } - // Steps the error code value by one and calls on the rest of the functions. - create_errors!(@step $code + 1i32, $(($(#[$docs])* $formatted_or_backtraced_tail, $names($($tail_arg_names: $tail_arg_types,)*), $messages, $helps),)*); + // Steps the code value by one and calls on the rest of the functions. + create_messages!(@step $code + 1i32, $(($(#[$docs])* $formatted_or_backtraced_tail, $names($($tail_arg_names: $tail_arg_types,)*), $messages, $helps),)*); }; } diff --git a/leo/errors/src/common/traits.rs b/leo/errors/src/common/traits.rs index ee3c8ac719..db5d32c059 100644 --- a/leo/errors/src/common/traits.rs +++ b/leo/errors/src/common/traits.rs @@ -14,19 +14,25 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -/// ErrorCode trait that all Errors should implement. -pub trait LeoErrorCode: Sized { +/// MessageCode trait that all Errors should implement. +pub trait LeoMessageCode: Sized { /// Returns the error's exit code for the program. fn exit_code(&self) -> i32; /// Returns the prefixed error identifier. fn error_code(&self) -> String; - /// Returns the error's exit code mask, as to avoid conflicts. - fn exit_code_mask() -> i32; + /// Returns the prefixed warning identifier. + fn warning_code(&self) -> String; - /// Returns the error's code type for the program. - fn error_type() -> String; + /// Returns the messages's exit code mask, as to avoid conflicts. + fn code_mask() -> i32; + + /// Returns the message's code type for the program. + fn message_type() -> String; + + /// Returns if the message is an error or warning. + fn is_error() -> bool; /// The LeoErrorCode which has a default code identifier of 037 /// (Leo upsidedown and backwards). This is to make the exit codes diff --git a/leo/errors/src/emitter/mod.rs b/leo/errors/src/emitter/mod.rs index 273259465d..f736e8c879 100644 --- a/leo/errors/src/emitter/mod.rs +++ b/leo/errors/src/emitter/mod.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +use crate::LeoWarning; + use super::LeoError; use core::default::Default; use core::fmt; @@ -24,6 +26,9 @@ use std::rc::Rc; pub trait Emitter { /// Emit the error `err`. fn emit_err(&mut self, err: LeoError); + + /// Emit the warning. + fn emit_warning(&mut self, warning: LeoWarning); } /// A trivial `Emitter` using the standard error. @@ -33,6 +38,10 @@ impl Emitter for StderrEmitter { fn emit_err(&mut self, err: LeoError) { eprintln!("{}", err); } + + fn emit_warning(&mut self, warning: LeoWarning) { + eprintln!("{warning}"); + } } /// A buffer of `T`s. @@ -72,34 +81,47 @@ impl fmt::Display for Buffer { /// A buffer of `LeoError`s. pub type ErrBuffer = Buffer; +/// A buffer of `LeoWarning`s. +pub type WarningBuffer = Buffer; /// An `Emitter` that collects into a list. #[derive(Default, Clone)] -pub struct BufferEmitter(Rc>); +pub struct BufferEmitter(Rc>, Rc>); impl BufferEmitter { /// Returns a new buffered emitter. pub fn new() -> Self { - BufferEmitter(<_>::default()) + BufferEmitter(<_>::default(), <_>::default()) } /// Extracts all the errors collected in this emitter. - pub fn extract(&self) -> ErrBuffer { + pub fn extract_errs(&self) -> ErrBuffer { self.0.take() } + + /// Extracts all the errors collected in this emitter. + pub fn extract_warnings(&self) -> WarningBuffer { + self.1.take() + } } impl Emitter for BufferEmitter { fn emit_err(&mut self, err: LeoError) { self.0.borrow_mut().push(err); } + + fn emit_warning(&mut self, warning: LeoWarning) { + self.1.borrow_mut().push(warning); + } } /// Contains the actual data for `Handler`. /// Modelled this way to afford an API using interior mutability. struct HandlerInner { /// Number of errors emitted thus far. - count: usize, + err_count: usize, + /// Number of warnings emitted thus far. + warn_count: usize, /// The sink through which errors will be emitted. emitter: Box, } @@ -107,9 +129,15 @@ struct HandlerInner { impl HandlerInner { /// Emit the error `err`. fn emit_err(&mut self, err: LeoError) { - self.count = self.count.saturating_add(1); + self.err_count = self.err_count.saturating_add(1); self.emitter.emit_err(err); } + + /// Emit the error `err`. + fn emit_warning(&mut self, warning: LeoWarning) { + self.warn_count = self.warn_count.saturating_add(1); + self.emitter.emit_warning(warning); + } } /// A handler deals with errors and other compiler output. @@ -128,7 +156,11 @@ impl Default for Handler { impl Handler { /// Construct a `Handler` using the given `emitter`. pub fn new(emitter: Box) -> Self { - let inner = RefCell::new(HandlerInner { count: 0, emitter }); + let inner = RefCell::new(HandlerInner { + err_count: 0, + warn_count: 0, + emitter, + }); Self { inner } } @@ -143,7 +175,7 @@ impl Handler { /// or if there were none, returns some `T`. pub fn with(logic: impl for<'a> FnOnce(&'a Handler) -> Result) -> Result { let (handler, buf) = Handler::new_with_buf(); - handler.extend_if_error(logic(&handler)).map_err(|_| buf.extract()) + handler.extend_if_error(logic(&handler)).map_err(|_| buf.extract_errs()) } /// Emit the error `err`. @@ -151,6 +183,11 @@ impl Handler { self.inner.borrow_mut().emit_err(err); } + /// Emit the error `err`. + pub fn emit_warning(&self, warning: LeoWarning) { + self.inner.borrow_mut().emit_warning(warning); + } + /// Emits the error `err`. /// This will immediately abort compilation. pub fn fatal_err(&self, err: LeoError) -> ! { @@ -161,7 +198,12 @@ impl Handler { /// The number of errors thus far. pub fn err_count(&self) -> usize { - self.inner.borrow().count + self.inner.borrow().err_count + } + + /// The number of warnings thus far. + pub fn warning_count(&self) -> usize { + self.inner.borrow().warn_count } /// Did we have any errors thus far? diff --git a/leo/errors/src/asg/asg_errors.rs b/leo/errors/src/errors/asg/asg_errors.rs similarity index 100% rename from leo/errors/src/asg/asg_errors.rs rename to leo/errors/src/errors/asg/asg_errors.rs diff --git a/leo/errors/src/asg/mod.rs b/leo/errors/src/errors/asg/mod.rs similarity index 100% rename from leo/errors/src/asg/mod.rs rename to leo/errors/src/errors/asg/mod.rs diff --git a/leo/errors/src/ast/ast_errors.rs b/leo/errors/src/errors/ast/ast_errors.rs similarity index 97% rename from leo/errors/src/ast/ast_errors.rs rename to leo/errors/src/errors/ast/ast_errors.rs index 73d37132dd..f52e1c6c3f 100644 --- a/leo/errors/src/ast/ast_errors.rs +++ b/leo/errors/src/errors/ast/ast_errors.rs @@ -14,17 +14,17 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::create_errors; +use crate::create_messages; use std::{ error::Error as ErrorArg, fmt::{Debug, Display}, }; -create_errors!( +create_messages!( /// AstError enum that represents all the errors for the `leo-ast` crate. AstError, - exit_code_mask: 2000i32, - error_code_prefix: "AST", + code_mask: 2000i32, + code_prefix: "AST", /// For when the AST fails to be represented as a JSON string. @backtraced diff --git a/leo/errors/src/ast/mod.rs b/leo/errors/src/errors/ast/mod.rs similarity index 100% rename from leo/errors/src/ast/mod.rs rename to leo/errors/src/errors/ast/mod.rs diff --git a/leo/errors/src/cli/cli_errors.rs b/leo/errors/src/errors/cli/cli_errors.rs similarity index 99% rename from leo/errors/src/cli/cli_errors.rs rename to leo/errors/src/errors/cli/cli_errors.rs index 86e1146ba0..e9d8d6b208 100644 --- a/leo/errors/src/cli/cli_errors.rs +++ b/leo/errors/src/errors/cli/cli_errors.rs @@ -14,17 +14,17 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::create_errors; +use crate::create_messages; use std::{ error::Error as ErrorArg, fmt::{Debug, Display}, }; -create_errors!( +create_messages!( /// CliError enum that represents all the errors for the `leo-lang` crate. CliError, - exit_code_mask: 7000i32, - error_code_prefix: "CLI", + code_mask: 7000i32, + code_prefix: "CLI", /// Not actually ever returned anywhere outside a test. @backtraced diff --git a/leo/errors/src/cli/mod.rs b/leo/errors/src/errors/cli/mod.rs similarity index 100% rename from leo/errors/src/cli/mod.rs rename to leo/errors/src/errors/cli/mod.rs diff --git a/leo/errors/src/compiler/compiler_errors.rs b/leo/errors/src/errors/compiler/compiler_errors.rs similarity index 99% rename from leo/errors/src/compiler/compiler_errors.rs rename to leo/errors/src/errors/compiler/compiler_errors.rs index fde3ccf4bf..9af638081e 100644 --- a/leo/errors/src/compiler/compiler_errors.rs +++ b/leo/errors/src/errors/compiler/compiler_errors.rs @@ -14,18 +14,18 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::create_errors; +use crate::create_messages; use std::{ error::Error as ErrorArg, fmt::{Debug, Display}, }; -create_errors!( +create_messages!( /// CompilerError enum that represents all the errors for the `leo-compiler` crate. CompilerError, - exit_code_mask: 6000i32, - error_code_prefix: "CMP", + code_mask: 6000i32, + code_prefix: "CMP", /// For when the test function has invalid test context. @backtraced diff --git a/leo/errors/src/compiler/mod.rs b/leo/errors/src/errors/compiler/mod.rs similarity index 100% rename from leo/errors/src/compiler/mod.rs rename to leo/errors/src/errors/compiler/mod.rs diff --git a/leo/errors/src/import/import_errors.rs b/leo/errors/src/errors/import/import_errors.rs similarity index 100% rename from leo/errors/src/import/import_errors.rs rename to leo/errors/src/errors/import/import_errors.rs diff --git a/leo/errors/src/import/mod.rs b/leo/errors/src/errors/import/mod.rs similarity index 100% rename from leo/errors/src/import/mod.rs rename to leo/errors/src/errors/import/mod.rs diff --git a/leo/errors/src/input/input_errors.rs b/leo/errors/src/errors/input/input_errors.rs similarity index 96% rename from leo/errors/src/input/input_errors.rs rename to leo/errors/src/errors/input/input_errors.rs index 1e337d264a..4ee87065cb 100644 --- a/leo/errors/src/input/input_errors.rs +++ b/leo/errors/src/errors/input/input_errors.rs @@ -14,14 +14,14 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::create_errors; +use crate::create_messages; use std::fmt::{Debug, Display}; -create_errors!( +create_messages!( /// InputError enum that represents all the errors for the inputs part of `leo-ast` crate. InputError, - exit_code_mask: 8000i32, - error_code_prefix: "INP", + code_mask: 8000i32, + code_prefix: "INP", /// For when declared variable type mismatches actual type. @formatted diff --git a/leo/errors/src/input/mod.rs b/leo/errors/src/errors/input/mod.rs similarity index 100% rename from leo/errors/src/input/mod.rs rename to leo/errors/src/errors/input/mod.rs diff --git a/leo/errors/src/errors/mod.rs b/leo/errors/src/errors/mod.rs new file mode 100644 index 0000000000..2970c9549a --- /dev/null +++ b/leo/errors/src/errors/mod.rs @@ -0,0 +1,99 @@ +// Copyright (C) 2019-2022 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +/// Contains the ASG error definitions. +use crate::LeoMessageCode; + +/// Contains the AST error definitions. +pub mod ast; +pub use self::ast::*; + +/// Contains the AST error definitions. +pub mod cli; +pub use self::cli::*; + +/// Contains the AST error definitions. +pub mod compiler; +pub use self::compiler::*; + +/// Contains the Input error definitions. +pub mod input; +pub use self::input::*; + +/// Contains the Package error definitions. +pub mod package; +pub use self::package::*; + +/// Contains the Parser error definitions. +pub mod parser; +pub use self::parser::*; + +/// The LeoError type that contains all sub error types. +/// This allows a unified error type throughout the Leo crates. +#[derive(Debug, Error)] +pub enum LeoError { + /// Represents an AST Error in a Leo Error. + #[error(transparent)] + AstError(#[from] AstError), + /// Represents an CLI Error in a Leo Error. + #[error(transparent)] + CliError(#[from] CliError), + /// Represents an Compiler Error in a Leo Error. + #[error(transparent)] + CompilerError(#[from] CompilerError), + /// Represents an Input Error in a Leo Error. + #[error(transparent)] + InputError(#[from] InputError), + /// Represents an Package Error in a Leo Error. + #[error(transparent)] + PackageError(#[from] PackageError), + /// Represents an Parser Error in a Leo Error. + #[error(transparent)] + ParserError(#[from] ParserError), +} + +impl LeoError { + /// Implement error code for each type of Error. + pub fn error_code(&self) -> String { + use LeoError::*; + + match self { + AstError(error) => error.error_code(), + CompilerError(error) => error.error_code(), + CliError(error) => error.error_code(), + InputError(error) => error.error_code(), + ParserError(error) => error.error_code(), + PackageError(error) => error.error_code(), + } + } + + /// Implement exit code for each type of Error. + pub fn exit_code(&self) -> i32 { + use LeoError::*; + + match self { + AstError(error) => error.exit_code(), + CompilerError(error) => error.exit_code(), + CliError(error) => error.exit_code(), + InputError(error) => error.exit_code(), + ParserError(error) => error.exit_code(), + PackageError(error) => error.exit_code(), + } + } +} + +/// A global result type for all Leo crates, that defaults the errors to be a LeoError. +pub type Result = core::result::Result; diff --git a/leo/errors/src/package/mod.rs b/leo/errors/src/errors/package/mod.rs similarity index 100% rename from leo/errors/src/package/mod.rs rename to leo/errors/src/errors/package/mod.rs diff --git a/leo/errors/src/package/package_errors.rs b/leo/errors/src/errors/package/package_errors.rs similarity index 99% rename from leo/errors/src/package/package_errors.rs rename to leo/errors/src/errors/package/package_errors.rs index 9fdadda845..b971c71f79 100644 --- a/leo/errors/src/package/package_errors.rs +++ b/leo/errors/src/errors/package/package_errors.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::create_errors; +use crate::create_messages; use std::{ error::Error as ErrorArg, @@ -23,11 +23,11 @@ use std::{ // todo (collin): redo these after Mazdak finishes error indexing. -create_errors!( +create_messages!( /// PackageError enum that represents all the errors for the `leo-package` crate. PackageError, - exit_code_mask: 5000i32, - error_code_prefix: "PAK", + code_mask: 5000i32, + code_prefix: "PAK", /// For when the specified import does not exist. @backtraced diff --git a/leo/errors/src/parser/mod.rs b/leo/errors/src/errors/parser/mod.rs similarity index 100% rename from leo/errors/src/parser/mod.rs rename to leo/errors/src/errors/parser/mod.rs diff --git a/leo/errors/src/parser/parser_errors.rs b/leo/errors/src/errors/parser/parser_errors.rs similarity index 94% rename from leo/errors/src/parser/parser_errors.rs rename to leo/errors/src/errors/parser/parser_errors.rs index 741f7ccd9b..5cad2575b8 100644 --- a/leo/errors/src/parser/parser_errors.rs +++ b/leo/errors/src/errors/parser/parser_errors.rs @@ -14,15 +14,15 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::create_errors; +use crate::create_messages; use std::fmt::{Debug, Display}; -create_errors!( +create_messages!( /// ParserError enum that represents all the errors for the `leo-parser` crate. ParserError, - exit_code_mask: 0000i32, - error_code_prefix: "PAR", + code_mask: 0000i32, + code_prefix: "PAR", /// For when the parser encountered an unexpected token. @formatted @@ -359,19 +359,11 @@ create_errors!( help: None, } - /// For when a user specified more than a type on a parameter. - @formatted - inputs_multiple_variable_types_specified { - args: (), - msg: "A parameter cannot be both public and const.", - help: None, - } - - /// For when a user used const on a parameter or input instead of constant. - @formatted - const_parameter_or_input { - args: (), - msg: "`constant` is preferred over `const` for function parameters to indicate a R1CS constant.", - help: None, - } + /// For when a user specified more than a type on a parameter. + @formatted + inputs_multiple_variable_types_specified { + args: (), + msg: "A parameter cannot be both public and const.", + help: None, + } ); diff --git a/leo/errors/src/snarkvm/mod.rs b/leo/errors/src/errors/snarkvm/mod.rs similarity index 100% rename from leo/errors/src/snarkvm/mod.rs rename to leo/errors/src/errors/snarkvm/mod.rs diff --git a/leo/errors/src/snarkvm/snarkvm_errors.rs b/leo/errors/src/errors/snarkvm/snarkvm_errors.rs similarity index 100% rename from leo/errors/src/snarkvm/snarkvm_errors.rs rename to leo/errors/src/errors/snarkvm/snarkvm_errors.rs diff --git a/leo/errors/src/state/mod.rs b/leo/errors/src/errors/state/mod.rs similarity index 100% rename from leo/errors/src/state/mod.rs rename to leo/errors/src/errors/state/mod.rs diff --git a/leo/errors/src/state/state_errors.rs b/leo/errors/src/errors/state/state_errors.rs similarity index 100% rename from leo/errors/src/state/state_errors.rs rename to leo/errors/src/errors/state/state_errors.rs diff --git a/leo/errors/src/lib.rs b/leo/errors/src/lib.rs index c76a766a44..63fa017f41 100644 --- a/leo/errors/src/lib.rs +++ b/leo/errors/src/lib.rs @@ -17,139 +17,20 @@ #![deny(clippy::all, clippy::missing_docs_in_private_items)] #![doc = include_str!("../README.md")] -/// Contains traits and types for channels through which errors go. -pub mod emitter; - -/// Contains the ASG error definitions. -pub mod asg; -pub use self::asg::*; - -/// Contains the AST error definitions. -pub mod ast; -pub use self::ast::*; - -/// Contains the CLI error definitions. -pub mod cli; -pub use self::cli::*; +#[macro_use] +extern crate thiserror; /// Contains the common functionalities for defining errors.. #[macro_use] pub mod common; pub use self::common::*; -/// Contains the Compiler error definitions. -pub mod compiler; -pub use self::compiler::*; +/// Contains traits and types for channels through which errors go. +pub mod emitter; +/// Contains the errors for the Leo lang. +pub mod errors; +pub use self::errors::*; -/// Contains the Import error definitions. -pub mod import; -pub use self::import::*; - -/// Contains the Input error definitions. -pub mod input; -pub use self::input::*; - -/// Contains the Package error definitions. -pub mod package; -pub use self::package::*; - -/// Contains the Parser error definitions. -pub mod parser; -pub use self::parser::*; - -/// Contains the SnarkVM error definitions. -pub mod snarkvm; -pub use self::snarkvm::*; - -/// Contains the State error definitions. -pub mod state; -pub use self::state::*; - -#[macro_use] -extern crate thiserror; - -/// The LeoError type that contains all sub error types. -/// This allows a unified error type throughout the Leo crates. -#[derive(Debug, Error)] -pub enum LeoError { - /// Represents an ASG Error in a Leo Error. - #[error(transparent)] - AsgError(#[from] AsgError), - - /// Represents an AST Error in a Leo Error. - #[error(transparent)] - AstError(#[from] AstError), - - /// Represents an CLI Error in a Leo Error. - #[error(transparent)] - CliError(#[from] CliError), - - /// Represents an Compiler Error in a Leo Error. - #[error(transparent)] - CompilerError(#[from] CompilerError), - - /// Represents an Import Error in a Leo Error. - #[error(transparent)] - ImportError(#[from] ImportError), - - /// Represents an Input Error in a Leo Error. - #[error(transparent)] - InputError(#[from] InputError), - - /// Represents an Package Error in a Leo Error. - #[error(transparent)] - PackageError(#[from] PackageError), - - /// Represents an Parser Error in a Leo Error. - #[error(transparent)] - ParserError(#[from] ParserError), - - /// Represents an SnarkVM Error in a Leo Error. - #[error(transparent)] - SnarkVMError(#[from] SnarkVMError), - - /// Represents an State Error in a Leo Error. - #[error(transparent)] - StateError(#[from] StateError), -} - -impl LeoError { - /// Implement error code for each type of Error. For the unsupported use a default value. - pub fn error_code(&self) -> String { - use LeoError::*; - - match self { - AsgError(error) => error.error_code(), - AstError(error) => error.error_code(), - CliError(error) => error.error_code(), - CompilerError(error) => error.error_code(), - ImportError(error) => error.error_code(), - InputError(error) => error.error_code(), - PackageError(error) => error.error_code(), - ParserError(error) => error.error_code(), - SnarkVMError(_error) => Default::default(), // TODO update once snarkvm implments a global top level error similar to LeoError. - StateError(error) => error.error_code(), - } - } - - /// Implement exit code for each type of Error, even the ones that don't have one. - pub fn exit_code(&self) -> i32 { - use LeoError::*; - - match self { - AsgError(error) => error.exit_code(), - AstError(error) => error.exit_code(), - CliError(error) => error.exit_code(), - CompilerError(error) => error.exit_code(), - ImportError(error) => error.exit_code(), - InputError(error) => error.exit_code(), - PackageError(error) => error.exit_code(), - ParserError(error) => error.exit_code(), - SnarkVMError(_error) => 1, // TODO update once snarkvm implments a global top level error similar to LeoError. - StateError(error) => error.exit_code(), - } - } -} - -/// A global result type for all Leo crates, that defaults the errors to be a LeoError. -pub type Result = core::result::Result; +/// Contains the warnings for the Leo lang. +pub mod warnings; +pub use self::warnings::*; diff --git a/leo/errors/src/warnings/mod.rs b/leo/errors/src/warnings/mod.rs new file mode 100644 index 0000000000..5a3e05ce35 --- /dev/null +++ b/leo/errors/src/warnings/mod.rs @@ -0,0 +1,43 @@ +// Copyright (C) 2019-2022 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +/// The LeoError type that contains all sub error types. +/// This allows a unified error type throughout the Leo crates. +use crate::LeoMessageCode; + +/// Contains the Parser warning definitions. +pub mod parser; +pub use self::parser::*; + +/// The LeoWarning type that contains all sub error types. +/// This allows a unified error type throughout the Leo crates. +#[derive(Debug, Error)] +pub enum LeoWarning { + /// Represents an Parser Error in a Leo Error. + #[error(transparent)] + ParserWarning(#[from] ParserWarning), +} + +impl LeoWarning { + /// Implement warning code for each type of Warning. + pub fn error_code(&self) -> String { + use LeoWarning::*; + + match self { + ParserWarning(warning) => warning.warning_code(), + } + } +} diff --git a/leo/errors/src/warnings/parser/mod.rs b/leo/errors/src/warnings/parser/mod.rs new file mode 100644 index 0000000000..3d2496c54e --- /dev/null +++ b/leo/errors/src/warnings/parser/mod.rs @@ -0,0 +1,19 @@ +// Copyright (C) 2019-2022 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +/// This module contains the Parser error definitions. +pub mod parser_warning; +pub use self::parser_warning::*; diff --git a/leo/errors/src/warnings/parser/parser_warning.rs b/leo/errors/src/warnings/parser/parser_warning.rs new file mode 100644 index 0000000000..a43ba91cf1 --- /dev/null +++ b/leo/errors/src/warnings/parser/parser_warning.rs @@ -0,0 +1,32 @@ +// Copyright (C) 2019-2022 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::create_messages; + +create_messages!( + /// ParserWarning enum that represents all the warnings for the `leo-parser` crate. + ParserWarning, + code_mask: 0000i32, + code_prefix: "PAR", + + /// For when a user used const on a parameter or input instead of constant. + @formatted + const_parameter_or_input { + args: (), + msg: "`constant` is preferred over `const` for function parameters to indicate a R1CS constant.", + help: None, + } +); diff --git a/tests/expectations/parser/parser/functions/const_input.leo.out b/tests/expectations/parser/parser/functions/const_input.leo.out new file mode 100644 index 0000000000..7d86cb98e3 --- /dev/null +++ b/tests/expectations/parser/parser/functions/const_input.leo.out @@ -0,0 +1,75 @@ +--- +namespace: Parse +expectation: Pass +outputs: + - name: "" + expected_input: [] + functions: + "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function x(const x: u8) {}\\\"}\"}": + identifier: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function x(const x: u8) {}\\\"}\"}" + input: + - Variable: + identifier: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":18,\\\"col_stop\\\":19,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function x(const x: u8) {}\\\"}\"}" + mode: Constant + type_: + IntegerType: U8 + span: + line_start: 3 + line_stop: 3 + col_start: 18 + col_stop: 19 + path: "" + content: "function x(const x: u8) {}" + const_: false + output: ~ + core_mapping: ~ + block: + statements: [] + span: + line_start: 3 + line_stop: 3 + col_start: 25 + col_stop: 27 + path: "" + content: "function x(const x: u8) {}" + span: + line_start: 3 + line_stop: 3 + col_start: 1 + col_stop: 27 + path: "" + content: "function x(const x: u8) {}" + "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function y(constant y: u64) {}\\\"}\"}": + identifier: "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function y(constant y: u64) {}\\\"}\"}" + input: + - Variable: + identifier: "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":21,\\\"col_stop\\\":22,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"function y(constant y: u64) {}\\\"}\"}" + mode: Constant + type_: + IntegerType: U64 + span: + line_start: 5 + line_stop: 5 + col_start: 21 + col_stop: 22 + path: "" + content: "function y(constant y: u64) {}" + const_: false + output: ~ + core_mapping: ~ + block: + statements: [] + span: + line_start: 5 + line_stop: 5 + col_start: 29 + col_stop: 31 + path: "" + content: "function y(constant y: u64) {}" + span: + line_start: 5 + line_stop: 5 + col_start: 1 + col_stop: 31 + path: "" + content: "function y(constant y: u64) {}" diff --git a/tests/expectations/parser/parser/functions/const_input_fail.leo.out b/tests/expectations/parser/parser/functions/const_input_fail.leo.out index 309a679337..d0d34e7510 100644 --- a/tests/expectations/parser/parser/functions/const_input_fail.leo.out +++ b/tests/expectations/parser/parser/functions/const_input_fail.leo.out @@ -2,4 +2,4 @@ namespace: Parse expectation: Fail outputs: - - "Error [EPAR0370042]: `constant` is preferred over `const` for function parameters to indicate a R1CS constant.\n --> test:3:12\n |\n 3 | function x(const input) {\n | ^^^^^\nError [EPAR0370009]: unexpected string: expected 'ident', got 'input'\n --> test:3:18\n |\n 3 | function x(const input) {\n | ^^^^^" + - "Error [EPAR0370009]: unexpected string: expected 'ident', got 'input'\n --> test:3:18\n |\n 3 | function x(const input) {\n | ^^^^^" diff --git a/tests/expectations/parser/parser/functions/const_input_kw_fail.leo.out b/tests/expectations/parser/parser/functions/const_input_kw_fail.leo.out new file mode 100644 index 0000000000..d0d34e7510 --- /dev/null +++ b/tests/expectations/parser/parser/functions/const_input_kw_fail.leo.out @@ -0,0 +1,5 @@ +--- +namespace: Parse +expectation: Fail +outputs: + - "Error [EPAR0370009]: unexpected string: expected 'ident', got 'input'\n --> test:3:18\n |\n 3 | function x(const input) {\n | ^^^^^" diff --git a/tests/expectations/parser/parser/functions/const_public_param_fail.leo.out b/tests/expectations/parser/parser/functions/const_public_param_fail.leo.out index 9b17602f02..24c32456b2 100644 --- a/tests/expectations/parser/parser/functions/const_public_param_fail.leo.out +++ b/tests/expectations/parser/parser/functions/const_public_param_fail.leo.out @@ -2,4 +2,4 @@ namespace: Parse expectation: Fail outputs: - - "Error [EPAR0370042]: `constant` is preferred over `const` for function parameters to indicate a R1CS constant.\n --> test:3:20\n |\n 3 | function x(x: u32, const public y: i32) {\n | ^^^^^\nError [EPAR0370009]: unexpected string: expected 'ident', got 'public'\n --> test:3:26\n |\n 3 | function x(x: u32, const public y: i32) {\n | ^^^^^^" + - "Error [EPAR0370009]: unexpected string: expected 'ident', got 'public'\n --> test:3:26\n |\n 3 | function x(x: u32, const public y: i32) {\n | ^^^^^^" diff --git a/tests/expectations/parser/parser/functions/public_const_param_fail.leo.out b/tests/expectations/parser/parser/functions/public_const_param_fail.leo.out index cd850eadcb..98cce4b400 100644 --- a/tests/expectations/parser/parser/functions/public_const_param_fail.leo.out +++ b/tests/expectations/parser/parser/functions/public_const_param_fail.leo.out @@ -2,4 +2,4 @@ namespace: Parse expectation: Fail outputs: - - "Error [EPAR0370042]: `constant` is preferred over `const` for function parameters to indicate a R1CS constant.\n --> test:3:27\n |\n 3 | function x(x: u32, public const y: i32) {\n | ^^^^^\nError [EPAR0370041]: A parameter cannot be both public and const.\n --> test:3:20\n |\n 3 | function x(x: u32, public const y: i32) {\n | ^^^^^^^^^^^^" + - "Error [EPAR0370041]: A parameter cannot be both public and const.\n --> test:3:20\n |\n 3 | function x(x: u32, public const y: i32) {\n | ^^^^^^^^^^^^" diff --git a/tests/expectations/parser/parser/inputs/input_const.leo.out b/tests/expectations/parser/parser/inputs/input_const.leo.out index 5d120639e3..90e76b3c73 100644 --- a/tests/expectations/parser/parser/inputs/input_const.leo.out +++ b/tests/expectations/parser/parser/inputs/input_const.leo.out @@ -1,5 +1,275 @@ --- namespace: Input -expectation: Fail +expectation: Pass outputs: - - "Error [EPAR0370042]: `constant` is preferred over `const` for function parameters to indicate a R1CS constant.\n --> test:4:1\n |\n 4 | const a: bool = true;\n | ^^^^^\nError [EPAR0370042]: `constant` is preferred over `const` for function parameters to indicate a R1CS constant.\n --> test:5:1\n |\n 5 | const b: u8 = 2;\n | ^^^^^\nError [EPAR0370042]: `constant` is preferred over `const` for function parameters to indicate a R1CS constant.\n --> test:6:1\n |\n 6 | const c: field = 0;\n | ^^^^^\nError [EPAR0370042]: `constant` is preferred over `const` for function parameters to indicate a R1CS constant.\n --> test:7:1\n |\n 7 | const d: group = (0, 1)group;\n | ^^^^^\nError [EPAR0370042]: `constant` is preferred over `const` for function parameters to indicate a R1CS constant.\n --> test:8:1\n |\n 8 | const e: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;\n | ^^^^^" + - sections: + - name: main + definitions: + - mode: Constant + type_: Boolean + name: "{\"name\":\"a\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"const a: bool = true;\\\"}\"}" + value: + Value: + Boolean: + - "true" + - span: + line_start: 4 + line_stop: 4 + col_start: 18 + col_stop: 22 + path: "" + content: "const a: bool = true;" + span: + line_start: 4 + line_stop: 4 + col_start: 10 + col_stop: 14 + path: "" + content: "const a: bool = true;" + - mode: Constant + type_: + IntegerType: U8 + name: "{\"name\":\"b\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"const b: u8 = 2;\\\"}\"}" + value: + Value: + Implicit: + - "2" + - span: + line_start: 5 + line_stop: 5 + col_start: 18 + col_stop: 19 + path: "" + content: "const b: u8 = 2;" + span: + line_start: 5 + line_stop: 5 + col_start: 10 + col_stop: 12 + path: "" + content: "const b: u8 = 2;" + - mode: Constant + type_: Field + name: "{\"name\":\"c\",\"span\":\"{\\\"line_start\\\":6,\\\"line_stop\\\":6,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"const c: field = 0;\\\"}\"}" + value: + Value: + Implicit: + - "0" + - span: + line_start: 6 + line_stop: 6 + col_start: 18 + col_stop: 19 + path: "" + content: "const c: field = 0;" + span: + line_start: 6 + line_stop: 6 + col_start: 10 + col_stop: 15 + path: "" + content: "const c: field = 0;" + - mode: Constant + type_: Group + name: "{\"name\":\"d\",\"span\":\"{\\\"line_start\\\":7,\\\"line_stop\\\":7,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"const d: group = (0, 1)group;\\\"}\"}" + value: + Value: + Group: + Tuple: + x: + Number: + - "0" + - span: + line_start: 7 + line_stop: 7 + col_start: 19 + col_stop: 20 + path: "" + content: "const d: group = (0, 1)group;" + y: + Number: + - "1" + - span: + line_start: 7 + line_stop: 7 + col_start: 22 + col_stop: 23 + path: "" + content: "const d: group = (0, 1)group;" + span: + line_start: 7 + line_stop: 7 + col_start: 18 + col_stop: 29 + path: "" + content: "const d: group = (0, 1)group;" + span: + line_start: 7 + line_stop: 7 + col_start: 10 + col_stop: 15 + path: "" + content: "const d: group = (0, 1)group;" + - mode: Constant + type_: Address + name: "{\"name\":\"e\",\"span\":\"{\\\"line_start\\\":8,\\\"line_stop\\\":8,\\\"col_start\\\":7,\\\"col_stop\\\":8,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"const e: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;\\\"}\"}" + value: + Value: + Address: + - aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8 + - span: + line_start: 8 + line_stop: 8 + col_start: 20 + col_stop: 83 + path: "" + content: "const e: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;" + span: + line_start: 8 + line_stop: 8 + col_start: 10 + col_stop: 17 + path: "" + content: "const e: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;" + span: + line_start: 3 + line_stop: 3 + col_start: 2 + col_stop: 6 + path: "" + content: "[main]" + - name: registers + definitions: + - mode: Private + type_: Boolean + name: "{\"name\":\"r0\",\"span\":\"{\\\"line_start\\\":11,\\\"line_stop\\\":11,\\\"col_start\\\":1,\\\"col_stop\\\":3,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"r0: bool = true;\\\"}\"}" + value: + Value: + Boolean: + - "true" + - span: + line_start: 11 + line_stop: 11 + col_start: 13 + col_stop: 17 + path: "" + content: "r0: bool = true;" + span: + line_start: 11 + line_stop: 11 + col_start: 5 + col_stop: 9 + path: "" + content: "r0: bool = true;" + - mode: Private + type_: + IntegerType: U8 + name: "{\"name\":\"r1\",\"span\":\"{\\\"line_start\\\":12,\\\"line_stop\\\":12,\\\"col_start\\\":1,\\\"col_stop\\\":3,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"r1: u8 = 2;\\\"}\"}" + value: + Value: + Implicit: + - "2" + - span: + line_start: 12 + line_stop: 12 + col_start: 13 + col_stop: 14 + path: "" + content: "r1: u8 = 2;" + span: + line_start: 12 + line_stop: 12 + col_start: 5 + col_stop: 7 + path: "" + content: "r1: u8 = 2;" + - mode: Private + type_: Field + name: "{\"name\":\"r2\",\"span\":\"{\\\"line_start\\\":13,\\\"line_stop\\\":13,\\\"col_start\\\":1,\\\"col_stop\\\":3,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"r2: field = 0;\\\"}\"}" + value: + Value: + Implicit: + - "0" + - span: + line_start: 13 + line_stop: 13 + col_start: 13 + col_stop: 14 + path: "" + content: "r2: field = 0;" + span: + line_start: 13 + line_stop: 13 + col_start: 5 + col_stop: 10 + path: "" + content: "r2: field = 0;" + - mode: Private + type_: Group + name: "{\"name\":\"r3\",\"span\":\"{\\\"line_start\\\":14,\\\"line_stop\\\":14,\\\"col_start\\\":1,\\\"col_stop\\\":3,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"r3: group = (0, 1)group;\\\"}\"}" + value: + Value: + Group: + Tuple: + x: + Number: + - "0" + - span: + line_start: 14 + line_stop: 14 + col_start: 14 + col_stop: 15 + path: "" + content: "r3: group = (0, 1)group;" + y: + Number: + - "1" + - span: + line_start: 14 + line_stop: 14 + col_start: 17 + col_stop: 18 + path: "" + content: "r3: group = (0, 1)group;" + span: + line_start: 14 + line_stop: 14 + col_start: 13 + col_stop: 24 + path: "" + content: "r3: group = (0, 1)group;" + span: + line_start: 14 + line_stop: 14 + col_start: 5 + col_stop: 10 + path: "" + content: "r3: group = (0, 1)group;" + - mode: Private + type_: Address + name: "{\"name\":\"r4\",\"span\":\"{\\\"line_start\\\":15,\\\"line_stop\\\":15,\\\"col_start\\\":1,\\\"col_stop\\\":3,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\"r4: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;\\\"}\"}" + value: + Value: + Address: + - aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8 + - span: + line_start: 15 + line_stop: 15 + col_start: 15 + col_stop: 78 + path: "" + content: "r4: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;" + span: + line_start: 15 + line_stop: 15 + col_start: 5 + col_stop: 12 + path: "" + content: "r4: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;" + span: + line_start: 10 + line_stop: 10 + col_start: 2 + col_stop: 11 + path: "" + content: "[registers]" diff --git a/tests/parser/functions/const_input.leo b/tests/parser/functions/const_input.leo new file mode 100644 index 0000000000..32354e61da --- /dev/null +++ b/tests/parser/functions/const_input.leo @@ -0,0 +1,8 @@ +/* +namespace: Parse +expectation: Pass +*/ + +function x(const x: u8) {} + +function y(constant y: u64) {} \ No newline at end of file diff --git a/tests/parser/functions/const_input_fail.leo b/tests/parser/functions/const_input_kw_fail.leo similarity index 100% rename from tests/parser/functions/const_input_fail.leo rename to tests/parser/functions/const_input_kw_fail.leo diff --git a/tests/parser/inputs/input_const.leo b/tests/parser/inputs/input_const.leo index bd7c15d93d..7b7f179978 100644 --- a/tests/parser/inputs/input_const.leo +++ b/tests/parser/inputs/input_const.leo @@ -1,6 +1,6 @@ /* namespace: Input -expectation: Fail +expectation: Pass */ [main] diff --git a/tests/test-framework/src/bin/errcov.rs b/tests/test-framework/src/bin/errcov.rs index a17a586874..6e6200f021 100644 --- a/tests/test-framework/src/bin/errcov.rs +++ b/tests/test-framework/src/bin/errcov.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_errors::{ - AsgError, AstError, CliError, CompilerError, ImportError, LeoErrorCode, PackageError, ParserError, StateError, -}; +use leo_errors::{AstError, InputError, LeoMessageCode, PackageError, ParserError}; use leo_test_framework::{ fetch::find_tests, output::TestExpectation, @@ -111,60 +109,32 @@ fn run_with_args(opt: Opt) -> Result<(), Box> { let mut all_codes = HashSet::new(); collect_error_codes( &mut all_codes, - AsgError::error_type(), - AsgError::code_identifier(), - AsgError::exit_code_mask(), - AsgError::num_exit_codes(), - ); - collect_error_codes( - &mut all_codes, - AstError::error_type(), + AstError::message_type(), AstError::code_identifier(), - AstError::exit_code_mask(), + AstError::code_mask(), AstError::num_exit_codes(), ); collect_error_codes( &mut all_codes, - CliError::error_type(), - CliError::code_identifier(), - CliError::exit_code_mask(), - CliError::num_exit_codes(), + InputError::message_type(), + InputError::code_identifier(), + InputError::code_mask(), + InputError::num_exit_codes(), ); collect_error_codes( &mut all_codes, - CompilerError::error_type(), - CompilerError::code_identifier(), - CompilerError::exit_code_mask(), - CompilerError::num_exit_codes(), - ); - collect_error_codes( - &mut all_codes, - ImportError::error_type(), - ImportError::code_identifier(), - ImportError::exit_code_mask(), - ImportError::num_exit_codes(), - ); - collect_error_codes( - &mut all_codes, - PackageError::error_type(), + PackageError::message_type(), PackageError::code_identifier(), - PackageError::exit_code_mask(), + PackageError::code_mask(), PackageError::num_exit_codes(), ); collect_error_codes( &mut all_codes, - ParserError::error_type(), + ParserError::message_type(), ParserError::code_identifier(), - ParserError::exit_code_mask(), + ParserError::code_mask(), ParserError::num_exit_codes(), ); - collect_error_codes( - &mut all_codes, - StateError::error_type(), - StateError::code_identifier(), - StateError::exit_code_mask(), - StateError::num_exit_codes(), - ); // Repackage data into values compatible with serde_yaml let mut covered_errors = serde_yaml::Mapping::new(); From 8c31079792c85c11311a10ee92bb0db40a15184b Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Tue, 19 Apr 2022 13:02:14 -0700 Subject: [PATCH 3/4] merge upstream grammar changes --- docs/grammar/README.md | Bin 23638 -> 49156 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/grammar/README.md b/docs/grammar/README.md index 95eb46c8cc1952a8ebd7f1252a287d90bb9dd239..b4ec72fcf633522aa5eb84bebe64bec336742bc2 100644 GIT binary patch literal 49156 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 F=U+H5OcnqD literal 23638 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 From f9dcbf3e8b10ab1646b246c5d010c1a079c520ea Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Wed, 20 Apr 2022 11:06:40 -0700 Subject: [PATCH 4/4] update leo errors readme --- leo/errors/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/leo/errors/README.md b/leo/errors/README.md index edfd180bff..0a0c4aa726 100644 --- a/leo/errors/README.md +++ b/leo/errors/README.md @@ -6,6 +6,15 @@ This directory contains the code for the Errors for all the Leo crates. +The errors are inspired by `rust` in a few different ways: + +- Each error has its own unique code. +- Error codes will never be changed upon a stable release. + - Meaning outdated errors will just deprecated. +- In addition we had a unique identifier to let you know where the compiler found the error. + +The purpose of these errors is such that searching an error in the documentation, or online for help, becomes easier. + ## [Common](./src/common) The common section of this crate contains a few sub files: