From f8668303e3a05b0998124dac0dee20cef562d7fe Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 19 Nov 2020 15:22:49 -0800 Subject: [PATCH 01/20] add self and mut self to grammar module --- grammar/src/circuits/circuit_member.rs | 7 ++----- grammar/src/circuits/mod.rs | 4 ++-- grammar/src/common/mod.rs | 3 +++ .../mut_self_keyword.rs} | 21 ++++++++++++++----- grammar/src/functions/input/input.rs | 3 +++ grammar/src/leo.pest | 10 +++++---- 6 files changed, 32 insertions(+), 16 deletions(-) rename grammar/src/{circuits/circuit_function.rs => common/mut_self_keyword.rs} (70%) diff --git a/grammar/src/circuits/circuit_member.rs b/grammar/src/circuits/circuit_member.rs index d3d949e99b..32da1ca4d3 100644 --- a/grammar/src/circuits/circuit_member.rs +++ b/grammar/src/circuits/circuit_member.rs @@ -14,10 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ - ast::Rule, - circuits::{CircuitFunction, CircuitVariableDefinition}, -}; +use crate::{ast::Rule, circuits::CircuitVariableDefinition, functions::Function}; use pest_ast::FromPest; use serde::Serialize; @@ -26,5 +23,5 @@ use serde::Serialize; #[pest_ast(rule(Rule::circuit_member))] pub enum CircuitMember<'ast> { CircuitVariableDefinition(CircuitVariableDefinition<'ast>), - CircuitFunction(CircuitFunction<'ast>), + CircuitFunction(Function<'ast>), } diff --git a/grammar/src/circuits/mod.rs b/grammar/src/circuits/mod.rs index 768a36fd7e..2f55b59400 100644 --- a/grammar/src/circuits/mod.rs +++ b/grammar/src/circuits/mod.rs @@ -23,8 +23,8 @@ pub use circuit_variable::*; pub mod circuit_variable_definition; pub use circuit_variable_definition::*; -pub mod circuit_function; -pub use circuit_function::*; +// pub mod circuit_function; +// pub use circuit_function::*; pub mod circuit_member; pub use circuit_member::*; diff --git a/grammar/src/common/mod.rs b/grammar/src/common/mod.rs index 119287f5cc..6a45652fc7 100644 --- a/grammar/src/common/mod.rs +++ b/grammar/src/common/mod.rs @@ -35,6 +35,9 @@ pub use line_end::*; pub mod mutable; pub use mutable::*; +pub mod mut_self_keyword; +pub use mut_self_keyword::*; + pub mod range; pub use range::*; diff --git a/grammar/src/circuits/circuit_function.rs b/grammar/src/common/mut_self_keyword.rs similarity index 70% rename from grammar/src/circuits/circuit_function.rs rename to grammar/src/common/mut_self_keyword.rs index 3fdeac1d02..12d269e191 100644 --- a/grammar/src/circuits/circuit_function.rs +++ b/grammar/src/common/mut_self_keyword.rs @@ -14,18 +14,29 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ast::Rule, common::Static, functions::Function, SpanDef}; +use crate::{ + ast::Rule, + common::{Mutable, SelfKeyword}, + SpanDef, +}; use pest::Span; use pest_ast::FromPest; use serde::Serialize; +use std::fmt; #[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::circuit_function))] -pub struct CircuitFunction<'ast> { - pub _static: Option, - pub function: Function<'ast>, +#[pest_ast(rule(Rule::mut_self_keyword))] +pub struct MutSelfKeyword<'ast> { + pub mutable: Mutable, + pub self_keyword: SelfKeyword<'ast>, #[pest_ast(outer())] #[serde(with = "SpanDef")] pub span: Span<'ast>, } + +impl<'ast> fmt::Display for MutSelfKeyword<'ast> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "mut {}", self.self_keyword) + } +} diff --git a/grammar/src/functions/input/input.rs b/grammar/src/functions/input/input.rs index d3cddee215..d6eb28250c 100644 --- a/grammar/src/functions/input/input.rs +++ b/grammar/src/functions/input/input.rs @@ -16,6 +16,7 @@ use crate::{ ast::Rule, + common::{MutSelfKeyword, SelfKeyword}, functions::{FunctionInput, InputKeyword}, }; @@ -26,5 +27,7 @@ use serde::Serialize; #[pest_ast(rule(Rule::input))] pub enum Input<'ast> { InputKeyword(InputKeyword<'ast>), + SelfKeyword(SelfKeyword<'ast>), + MutSelfKeyword(MutSelfKeyword<'ast>), FunctionInput(FunctionInput<'ast>), } diff --git a/grammar/src/leo.pest b/grammar/src/leo.pest index e695e3bb9f..b065834413 100644 --- a/grammar/src/leo.pest +++ b/grammar/src/leo.pest @@ -47,6 +47,9 @@ protected_name = { // Declared in common/self_keyword.rs self_keyword = { "self" } +// Declared in common/mut_self_keyword.rs +mut_self_keyword = { mutable ~ self_keyword } + // Declared in common/self_keyword_or_identifier.rs self_keyword_or_identifier = { self_keyword @@ -321,11 +324,8 @@ circuit_variable = { identifier ~ ":" ~ expression } // Declared in circuits/circuit_variable_definition.rs circuit_variable_definition = { mutable? ~ identifier ~ ":" ~ type_ ~ ","?} -// Declared in circuits/circuit_function.rs -circuit_function = { static_? ~ function } - // Declared in circuits/circuit_member.rs -circuit_member = { circuit_function | circuit_variable_definition ~ NEWLINE*} +circuit_member = { function | circuit_variable_definition ~ NEWLINE*} /// Conditionals @@ -429,6 +429,8 @@ input_keyword = { "input" } // Declared in functions/input/input.rs input = { input_keyword + | self_keyword + | mut_self_keyword | function_input } input_tuple = _{ "(" ~ NEWLINE* ~ (input ~ ("," ~ NEWLINE* ~ input)* ~ ","?)? ~ NEWLINE* ~ ")"} From 2c72156370e4e1c965a0b539007692135e379e7d Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 23 Nov 2020 12:10:58 -0500 Subject: [PATCH 02/20] add input keyword objects to ast module --- ast/src/circuits/circuit_member.rs | 25 +++++--------- ast/src/common/input_keyword.rs | 42 +++++++++++++++++++++++ ast/src/common/mod.rs | 9 +++++ ast/src/common/mut_self_keyword.rs | 41 ++++++++++++++++++++++ ast/src/common/self_keyword.rs | 42 +++++++++++++++++++++++ ast/src/functions/input/input_variable.rs | 4 ++- grammar/src/circuits/mod.rs | 3 -- 7 files changed, 146 insertions(+), 20 deletions(-) create mode 100644 ast/src/common/input_keyword.rs create mode 100644 ast/src/common/mut_self_keyword.rs create mode 100644 ast/src/common/self_keyword.rs diff --git a/ast/src/circuits/circuit_member.rs b/ast/src/circuits/circuit_member.rs index f8e885dd9d..2d18e70fcc 100644 --- a/ast/src/circuits/circuit_member.rs +++ b/ast/src/circuits/circuit_member.rs @@ -15,10 +15,9 @@ // along with the Leo library. If not, see . use crate::{Function, Identifier, Type}; -use leo_grammar::circuits::{ - CircuitFunction as GrammarCircuitFunction, - CircuitMember as GrammarCircuitMember, - CircuitVariableDefinition as GrammarCircuitVariableDefinition, +use leo_grammar::{ + circuits::{CircuitMember as GrammarCircuitMember, CircuitVariableDefinition as GrammarCircuitVariableDefinition}, + functions::Function as GrammarFunction, }; use serde::{Deserialize, Serialize}; @@ -28,8 +27,8 @@ use std::fmt; pub enum CircuitMember { // (is_mutable, variable_name, variable_type) CircuitVariable(bool, Identifier, Type), - // (is_static, function) - CircuitFunction(bool, Function), + // (function) + CircuitFunction(Function), } impl<'ast> From> for CircuitMember { @@ -42,12 +41,9 @@ impl<'ast> From> for CircuitMember { } } -impl<'ast> From> for CircuitMember { - fn from(circuit_function: GrammarCircuitFunction<'ast>) -> Self { - CircuitMember::CircuitFunction( - circuit_function._static.is_some(), - Function::from(circuit_function.function), - ) +impl<'ast> From> for CircuitMember { + fn from(circuit_function: GrammarFunction<'ast>) -> Self { + CircuitMember::CircuitFunction(Function::from(circuit_function)) } } @@ -69,10 +65,7 @@ impl fmt::Display for CircuitMember { } write!(f, "{}: {}", identifier, type_) } - CircuitMember::CircuitFunction(ref static_, ref function) => { - if *static_ { - write!(f, "static ")?; - } + CircuitMember::CircuitFunction(ref function) => { write!(f, "{}", function) } } diff --git a/ast/src/common/input_keyword.rs b/ast/src/common/input_keyword.rs new file mode 100644 index 0000000000..029e254b6a --- /dev/null +++ b/ast/src/common/input_keyword.rs @@ -0,0 +1,42 @@ +// 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 . + +use crate::Span; +use leo_grammar::functions::InputKeyword as GrammarInputKeyword; + +use serde::Serialize; +use std::fmt; + +/// The `input` keyword can view program register, record, and state values. +/// Values cannot be modified. The `input` keyword cannot be made mutable. +#[derive(Clone, Serialize, Deserialize)] +pub struct InputKeyword { + pub span: Span, +} + +impl<'ast> From> for InputKeyword { + fn from(grammar: GrammarInputKeyword<'ast>) -> Self { + Self { + span: Span::from(grammar.span), + } + } +} + +impl fmt::Display for InputKeyword { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "input") + } +} diff --git a/ast/src/common/mod.rs b/ast/src/common/mod.rs index 382d82142c..4d20d843aa 100644 --- a/ast/src/common/mod.rs +++ b/ast/src/common/mod.rs @@ -26,12 +26,21 @@ pub use declare::*; pub mod identifier; pub use identifier::*; +pub mod input_keyword; +pub use input_keyword::*; + +pub mod mut_self_keyword; +pub use mut_self_keyword::*; + pub mod positive_number; pub use positive_number::*; pub mod range_or_expression; pub use range_or_expression::*; +pub mod self_keyword; +pub use self_keyword::*; + pub mod span; pub use span::*; diff --git a/ast/src/common/mut_self_keyword.rs b/ast/src/common/mut_self_keyword.rs new file mode 100644 index 0000000000..d3a93ca2f6 --- /dev/null +++ b/ast/src/common/mut_self_keyword.rs @@ -0,0 +1,41 @@ +// 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 . + +use crate::Span; +use leo_grammar::common::MutSelfKeyword as GrammarMutSelfKeyword; + +use serde::Serialize; +use std::fmt; + +/// The `mut self` keyword can view and modify circuit values inside of a circuit function. +#[derive(Clone, Serialize, Deserialize)] +pub struct MutSelfKeyword { + pub span: Span, +} + +impl<'ast> From> for MutSelfKeyword { + fn from(grammar: GrammarMutSelfKeyword<'ast>) -> Self { + Self { + span: Span::from(grammar.span), + } + } +} + +impl fmt::Display for MutSelfKeyword { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "mut self") + } +} diff --git a/ast/src/common/self_keyword.rs b/ast/src/common/self_keyword.rs new file mode 100644 index 0000000000..92502978ec --- /dev/null +++ b/ast/src/common/self_keyword.rs @@ -0,0 +1,42 @@ +// 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 . + +use crate::Span; +use leo_grammar::common::SelfKeyword as GrammarSelfKeyword; + +use serde::Serialize; +use std::fmt; + +/// The `self` keyword can view circuit values inside of a circuit function. +/// Circuit values cannot be modified. To modify values use the `mut self` [MutSelfKeyword]. +#[derive(Clone, Serialize, Deserialize)] +pub struct SelfKeyword { + pub span: Span, +} + +impl<'ast> From> for SelfKeyword { + fn from(grammar: GrammarSelfKeyword<'ast>) -> Self { + Self { + span: Span::from(grammar.span), + } + } +} + +impl fmt::Display for SelfKeyword { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "self") + } +} diff --git a/ast/src/functions/input/input_variable.rs b/ast/src/functions/input/input_variable.rs index cc7c75231c..83bf522cd6 100644 --- a/ast/src/functions/input/input_variable.rs +++ b/ast/src/functions/input/input_variable.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::{FunctionInputVariable, Identifier, Span}; +use crate::{FunctionInputVariable, Identifier, MutSelfKeyword, SelfKeyword, Span}; use leo_grammar::functions::input::Input as GrammarInput; use serde::{Deserialize, Serialize}; @@ -23,6 +23,8 @@ use std::fmt; #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum FunctionInput { InputKeyword(Identifier), + SelfKeyword(SelfKeyword), + MutSelfKeyword(MutSelfKeyword), Variable(FunctionInputVariable), } diff --git a/grammar/src/circuits/mod.rs b/grammar/src/circuits/mod.rs index 2f55b59400..c967ed655e 100644 --- a/grammar/src/circuits/mod.rs +++ b/grammar/src/circuits/mod.rs @@ -23,8 +23,5 @@ pub use circuit_variable::*; pub mod circuit_variable_definition; pub use circuit_variable_definition::*; -// pub mod circuit_function; -// pub use circuit_function::*; - pub mod circuit_member; pub use circuit_member::*; From efe734afaf530213cf41526b18759130aa1470f1 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 23 Nov 2020 14:49:20 -0500 Subject: [PATCH 03/20] add input, self, mut self keyword functionality to ast module --- ast/src/common/identifier.rs | 64 ++++++++++++++++---- ast/src/common/input_keyword.rs | 2 +- ast/src/common/mut_self_keyword.rs | 2 +- ast/src/common/self_keyword.rs | 2 +- ast/src/functions/input/input_variable.rs | 37 +++++++---- compiler/src/function/input/input_keyword.rs | 14 ++--- compiler/src/function/main_function.rs | 12 ++-- 7 files changed, 96 insertions(+), 37 deletions(-) diff --git a/ast/src/common/identifier.rs b/ast/src/common/identifier.rs index e6f3f4baf2..84dc49fa87 100644 --- a/ast/src/common/identifier.rs +++ b/ast/src/common/identifier.rs @@ -14,12 +14,18 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::Span; +use crate::{InputKeyword, MutSelfKeyword, SelfKeyword, Span}; use leo_grammar::{ annotations::AnnotationArgument, - common::{Identifier as GrammarIdentifier, KeywordOrIdentifier, SelfKeyword, SelfKeywordOrIdentifier}, + common::{ + Identifier as GrammarIdentifier, + KeywordOrIdentifier, + MutSelfKeyword as GrammarMutSelfKeyword, + SelfKeyword as GrammarSelfKeyword, + SelfKeywordOrIdentifier, + }, expressions::CircuitName, - functions::InputKeyword, + functions::InputKeyword as GrammarInputKeyword, imports::PackageName as GrammarPackageName, types::SelfType, }; @@ -128,20 +134,56 @@ impl<'ast> From> for Identifier { } } -impl<'ast> From> for Identifier { - fn from(self_: SelfKeyword<'ast>) -> Self { +impl<'ast> From> for Identifier { + fn from(grammar: GrammarSelfKeyword<'ast>) -> Self { Self { - name: self_.keyword, - span: Span::from(self_.span), + name: grammar.keyword, + span: Span::from(grammar.span), } } } -impl<'ast> From> for Identifier { - fn from(input: InputKeyword<'ast>) -> Self { +impl From for Identifier { + fn from(keyword: SelfKeyword) -> Self { Self { - name: input.keyword, - span: Span::from(input.span), + name: keyword.to_string(), + span: keyword.span, + } + } +} + +impl<'ast> From> for Identifier { + fn from(grammar: GrammarMutSelfKeyword<'ast>) -> Self { + Self { + name: grammar.to_string(), + span: Span::from(grammar.span), + } + } +} + +impl From for Identifier { + fn from(keyword: MutSelfKeyword) -> Self { + Self { + name: keyword.to_string(), + span: keyword.span, + } + } +} + +impl<'ast> From> for Identifier { + fn from(grammar: GrammarInputKeyword<'ast>) -> Self { + Self { + name: grammar.keyword, + span: Span::from(grammar.span), + } + } +} + +impl From for Identifier { + fn from(keyword: InputKeyword) -> Self { + Self { + name: keyword.to_string(), + span: keyword.span, } } } diff --git a/ast/src/common/input_keyword.rs b/ast/src/common/input_keyword.rs index 029e254b6a..5df0aa7b08 100644 --- a/ast/src/common/input_keyword.rs +++ b/ast/src/common/input_keyword.rs @@ -17,7 +17,7 @@ use crate::Span; use leo_grammar::functions::InputKeyword as GrammarInputKeyword; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use std::fmt; /// The `input` keyword can view program register, record, and state values. diff --git a/ast/src/common/mut_self_keyword.rs b/ast/src/common/mut_self_keyword.rs index d3a93ca2f6..b11a8df0ac 100644 --- a/ast/src/common/mut_self_keyword.rs +++ b/ast/src/common/mut_self_keyword.rs @@ -17,7 +17,7 @@ use crate::Span; use leo_grammar::common::MutSelfKeyword as GrammarMutSelfKeyword; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use std::fmt; /// The `mut self` keyword can view and modify circuit values inside of a circuit function. diff --git a/ast/src/common/self_keyword.rs b/ast/src/common/self_keyword.rs index 92502978ec..8dfdfecc70 100644 --- a/ast/src/common/self_keyword.rs +++ b/ast/src/common/self_keyword.rs @@ -17,7 +17,7 @@ use crate::Span; use leo_grammar::common::SelfKeyword as GrammarSelfKeyword; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use std::fmt; /// The `self` keyword can view circuit values inside of a circuit function. diff --git a/ast/src/functions/input/input_variable.rs b/ast/src/functions/input/input_variable.rs index 83bf522cd6..bfa5b22abe 100644 --- a/ast/src/functions/input/input_variable.rs +++ b/ast/src/functions/input/input_variable.rs @@ -14,15 +14,16 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{FunctionInputVariable, Identifier, MutSelfKeyword, SelfKeyword, Span}; +use crate::{FunctionInputVariable, InputKeyword, MutSelfKeyword, SelfKeyword}; use leo_grammar::functions::input::Input as GrammarInput; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] +/// Enumerates the possible inputs to a function. +#[derive(Clone, Serialize, Deserialize)] pub enum FunctionInput { - InputKeyword(Identifier), + InputKeyword(InputKeyword), SelfKeyword(SelfKeyword), MutSelfKeyword(MutSelfKeyword), Variable(FunctionInputVariable), @@ -31,14 +32,9 @@ pub enum FunctionInput { impl<'ast> From> for FunctionInput { fn from(input: GrammarInput<'ast>) -> Self { match input { - GrammarInput::InputKeyword(input_keyword) => { - let id = Identifier { - name: input_keyword.keyword, - span: Span::from(input_keyword.span), - }; - - FunctionInput::InputKeyword(id) - } + GrammarInput::InputKeyword(keyword) => FunctionInput::InputKeyword(InputKeyword::from(keyword)), + GrammarInput::SelfKeyword(keyword) => FunctionInput::SelfKeyword(SelfKeyword::from(keyword)), + GrammarInput::MutSelfKeyword(keyword) => FunctionInput::MutSelfKeyword(MutSelfKeyword::from(keyword)), GrammarInput::FunctionInput(function_input) => { FunctionInput::Variable(FunctionInputVariable::from(function_input)) } @@ -49,7 +45,9 @@ impl<'ast> From> for FunctionInput { impl FunctionInput { fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - FunctionInput::InputKeyword(id) => write!(f, "{}", id), + FunctionInput::InputKeyword(keyword) => write!(f, "{}", keyword), + FunctionInput::SelfKeyword(keyword) => write!(f, "{}", keyword), + FunctionInput::MutSelfKeyword(keyword) => write!(f, "{}", keyword), FunctionInput::Variable(function_input) => write!(f, "{}", function_input), } } @@ -66,3 +64,18 @@ impl fmt::Debug for FunctionInput { self.format(f) } } + +impl PartialEq for FunctionInput { + /// Returns true if `self == other`. Does not compare spans. + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (FunctionInput::InputKeyword(_), FunctionInput::InputKeyword(_)) => true, + (FunctionInput::SelfKeyword(_), FunctionInput::SelfKeyword(_)) => true, + (FunctionInput::MutSelfKeyword(_), FunctionInput::MutSelfKeyword(_)) => true, + (FunctionInput::Variable(left), FunctionInput::Variable(right)) => left.eq(right), + _ => false, + } + } +} + +impl Eq for FunctionInput {} diff --git a/compiler/src/function/input/input_keyword.rs b/compiler/src/function/input/input_keyword.rs index 5d74e55f70..3d40090a3f 100644 --- a/compiler/src/function/input/input_keyword.rs +++ b/compiler/src/function/input/input_keyword.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::FunctionError, ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue, GroupType}; -use leo_ast::{Identifier, Input}; +use leo_ast::{Identifier, Input, InputKeyword}; use snarkos_models::{ curves::{Field, PrimeField}, @@ -31,26 +31,26 @@ impl> ConstrainedProgram { pub fn allocate_input_keyword>( &mut self, cs: &mut CS, - identifier: Identifier, + keyword: InputKeyword, input: &Input, ) -> Result, FunctionError> { // Create an identifier for each input variable let registers_name = Identifier { name: REGISTERS_VARIABLE_NAME.to_string(), - span: identifier.span.clone(), + span: keyword.span.clone(), }; let record_name = Identifier { name: RECORD_VARIABLE_NAME.to_string(), - span: identifier.span.clone(), + span: keyword.span.clone(), }; let state_name = Identifier { name: STATE_VARIABLE_NAME.to_string(), - span: identifier.span.clone(), + span: keyword.span.clone(), }; let state_leaf_name = Identifier { name: STATE_LEAF_VARIABLE_NAME.to_string(), - span: identifier.span.clone(), + span: keyword.span.clone(), }; // Fetch each input variable's definitions @@ -82,6 +82,6 @@ impl> ConstrainedProgram { // Return input variable keyword as circuit expression - Ok(ConstrainedValue::CircuitExpression(identifier, members)) + Ok(ConstrainedValue::CircuitExpression(Identifier::from(keyword), members)) } } diff --git a/compiler/src/function/main_function.rs b/compiler/src/function/main_function.rs index 7604a80b28..85c7b52b19 100644 --- a/compiler/src/function/main_function.rs +++ b/compiler/src/function/main_function.rs @@ -23,7 +23,7 @@ use crate::{ OutputBytes, }; -use leo_ast::{Expression, Function, FunctionInput, Input}; +use leo_ast::{Expression, Function, FunctionInput, Identifier, Input}; use snarkos_models::{ curves::{Field, PrimeField}, @@ -44,12 +44,16 @@ impl> ConstrainedProgram { // Iterate over main function input variables and allocate new values let mut input_variables = Vec::with_capacity(function.input.len()); for input_model in function.input.clone().into_iter() { - let (identifier, value) = match input_model { + let (input_id, value) = match input_model { FunctionInput::InputKeyword(identifier) => { let value = self.allocate_input_keyword(cs, identifier.clone(), &input)?; (identifier, value) } + FunctionInput::SelfKeyword(_) => unimplemented!("cannot access self keyword in main function"), + FunctionInput::MutSelfKeyword(_) => { + unimplemented!("cannot access mut self keyword in main function") + } FunctionInput::Variable(input_model) => { let name = input_model.identifier.name.clone(); let input_option = input @@ -63,12 +67,12 @@ impl> ConstrainedProgram { }; // Store input as variable with {function_name}_{identifier_name} - let input_name = new_scope(&function_name, &identifier.name); + let input_name = new_scope(&function_name, &input_id.to_string()); // Store a new variable for every allocated main function input self.store(input_name, value); - input_variables.push(Expression::Identifier(identifier)); + input_variables.push(Expression::Identifier(Identifier::from(input_id))); } let span = function.span.clone(); From 1b1cfd015d6db6f94dfef1a5631280a24761ac85 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 23 Nov 2020 16:01:30 -0500 Subject: [PATCH 04/20] fix circuit function struct in core module --- core/src/packages/unstable/blake2s.rs | 117 +++++++++++++------------- 1 file changed, 57 insertions(+), 60 deletions(-) diff --git a/core/src/packages/unstable/blake2s.rs b/core/src/packages/unstable/blake2s.rs index c4c37c4c91..22d8119e63 100644 --- a/core/src/packages/unstable/blake2s.rs +++ b/core/src/packages/unstable/blake2s.rs @@ -61,72 +61,69 @@ impl CoreCircuit for Blake2sCircuit { fn ast(circuit_name: Identifier, span: Span) -> Circuit { Circuit { circuit_name, - members: vec![CircuitMember::CircuitFunction( - true, // static function - Function { - identifier: Identifier { - name: "hash".to_owned(), + members: vec![CircuitMember::CircuitFunction(Function { + identifier: Identifier { + name: "hash".to_owned(), + span: span.clone(), + }, + input: vec![ + FunctionInput::Variable(FunctionInputVariable { + identifier: Identifier { + name: "seed".to_owned(), + span: span.clone(), + }, + mutable: false, + type_: Type::Array( + Box::new(Type::IntegerType(IntegerType::U8)), + ArrayDimensions(vec![PositiveNumber { + value: 32usize.to_string(), + span: span.clone(), + }]), + ), span: span.clone(), - }, - input: vec![ - FunctionInput::Variable(FunctionInputVariable { - identifier: Identifier { + }), + FunctionInput::Variable(FunctionInputVariable { + identifier: Identifier { + name: "message".to_owned(), + span: span.clone(), + }, + mutable: false, + type_: Type::Array( + Box::new(Type::IntegerType(IntegerType::U8)), + ArrayDimensions(vec![PositiveNumber { + value: 32usize.to_string(), + span: span.clone(), + }]), + ), + span: span.clone(), + }), + ], + output: Some(Type::Array( + Box::new(Type::IntegerType(IntegerType::U8)), + ArrayDimensions(vec![PositiveNumber { + value: 32usize.to_string(), + span: span.clone(), + }]), + )), + statements: vec![Statement::Return( + Expression::CoreFunctionCall( + Self::name(), + vec![ + Expression::Identifier(Identifier { name: "seed".to_owned(), span: span.clone(), - }, - mutable: false, - type_: Type::Array( - Box::new(Type::IntegerType(IntegerType::U8)), - ArrayDimensions(vec![PositiveNumber { - value: 32usize.to_string(), - span: span.clone(), - }]), - ), - span: span.clone(), - }), - FunctionInput::Variable(FunctionInputVariable { - identifier: Identifier { + }), + Expression::Identifier(Identifier { name: "message".to_owned(), span: span.clone(), - }, - mutable: false, - type_: Type::Array( - Box::new(Type::IntegerType(IntegerType::U8)), - ArrayDimensions(vec![PositiveNumber { - value: 32usize.to_string(), - span: span.clone(), - }]), - ), - span: span.clone(), - }), - ], - output: Some(Type::Array( - Box::new(Type::IntegerType(IntegerType::U8)), - ArrayDimensions(vec![PositiveNumber { - value: 32usize.to_string(), - span: span.clone(), - }]), - )), - statements: vec![Statement::Return( - Expression::CoreFunctionCall( - Self::name(), - vec![ - Expression::Identifier(Identifier { - name: "seed".to_owned(), - span: span.clone(), - }), - Expression::Identifier(Identifier { - name: "message".to_owned(), - span: span.clone(), - }), - ], - span.clone(), - ), + }), + ], span.clone(), - )], - span, - }, - )], + ), + span.clone(), + )], + span, + })], } } From 58cb5101ebb703c24e08244030dffc36b512344f Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 24 Nov 2020 21:42:59 -0500 Subject: [PATCH 05/20] update self mut self keywords in symbol table module --- symbol-table/src/types/circuits/circuit.rs | 30 +++++-------------- .../src/types/circuits/circuit_function.rs | 27 ----------------- symbol-table/src/types/circuits/mod.rs | 3 -- .../src/types/functions/function_input.rs | 20 +++++++++++-- type-inference/src/objects/frame.rs | 30 +++++++------------ 5 files changed, 35 insertions(+), 75 deletions(-) delete mode 100644 symbol-table/src/types/circuits/circuit_function.rs diff --git a/symbol-table/src/types/circuits/circuit.rs b/symbol-table/src/types/circuits/circuit.rs index 2e6ea923f0..d05ee64e90 100644 --- a/symbol-table/src/types/circuits/circuit.rs +++ b/symbol-table/src/types/circuits/circuit.rs @@ -14,14 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ - types::circuits::{CircuitFunctionType, CircuitVariableType}, - Attribute, - FunctionType, - SymbolTable, - Type, - TypeError, -}; +use crate::{types::circuits::CircuitVariableType, Attribute, FunctionType, SymbolTable, Type, TypeError}; use leo_ast::{Circuit, CircuitMember, Identifier, InputValue, Parameter, Span}; use serde::{Deserialize, Serialize}; @@ -43,7 +36,7 @@ pub struct CircuitType { pub variables: Vec, /// The circuit functions. - pub functions: Vec, + pub functions: Vec, } impl CircuitType { @@ -83,21 +76,12 @@ impl CircuitType { // Store the circuit variable type. variables.push(variable); } - CircuitMember::CircuitFunction(is_static, function) => { + CircuitMember::CircuitFunction(function) => { // Resolve the type of the circuit member function. let function_type = FunctionType::from_circuit(table, circuit_identifier.clone(), function)?; - // Check if the circuit member function is static. - let attribute = if is_static { Some(Attribute::Static) } else { None }; - - // Create a new circuit function type. - let function = CircuitFunctionType { - function: function_type, - attribute, - }; - // Store the circuit function type. - functions.push(function); + functions.push(function_type); } } } @@ -113,10 +97,10 @@ impl CircuitType { /// /// Returns the function type of a circuit member given an identifier. /// - pub fn member_function_type(&self, identifier: &Identifier) -> Option<&CircuitFunctionType> { + pub fn member_function_type(&self, identifier: &Identifier) -> Option<&FunctionType> { self.functions .iter() - .find(|function| function.function.identifier.eq(identifier)) + .find(|function| function.identifier.eq(identifier)) } /// @@ -139,7 +123,7 @@ impl CircuitType { let matched_function = self.member_function_type(identifier); match matched_function { - Some(function) => Ok(Type::Function(function.function.identifier.to_owned())), + Some(function) => Ok(Type::Function(function.identifier.to_owned())), None => Err(TypeError::undefined_circuit_member(identifier.clone())), } } diff --git a/symbol-table/src/types/circuits/circuit_function.rs b/symbol-table/src/types/circuits/circuit_function.rs deleted file mode 100644 index 4c6d8686a9..0000000000 --- a/symbol-table/src/types/circuits/circuit_function.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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 . - -use crate::{types::FunctionType, Attribute}; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct CircuitFunctionType { - /// The function signature of the circuit function - pub function: FunctionType, - /// The attributes of the circuit function - pub attribute: Option, -} diff --git a/symbol-table/src/types/circuits/mod.rs b/symbol-table/src/types/circuits/mod.rs index 8205016c50..5af76a09fe 100644 --- a/symbol-table/src/types/circuits/mod.rs +++ b/symbol-table/src/types/circuits/mod.rs @@ -17,8 +17,5 @@ pub mod circuit; pub use self::circuit::*; -pub mod circuit_function; -pub use self::circuit_function::*; - pub mod circuit_variable; pub use self::circuit_variable::*; diff --git a/symbol-table/src/types/functions/function_input.rs b/symbol-table/src/types/functions/function_input.rs index 297e09287f..ccbd0c5670 100644 --- a/symbol-table/src/types/functions/function_input.rs +++ b/symbol-table/src/types/functions/function_input.rs @@ -22,6 +22,8 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum FunctionInputType { InputKeyword(Identifier), + SelfKeyword(Identifier), + MutSelfKeyword(Identifier), Variable(FunctionInputVariableType), } @@ -32,6 +34,8 @@ impl FunctionInputType { pub fn identifier(&self) -> &Identifier { match self { FunctionInputType::InputKeyword(identifier) => identifier, + FunctionInputType::SelfKeyword(identifier) => identifier, + FunctionInputType::MutSelfKeyword(identifier) => identifier, FunctionInputType::Variable(variable) => &variable.identifier, } } @@ -42,6 +46,8 @@ impl FunctionInputType { pub fn type_(&self) -> Type { match self { FunctionInputType::InputKeyword(identifier) => Type::Circuit(identifier.to_owned()), + FunctionInputType::SelfKeyword(identifier) => Type::Circuit(identifier.to_owned()), + FunctionInputType::MutSelfKeyword(identifier) => Type::Circuit(identifier.to_owned()), FunctionInputType::Variable(variable) => variable.type_.to_owned(), } } @@ -52,6 +58,8 @@ impl FunctionInputType { pub fn span(&self) -> &Span { match self { FunctionInputType::InputKeyword(identifier) => &identifier.span, + FunctionInputType::SelfKeyword(identifier) => &identifier.span, + FunctionInputType::MutSelfKeyword(identifier) => &identifier.span, FunctionInputType::Variable(variable) => &variable.span, } } @@ -64,7 +72,9 @@ impl FunctionInputType { /// pub fn new(table: &SymbolTable, unresolved: FunctionInput) -> Result { Ok(match unresolved { - FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), + FunctionInput::InputKeyword(keyword) => FunctionInputType::InputKeyword(Identifier::from(keyword)), + FunctionInput::SelfKeyword(_) => unimplemented!("cannot call self keyword from non-circuit context"), + FunctionInput::MutSelfKeyword(_) => unimplemented!("cannot call mut self keyword from non-circuit context"), FunctionInput::Variable(variable) => { let variable_resolved = FunctionInputVariableType::new(table, variable)?; @@ -88,7 +98,13 @@ impl FunctionInputType { circuit_name: Identifier, ) -> Result { Ok(match unresolved { - FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), + FunctionInput::InputKeyword(keyword) => FunctionInputType::InputKeyword(Identifier::from(keyword)), + FunctionInput::SelfKeyword(keyword) => { + FunctionInputType::SelfKeyword(Identifier::new_with_span(&circuit_name.name, &keyword.span)) + } + FunctionInput::MutSelfKeyword(keyword) => { + FunctionInputType::MutSelfKeyword(Identifier::new_with_span(&circuit_name.name, &keyword.span)) + } FunctionInput::Variable(unresolved_function_input) => { let function_input = FunctionInputVariableType::new_from_circuit(table, unresolved_function_input, circuit_name)?; diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs index 0daeba20dd..d69fbabb28 100644 --- a/type-inference/src/objects/frame.rs +++ b/type-inference/src/objects/frame.rs @@ -34,7 +34,7 @@ use leo_ast::{ Statement, Variables, }; -use leo_symbol_table::{Attribute, CircuitFunctionType, CircuitType, FunctionType, SymbolTable, Type, TypeVariable}; +use leo_symbol_table::{Attribute, CircuitType, FunctionType, SymbolTable, Type, TypeVariable}; /// A vector of `TypeAssertion` predicates created from a function body. #[derive(Clone)] @@ -100,13 +100,13 @@ impl Frame { let identifier = &function.identifier; // Find function name in circuit members. - let circuit_function_type = self_type.member_function_type(identifier).unwrap().to_owned(); + let function_type = self_type.member_function_type(identifier).unwrap().to_owned(); // Create a new scope for the function variables. let mut scope = Scope::new(Some(parent_scope)); // Initialize function inputs as variables. - scope.insert_function_inputs(&circuit_function_type.function.inputs)?; + scope.insert_function_inputs(&function_type.inputs)?; // Create new list of scopes for frame. let scopes = vec![scope]; @@ -114,7 +114,7 @@ impl Frame { // Create new frame struct. // Update variables when encountering let/const variable definitions. let mut frame = Self { - function_type: circuit_function_type.function, + function_type, self_type: Some(self_type), scopes, statements: function.statements, @@ -1029,7 +1029,7 @@ impl Frame { self.parse_circuit_function(expression, identifier, span) } Expression::CircuitStaticFunctionAccess(expression, identifier, span) => { - self.parse_static_circuit_function(expression, identifier, span) + self.parse_circuit_function(expression, identifier, span) } expression => Err(FrameError::invalid_function(expression, span)), } @@ -1053,7 +1053,7 @@ impl Frame { expression: &Expression, identifier: &Identifier, span: &Span, - ) -> Result<&CircuitFunctionType, FrameError> { + ) -> Result<&FunctionType, FrameError> { // Parse circuit name. let type_ = self.parse_expression(expression)?; @@ -1076,15 +1076,10 @@ impl Frame { span: &Span, ) -> Result { // Find circuit function type. - let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span)?; - - // Check that the function is non-static. - if let Some(Attribute::Static) = circuit_function_type.attribute { - return Err(FrameError::invalid_static_access(identifier)); - } + let function_type = self.parse_circuit_function_type(expression, identifier, span)?; // Return the function type. - Ok(circuit_function_type.function.to_owned()) + Ok(function_type.to_owned()) } /// @@ -1097,14 +1092,9 @@ impl Frame { span: &Span, ) -> Result { // Find circuit function type. - let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span)?; + let function_type = self.parse_circuit_function_type(expression, identifier, span)?; - // Check that the function is static. - if let Some(Attribute::Static) = circuit_function_type.attribute { - Ok(circuit_function_type.function.to_owned()) - } else { - Err(FrameError::invalid_member_access(identifier)) - } + Ok(function_type.to_owned()) } /// From 8873971f56457b1e571607ee25bc12d30936242b Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 25 Nov 2020 00:37:19 -0500 Subject: [PATCH 06/20] update self mut self keywords in type inference module --- type-inference/src/objects/frame.rs | 2 +- type-inference/src/type_inference.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs index d69fbabb28..d1c590d2d1 100644 --- a/type-inference/src/objects/frame.rs +++ b/type-inference/src/objects/frame.rs @@ -34,7 +34,7 @@ use leo_ast::{ Statement, Variables, }; -use leo_symbol_table::{Attribute, CircuitType, FunctionType, SymbolTable, Type, TypeVariable}; +use leo_symbol_table::{CircuitType, FunctionType, SymbolTable, Type, TypeVariable}; /// A vector of `TypeAssertion` predicates created from a function body. #[derive(Clone)] diff --git a/type-inference/src/type_inference.rs b/type-inference/src/type_inference.rs index fee87bb035..17baf6db4c 100644 --- a/type-inference/src/type_inference.rs +++ b/type-inference/src/type_inference.rs @@ -82,7 +82,7 @@ impl TypeInference { // Create a new function for each circuit member function. for circuit_member in &circuit.members { // ignore circuit member variables - if let CircuitMember::CircuitFunction(_, function) = circuit_member { + if let CircuitMember::CircuitFunction(function) = circuit_member { // Collect `TypeAssertion` predicates from the function. // Pass down circuit self type and circuit variable types to each function. let frame = Frame::new_circuit_function( From d4d5f336c4020038db3361e8fd2d8bac30e5c4e2 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 30 Nov 2020 13:06:11 -0500 Subject: [PATCH 07/20] refactor compiler to use new ast --- compiler/src/expression/circuit/circuit.rs | 10 +++++----- .../src/expression/circuit/static_access.rs | 13 ++----------- compiler/src/function/function.rs | 18 +++++++++++++++--- compiler/src/function/main_function.rs | 9 +++++---- type-inference/src/objects/frame.rs | 15 --------------- 5 files changed, 27 insertions(+), 38 deletions(-) diff --git a/compiler/src/expression/circuit/circuit.rs b/compiler/src/expression/circuit/circuit.rs index e78cd00e91..f89a056cc2 100644 --- a/compiler/src/expression/circuit/circuit.rs +++ b/compiler/src/expression/circuit/circuit.rs @@ -84,14 +84,14 @@ impl> ConstrainedProgram { None => return Err(ExpressionError::expected_circuit_member(identifier.to_string(), span)), } } - CircuitMember::CircuitFunction(_static, function) => { + CircuitMember::CircuitFunction(function) => { let identifier = function.identifier.clone(); - let mut constrained_function_value = + let constrained_function_value = ConstrainedValue::Function(Some(circuit_identifier.clone()), function); - if _static { - constrained_function_value = ConstrainedValue::Static(Box::new(constrained_function_value)); - } + // if _static { + // constrained_function_value = ConstrainedValue::Static(Box::new(constrained_function_value)); + // } resolved_members.push(ConstrainedCircuitMember(identifier, constrained_function_value)); } diff --git a/compiler/src/expression/circuit/static_access.rs b/compiler/src/expression/circuit/static_access.rs index 31ed5bb865..27086ac55c 100644 --- a/compiler/src/expression/circuit/static_access.rs +++ b/compiler/src/expression/circuit/static_access.rs @@ -56,22 +56,13 @@ impl> ConstrainedProgram { // Find static circuit function let matched_function = circuit.members.into_iter().find(|member| match member { - CircuitMember::CircuitFunction(_static, function) => function.identifier == circuit_member, + CircuitMember::CircuitFunction(function) => function.identifier == circuit_member, _ => false, }); // Return errors if no static function exists let function = match matched_function { - Some(CircuitMember::CircuitFunction(_static, function)) => { - if _static { - function - } else { - return Err(ExpressionError::invalid_member_access( - function.identifier.to_string(), - span, - )); - } - } + Some(CircuitMember::CircuitFunction(function)) => function, _ => { return Err(ExpressionError::undefined_member_access( circuit.circuit_name.to_string(), diff --git a/compiler/src/function/function.rs b/compiler/src/function/function.rs index ab944103f0..270d824862 100644 --- a/compiler/src/function/function.rs +++ b/compiler/src/function/function.rs @@ -57,11 +57,23 @@ impl> ConstrainedProgram { // Store input values as new variables in resolved program for (input_model, input_expression) in function.input.iter().zip(input.into_iter()) { let (name, value) = match input_model { - FunctionInput::InputKeyword(identifier) => { + FunctionInput::InputKeyword(keyword) => { let input_value = self.enforce_function_input(cs, scope, caller_scope, &function_name, None, input_expression)?; - (&identifier.name, input_value) + (keyword.to_string(), input_value) + } + FunctionInput::SelfKeyword(keyword) => { + let input_value = + self.enforce_function_input(cs, scope, caller_scope, &function_name, None, input_expression)?; + + (keyword.to_string(), input_value) + } + FunctionInput::MutSelfKeyword(keyword) => { + let input_value = + self.enforce_function_input(cs, scope, caller_scope, &function_name, None, input_expression)?; + + (keyword.to_string(), input_value) } FunctionInput::Variable(input_model) => { // First evaluate input expression @@ -78,7 +90,7 @@ impl> ConstrainedProgram { input_value = ConstrainedValue::Mutable(Box::new(input_value)) } - (&input_model.identifier.name, input_value) + (input_model.identifier.name.clone(), input_value) } }; diff --git a/compiler/src/function/main_function.rs b/compiler/src/function/main_function.rs index 85c7b52b19..1d3f5d1380 100644 --- a/compiler/src/function/main_function.rs +++ b/compiler/src/function/main_function.rs @@ -45,10 +45,11 @@ impl> ConstrainedProgram { let mut input_variables = Vec::with_capacity(function.input.len()); for input_model in function.input.clone().into_iter() { let (input_id, value) = match input_model { - FunctionInput::InputKeyword(identifier) => { - let value = self.allocate_input_keyword(cs, identifier.clone(), &input)?; + FunctionInput::InputKeyword(keyword) => { + let input_id = Identifier::new_with_span(&keyword.to_string(), &keyword.span); + let value = self.allocate_input_keyword(cs, keyword, &input)?; - (identifier, value) + (input_id, value) } FunctionInput::SelfKeyword(_) => unimplemented!("cannot access self keyword in main function"), FunctionInput::MutSelfKeyword(_) => { @@ -72,7 +73,7 @@ impl> ConstrainedProgram { // Store a new variable for every allocated main function input self.store(input_name, value); - input_variables.push(Expression::Identifier(Identifier::from(input_id))); + input_variables.push(Expression::Identifier(input_id)); } let span = function.span.clone(); diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs index d1c590d2d1..72a4d57be8 100644 --- a/type-inference/src/objects/frame.rs +++ b/type-inference/src/objects/frame.rs @@ -1082,21 +1082,6 @@ impl Frame { Ok(function_type.to_owned()) } - /// - /// Returns a `FunctionType` given a circuit expression and static function identifier. - /// - fn parse_static_circuit_function( - &mut self, - expression: &Expression, - identifier: &Identifier, - span: &Span, - ) -> Result { - // Find circuit function type. - let function_type = self.parse_circuit_function_type(expression, identifier, span)?; - - Ok(function_type.to_owned()) - } - /// /// Returns the type returned by calling the function. /// From 04081beb4b028295a75045609daacae3a10cd193 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 30 Nov 2020 13:34:21 -0500 Subject: [PATCH 08/20] move function input length check to type checking phase --- compiler/src/errors/function.rs | 6 ------ compiler/src/function/function.rs | 14 +------------- symbol-table/src/types/functions/function.rs | 10 ++++++++++ symbol-table/src/types/functions/function_input.rs | 14 ++++++++++++++ type-inference/src/objects/frame.rs | 4 ++-- 5 files changed, 27 insertions(+), 21 deletions(-) diff --git a/compiler/src/errors/function.rs b/compiler/src/errors/function.rs index 8f22e1fb87..49dfae9467 100644 --- a/compiler/src/errors/function.rs +++ b/compiler/src/errors/function.rs @@ -82,12 +82,6 @@ impl FunctionError { FunctionError::Error(FormattedError::new_from_span(message, span)) } - pub fn arguments_length(expected: usize, actual: usize, span: Span) -> Self { - let message = format!("function expected {} input variables, found {}", expected, actual); - - Self::new_from_span(message, span) - } - pub fn invalid_array(actual: String, span: Span) -> Self { let message = format!("Expected function input array, found `{}`", actual); diff --git a/compiler/src/function/function.rs b/compiler/src/function/function.rs index 270d824862..9a385452c2 100644 --- a/compiler/src/function/function.rs +++ b/compiler/src/function/function.rs @@ -23,22 +23,13 @@ use crate::{ GroupType, }; -use leo_ast::{Expression, Function, FunctionInput, Span, Type}; +use leo_ast::{Expression, Function, FunctionInput, Type}; use snarkos_models::{ curves::{Field, PrimeField}, gadgets::r1cs::ConstraintSystem, }; -pub fn check_arguments_length(expected: usize, actual: usize, span: &Span) -> Result<(), FunctionError> { - // Make sure we are given the correct number of arguments - if expected != actual { - Err(FunctionError::arguments_length(expected, actual, span.to_owned())) - } else { - Ok(()) - } -} - impl> ConstrainedProgram { pub(crate) fn enforce_function>( &mut self, @@ -51,9 +42,6 @@ impl> ConstrainedProgram { ) -> Result, FunctionError> { let function_name = new_scope(scope, function.get_name()); - // Make sure we are given the correct number of input variables - check_arguments_length(function.input.len(), input.len(), &function.span)?; - // Store input values as new variables in resolved program for (input_model, input_expression) in function.input.iter().zip(input.into_iter()) { let (name, value) = match input_model { diff --git a/symbol-table/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs index 0abdc87aa9..6d3d7700ba 100644 --- a/symbol-table/src/types/functions/function.rs +++ b/symbol-table/src/types/functions/function.rs @@ -119,6 +119,16 @@ impl FunctionType { Ok(()) } + + /// + /// Returns the number of input variables to the function. + /// The `self` and `mut self` keywords are not counted as input variables. + /// + pub fn num_inputs(&self) -> usize { + self.inputs + .iter() + .fold(0, |acc, function_input| acc + function_input.count()) + } } impl PartialEq for FunctionType { diff --git a/symbol-table/src/types/functions/function_input.rs b/symbol-table/src/types/functions/function_input.rs index ccbd0c5670..8819563112 100644 --- a/symbol-table/src/types/functions/function_input.rs +++ b/symbol-table/src/types/functions/function_input.rs @@ -64,6 +64,20 @@ impl FunctionInputType { } } + /// + /// Returns `1` if a variable must be provided in a call to the function. + /// Returns `0` if the function input is a `self` or `mut self` keyword which does not have to + /// provided in a call to the function. + /// + pub fn count(&self) -> usize { + match self { + FunctionInputType::InputKeyword(_) => 1, + FunctionInputType::SelfKeyword(_) => 0, + FunctionInputType::MutSelfKeyword(_) => 0, + FunctionInputType::Variable(_) => 1, + } + } + /// /// Return a new `FunctionInputType` from a given `FunctionInput`. /// diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs index 72a4d57be8..f61a84550c 100644 --- a/type-inference/src/objects/frame.rs +++ b/type-inference/src/objects/frame.rs @@ -1097,8 +1097,8 @@ impl Frame { let function_type = self.parse_function_name(expression, span)?; // Check the length of arguments - if function_type.inputs.len() != inputs.len() { - return Err(FrameError::num_inputs(function_type.inputs.len(), inputs.len(), span)); + if function_type.num_inputs() != inputs.len() { + return Err(FrameError::num_inputs(function_type.num_inputs(), inputs.len(), span)); } // Assert function inputs are correct types. From a37aa7bae4a8e9c4cfa6a4f90d05d022c8f2e964 Mon Sep 17 00:00:00 2001 From: howardwu Date: Mon, 30 Nov 2020 18:06:46 -0400 Subject: [PATCH 09/20] Update ci.yml --- .github/workflows/ci.yml | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d12928e66..94a17e9cac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,49 @@ jobs: command: fmt args: --all -- --check + clippy: + name: Clippy + runs-on: ubuntu-latest + env: + RUSTFLAGS: -Dwarnings + strategy: + matrix: + rust: + - stable + - nightly + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install Rust (${{ matrix.rust }}) + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + override: true + components: clippy + + - name: Check examples + uses: actions-rs/cargo@v1 + with: + command: clippy + args: --examples --all + + - name: Check examples with all features on stable + uses: actions-rs/cargo@v1 + with: + command: clippy + args: --examples --all-features --all + if: matrix.rust == 'stable' + + - name: Check benchmarks on nightly + uses: actions-rs/cargo@v1 + with: + command: clippy + args: --all-features --examples --all --benches + if: matrix.rust == 'nightly' + test: name: Test runs-on: ubuntu-latest From 74f77494627a6783ddd3979ee92f4877d1c78a6f Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 30 Nov 2020 17:54:41 -0500 Subject: [PATCH 10/20] pass circuit members into function by value when self keyword is present --- ast/src/functions/function.rs | 8 ++++++++ ast/src/functions/input/input_variable.rs | 13 +++++++++++++ compiler/src/expression/circuit/access.rs | 17 ++++++++++------- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/ast/src/functions/function.rs b/ast/src/functions/function.rs index be15d5131e..81dd3cba47 100644 --- a/ast/src/functions/function.rs +++ b/ast/src/functions/function.rs @@ -60,6 +60,14 @@ impl Function { &self.identifier.name } + /// + /// Returns `true` if the function has input `self` or `mut self`. + /// Returns `false` otherwise. + /// + pub fn contains_self(&self) -> bool { + self.input.iter().find(|param| param.is_self()).is_some() + } + fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "function {}", self.identifier)?; diff --git a/ast/src/functions/input/input_variable.rs b/ast/src/functions/input/input_variable.rs index bfa5b22abe..565efa05a5 100644 --- a/ast/src/functions/input/input_variable.rs +++ b/ast/src/functions/input/input_variable.rs @@ -43,6 +43,19 @@ impl<'ast> From> for FunctionInput { } impl FunctionInput { + /// + /// Returns `true` if the function input is the `self` or `mut self` keyword. + /// Returns `false` otherwise. + /// + pub fn is_self(&self) -> bool { + match self { + FunctionInput::InputKeyword(_) => false, + FunctionInput::SelfKeyword(_) => true, + FunctionInput::MutSelfKeyword(_) => true, + FunctionInput::Variable(_) => false, + } + } + fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { FunctionInput::InputKeyword(keyword) => write!(f, "{}", keyword), diff --git a/compiler/src/expression/circuit/access.rs b/compiler/src/expression/circuit/access.rs index 0d3864c295..4172c8c476 100644 --- a/compiler/src/expression/circuit/access.rs +++ b/compiler/src/expression/circuit/access.rs @@ -67,14 +67,17 @@ impl> ConstrainedProgram { match matched_member { Some(member) => { match &member.1 { - ConstrainedValue::Function(ref _circuit_identifier, ref _function) => { - // Pass circuit members into function call by value - for stored_member in members { - let circuit_scope = new_scope(&file_scope, &circuit_name.name); - let self_keyword = new_scope(&circuit_scope, SELF_KEYWORD); - let variable = new_scope(&self_keyword, &stored_member.0.name); + ConstrainedValue::Function(ref _circuit_identifier, ref function) => { + // Check for function input `self` or `mut self`. + if function.contains_self() { + // Pass circuit members into function call by value + for stored_member in members { + let circuit_scope = new_scope(&file_scope, &circuit_name.name); + let self_keyword = new_scope(&circuit_scope, SELF_KEYWORD); + let variable = new_scope(&self_keyword, &stored_member.0.name); - self.store(variable, stored_member.1.clone()); + self.store(variable, stored_member.1.clone()); + } } } ConstrainedValue::Static(value) => { From 82e13edbbea374072689b59d6d9f28f915fcade4 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 1 Dec 2020 10:12:50 -0500 Subject: [PATCH 11/20] pass mutable reference to circuit variable when 'mut self' keyword is present --- ast/src/functions/function.rs | 8 +++++ ast/src/functions/input/input_variable.rs | 13 ++++++++ compiler/src/function/function.rs | 15 +++++---- compiler/src/statement/assign/assign.rs | 3 +- .../src/statement/assign/circuit_variable.rs | 31 +++++++++++++++---- compiler/src/statement/branch/branch.rs | 2 ++ .../src/statement/conditional/conditional.rs | 4 +++ compiler/src/statement/iteration/iteration.rs | 2 ++ compiler/src/statement/statement.rs | 4 +++ 9 files changed, 69 insertions(+), 13 deletions(-) diff --git a/ast/src/functions/function.rs b/ast/src/functions/function.rs index 81dd3cba47..34bf69c8ce 100644 --- a/ast/src/functions/function.rs +++ b/ast/src/functions/function.rs @@ -68,6 +68,14 @@ impl Function { self.input.iter().find(|param| param.is_self()).is_some() } + /// + /// Returns `true` if the function has input `mut self`. + /// Returns `false` otherwise. + /// + pub fn contains_mut_self(&self) -> bool { + self.input.iter().find(|param| param.is_mut_self()).is_some() + } + fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "function {}", self.identifier)?; diff --git a/ast/src/functions/input/input_variable.rs b/ast/src/functions/input/input_variable.rs index 565efa05a5..3286496b89 100644 --- a/ast/src/functions/input/input_variable.rs +++ b/ast/src/functions/input/input_variable.rs @@ -56,6 +56,19 @@ impl FunctionInput { } } + /// + /// Returns `true` if the function input is the `mut self` keyword. + /// Returns `false` otherwise. + /// + pub fn is_mut_self(&self) -> bool { + match self { + FunctionInput::InputKeyword(_) => false, + FunctionInput::SelfKeyword(_) => false, + FunctionInput::MutSelfKeyword(_) => true, + FunctionInput::Variable(_) => false, + } + } + fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { FunctionInput::InputKeyword(keyword) => write!(f, "{}", keyword), diff --git a/compiler/src/function/function.rs b/compiler/src/function/function.rs index 9a385452c2..d873144cc2 100644 --- a/compiler/src/function/function.rs +++ b/compiler/src/function/function.rs @@ -46,22 +46,22 @@ impl> ConstrainedProgram { for (input_model, input_expression) in function.input.iter().zip(input.into_iter()) { let (name, value) = match input_model { FunctionInput::InputKeyword(keyword) => { - let input_value = + let value = self.enforce_function_input(cs, scope, caller_scope, &function_name, None, input_expression)?; - (keyword.to_string(), input_value) + (keyword.to_string(), value) } FunctionInput::SelfKeyword(keyword) => { - let input_value = + let value = self.enforce_function_input(cs, scope, caller_scope, &function_name, None, input_expression)?; - (keyword.to_string(), input_value) + (keyword.to_string(), value) } FunctionInput::MutSelfKeyword(keyword) => { - let input_value = + let value = self.enforce_function_input(cs, scope, caller_scope, &function_name, None, input_expression)?; - (keyword.to_string(), input_value) + (keyword.to_string(), value) } FunctionInput::Variable(input_model) => { // First evaluate input expression @@ -87,6 +87,8 @@ impl> ConstrainedProgram { self.store(input_program_identifier, value); } + let mut_self = function.contains_mut_self(); + // Evaluate every statement in the function and save all potential results let mut results = vec![]; @@ -99,6 +101,7 @@ impl> ConstrainedProgram { statement.clone(), function.output.clone(), declared_circuit_reference, + mut_self, )?; results.append(&mut result); diff --git a/compiler/src/statement/assign/assign.rs b/compiler/src/statement/assign/assign.rs index 8899c9b286..9403854726 100644 --- a/compiler/src/statement/assign/assign.rs +++ b/compiler/src/statement/assign/assign.rs @@ -42,6 +42,7 @@ impl> ConstrainedProgram { file_scope: &str, function_scope: &str, declared_circuit_reference: &str, + mut_self: bool, indicator: Option, assignee: Assignee, expression: Expression, @@ -88,7 +89,7 @@ impl> ConstrainedProgram { } AssigneeAccess::Member(identifier) => { // Mutate a circuit variable using the self keyword. - if assignee.identifier.is_self() { + if assignee.identifier.is_self() && mut_self { let self_circuit_variable_name = new_scope(&assignee.identifier.name, &identifier.name); let self_variable_name = new_scope(file_scope, &self_circuit_variable_name); let value = self.mutate_circuit_variable( diff --git a/compiler/src/statement/assign/circuit_variable.rs b/compiler/src/statement/assign/circuit_variable.rs index 146c95f983..7574869703 100644 --- a/compiler/src/statement/assign/circuit_variable.rs +++ b/compiler/src/statement/assign/circuit_variable.rs @@ -89,12 +89,31 @@ impl> ConstrainedProgram { Ok(selected_value) } - _ => { - // Throw an error if we try to mutate an immutable circuit variable - Err(StatementError::immutable_circuit_variable( - variable_name.name, - span.to_owned(), - )) + value => { + // Check that the new value type == old value type + new_value.resolve_type(Some(value.to_type(span)?), span)?; + + // Conditionally select the value if this branch is executed. + let mut selected_value = ConstrainedValue::conditionally_select( + cs.ns(|| format!("select {} {}:{}", new_value, span.line, span.start)), + &condition, + &new_value, + &member.1, + ) + .map_err(|_| { + StatementError::select_fail( + new_value.to_string(), + member.1.to_string(), + span.to_owned(), + ) + })?; + + // Make sure the new value is still mutable + selected_value = ConstrainedValue::Mutable(Box::new(selected_value)); + + member.1 = selected_value.to_owned(); + + Ok(selected_value) } }, None => { diff --git a/compiler/src/statement/branch/branch.rs b/compiler/src/statement/branch/branch.rs index 9d0d208036..af4d804440 100644 --- a/compiler/src/statement/branch/branch.rs +++ b/compiler/src/statement/branch/branch.rs @@ -33,6 +33,7 @@ impl> ConstrainedProgram { indicator: Option, statements: Vec, return_type: Option, + mut_self: bool, ) -> StatementResult>> { let mut results = Vec::with_capacity(statements.len()); // Evaluate statements. Only allow a single return argument to be returned. @@ -45,6 +46,7 @@ impl> ConstrainedProgram { statement, return_type.clone(), "", + mut_self, )?; results.append(&mut value); diff --git a/compiler/src/statement/conditional/conditional.rs b/compiler/src/statement/conditional/conditional.rs index 48bad283b8..7d795c9409 100644 --- a/compiler/src/statement/conditional/conditional.rs +++ b/compiler/src/statement/conditional/conditional.rs @@ -52,6 +52,7 @@ impl> ConstrainedProgram { indicator: Option, statement: ConditionalStatement, return_type: Option, + mut_self: bool, span: &Span, ) -> StatementResult>> { let statement_string = statement.to_string(); @@ -95,6 +96,7 @@ impl> ConstrainedProgram { Some(branch_1_indicator), statement.statements, return_type.clone(), + mut_self, )?; results.append(&mut branch_1_result); @@ -123,6 +125,7 @@ impl> ConstrainedProgram { Some(branch_2_indicator), *nested, return_type, + mut_self, span, )?, ConditionalNestedOrEndStatement::End(statements) => self.evaluate_branch( @@ -132,6 +135,7 @@ impl> ConstrainedProgram { Some(branch_2_indicator), statements, return_type, + mut_self, )?, }, None => vec![], diff --git a/compiler/src/statement/iteration/iteration.rs b/compiler/src/statement/iteration/iteration.rs index 64104cbb45..2ed50570a4 100644 --- a/compiler/src/statement/iteration/iteration.rs +++ b/compiler/src/statement/iteration/iteration.rs @@ -48,6 +48,7 @@ impl> ConstrainedProgram { stop: Expression, statements: Vec, return_type: Option, + mut_self: bool, span: &Span, ) -> StatementResult>> { let mut results = vec![]; @@ -74,6 +75,7 @@ impl> ConstrainedProgram { indicator, statements.clone(), return_type.clone(), + mut_self, )?; results.append(&mut result); diff --git a/compiler/src/statement/statement.rs b/compiler/src/statement/statement.rs index 763ea328a7..bf5b8ef5e2 100644 --- a/compiler/src/statement/statement.rs +++ b/compiler/src/statement/statement.rs @@ -45,6 +45,7 @@ impl> ConstrainedProgram { statement: Statement, return_type: Option, declared_circuit_reference: &str, + mut_self: bool, ) -> StatementResult>> { let mut results = vec![]; @@ -74,6 +75,7 @@ impl> ConstrainedProgram { file_scope, function_scope, declared_circuit_reference, + mut_self, indicator, variable, expression, @@ -88,6 +90,7 @@ impl> ConstrainedProgram { indicator, statement, return_type, + mut_self, &span, )?; @@ -104,6 +107,7 @@ impl> ConstrainedProgram { start_stop.1, statements, return_type, + mut_self, &span, )?; From 7977b20ad2ec76ce8956cafdbbfe660e46c5a5d7 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 1 Dec 2020 10:19:02 -0500 Subject: [PATCH 12/20] remove mut variable keyword --- ast/src/circuits/circuit_member.rs | 10 +++------- compiler/src/expression/circuit/circuit.rs | 11 +---------- grammar/src/circuits/circuit_variable_definition.rs | 1 - grammar/src/leo.pest | 2 +- symbol-table/src/types/circuits/circuit.rs | 9 +++------ 5 files changed, 8 insertions(+), 25 deletions(-) diff --git a/ast/src/circuits/circuit_member.rs b/ast/src/circuits/circuit_member.rs index 2d18e70fcc..c86ae4156b 100644 --- a/ast/src/circuits/circuit_member.rs +++ b/ast/src/circuits/circuit_member.rs @@ -25,8 +25,8 @@ use std::fmt; #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum CircuitMember { - // (is_mutable, variable_name, variable_type) - CircuitVariable(bool, Identifier, Type), + // (variable_name, variable_type) + CircuitVariable(Identifier, Type), // (function) CircuitFunction(Function), } @@ -34,7 +34,6 @@ pub enum CircuitMember { impl<'ast> From> for CircuitMember { fn from(circuit_value: GrammarCircuitVariableDefinition<'ast>) -> Self { CircuitMember::CircuitVariable( - circuit_value.mutable.is_some(), Identifier::from(circuit_value.identifier), Type::from(circuit_value.type_), ) @@ -59,10 +58,7 @@ impl<'ast> From> for CircuitMember { impl fmt::Display for CircuitMember { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - CircuitMember::CircuitVariable(ref mutable, ref identifier, ref type_) => { - if *mutable { - write!(f, "mut ")?; - } + CircuitMember::CircuitVariable(ref identifier, ref type_) => { write!(f, "{}: {}", identifier, type_) } CircuitMember::CircuitFunction(ref function) => { diff --git a/compiler/src/expression/circuit/circuit.rs b/compiler/src/expression/circuit/circuit.rs index f89a056cc2..aa896df2b9 100644 --- a/compiler/src/expression/circuit/circuit.rs +++ b/compiler/src/expression/circuit/circuit.rs @@ -58,7 +58,7 @@ impl> ConstrainedProgram { for member in circuit.members.into_iter() { match member { - CircuitMember::CircuitVariable(is_mutable, identifier, type_) => { + CircuitMember::CircuitVariable(identifier, type_) => { let matched_variable = members .clone() .into_iter() @@ -74,11 +74,6 @@ impl> ConstrainedProgram { variable.expression, )?; - // Add mutability to circuit variable - if is_mutable { - variable_value = ConstrainedValue::Mutable(Box::new(variable_value)) - } - resolved_members.push(ConstrainedCircuitMember(identifier, variable_value)) } None => return Err(ExpressionError::expected_circuit_member(identifier.to_string(), span)), @@ -89,10 +84,6 @@ impl> ConstrainedProgram { let constrained_function_value = ConstrainedValue::Function(Some(circuit_identifier.clone()), function); - // if _static { - // constrained_function_value = ConstrainedValue::Static(Box::new(constrained_function_value)); - // } - resolved_members.push(ConstrainedCircuitMember(identifier, constrained_function_value)); } }; diff --git a/grammar/src/circuits/circuit_variable_definition.rs b/grammar/src/circuits/circuit_variable_definition.rs index 8bd462a099..4de596cd50 100644 --- a/grammar/src/circuits/circuit_variable_definition.rs +++ b/grammar/src/circuits/circuit_variable_definition.rs @@ -28,7 +28,6 @@ use serde::Serialize; #[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::circuit_variable_definition))] pub struct CircuitVariableDefinition<'ast> { - pub mutable: Option, pub identifier: Identifier<'ast>, pub type_: Type<'ast>, #[pest_ast(outer())] diff --git a/grammar/src/leo.pest b/grammar/src/leo.pest index b065834413..3879aa73f7 100644 --- a/grammar/src/leo.pest +++ b/grammar/src/leo.pest @@ -322,7 +322,7 @@ circuit = { "circuit " ~ identifier ~ "{" ~ NEWLINE* ~ circuit_member* ~ NEWLINE circuit_variable = { identifier ~ ":" ~ expression } // Declared in circuits/circuit_variable_definition.rs -circuit_variable_definition = { mutable? ~ identifier ~ ":" ~ type_ ~ ","?} +circuit_variable_definition = { identifier ~ ":" ~ type_ ~ ","?} // Declared in circuits/circuit_member.rs circuit_member = { function | circuit_variable_definition ~ NEWLINE*} diff --git a/symbol-table/src/types/circuits/circuit.rs b/symbol-table/src/types/circuits/circuit.rs index d05ee64e90..df67e3495d 100644 --- a/symbol-table/src/types/circuits/circuit.rs +++ b/symbol-table/src/types/circuits/circuit.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::{types::circuits::CircuitVariableType, Attribute, FunctionType, SymbolTable, Type, TypeError}; +use crate::{types::circuits::CircuitVariableType, FunctionType, SymbolTable, Type, TypeError}; use leo_ast::{Circuit, CircuitMember, Identifier, InputValue, Parameter, Span}; use serde::{Deserialize, Serialize}; @@ -54,7 +54,7 @@ impl CircuitType { // Resolve the type of every circuit member. for member in unresolved.members { match member { - CircuitMember::CircuitVariable(is_mutable, variable_identifier, type_) => { + CircuitMember::CircuitVariable(variable_identifier, type_) => { // Resolve the type of the circuit member variable. let type_ = Type::new_from_circuit( table, @@ -63,14 +63,11 @@ impl CircuitType { circuit_identifier.span.clone(), )?; - // Check if the circuit member variable is mutable. - let attribute = if is_mutable { Some(Attribute::Mutable) } else { None }; - // Create a new circuit variable type. let variable = CircuitVariableType { identifier: variable_identifier, type_, - attribute, + attribute: None, }; // Store the circuit variable type. From 8457b05354aea1ef4803213d009b3b71f65e7406 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 1 Dec 2020 11:54:51 -0500 Subject: [PATCH 13/20] remove mut circuit variable definition --- compiler/src/expression/circuit/circuit.rs | 2 +- ...define_circuit_inside_circuit_function.leo | 2 +- .../circuits/member_function_invalid.leo | 2 +- .../tests/circuits/member_function_nested.leo | 4 +- compiler/tests/circuits/mod.rs | 8 ++- .../circuit_static_function_mut.leo | 2 +- .../tests/mutability/circuit_variable_mut.leo | 2 +- compiler/tests/mutability/mod.rs | 2 +- .../circuits/circuit_variable_definition.rs | 7 +-- symbol-table/src/types/functions/function.rs | 8 +++ .../src/types/functions/function_input.rs | 22 +++++--- type-inference/src/errors/frame.rs | 21 ++++++++ type-inference/src/objects/frame.rs | 51 ++++++++++++------- 13 files changed, 93 insertions(+), 40 deletions(-) diff --git a/compiler/src/expression/circuit/circuit.rs b/compiler/src/expression/circuit/circuit.rs index aa896df2b9..6a6e129fe3 100644 --- a/compiler/src/expression/circuit/circuit.rs +++ b/compiler/src/expression/circuit/circuit.rs @@ -66,7 +66,7 @@ impl> ConstrainedProgram { match matched_variable { Some(variable) => { // Resolve and enforce circuit variable - let mut variable_value = self.enforce_expression( + let variable_value = self.enforce_expression( cs, file_scope, function_scope, diff --git a/compiler/tests/circuits/define_circuit_inside_circuit_function.leo b/compiler/tests/circuits/define_circuit_inside_circuit_function.leo index 17a8522b97..8c25c1e9d9 100644 --- a/compiler/tests/circuits/define_circuit_inside_circuit_function.leo +++ b/compiler/tests/circuits/define_circuit_inside_circuit_function.leo @@ -3,7 +3,7 @@ circuit Foo { } circuit Bar { - static function bar() { + function bar() { let f = Foo { a: 0u32 }; } } diff --git a/compiler/tests/circuits/member_function_invalid.leo b/compiler/tests/circuits/member_function_invalid.leo index d0a7271a07..bb834e9562 100644 --- a/compiler/tests/circuits/member_function_invalid.leo +++ b/compiler/tests/circuits/member_function_invalid.leo @@ -1,5 +1,5 @@ circuit Foo { - static function echo(x: u32) -> u32 { + function echo(x: u32) -> u32 { return x } } diff --git a/compiler/tests/circuits/member_function_nested.leo b/compiler/tests/circuits/member_function_nested.leo index 4146ef9492..cc6cae2475 100644 --- a/compiler/tests/circuits/member_function_nested.leo +++ b/compiler/tests/circuits/member_function_nested.leo @@ -1,11 +1,11 @@ circuit Foo { x: u32, - function add_x(y: u32) -> u32 { + function add_x(self, y: u32) -> u32 { return self.x + y } - function call_add_x(y: u32) -> u32 { + function call_add_x(self, y: u32) -> u32 { return self.add_x(y) } } diff --git a/compiler/tests/circuits/mod.rs b/compiler/tests/circuits/mod.rs index 33d0d41ea9..c599c29023 100644 --- a/compiler/tests/circuits/mod.rs +++ b/compiler/tests/circuits/mod.rs @@ -14,7 +14,13 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{assert_satisfied, expect_compiler_error, expect_type_inference_error, parse_program}; +use crate::{ + assert_satisfied, + expect_compiler_error, + expect_symbol_table_error, + expect_type_inference_error, + parse_program, +}; // Expressions diff --git a/compiler/tests/mutability/circuit_static_function_mut.leo b/compiler/tests/mutability/circuit_static_function_mut.leo index 0717f51c44..eba1d02c0e 100644 --- a/compiler/tests/mutability/circuit_static_function_mut.leo +++ b/compiler/tests/mutability/circuit_static_function_mut.leo @@ -1,6 +1,6 @@ // Adding the `mut` keyword makes a circuit variable mutable. circuit Foo { - static function bar() {} + function bar() {} } function main() { diff --git a/compiler/tests/mutability/circuit_variable_mut.leo b/compiler/tests/mutability/circuit_variable_mut.leo index f87668c48e..27bd6109b2 100644 --- a/compiler/tests/mutability/circuit_variable_mut.leo +++ b/compiler/tests/mutability/circuit_variable_mut.leo @@ -1,6 +1,6 @@ // Adding the `mut` keyword makes a circuit variable mutable. circuit Foo { - mut x: u32 + x: u32 } function main() { diff --git a/compiler/tests/mutability/mod.rs b/compiler/tests/mutability/mod.rs index 8442357044..4da49d1765 100644 --- a/compiler/tests/mutability/mod.rs +++ b/compiler/tests/mutability/mod.rs @@ -78,7 +78,7 @@ fn test_circuit_mut() { let bytes = include_bytes!("circuit_mut.leo"); let program = parse_program(bytes).unwrap(); - expect_compiler_error(program); + assert_satisfied(program); } #[test] diff --git a/grammar/src/circuits/circuit_variable_definition.rs b/grammar/src/circuits/circuit_variable_definition.rs index 4de596cd50..b3a84ef629 100644 --- a/grammar/src/circuits/circuit_variable_definition.rs +++ b/grammar/src/circuits/circuit_variable_definition.rs @@ -14,12 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ - ast::Rule, - common::{Identifier, Mutable}, - types::Type, - SpanDef, -}; +use crate::{ast::Rule, common::Identifier, types::Type, SpanDef}; use pest::Span; use pest_ast::FromPest; diff --git a/symbol-table/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs index 6d3d7700ba..c03cf3a3ba 100644 --- a/symbol-table/src/types/functions/function.rs +++ b/symbol-table/src/types/functions/function.rs @@ -129,6 +129,14 @@ impl FunctionType { .iter() .fold(0, |acc, function_input| acc + function_input.count()) } + + /// + /// Returns `true` if the input `self` or `mut self` is present. + /// Returns `false` otherwise. + /// + pub fn contains_self(&self) -> bool { + self.inputs.iter().find(|param| param.is_self()).is_some() + } } impl PartialEq for FunctionType { diff --git a/symbol-table/src/types/functions/function_input.rs b/symbol-table/src/types/functions/function_input.rs index 8819563112..66a8180f98 100644 --- a/symbol-table/src/types/functions/function_input.rs +++ b/symbol-table/src/types/functions/function_input.rs @@ -65,17 +65,25 @@ impl FunctionInputType { } /// - /// Returns `1` if a variable must be provided in a call to the function. + /// Returns `true` if input `self` or `mut self` is present. + /// Returns `false` otherwise. + /// + pub fn is_self(&self) -> bool { + match self { + FunctionInputType::InputKeyword(_) => false, + FunctionInputType::SelfKeyword(_) => true, + FunctionInputType::MutSelfKeyword(_) => true, + FunctionInputType::Variable(_) => false, + } + } + + /// /// Returns `0` if the function input is a `self` or `mut self` keyword which does not have to /// provided in a call to the function. + /// Returns `1` if a variable must be provided in a call to the function. /// pub fn count(&self) -> usize { - match self { - FunctionInputType::InputKeyword(_) => 1, - FunctionInputType::SelfKeyword(_) => 0, - FunctionInputType::MutSelfKeyword(_) => 0, - FunctionInputType::Variable(_) => 1, - } + if self.is_self() { 0 } else { 1 } } /// diff --git a/type-inference/src/errors/frame.rs b/type-inference/src/errors/frame.rs index 36e8576832..814d2e8ff2 100644 --- a/type-inference/src/errors/frame.rs +++ b/type-inference/src/errors/frame.rs @@ -172,6 +172,27 @@ impl FrameError { Self::new_from_span(message, span) } + /// + /// The `self` keyword was used in a static circuit function signature. + /// + pub fn self_not_available(span: &Span) -> Self { + let message = "keyword `self` is only available in static circuit functions.".to_string(); + + Self::new_from_span(message, span) + } + + /// + /// A static function was accessed using dot `.` syntax instead of double colon `::` syntax. + /// + pub fn static_call_invalid(identifier: &Identifier) -> Self { + let message = format!( + "Static function `{}` must be called using double colon `::` syntax.", + identifier.name + ); + + Self::new_from_span(message, &identifier.span) + } + /// /// Attempted to access the index of a non-tuple type. /// diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs index f61a84550c..fe3943eca7 100644 --- a/type-inference/src/objects/frame.rs +++ b/type-inference/src/objects/frame.rs @@ -952,22 +952,6 @@ impl Frame { Ok(Type::Circuit(circuit_type.identifier)) } - /// - /// Returns the type of the accessed circuit member when called as an expression. - /// - fn parse_expression_circuit_member_access( - &mut self, - expression: &Expression, - identifier: &Identifier, - span: &Span, - ) -> Result { - // Parse circuit name. - let type_ = self.parse_expression(expression)?; - - // Parse the circuit member access. - self.parse_circuit_member_access(type_, identifier, span) - } - /// /// Returns the type of the accessed circuit member. /// @@ -984,6 +968,22 @@ impl Frame { Ok(circuit_type.member_type(&identifier)?) } + /// + /// Returns the type of the accessed circuit member when called as an expression. + /// + fn parse_expression_circuit_member_access( + &mut self, + expression: &Expression, + identifier: &Identifier, + span: &Span, + ) -> Result { + // Parse circuit name. + let type_ = self.parse_expression(expression)?; + + // Parse the circuit member access. + self.parse_circuit_member_access(type_, identifier, span) + } + /// /// Returns the type returned by calling the static circuit function. /// @@ -1026,10 +1026,10 @@ impl Frame { match expression { Expression::Identifier(identifier) => self.parse_program_function(identifier, span), Expression::CircuitMemberAccess(expression, identifier, span) => { - self.parse_circuit_function(expression, identifier, span) + self.parse_circuit_function(expression, identifier, span, false) } Expression::CircuitStaticFunctionAccess(expression, identifier, span) => { - self.parse_circuit_function(expression, identifier, span) + self.parse_circuit_function(expression, identifier, span, true) } expression => Err(FrameError::invalid_function(expression, span)), } @@ -1074,10 +1074,25 @@ impl Frame { expression: &Expression, identifier: &Identifier, span: &Span, + is_static: bool, ) -> Result { // Find circuit function type. let function_type = self.parse_circuit_function_type(expression, identifier, span)?; + // Case 1: static call + self keyword => Error + // Case 2: no static call + no self keywords => Error + // Case 3: static call + no self keywords => Ok + // Case 4: no static call + self keyword => Ok + println!("static {}", is_static); + println!("function contains self {}", function_type.contains_self()); + if is_static && function_type.contains_self() { + return Err(FrameError::self_not_available(&identifier.span)); + } else if !is_static && !function_type.contains_self() { + return Err(FrameError::static_call_invalid(&identifier)); + } + + if is_static && function_type.contains_self() {} + // Return the function type. Ok(function_type.to_owned()) } From d8c08fedd78784e830fe1365fa80ffdb7139a34b Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 1 Dec 2020 15:37:44 -0500 Subject: [PATCH 14/20] fix tests --- ast/src/functions/function.rs | 10 ++++++++++ compiler/src/errors/expression.rs | 2 +- compiler/src/function/function.rs | 7 ++++--- .../tests/circuits/member_function_nested.leo | 2 +- .../tests/circuits/member_static_function.leo | 2 +- .../circuits/member_static_function_invalid.leo | 2 +- .../circuits/member_static_function_nested.leo | 6 +++--- .../member_static_function_undefined.leo | 2 +- .../circuits/member_variable_and_function.leo | 2 +- compiler/tests/circuits/mod.rs | 16 +++++----------- .../tests/circuits/mut_self_function_fail.leo | 2 +- .../circuits/mut_self_static_function_fail.leo | 4 ++-- compiler/tests/circuits/mut_self_variable.leo | 4 ++-- .../tests/circuits/mut_self_variable_fail.leo | 2 +- .../tests/circuits/mut_static_function_fail.leo | 2 +- compiler/tests/circuits/mut_variable.leo | 2 +- compiler/tests/circuits/mut_variable_fail.leo | 2 +- compiler/tests/circuits/pedersen_mock.leo | 4 ++-- compiler/tests/circuits/self_member.leo | 2 +- compiler/tests/syntax/mod.rs | 2 +- symbol-table/src/types/functions/function.rs | 10 ++++++++++ type-inference/src/objects/frame.rs | 13 ++++++++----- 22 files changed, 59 insertions(+), 41 deletions(-) diff --git a/ast/src/functions/function.rs b/ast/src/functions/function.rs index 34bf69c8ce..c6a92c3a6f 100644 --- a/ast/src/functions/function.rs +++ b/ast/src/functions/function.rs @@ -76,6 +76,16 @@ impl Function { self.input.iter().find(|param| param.is_mut_self()).is_some() } + /// + /// Returns a vector of [&FunctionInput] removing `self` and `mut self` inputs. + /// + pub fn filter_self_inputs(&self) -> Vec<&FunctionInput> { + self.input + .iter() + .filter(|input| !input.is_self()) + .collect::>() + } + fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "function {}", self.identifier)?; diff --git a/compiler/src/errors/expression.rs b/compiler/src/errors/expression.rs index 41a83cd6f2..be0deb5925 100644 --- a/compiler/src/errors/expression.rs +++ b/compiler/src/errors/expression.rs @@ -206,7 +206,7 @@ impl ExpressionError { } pub fn undefined_identifier(identifier: Identifier) -> Self { - let message = format!("cannot find value `{}` in this scope", identifier.name); + let message = format!("Cannot find value `{}` in this scope", identifier.name); Self::new_from_span(message, identifier.span) } diff --git a/compiler/src/function/function.rs b/compiler/src/function/function.rs index d873144cc2..4d438d5221 100644 --- a/compiler/src/function/function.rs +++ b/compiler/src/function/function.rs @@ -42,8 +42,11 @@ impl> ConstrainedProgram { ) -> Result, FunctionError> { let function_name = new_scope(scope, function.get_name()); + // Store if function contains input `mut self`. + let mut_self = function.contains_mut_self(); + // Store input values as new variables in resolved program - for (input_model, input_expression) in function.input.iter().zip(input.into_iter()) { + for (input_model, input_expression) in function.filter_self_inputs().iter().zip(input.into_iter()) { let (name, value) = match input_model { FunctionInput::InputKeyword(keyword) => { let value = @@ -87,8 +90,6 @@ impl> ConstrainedProgram { self.store(input_program_identifier, value); } - let mut_self = function.contains_mut_self(); - // Evaluate every statement in the function and save all potential results let mut results = vec![]; diff --git a/compiler/tests/circuits/member_function_nested.leo b/compiler/tests/circuits/member_function_nested.leo index cc6cae2475..9e07cc9acf 100644 --- a/compiler/tests/circuits/member_function_nested.leo +++ b/compiler/tests/circuits/member_function_nested.leo @@ -12,7 +12,7 @@ circuit Foo { function main() { let a = Foo { x: 1u32 }; - let b = a.call_add_x(1u32); + let b = a.add_x(1u32); console.assert(b == 2u32); } diff --git a/compiler/tests/circuits/member_static_function.leo b/compiler/tests/circuits/member_static_function.leo index ac96c89088..4bf51190f0 100644 --- a/compiler/tests/circuits/member_static_function.leo +++ b/compiler/tests/circuits/member_static_function.leo @@ -1,5 +1,5 @@ circuit Foo { - static function echo(x: u32) -> u32 { + function echo(x: u32) -> u32 { return x } } diff --git a/compiler/tests/circuits/member_static_function_invalid.leo b/compiler/tests/circuits/member_static_function_invalid.leo index b2782bfed4..513d78b67d 100644 --- a/compiler/tests/circuits/member_static_function_invalid.leo +++ b/compiler/tests/circuits/member_static_function_invalid.leo @@ -5,5 +5,5 @@ circuit Foo { } function main() { - let err = Foo::echo(1u32); // echo is a non-static function and must be accessed using `.` + let err = Foo::echo(1u32); // Correct, echo is a static function and must be accessed using `::` } \ No newline at end of file diff --git a/compiler/tests/circuits/member_static_function_nested.leo b/compiler/tests/circuits/member_static_function_nested.leo index 8f717f3f7c..ef536e3f6e 100644 --- a/compiler/tests/circuits/member_static_function_nested.leo +++ b/compiler/tests/circuits/member_static_function_nested.leo @@ -1,11 +1,11 @@ circuit Foo { - static function qux() {} + function qux() {} - static function bar() { + function bar() { Self::qux(); } - static function baz() { + function baz() { Self::bar(); } } diff --git a/compiler/tests/circuits/member_static_function_undefined.leo b/compiler/tests/circuits/member_static_function_undefined.leo index e8e5cb20bc..cf9f98c7b4 100644 --- a/compiler/tests/circuits/member_static_function_undefined.leo +++ b/compiler/tests/circuits/member_static_function_undefined.leo @@ -1,5 +1,5 @@ circuit Foo { - static function echo(x: u32) -> u32 { + function echo(x: u32) -> u32 { return x } } diff --git a/compiler/tests/circuits/member_variable_and_function.leo b/compiler/tests/circuits/member_variable_and_function.leo index 35f413a361..074feab7b8 100644 --- a/compiler/tests/circuits/member_variable_and_function.leo +++ b/compiler/tests/circuits/member_variable_and_function.leo @@ -1,7 +1,7 @@ circuit Foo { foo: u32, - static function bar() -> u32 { + function bar() -> u32 { return 1u32 } } diff --git a/compiler/tests/circuits/mod.rs b/compiler/tests/circuits/mod.rs index c599c29023..848d7a01c7 100644 --- a/compiler/tests/circuits/mod.rs +++ b/compiler/tests/circuits/mod.rs @@ -14,13 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ - assert_satisfied, - expect_compiler_error, - expect_symbol_table_error, - expect_type_inference_error, - parse_program, -}; +use crate::{assert_satisfied, expect_compiler_error, expect_type_inference_error, parse_program}; // Expressions @@ -125,9 +119,9 @@ fn test_member_static_function_nested() { #[test] fn test_member_static_function_invalid() { let bytes = include_bytes!("member_static_function_invalid.leo"); - let error = parse_program(bytes).err().unwrap(); + let program = parse_program(bytes).unwrap(); - expect_type_inference_error(error) + assert_satisfied(program) } #[test] @@ -225,9 +219,9 @@ fn test_self_member_pass() { #[test] fn test_self_member_invalid() { let bytes = include_bytes!("self_member_invalid.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - let _err = expect_compiler_error(program); + expect_type_inference_error(error); } #[test] diff --git a/compiler/tests/circuits/mut_self_function_fail.leo b/compiler/tests/circuits/mut_self_function_fail.leo index 18da32c5fb..8c9b99f6ae 100644 --- a/compiler/tests/circuits/mut_self_function_fail.leo +++ b/compiler/tests/circuits/mut_self_function_fail.leo @@ -3,7 +3,7 @@ circuit Foo { function bar() {} - function set_a(new: u8) { + function set_a(mut self, new: u8) { self.bar = new; } } diff --git a/compiler/tests/circuits/mut_self_static_function_fail.leo b/compiler/tests/circuits/mut_self_static_function_fail.leo index de87c5fadf..8c9b99f6ae 100644 --- a/compiler/tests/circuits/mut_self_static_function_fail.leo +++ b/compiler/tests/circuits/mut_self_static_function_fail.leo @@ -1,9 +1,9 @@ circuit Foo { a: u8, - static function bar() {} + function bar() {} - function set_a(new: u8) { + function set_a(mut self, new: u8) { self.bar = new; } } diff --git a/compiler/tests/circuits/mut_self_variable.leo b/compiler/tests/circuits/mut_self_variable.leo index 47b9aeed70..f5a35ec754 100644 --- a/compiler/tests/circuits/mut_self_variable.leo +++ b/compiler/tests/circuits/mut_self_variable.leo @@ -1,7 +1,7 @@ circuit Foo { - mut a: u8, + a: u8, - function set_a(new: u8) { + function set_a(mut self, new: u8) { self.a = new; console.assert(self.a == new); } diff --git a/compiler/tests/circuits/mut_self_variable_fail.leo b/compiler/tests/circuits/mut_self_variable_fail.leo index 551b041c9e..fdbb556bca 100644 --- a/compiler/tests/circuits/mut_self_variable_fail.leo +++ b/compiler/tests/circuits/mut_self_variable_fail.leo @@ -1,7 +1,7 @@ circuit Foo { a: u8, - function set_a(new: u8) { + function set_a(self, new: u8) { self.a = new; } } diff --git a/compiler/tests/circuits/mut_static_function_fail.leo b/compiler/tests/circuits/mut_static_function_fail.leo index f1bccaaf89..ed3092c656 100644 --- a/compiler/tests/circuits/mut_static_function_fail.leo +++ b/compiler/tests/circuits/mut_static_function_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - static function bar() {} + function bar() {} } function main() { diff --git a/compiler/tests/circuits/mut_variable.leo b/compiler/tests/circuits/mut_variable.leo index eaf61ddf02..243d7a2cf2 100644 --- a/compiler/tests/circuits/mut_variable.leo +++ b/compiler/tests/circuits/mut_variable.leo @@ -1,5 +1,5 @@ circuit Foo { - mut a: u8, + a: u8, } function main() { diff --git a/compiler/tests/circuits/mut_variable_fail.leo b/compiler/tests/circuits/mut_variable_fail.leo index bb2e653ee3..4d58150c95 100644 --- a/compiler/tests/circuits/mut_variable_fail.leo +++ b/compiler/tests/circuits/mut_variable_fail.leo @@ -3,7 +3,7 @@ circuit Foo { } function main() { - let mut f = Foo { a: 0u8 }; + let f = Foo { a: 0u8 }; f.a = 1u8; } \ No newline at end of file diff --git a/compiler/tests/circuits/pedersen_mock.leo b/compiler/tests/circuits/pedersen_mock.leo index 2b58019d8d..0b42c64a6e 100644 --- a/compiler/tests/circuits/pedersen_mock.leo +++ b/compiler/tests/circuits/pedersen_mock.leo @@ -1,11 +1,11 @@ circuit PedersenHash { parameters: [u32; 512] - static function new(parameters: [u32; 512]) -> Self { + function new(parameters: [u32; 512]) -> Self { return Self { parameters: parameters } } - function hash(bits: [bool; 512]) -> u32 { + function hash(self, bits: [bool; 512]) -> u32 { let mut digest: u32 = 0; for i in 0..512 { let base = if bits[i] ? self.parameters[i] : 0u32; diff --git a/compiler/tests/circuits/self_member.leo b/compiler/tests/circuits/self_member.leo index a075894af0..1bd978433d 100644 --- a/compiler/tests/circuits/self_member.leo +++ b/compiler/tests/circuits/self_member.leo @@ -1,7 +1,7 @@ circuit Foo { f: u32, - function bar() -> u32 { + function bar(self) -> u32 { return self.f } } diff --git a/compiler/tests/syntax/mod.rs b/compiler/tests/syntax/mod.rs index 55b7292d2a..017d01a707 100644 --- a/compiler/tests/syntax/mod.rs +++ b/compiler/tests/syntax/mod.rs @@ -53,7 +53,7 @@ fn test_undefined() { " 2 | return a", " | ^", " |", - " = cannot find value `a` in this scope", + " = Cannot find value `a` in this scope", ] .join("\n") ); diff --git a/symbol-table/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs index c03cf3a3ba..194ab7a72e 100644 --- a/symbol-table/src/types/functions/function.rs +++ b/symbol-table/src/types/functions/function.rs @@ -137,6 +137,16 @@ impl FunctionType { pub fn contains_self(&self) -> bool { self.inputs.iter().find(|param| param.is_self()).is_some() } + + /// + /// Returns a vector of [&FunctionInputType] removing `self` and `mut self` inputs. + /// + pub fn filter_self_inputs(&self) -> Vec<&FunctionInputType> { + self.inputs + .iter() + .filter(|input| !input.is_self()) + .collect::>() + } } impl PartialEq for FunctionType { diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs index fe3943eca7..822fdf9448 100644 --- a/type-inference/src/objects/frame.rs +++ b/type-inference/src/objects/frame.rs @@ -1083,8 +1083,6 @@ impl Frame { // Case 2: no static call + no self keywords => Error // Case 3: static call + no self keywords => Ok // Case 4: no static call + self keyword => Ok - println!("static {}", is_static); - println!("function contains self {}", function_type.contains_self()); if is_static && function_type.contains_self() { return Err(FrameError::self_not_available(&identifier.span)); } else if !is_static && !function_type.contains_self() { @@ -1112,12 +1110,17 @@ impl Frame { let function_type = self.parse_function_name(expression, span)?; // Check the length of arguments - if function_type.num_inputs() != inputs.len() { - return Err(FrameError::num_inputs(function_type.num_inputs(), inputs.len(), span)); + let num_inputs = function_type.num_inputs(); + + if num_inputs != inputs.len() { + return Err(FrameError::num_inputs(num_inputs, inputs.len(), span)); } + // Filter out `self` and `mut self` keywords. + let expected_inputs = function_type.filter_self_inputs(); + // Assert function inputs are correct types. - for (expected_input, actual_input) in function_type.inputs.iter().zip(inputs) { + for (expected_input, actual_input) in expected_inputs.iter().zip(inputs) { // Parse expected input type. let expected_type = expected_input.type_(); From 7ce927ff7801b1f5144e375f3fa91e20eac855f5 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 1 Dec 2020 15:43:35 -0500 Subject: [PATCH 15/20] remove unused branch --- .../src/statement/assign/circuit_variable.rs | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/compiler/src/statement/assign/circuit_variable.rs b/compiler/src/statement/assign/circuit_variable.rs index 7574869703..c5d1a0ddcc 100644 --- a/compiler/src/statement/assign/circuit_variable.rs +++ b/compiler/src/statement/assign/circuit_variable.rs @@ -61,34 +61,6 @@ impl> ConstrainedProgram { span.to_owned(), )) } - ConstrainedValue::Mutable(value) => { - // Mutate the circuit variable's value in place - - // Check that the new value type == old value type - new_value.resolve_type(Some(value.to_type(span)?), span)?; - - // Conditionally select the value if this branch is executed. - let mut selected_value = ConstrainedValue::conditionally_select( - cs.ns(|| format!("select {} {}:{}", new_value, span.line, span.start)), - &condition, - &new_value, - &member.1, - ) - .map_err(|_| { - StatementError::select_fail( - new_value.to_string(), - member.1.to_string(), - span.to_owned(), - ) - })?; - - // Make sure the new value is still mutable - selected_value = ConstrainedValue::Mutable(Box::new(selected_value)); - - member.1 = selected_value.to_owned(); - - Ok(selected_value) - } value => { // Check that the new value type == old value type new_value.resolve_type(Some(value.to_type(span)?), span)?; From 74f7f24b193777cf7152c36dda24da6f6d4fc765 Mon Sep 17 00:00:00 2001 From: howardwu Date: Tue, 1 Dec 2020 22:57:11 -0400 Subject: [PATCH 16/20] chore(leo): bump version for new release --- Cargo.lock | 26 +++++++++++++------------- Cargo.toml | 18 +++++++++--------- ast/Cargo.toml | 6 +++--- compiler/Cargo.toml | 22 +++++++++++----------- core/Cargo.toml | 6 +++--- gadgets/Cargo.toml | 2 +- grammar/Cargo.toml | 2 +- imports/Cargo.toml | 22 +++++++++++----------- input/Cargo.toml | 2 +- leo/leo-version | 2 +- linter/Cargo.toml | 2 +- package/Cargo.toml | 2 +- state/Cargo.toml | 6 +++--- symbol-table/Cargo.toml | 22 +++++++++++----------- type-inference/Cargo.toml | 22 +++++++++++----------- 15 files changed, 81 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b44b12e21..67d4356b5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1296,7 +1296,7 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "leo-ast" -version = "1.0.4" +version = "1.0.5" dependencies = [ "criterion", "leo-grammar", @@ -1310,7 +1310,7 @@ dependencies = [ [[package]] name = "leo-compiler" -version = "1.0.4" +version = "1.0.5" dependencies = [ "bincode", "hex", @@ -1345,7 +1345,7 @@ dependencies = [ [[package]] name = "leo-core" -version = "1.0.4" +version = "1.0.5" dependencies = [ "leo-ast", "leo-gadgets", @@ -1361,7 +1361,7 @@ dependencies = [ [[package]] name = "leo-gadgets" -version = "1.0.4" +version = "1.0.5" dependencies = [ "criterion", "rand", @@ -1374,7 +1374,7 @@ dependencies = [ [[package]] name = "leo-grammar" -version = "1.0.4" +version = "1.0.5" dependencies = [ "criterion", "from-pest", @@ -1390,7 +1390,7 @@ dependencies = [ [[package]] name = "leo-imports" -version = "1.0.4" +version = "1.0.5" dependencies = [ "leo-ast", "leo-grammar", @@ -1400,7 +1400,7 @@ dependencies = [ [[package]] name = "leo-input" -version = "1.0.4" +version = "1.0.5" dependencies = [ "from-pest", "pest", @@ -1417,7 +1417,7 @@ dependencies = [ [[package]] name = "leo-lang" -version = "1.0.4" +version = "1.0.5" dependencies = [ "clap", "colored", @@ -1458,11 +1458,11 @@ dependencies = [ [[package]] name = "leo-linter" -version = "1.0.4" +version = "1.0.5" [[package]] name = "leo-package" -version = "1.0.4" +version = "1.0.5" dependencies = [ "lazy_static", "serde", @@ -1476,7 +1476,7 @@ dependencies = [ [[package]] name = "leo-state" -version = "1.0.4" +version = "1.0.5" dependencies = [ "leo-ast", "leo-input", @@ -1495,7 +1495,7 @@ dependencies = [ [[package]] name = "leo-symbol-table" -version = "1.0.4" +version = "1.0.5" dependencies = [ "leo-ast", "leo-core", @@ -1507,7 +1507,7 @@ dependencies = [ [[package]] name = "leo-type-inference" -version = "1.0.4" +version = "1.0.5" dependencies = [ "leo-ast", "leo-grammar", diff --git a/Cargo.toml b/Cargo.toml index b07b3f0a8b..7375e21117 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-lang" -version = "1.0.4" +version = "1.0.5" authors = [ "The Aleo Team " ] description = "The Leo programming language" homepage = "https://aleo.org" @@ -37,36 +37,36 @@ members = [ "package", "state", "symbol-table", - "type-inference", + "type-inference" ] [dependencies.leo-ast] path = "./ast" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-compiler] path = "./compiler" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-gadgets] path = "./gadgets" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-imports] path = "./imports" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-input] path = "./input" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-package] path = "./package" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-state] path = "./state" -version = "1.0.4" +version = "1.0.5" [dependencies.snarkos-algorithms] version = "1.1.3" diff --git a/ast/Cargo.toml b/ast/Cargo.toml index 49cc0ae71e..055ea6f6d4 100644 --- a/ast/Cargo.toml +++ b/ast/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-ast" -version = "1.0.4" +version = "1.0.5" authors = [ "The Aleo Team " ] description = "Core AST of the Leo programming language" homepage = "https://aleo.org" @@ -28,11 +28,11 @@ harness = false [dependencies.leo-grammar] path = "../grammar" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-input] path = "../input" -version = "1.0.4" +version = "1.0.5" [dependencies.snarkos-errors] version = "1.1.3" diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 7cb81be57c..88b69c7483 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-compiler" -version = "1.0.4" +version = "1.0.5" authors = [ "The Aleo Team " ] description = "Compiler of the Leo programming language" homepage = "https://aleo.org" @@ -19,43 +19,43 @@ edition = "2018" [dependencies.leo-ast] path = "../ast" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-core] path = "../core" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-gadgets] path = "../gadgets" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-grammar] path = "../grammar" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-imports] path = "../imports" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-input] path = "../input" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-package] path = "../package" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-state] path = "../state" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-symbol-table] path = "../symbol-table" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-type-inference] path = "../type-inference" -version = "1.0.4" +version = "1.0.5" [dependencies.snarkos-curves] version = "1.1.3" diff --git a/core/Cargo.toml b/core/Cargo.toml index f62744892d..595342e3b7 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-core" -version = "1.0.4" +version = "1.0.5" authors = [ "The Aleo Team " ] description = "Core package dependencies of the Leo programming language" homepage = "https://aleo.org" @@ -19,11 +19,11 @@ edition = "2018" [dependencies.leo-ast] path = "../ast" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-gadgets] path = "../gadgets" -version = "1.0.4" +version = "1.0.5" [dependencies.snarkos-errors] version = "1.1.3" diff --git a/gadgets/Cargo.toml b/gadgets/Cargo.toml index de97fc34d0..b51d65e0ca 100644 --- a/gadgets/Cargo.toml +++ b/gadgets/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-gadgets" -version = "1.0.4" +version = "1.0.5" authors = [ "The Aleo Team " ] description = "Gadgets of the Leo programming language" homepage = "https://aleo.org" diff --git a/grammar/Cargo.toml b/grammar/Cargo.toml index c33d877dba..2b0842baf7 100644 --- a/grammar/Cargo.toml +++ b/grammar/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-grammar" -version = "1.0.4" +version = "1.0.5" authors = [ "The Aleo Team " ] description = "AST generated by pest from the Leo grammar rules" homepage = "https://aleo.org" diff --git a/imports/Cargo.toml b/imports/Cargo.toml index 691215fec6..03383d14ad 100644 --- a/imports/Cargo.toml +++ b/imports/Cargo.toml @@ -1,32 +1,32 @@ [package] name = "leo-imports" -version = "1.0.4" -authors = [ "The Aleo Team "] +version = "1.0.5" +authors = [ "The Aleo Team " ] description = "Import parser for Leo program package dependencies" homepage = "https://aleo.org" repository = "https://github.com/AleoHQ/leo" keywords = [ - "aleo", - "cryptography", - "leo", - "programming-language", - "zero-knowledge" + "aleo", + "cryptography", + "leo", + "programming-language", + "zero-knowledge" ] categories = [ "cryptography::cryptocurrencies", "web-programming" ] -include = ["Cargo.toml", "src", "README.md", "LICENSE.md" ] +include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] license = "GPL-3.0" edition = "2018" [dependencies.leo-ast] path = "../ast" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-grammar] path = "../grammar" -version = "1.0.4" +version = "1.0.5" [dependencies.thiserror] version = "1.0" [dependencies.tracing] -version = "0.1" \ No newline at end of file +version = "0.1" diff --git a/input/Cargo.toml b/input/Cargo.toml index 20003c5fb2..c02d8a6390 100644 --- a/input/Cargo.toml +++ b/input/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-input" -version = "1.0.4" +version = "1.0.5" authors = [ "The Aleo Team " ] description = "Input parser of the Leo programming language" homepage = "https://aleo.org" diff --git a/leo/leo-version b/leo/leo-version index 3b9e5dbc90..c1757a8d60 100644 --- a/leo/leo-version +++ b/leo/leo-version @@ -1 +1 @@ -v1.0.4 \ No newline at end of file +v1.0.5 \ No newline at end of file diff --git a/linter/Cargo.toml b/linter/Cargo.toml index 8fafd81540..271981f6cc 100644 --- a/linter/Cargo.toml +++ b/linter/Cargo.toml @@ -2,7 +2,7 @@ dependencies = { } [package] name = "leo-linter" -version = "1.0.4" +version = "1.0.5" authors = [ "The Aleo Team " ] description = "Linter of the Leo programming language" homepage = "https://aleo.org" diff --git a/package/Cargo.toml b/package/Cargo.toml index dbe41fadbb..4d1d6470a1 100644 --- a/package/Cargo.toml +++ b/package/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-package" -version = "1.0.4" +version = "1.0.5" authors = [ "The Aleo Team " ] description = "Package parser of the Leo programming language" homepage = "https://aleo.org" diff --git a/state/Cargo.toml b/state/Cargo.toml index 6f8b9063b7..945da8a82d 100644 --- a/state/Cargo.toml +++ b/state/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-state" -version = "1.0.4" +version = "1.0.5" authors = [ "The Aleo Team " ] description = "State parser of the Leo programming language" homepage = "https://aleo.org" @@ -19,11 +19,11 @@ edition = "2018" [dependencies.leo-input] path = "../input" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-ast] path = "../ast" -version = "1.0.4" +version = "1.0.5" [dependencies.snarkos-algorithms] version = "1.1.3" diff --git a/symbol-table/Cargo.toml b/symbol-table/Cargo.toml index 0e821fd122..fe7987616b 100644 --- a/symbol-table/Cargo.toml +++ b/symbol-table/Cargo.toml @@ -1,16 +1,16 @@ [package] name = "leo-symbol-table" -version = "1.0.4" +version = "1.0.5" authors = [ "The Aleo Team " ] description = "Stores user-defined variables during type resolution" homepage = "https://aleo.org" repository = "https://github.com/AleoHQ/leo" keywords = [ - "aleo", - "cryptography", - "leo", - "programming-language", - "zero-knowledge" + "aleo", + "cryptography", + "leo", + "programming-language", + "zero-knowledge" ] categories = [ "cryptography::croptocurrencies", "web-programming" ] include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] @@ -19,22 +19,22 @@ edition = "2018" [dependencies.leo-ast] path = "../ast" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-core] path = "../core" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-grammar] path = "../grammar" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-imports] path = "../imports" -version = "1.0.4" +version = "1.0.5" [dependencies.serde] version = "1.0" [dependencies.thiserror] -version = "1.0" \ No newline at end of file +version = "1.0" diff --git a/type-inference/Cargo.toml b/type-inference/Cargo.toml index a0f38f7418..3b0e496a77 100644 --- a/type-inference/Cargo.toml +++ b/type-inference/Cargo.toml @@ -1,16 +1,16 @@ [package] name = "leo-type-inference" -version = "1.0.4" +version = "1.0.5" authors = [ "The Aleo Team " ] description = "Checks that a program is correct using type inference" homepage = "https://aleo.org" repository = "https://github.com/AleoHQ/leo" keywords = [ - "aleo", - "cryptography", - "leo", - "programming-language", - "zero-knowledge" + "aleo", + "cryptography", + "leo", + "programming-language", + "zero-knowledge" ] categories = [ "cryptography::croptocurrencies", "web-programming" ] include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] @@ -19,19 +19,19 @@ edition = "2018" [dependencies.leo-ast] path = "../ast" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-imports] path = "../imports" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-grammar] path = "../grammar" -version = "1.0.4" +version = "1.0.5" [dependencies.leo-symbol-table] path = "../symbol-table" -version = "1.0.4" +version = "1.0.5" [dependencies.serde_json] version = "1.0" @@ -40,4 +40,4 @@ version = "1.0" version = "1.0" [dependencies.thiserror] -version = "1.0" \ No newline at end of file +version = "1.0" From bac106b9616665e8b051a9d045a08764d30dac4f Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 2 Dec 2020 12:06:25 -0500 Subject: [PATCH 17/20] cargo clippy --- ast/benches/leo_ast.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ast/benches/leo_ast.rs b/ast/benches/leo_ast.rs index 72ab41037c..8c4bab6a53 100644 --- a/ast/benches/leo_ast.rs +++ b/ast/benches/leo_ast.rs @@ -20,64 +20,64 @@ use leo_grammar::Grammar; use criterion::{criterion_group, criterion_main, Criterion}; use std::{path::Path, time::Duration}; -fn ast<'ast>(ast: &Grammar<'ast>) -> Ast { +fn ast(ast: &Grammar) -> Ast { Ast::new("leo_tree", &ast) } fn bench_big_if_else(c: &mut Criterion) { let filepath = Path::new("./big_if_else.leo").to_path_buf(); let program_string = include_str!("./big_if_else.leo"); - let ast = Grammar::new(&filepath, program_string).unwrap(); + let grammar = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("Ast::big_if_else", |b| b.iter(|| ast(&ast))); + c.bench_function("Ast::big_if_else", |b| b.iter(|| ast(&grammar))); } fn bench_big_ternary(c: &mut Criterion) { let filepath = Path::new("./big_ternary.leo").to_path_buf(); let program_string = include_str!("./big_ternary.leo"); - let ast = Grammar::new(&filepath, program_string).unwrap(); + let grammar = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("Ast::big_ternary", |b| b.iter(|| ast(&ast))); + c.bench_function("Ast::big_ternary", |b| b.iter(|| ast(&grammar))); } fn bench_big_circuit(c: &mut Criterion) { let filepath = Path::new("./big_circuit.leo").to_path_buf(); let program_string = include_str!("./big_circuit.leo"); - let ast = Grammar::new(&filepath, program_string).unwrap(); + let grammar = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("Ast::big_circuit", |b| b.iter(|| ast(&ast))); + c.bench_function("Ast::big_circuit", |b| b.iter(|| ast(&grammar))); } fn bench_long_expr(c: &mut Criterion) { let filepath = Path::new("./long_expr.leo").to_path_buf(); let program_string = include_str!("./long_expr.leo"); - let ast = Grammar::new(&filepath, program_string).unwrap(); + let grammar = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("Ast::long_expr", |b| b.iter(|| ast(&ast))); + c.bench_function("Ast::long_expr", |b| b.iter(|| ast(&grammar))); } fn bench_long_array(c: &mut Criterion) { let filepath = Path::new("./long_array.leo").to_path_buf(); let program_string = include_str!("./long_array.leo"); - let ast = Grammar::new(&filepath, program_string).unwrap(); + let grammar = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("Ast::long_array", |b| b.iter(|| ast(&ast))); + c.bench_function("Ast::long_array", |b| b.iter(|| ast(&grammar))); } fn bench_many_foos(c: &mut Criterion) { let filepath = Path::new("./many_foos.leo").to_path_buf(); let program_string = include_str!("./many_foos.leo"); - let ast = Grammar::new(&filepath, program_string).unwrap(); + let grammar = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("Ast::many_foos", |b| b.iter(|| ast(&ast))); + c.bench_function("Ast::many_foos", |b| b.iter(|| ast(&grammar))); } fn bench_many_assigns(c: &mut Criterion) { let filepath = Path::new("./many_assigns.leo").to_path_buf(); let program_string = include_str!("./many_assigns.leo"); - let ast = Grammar::new(&filepath, program_string).unwrap(); + let grammar = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("Ast::many_assigns", |b| b.iter(|| ast(&ast))); + c.bench_function("Ast::many_assigns", |b| b.iter(|| ast(&grammar))); } criterion_group!( From 4e9c2253fef99844744785a0cb830001825d5dc9 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 2 Dec 2020 12:36:50 -0500 Subject: [PATCH 18/20] fix failing clippy check --- ast/src/input/input_value.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ast/src/input/input_value.rs b/ast/src/input/input_value.rs index 1f6124e518..975b99dd17 100644 --- a/ast/src/input/input_value.rs +++ b/ast/src/input/input_value.rs @@ -53,8 +53,8 @@ impl InputValue { Ok(InputValue::Boolean(boolean)) } - fn from_number(integer_type: IntegerType, number: String) -> Result { - Ok(InputValue::Integer(integer_type, number)) + fn from_number(integer_type: IntegerType, number: String) -> Self { + InputValue::Integer(integer_type, number) } fn from_group(group: InputGroupValue) -> Self { @@ -69,7 +69,7 @@ impl InputValue { match data_type { DataType::Address(_) => Err(InputParserError::implicit_type(data_type, implicit)), DataType::Boolean(_) => Err(InputParserError::implicit_type(data_type, implicit)), - DataType::Integer(integer_type) => InputValue::from_number(integer_type, implicit.to_string()), + DataType::Integer(integer_type) => Ok(InputValue::from_number(integer_type, implicit.to_string())), DataType::Group(_) => Err(InputParserError::implicit_group(implicit)), DataType::Field(_) => Ok(InputValue::Field(implicit.to_string())), } @@ -80,7 +80,7 @@ impl InputValue { (DataType::Address(_), Value::Address(address)) => Ok(InputValue::from_address_value(address)), (DataType::Boolean(_), Value::Boolean(boolean)) => InputValue::from_boolean(boolean), (DataType::Integer(integer_type), Value::Integer(integer)) => { - InputValue::from_number(integer_type, integer.to_string()) + Ok(InputValue::from_number(integer_type, integer.to_string())) } (DataType::Group(_), Value::Group(group)) => Ok(InputValue::from_group(group)), (DataType::Field(_), Value::Field(field)) => Ok(InputValue::from_field(field)), From dbae691e4943718df04a16fdf7967d2cf0ee181d Mon Sep 17 00:00:00 2001 From: howardwu Date: Thu, 3 Dec 2020 16:16:42 -0400 Subject: [PATCH 19/20] chore(leo): bump version for new release --- Cargo.lock | 26 +++++++++++++------------- Cargo.toml | 16 ++++++++-------- ast/Cargo.toml | 6 +++--- compiler/Cargo.toml | 22 +++++++++++----------- core/Cargo.toml | 6 +++--- gadgets/Cargo.toml | 2 +- grammar/Cargo.toml | 2 +- imports/Cargo.toml | 6 +++--- input/Cargo.toml | 2 +- leo/leo-version | 2 +- linter/Cargo.toml | 2 +- package/Cargo.toml | 2 +- state/Cargo.toml | 6 +++--- symbol-table/Cargo.toml | 10 +++++----- type-inference/Cargo.toml | 10 +++++----- 15 files changed, 60 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 67d4356b5c..d04a8d65f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1296,7 +1296,7 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "leo-ast" -version = "1.0.5" +version = "1.0.6" dependencies = [ "criterion", "leo-grammar", @@ -1310,7 +1310,7 @@ dependencies = [ [[package]] name = "leo-compiler" -version = "1.0.5" +version = "1.0.6" dependencies = [ "bincode", "hex", @@ -1345,7 +1345,7 @@ dependencies = [ [[package]] name = "leo-core" -version = "1.0.5" +version = "1.0.6" dependencies = [ "leo-ast", "leo-gadgets", @@ -1361,7 +1361,7 @@ dependencies = [ [[package]] name = "leo-gadgets" -version = "1.0.5" +version = "1.0.6" dependencies = [ "criterion", "rand", @@ -1374,7 +1374,7 @@ dependencies = [ [[package]] name = "leo-grammar" -version = "1.0.5" +version = "1.0.6" dependencies = [ "criterion", "from-pest", @@ -1390,7 +1390,7 @@ dependencies = [ [[package]] name = "leo-imports" -version = "1.0.5" +version = "1.0.6" dependencies = [ "leo-ast", "leo-grammar", @@ -1400,7 +1400,7 @@ dependencies = [ [[package]] name = "leo-input" -version = "1.0.5" +version = "1.0.6" dependencies = [ "from-pest", "pest", @@ -1417,7 +1417,7 @@ dependencies = [ [[package]] name = "leo-lang" -version = "1.0.5" +version = "1.0.6" dependencies = [ "clap", "colored", @@ -1458,11 +1458,11 @@ dependencies = [ [[package]] name = "leo-linter" -version = "1.0.5" +version = "1.0.6" [[package]] name = "leo-package" -version = "1.0.5" +version = "1.0.6" dependencies = [ "lazy_static", "serde", @@ -1476,7 +1476,7 @@ dependencies = [ [[package]] name = "leo-state" -version = "1.0.5" +version = "1.0.6" dependencies = [ "leo-ast", "leo-input", @@ -1495,7 +1495,7 @@ dependencies = [ [[package]] name = "leo-symbol-table" -version = "1.0.5" +version = "1.0.6" dependencies = [ "leo-ast", "leo-core", @@ -1507,7 +1507,7 @@ dependencies = [ [[package]] name = "leo-type-inference" -version = "1.0.5" +version = "1.0.6" dependencies = [ "leo-ast", "leo-grammar", diff --git a/Cargo.toml b/Cargo.toml index 7375e21117..970e89f51e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-lang" -version = "1.0.5" +version = "1.0.6" authors = [ "The Aleo Team " ] description = "The Leo programming language" homepage = "https://aleo.org" @@ -42,31 +42,31 @@ members = [ [dependencies.leo-ast] path = "./ast" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-compiler] path = "./compiler" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-gadgets] path = "./gadgets" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-imports] path = "./imports" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-input] path = "./input" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-package] path = "./package" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-state] path = "./state" -version = "1.0.5" +version = "1.0.6" [dependencies.snarkos-algorithms] version = "1.1.3" diff --git a/ast/Cargo.toml b/ast/Cargo.toml index 055ea6f6d4..eec77394f0 100644 --- a/ast/Cargo.toml +++ b/ast/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-ast" -version = "1.0.5" +version = "1.0.6" authors = [ "The Aleo Team " ] description = "Core AST of the Leo programming language" homepage = "https://aleo.org" @@ -28,11 +28,11 @@ harness = false [dependencies.leo-grammar] path = "../grammar" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-input] path = "../input" -version = "1.0.5" +version = "1.0.6" [dependencies.snarkos-errors] version = "1.1.3" diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 88b69c7483..cbf0636741 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-compiler" -version = "1.0.5" +version = "1.0.6" authors = [ "The Aleo Team " ] description = "Compiler of the Leo programming language" homepage = "https://aleo.org" @@ -19,43 +19,43 @@ edition = "2018" [dependencies.leo-ast] path = "../ast" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-core] path = "../core" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-gadgets] path = "../gadgets" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-grammar] path = "../grammar" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-imports] path = "../imports" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-input] path = "../input" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-package] path = "../package" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-state] path = "../state" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-symbol-table] path = "../symbol-table" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-type-inference] path = "../type-inference" -version = "1.0.5" +version = "1.0.6" [dependencies.snarkos-curves] version = "1.1.3" diff --git a/core/Cargo.toml b/core/Cargo.toml index 595342e3b7..e864dfbb6c 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-core" -version = "1.0.5" +version = "1.0.6" authors = [ "The Aleo Team " ] description = "Core package dependencies of the Leo programming language" homepage = "https://aleo.org" @@ -19,11 +19,11 @@ edition = "2018" [dependencies.leo-ast] path = "../ast" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-gadgets] path = "../gadgets" -version = "1.0.5" +version = "1.0.6" [dependencies.snarkos-errors] version = "1.1.3" diff --git a/gadgets/Cargo.toml b/gadgets/Cargo.toml index b51d65e0ca..650c5ee8ec 100644 --- a/gadgets/Cargo.toml +++ b/gadgets/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-gadgets" -version = "1.0.5" +version = "1.0.6" authors = [ "The Aleo Team " ] description = "Gadgets of the Leo programming language" homepage = "https://aleo.org" diff --git a/grammar/Cargo.toml b/grammar/Cargo.toml index 2b0842baf7..3dec5aa9ed 100644 --- a/grammar/Cargo.toml +++ b/grammar/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-grammar" -version = "1.0.5" +version = "1.0.6" authors = [ "The Aleo Team " ] description = "AST generated by pest from the Leo grammar rules" homepage = "https://aleo.org" diff --git a/imports/Cargo.toml b/imports/Cargo.toml index 03383d14ad..3a4bd13771 100644 --- a/imports/Cargo.toml +++ b/imports/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-imports" -version = "1.0.5" +version = "1.0.6" authors = [ "The Aleo Team " ] description = "Import parser for Leo program package dependencies" homepage = "https://aleo.org" @@ -19,11 +19,11 @@ edition = "2018" [dependencies.leo-ast] path = "../ast" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-grammar] path = "../grammar" -version = "1.0.5" +version = "1.0.6" [dependencies.thiserror] version = "1.0" diff --git a/input/Cargo.toml b/input/Cargo.toml index c02d8a6390..cb22145186 100644 --- a/input/Cargo.toml +++ b/input/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-input" -version = "1.0.5" +version = "1.0.6" authors = [ "The Aleo Team " ] description = "Input parser of the Leo programming language" homepage = "https://aleo.org" diff --git a/leo/leo-version b/leo/leo-version index c1757a8d60..6df8b11430 100644 --- a/leo/leo-version +++ b/leo/leo-version @@ -1 +1 @@ -v1.0.5 \ No newline at end of file +v1.0.6 \ No newline at end of file diff --git a/linter/Cargo.toml b/linter/Cargo.toml index 271981f6cc..502578d2dc 100644 --- a/linter/Cargo.toml +++ b/linter/Cargo.toml @@ -2,7 +2,7 @@ dependencies = { } [package] name = "leo-linter" -version = "1.0.5" +version = "1.0.6" authors = [ "The Aleo Team " ] description = "Linter of the Leo programming language" homepage = "https://aleo.org" diff --git a/package/Cargo.toml b/package/Cargo.toml index 4d1d6470a1..f1a1befb49 100644 --- a/package/Cargo.toml +++ b/package/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-package" -version = "1.0.5" +version = "1.0.6" authors = [ "The Aleo Team " ] description = "Package parser of the Leo programming language" homepage = "https://aleo.org" diff --git a/state/Cargo.toml b/state/Cargo.toml index 945da8a82d..e2a3f143ea 100644 --- a/state/Cargo.toml +++ b/state/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-state" -version = "1.0.5" +version = "1.0.6" authors = [ "The Aleo Team " ] description = "State parser of the Leo programming language" homepage = "https://aleo.org" @@ -19,11 +19,11 @@ edition = "2018" [dependencies.leo-input] path = "../input" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-ast] path = "../ast" -version = "1.0.5" +version = "1.0.6" [dependencies.snarkos-algorithms] version = "1.1.3" diff --git a/symbol-table/Cargo.toml b/symbol-table/Cargo.toml index fe7987616b..809f0de36f 100644 --- a/symbol-table/Cargo.toml +++ b/symbol-table/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-symbol-table" -version = "1.0.5" +version = "1.0.6" authors = [ "The Aleo Team " ] description = "Stores user-defined variables during type resolution" homepage = "https://aleo.org" @@ -19,19 +19,19 @@ edition = "2018" [dependencies.leo-ast] path = "../ast" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-core] path = "../core" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-grammar] path = "../grammar" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-imports] path = "../imports" -version = "1.0.5" +version = "1.0.6" [dependencies.serde] version = "1.0" diff --git a/type-inference/Cargo.toml b/type-inference/Cargo.toml index 3b0e496a77..4728d0e3d9 100644 --- a/type-inference/Cargo.toml +++ b/type-inference/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-type-inference" -version = "1.0.5" +version = "1.0.6" authors = [ "The Aleo Team " ] description = "Checks that a program is correct using type inference" homepage = "https://aleo.org" @@ -19,19 +19,19 @@ edition = "2018" [dependencies.leo-ast] path = "../ast" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-imports] path = "../imports" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-grammar] path = "../grammar" -version = "1.0.5" +version = "1.0.6" [dependencies.leo-symbol-table] path = "../symbol-table" -version = "1.0.5" +version = "1.0.6" [dependencies.serde_json] version = "1.0" From f1bd5399a1119449675da31813a510f1821a8c69 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 4 Dec 2020 16:47:03 -0500 Subject: [PATCH 20/20] cargo clippy --- ast/src/functions/function.rs | 4 ++-- compiler/src/statement/branch/branch.rs | 3 +++ symbol-table/src/types/functions/function.rs | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ast/src/functions/function.rs b/ast/src/functions/function.rs index c6a92c3a6f..c55daf03d3 100644 --- a/ast/src/functions/function.rs +++ b/ast/src/functions/function.rs @@ -65,7 +65,7 @@ impl Function { /// Returns `false` otherwise. /// pub fn contains_self(&self) -> bool { - self.input.iter().find(|param| param.is_self()).is_some() + self.input.iter().any(|param| param.is_self()) } /// @@ -73,7 +73,7 @@ impl Function { /// Returns `false` otherwise. /// pub fn contains_mut_self(&self) -> bool { - self.input.iter().find(|param| param.is_mut_self()).is_some() + self.input.iter().any(|param| param.is_mut_self()) } /// diff --git a/compiler/src/statement/branch/branch.rs b/compiler/src/statement/branch/branch.rs index af4d804440..a8e80a7945 100644 --- a/compiler/src/statement/branch/branch.rs +++ b/compiler/src/statement/branch/branch.rs @@ -25,6 +25,9 @@ use snarkos_models::{ }; impl> ConstrainedProgram { + /// Evaluates a branch of one or more statements and returns a result in + /// the given scope. + #[allow(clippy::too_many_arguments)] pub fn evaluate_branch>( &mut self, cs: &mut CS, diff --git a/symbol-table/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs index 194ab7a72e..ffc35fde98 100644 --- a/symbol-table/src/types/functions/function.rs +++ b/symbol-table/src/types/functions/function.rs @@ -135,7 +135,7 @@ impl FunctionType { /// Returns `false` otherwise. /// pub fn contains_self(&self) -> bool { - self.inputs.iter().find(|param| param.is_self()).is_some() + self.inputs.iter().any(|param| param.is_self()) } ///