pull latest master

This commit is contained in:
gluaxspeed 2021-01-28 12:01:47 -05:00
commit 3200a9cea1
29 changed files with 397 additions and 66 deletions

1
Cargo.lock generated
View File

@ -1230,6 +1230,7 @@ dependencies = [
"pest",
"serde",
"serde_json",
"thiserror",
]
[[package]]

View File

@ -47,6 +47,9 @@ version = "1.0"
[dependencies.serde_json]
version = "1.0"
[dependencies.thiserror]
version = "1.0"
[dev-dependencies.criterion]
version = "0.3"

View File

@ -21,7 +21,7 @@ use criterion::{criterion_group, criterion_main, Criterion};
use std::{path::Path, time::Duration};
fn ast(ast: &Grammar) -> Ast {
Ast::new("leo_tree", &ast)
Ast::new("leo_tree", &ast).unwrap()
}
fn bench_big_if_else(c: &mut Criterion) {

View File

@ -14,12 +14,14 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{Circuit, Function, FunctionInput, Identifier, ImportStatement, TestFunction};
use crate::{Circuit, DeprecatedError, Function, FunctionInput, Identifier, ImportStatement, TestFunction};
use leo_grammar::{
annotations::{Annotation, AnnotationArguments, AnnotationName},
definitions::{AnnotatedDefinition, Definition},
};
use std::convert::TryFrom;
use indexmap::IndexMap;
pub fn load_annotation(
@ -29,19 +31,37 @@ pub fn load_annotation(
_functions: &mut IndexMap<Identifier, Function>,
tests: &mut IndexMap<Identifier, TestFunction>,
_expected: &mut Vec<FunctionInput>,
) {
) -> Result<(), DeprecatedError> {
let ast_annotation = annotated_definition.annotation;
let ast_definition = *annotated_definition.definition;
match ast_definition {
Definition::Import(_) => unimplemented!("annotated imports are not supported yet"),
Definition::Circuit(_) => unimplemented!("annotated circuits are not supported yet"),
Definition::Function(_) => unimplemented!("annotated functions are not supported yet"),
Definition::TestFunction(ast_test) => {
let test = TestFunction::from(ast_test);
load_annotated_test(test, ast_annotation, tests)
Definition::Import(_) => {
unimplemented!("annotated imports are not supported yet");
}
Definition::Circuit(_) => {
unimplemented!("annotated circuits are not supported yet");
}
Definition::Function(function) => match ast_annotation.name {
// If it's deprecated for more than one type of syntax,
// we could just call it before the match on ast_definition.
AnnotationName::Context(_) => Err(DeprecatedError::try_from(ast_annotation.name).unwrap()),
AnnotationName::Test(_) => {
let ident = Identifier::from(function.identifier.clone());
_functions.remove(&ident);
let test_function = leo_grammar::functions::TestFunction::from(function);
let test = TestFunction::from(test_function);
tests.insert(ident, test.clone());
load_annotated_test(test, ast_annotation, tests);
Ok(())
}
},
Definition::Deprecated(_) => Ok(()),
Definition::Annotated(_) => {
unimplemented!("nested annotations are not supported yet");
}
Definition::Annotated(_) => unimplemented!("nested annotations are not supported yet"),
}
}
@ -50,7 +70,10 @@ pub fn load_annotated_test(test: TestFunction, annotation: Annotation, tests: &m
let ast_arguments = annotation.arguments;
match name {
AnnotationName::Context(_) => load_annotated_test_context(test, ast_arguments, tests),
AnnotationName::Test(_) if ast_arguments.is_some() => {
load_annotated_test_context(test, ast_arguments.unwrap(), tests)
}
_ => (),
}
}

View File

@ -0,0 +1,63 @@
// Copyright (C) 2019-2020 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 <https://www.gnu.org/licenses/>.
use crate::{Error as FormattedError, Span};
use leo_grammar::{annotations::AnnotationName, definitions::Deprecated};
use std::{convert::TryFrom, path::Path};
#[derive(Debug, Error)]
pub enum DeprecatedError {
#[error("{}", _0)]
Error(#[from] FormattedError),
}
impl DeprecatedError {
pub fn set_path(&mut self, path: &Path) {
match self {
DeprecatedError::Error(error) => error.set_path(path),
}
}
fn new_from_span(message: String, span: Span) -> Self {
DeprecatedError::Error(FormattedError::new_from_span(message, span))
}
}
impl<'ast> From<Deprecated<'ast>> for DeprecatedError {
fn from(deprecated: Deprecated<'ast>) -> Self {
match deprecated {
Deprecated::TestFunction(test_function) => DeprecatedError::new_from_span(
"\"test function...\" is deprecated. Did you mean @test annotation?".to_string(),
Span::from(test_function.span.clone()),
),
}
}
}
impl<'ast> TryFrom<AnnotationName<'ast>> for DeprecatedError {
type Error = bool;
fn try_from(annotation_name: AnnotationName<'ast>) -> Result<Self, bool> {
match annotation_name {
AnnotationName::Context(context) => Ok(DeprecatedError::new_from_span(
"\"@context(...)\" is deprecated. Did you mean @test annotation?".to_string(),
Span::from(context.span.clone()),
)),
_ => Err(false),
}
}
}

View File

@ -14,5 +14,30 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
pub mod deprecated;
pub use deprecated::*;
pub mod error;
pub use error::*;
use error::Error as FormattedError;
use leo_grammar::ParserError;
#[derive(Debug, Error)]
pub enum AstError {
#[error("{}", _0)]
DeprecatedError(#[from] DeprecatedError),
#[error("{}", _0)]
Error(#[from] FormattedError),
#[error("{}", _0)]
IoError(#[from] std::io::Error),
#[error("{}", _0)]
ParserError(#[from] ParserError),
#[error("{}", _0)]
JsonError(#[from] serde_json::error::Error),
}

View File

@ -19,6 +19,8 @@
//! This module contains the [`Ast`] type, a wrapper around the [`Program`] type.
//! The [`Ast`] type is intended to be parsed and modified by different passes
//! of the Leo compiler. The Leo compiler can generate a set of R1CS constraints from any [`Ast`].
#[macro_use]
extern crate thiserror;
pub mod annotation;
pub use self::annotation::*;
@ -74,10 +76,10 @@ pub struct Ast {
impl Ast {
/// Creates a new ast from a given program name and grammar tree.
pub fn new<'ast>(program_name: &str, ast: &Grammar<'ast>) -> Self {
Self {
ast: Program::from(program_name, ast.as_repr()),
}
pub fn new<'ast>(program_name: &str, ast: &Grammar<'ast>) -> Result<Self, AstError> {
Ok(Self {
ast: Program::from(program_name, ast.as_repr())?,
})
}
/// Returns a reference to the inner program ast representation.

View File

@ -14,11 +14,11 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use leo_ast::Ast;
use leo_grammar::{Grammar, ParserError};
use leo_ast::{Ast, AstError};
use leo_grammar::Grammar;
use std::{env, fs, path::Path};
fn to_leo_tree(filepath: &Path) -> Result<String, ParserError> {
fn to_leo_tree(filepath: &Path) -> Result<String, AstError> {
// Loads the Leo code as a string from the given file path.
let program_filepath = filepath.to_path_buf();
let program_string = Grammar::load_file(&program_filepath)?;
@ -27,15 +27,14 @@ fn to_leo_tree(filepath: &Path) -> Result<String, ParserError> {
let ast = Grammar::new(&program_filepath, &program_string)?;
// Parse the pest ast and constructs a ast.
let leo_ast = Ast::new("leo_tree", &ast);
let leo_ast = Ast::new("leo_tree", &ast)?;
// Serializes the tree into JSON format.
let serialized_leo_ast = Ast::to_json_string(&leo_ast)?;
Ok(serialized_leo_ast)
}
fn main() -> Result<(), ParserError> {
fn main() -> Result<(), AstError> {
// Parse the command-line arguments as strings.
let cli_arguments = env::args().collect::<Vec<String>>();

View File

@ -17,7 +17,16 @@
//! A Leo program consists of import, circuit, and function definitions.
//! Each defined type consists of ast statements and expressions.
use crate::{load_annotation, Circuit, Function, FunctionInput, Identifier, ImportStatement, TestFunction};
use crate::{
load_annotation,
Circuit,
DeprecatedError,
Function,
FunctionInput,
Identifier,
ImportStatement,
TestFunction,
};
use leo_grammar::{definitions::Definition, files::File};
use indexmap::IndexMap;
@ -37,7 +46,7 @@ const MAIN_FUNCTION_NAME: &str = "main";
impl<'ast> Program {
//! Logic to convert from an abstract syntax tree (ast) representation to a Leo program.
pub fn from(program_name: &str, program_ast: &File<'ast>) -> Self {
pub fn from(program_name: &str, program_ast: &File<'ast>) -> Result<Self, DeprecatedError> {
let mut imports = vec![];
let mut circuits = IndexMap::new();
let mut functions = IndexMap::new();
@ -48,10 +57,15 @@ impl<'ast> Program {
.definitions
.to_owned()
.into_iter()
.for_each(|definition| match definition {
Definition::Import(import) => imports.push(ImportStatement::from(import)),
// Use of Infallible to say we never expect an Some(Ok(...))
.find_map::<Result<std::convert::Infallible, _>, _>(|definition| match definition {
Definition::Import(import) => {
imports.push(ImportStatement::from(import));
None
}
Definition::Circuit(circuit) => {
circuits.insert(Identifier::from(circuit.identifier.clone()), Circuit::from(circuit));
None
}
Definition::Function(function_def) => {
let function = Function::from(function_def);
@ -59,13 +73,13 @@ impl<'ast> Program {
expected_input = function.input.clone();
}
functions.insert(function.identifier.clone(), function);
None
}
Definition::TestFunction(test_def) => {
let test = TestFunction::from(test_def);
tests.insert(test.function.identifier.clone(), test);
Definition::Deprecated(deprecated) => {
Some(Err(DeprecatedError::from(deprecated)))
}
Definition::Annotated(annotated_definition) => {
load_annotation(
let loaded_annotation = load_annotation(
annotated_definition,
&mut imports,
&mut circuits,
@ -73,17 +87,23 @@ impl<'ast> Program {
&mut tests,
&mut expected_input,
);
}
});
Self {
match loaded_annotation {
Ok(_) => None,
Err(deprecated_err) => Some(Err(deprecated_err))
}
}
})
.transpose()?;
Ok(Self {
name: program_name.to_string(),
expected_input,
imports,
circuits,
functions,
tests,
}
})
}
}

View File

@ -0,0 +1,7 @@
function main() {
return 1 + 1
}
test function old {
console.log("old");
}

View File

@ -14,19 +14,19 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use leo_ast::Ast;
#[cfg(not(feature = "ci_skip"))]
use leo_ast::Program;
use leo_grammar::Grammar;
use leo_ast::{Ast, AstError};
use leo_grammar::{Grammar, ParserError};
use std::path::{Path, PathBuf};
fn to_ast(program_filepath: &Path) -> Ast {
fn to_ast(program_filepath: &Path) -> Result<Ast, AstError> {
// Loads the Leo code as a string from the given file path.
let program_string = Grammar::load_file(program_filepath).unwrap();
let program_string = Grammar::load_file(program_filepath)?;
// Parses the Leo file and constructs a grammar ast.
let ast = Grammar::new(&program_filepath, &program_string).unwrap();
let ast = Grammar::new(&program_filepath, &program_string)?;
// Parses the pest ast and constructs a Leo ast.
Ast::new("leo_tree", &ast)
@ -40,7 +40,7 @@ fn test_serialize() {
let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
program_filepath.push("tests/serialization/main.leo");
to_ast(&program_filepath)
to_ast(&program_filepath).unwrap()
};
// Serializes the ast into JSON format.
@ -60,7 +60,7 @@ fn test_deserialize() {
let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
program_filepath.push("tests/serialization/main.leo");
to_ast(&program_filepath)
to_ast(&program_filepath).unwrap()
};
// Construct an ast by deserializing a ast JSON file.
@ -77,7 +77,7 @@ fn test_serialize_deserialize_serialize() {
let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
program_filepath.push("tests/serialization/main.leo");
to_ast(&program_filepath)
to_ast(&program_filepath).unwrap()
};
// Serializes the ast into JSON format.
@ -91,3 +91,29 @@ fn test_serialize_deserialize_serialize() {
assert_eq!(serialized_ast, reserialized_ast);
}
#[test]
fn test_file_read_error() {
let error_result = {
let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
program_filepath.push("tests/serialization/dne.leo");
to_ast(&program_filepath)
}
.map_err(|err| matches!(err, AstError::ParserError(x) if matches!(x, ParserError::FileReadError(_))));
assert!(error_result.err().unwrap());
}
#[test]
fn test_generic_parser_error() {
let error_result = {
let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
program_filepath.push("tests/serialization/parser_error.leo");
to_ast(&program_filepath)
}
.map_err(|err| matches!(err, AstError::ParserError(_)));
assert!(error_result.err().unwrap());
}

View File

@ -0,0 +1 @@
invalid

View File

@ -184,7 +184,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
})?;
// Construct the core ast from the pest ast.
let core_ast = Ast::new(&self.package_name, &pest_ast);
let core_ast = Ast::new(&self.package_name, &pest_ast)?;
// Store the main program file.
self.program = core_ast.into_repr();
@ -241,7 +241,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
let package_name = &self.package_name;
// Construct the core ast from the pest ast.
let core_ast = Ast::new(package_name, &ast);
let core_ast = Ast::new(package_name, &ast)?;
// Store the main program file.
self.program = core_ast.into_repr();

View File

@ -15,6 +15,7 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::errors::{FunctionError, ImportError, OutputBytesError, OutputFileError};
use leo_ast::AstError;
use leo_grammar::ParserError;
use leo_imports::ImportParserError;
use leo_input::InputParserError;
@ -27,6 +28,9 @@ use std::path::{Path, PathBuf};
#[derive(Debug, Error)]
pub enum CompilerError {
#[error("{}", _0)]
AstError(#[from] AstError),
#[error("{}", _0)]
ImportError(#[from] ImportError),

View File

@ -1,4 +1,5 @@
test function fake_test() {}
@test
function fake_test() {}
function main() {}

View File

@ -24,6 +24,7 @@ use serde::Serialize;
#[pest_ast(rule(Rule::annotation_name))]
pub enum AnnotationName<'ast> {
Context(Context<'ast>),
Test(Test<'ast>),
}
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
@ -33,3 +34,11 @@ pub struct Context<'ast> {
#[serde(with = "SpanDef")]
pub span: Span<'ast>,
}
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::test))]
pub struct Test<'ast> {
#[pest_ast(outer())]
#[serde(with = "SpanDef")]
pub span: Span<'ast>,
}

View File

@ -29,7 +29,7 @@ use serde::Serialize;
pub struct Annotation<'ast> {
pub symbol: AnnotationSymbol<'ast>,
pub name: AnnotationName<'ast>,
pub arguments: AnnotationArguments<'ast>,
pub arguments: Option<AnnotationArguments<'ast>>,
#[pest_ast(outer())]
#[serde(with = "SpanDef")]
pub span: Span<'ast>,

View File

@ -17,8 +17,8 @@
use crate::{
ast::Rule,
circuits::Circuit,
definitions::AnnotatedDefinition,
functions::{Function, TestFunction},
definitions::{AnnotatedDefinition, Deprecated},
functions::Function,
imports::Import,
};
@ -32,5 +32,5 @@ pub enum Definition<'ast> {
Import(Import<'ast>),
Circuit(Circuit<'ast>),
Function(Function<'ast>),
TestFunction(TestFunction<'ast>),
Deprecated(Deprecated<'ast>),
}

View File

@ -0,0 +1,26 @@
// Copyright (C) 2019-2020 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 <https://www.gnu.org/licenses/>.
use crate::{ast::Rule, functions::TestFunction};
use pest_ast::FromPest;
use serde::Serialize;
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::deprecated))]
pub enum Deprecated<'ast> {
TestFunction(TestFunction<'ast>),
}

View File

@ -19,3 +19,6 @@ pub use annotated_definition::*;
pub mod definition;
pub use definition::*;
pub mod deprecated;
pub use deprecated::*;

View File

@ -27,6 +27,9 @@ pub enum ParserError {
#[error("Cannot read from the provided file path - {:?}", _0)]
FileReadError(PathBuf),
#[error("{}", _0)]
IoError(#[from] std::io::Error),
#[error("{}", _0)]
JsonError(#[from] serde_json::error::Error),
@ -59,9 +62,3 @@ impl From<Error<Rule>> for ParserError {
ParserError::SyntaxError(SyntaxError::from(error))
}
}
impl From<std::io::Error> for ParserError {
fn from(error: std::io::Error) -> Self {
ParserError::Crate("std::io", error.to_string())
}
}

View File

@ -28,3 +28,10 @@ pub struct TestFunction<'ast> {
#[serde(with = "SpanDef")]
pub span: Span<'ast>,
}
impl<'ast> From<Function<'ast>> for TestFunction<'ast> {
fn from(function: Function<'ast>) -> Self {
let span = function.span.clone();
TestFunction { function, span }
}
}

View File

@ -12,7 +12,12 @@ definition = {
| import
| circuit
| function
| test_function
| deprecated
}
// Declared in definitions/deprecated.rs
deprecated = {
test_function
}
// Declared in definitions/annotated_definition.rs
@ -416,6 +421,9 @@ statement_definition = { declare ~ variables ~ "=" ~ expression ~ LINE_END}
// Declared in statements/expression_statement.rs
statement_expression = { expression ~ LINE_END }
// Decalred in functions/test_function.rs
test_function = { "test" ~ function }
// Declared in statements/for_statement.rs
statement_for = { "for " ~ identifier ~ "in " ~ expression ~ ".." ~ expression ~ block }
@ -424,9 +432,6 @@ statement_return = { "return " ~ expression}
/// Functions
// Declared in functions/test_function.rs
test_function = { "test " ~ function }
// Declared in functions/function.rs
function = { "function " ~ identifier ~ input_tuple ~ ("->" ~ type_)? ~ block }
@ -520,18 +525,20 @@ formatted_container = { "{" ~ "}"}
/// Annotations
// Declared in annotations/annotation.rs
annotation = ${annotation_symbol ~ annotation_name ~ annotation_arguments}
annotation = ${annotation_symbol ~ annotation_name ~ annotation_arguments? }
// Declared in annotations/annotation_symbol.rs
annotation_symbol = ${"@"}
// Declared in annotations/annotation_name.rs
annotation_name = {
context
context // deprecated
| test
}
// Declared in annotations/context.rs
// Declared in annotations/annotation_name.rs
context = {"context"}
test = {"test"}
// Declared in annotations/annotation_argument.rs
annotation_arguments = !{"(" ~ annotation_argument ~ ("," ~ annotation_argument)* ~ ","? ~ NEWLINE* ~ ")"}

View File

@ -0,0 +1,43 @@
// Copyright (C) 2019-2020 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 <https://www.gnu.org/licenses/>.
use leo_grammar::ast::{LanguageParser, Rule};
use pest::*;
#[test]
fn test_annotation_no_context_test() {
parses_to! {
parser: LanguageParser,
input: "@test",
rule: Rule::annotation,
tokens: [
annotation(0, 5, [annotation_symbol(0, 1, []), annotation_name(1, 5, [test(1, 5, [])])])
]
}
}
#[test]
fn test_annotation_context_test() {
parses_to! {
parser: LanguageParser,
input: "@test(custom)",
rule: Rule::annotation,
tokens: [
annotation(0, 13, [annotation_symbol(0, 1, []), annotation_name(1, 5, [test(1, 5, [])]), annotation_arguments(5, 13, [annotation_argument(6, 12, [])])])
]
}
}

View File

@ -0,0 +1,56 @@
// Copyright (C) 2019-2020 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 <https://www.gnu.org/licenses/>.
use leo_grammar::ast::{LanguageParser, Rule};
use pest::*;
#[test]
fn test_deprecated_test_function() {
parses_to! {
parser: LanguageParser,
input: r#"test function old() {
return ()
}"#,
rule: Rule::deprecated,
tokens: [
deprecated(0, 37, [
test_function(0, 37, [
function(5, 37, [
identifier(14, 17, []),
block(20, 37, [
statement(26, 36, [
statement_return(26, 36, [expression(33, 36, [expression_term(33, 35, [expression_tuple(33, 35, [])])])])
])
])
])
])
])
]
}
}
#[test]
fn test_deprecated_context_function() {
parses_to! {
parser: LanguageParser,
input: "@context(custom)",
rule: Rule::annotation,
tokens: [
annotation(0, 16, [annotation_symbol(0, 1, []), annotation_name(1, 8, [context(1, 8, [])]), annotation_arguments(8, 16, [annotation_argument(9, 15, [])])])
]
}
}

View File

@ -13,13 +13,16 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use leo_ast::{Error as FormattedError, Identifier, Span};
use leo_ast::{DeprecatedError, Error as FormattedError, Identifier, Span};
use leo_grammar::ParserError;
use std::{io, path::Path};
#[derive(Debug, Error)]
pub enum ImportParserError {
#[error("{}", _0)]
DeprecatedError(#[from] DeprecatedError),
#[error("{}", _0)]
Error(#[from] FormattedError),

View File

@ -55,7 +55,7 @@ fn parse_import_file(package: &DirEntry, span: &Span) -> Result<Program, ImportP
let ast = &Grammar::new(&file_path, &program_string)?;
// Build the package Leo syntax tree from the package abstract syntax tree.
Ok(Program::from(&file_name, ast.as_repr()))
Ok(Program::from(&file_name, ast.as_repr())?)
}
impl ImportParser {

View File

@ -42,9 +42,12 @@ impl TestSymbolTable {
let grammar = Grammar::new(&file_path, program_string).unwrap();
// Get Leo syntax tree.
let ast = Ast::new(TEST_PROGRAM_PATH, &grammar);
let ast_result = Ast::new(TEST_PROGRAM_PATH, &grammar);
Self { ast }
// We always expect a valid ast for testing.
Self {
ast: ast_result.unwrap(),
}
}
///

View File

@ -46,8 +46,10 @@ impl TestTypeInference {
// Get parser syntax tree.
let ast = Grammar::new(&file_path, program_string).unwrap();
let result = Ast::new(TEST_PROGRAM_NAME, &ast);
// Get typed syntax tree.
let typed = Ast::new(TEST_PROGRAM_NAME, &ast);
// Always expect a valid SyntaxTree for testing.
let typed = result.unwrap();
let program = typed.into_repr();
// Create empty import parser.