mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-01 10:17:30 +03:00
Merge pull request #1136 from AleoHQ/bug/misc-bugs
[Bugfix] printing/outputs, windows warnings, constant inputs
This commit is contained in:
commit
64ad6a67f3
5
.gitignore
vendored
5
.gitignore
vendored
@ -8,3 +8,8 @@
|
||||
**/.crates.toml
|
||||
**/.crates2.json
|
||||
**/bin/
|
||||
|
||||
# Emacs gitignore files
|
||||
*~
|
||||
\#*\#
|
||||
.\#*
|
||||
|
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -2801,9 +2801,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.2.18"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa5553bf0883ba7c9cbe493b085c29926bd41b66afc31ff72cf17ff4fb60dcd5"
|
||||
checksum = "ab69019741fca4d98be3c62d2b75254528b5432233fd8a4d2739fec20278de48"
|
||||
dependencies = [
|
||||
"ansi_term 0.12.1",
|
||||
"chrono",
|
||||
|
@ -149,7 +149,7 @@ version = "0.5"
|
||||
version = "0.1"
|
||||
|
||||
[dependencies.tracing-subscriber]
|
||||
version = "0.2"
|
||||
version = "0.2.19"
|
||||
features = [ "fmt" ]
|
||||
|
||||
[dependencies.zip]
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use leo_ast::{FormattedError, IntegerType, LeoError, Span};
|
||||
use leo_ast::{FormattedError, LeoError, Span};
|
||||
|
||||
use snarkvm_gadgets::errors::{SignedIntegerError, UnsignedIntegerError};
|
||||
use snarkvm_r1cs::SynthesisError;
|
||||
@ -68,7 +68,7 @@ impl IntegerError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn integer_type_mismatch(expected: &IntegerType, received: IntegerType, span: &Span) -> Self {
|
||||
pub fn integer_type_mismatch(expected: String, received: String, span: &Span) -> Self {
|
||||
let message = format!("expected data type `{}`, found `{}`", expected, received);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{
|
||||
address::Address,
|
||||
errors::FunctionError,
|
||||
errors::{FunctionError, IntegerError},
|
||||
program::ConstrainedProgram,
|
||||
value::{
|
||||
boolean::input::bool_from_input,
|
||||
@ -101,9 +101,19 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
Ok(ConstrainedValue::Field(FieldType::constant(cs, value, span)?))
|
||||
}
|
||||
(Type::Group, InputValue::Group(value)) => Ok(ConstrainedValue::Group(G::constant(&value.into(), span)?)),
|
||||
(Type::Integer(integer_type), InputValue::Integer(_, value)) => Ok(ConstrainedValue::Integer(
|
||||
Integer::new(&ConstInt::parse(integer_type, &value, span)?),
|
||||
)),
|
||||
(Type::Integer(integer_type), InputValue::Integer(input_type, value)) => {
|
||||
let parsed = ConstInt::parse(integer_type, &value, span)?;
|
||||
let parsed_type = parsed.get_int_type();
|
||||
let input_type = input_type.into();
|
||||
if std::mem::discriminant(&parsed_type) != std::mem::discriminant(&input_type) {
|
||||
return Err(FunctionError::from(IntegerError::integer_type_mismatch(
|
||||
input_type.to_string(),
|
||||
parsed_type.to_string(),
|
||||
span,
|
||||
)));
|
||||
}
|
||||
Ok(ConstrainedValue::Integer(Integer::new(&parsed)))
|
||||
}
|
||||
(Type::Array(type_, arr_len), InputValue::Array(values)) => {
|
||||
if *arr_len != values.len() {
|
||||
return Err(FunctionError::invalid_input_array_dimensions(
|
||||
|
@ -247,6 +247,9 @@ impl<F: PrimeField> ToBytesGadget<F> for FieldType<F> {
|
||||
|
||||
impl<F: PrimeField> std::fmt::Display for FieldType<F> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{:?}", self.get_value().ok_or(std::fmt::Error))
|
||||
match self.get_value().ok_or(std::fmt::Error) {
|
||||
Ok(value) => write!(f, "{}", value),
|
||||
value => write!(f, "{:?}", value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -539,8 +539,11 @@ impl One for EdwardsGroupType {
|
||||
impl std::fmt::Display for EdwardsGroupType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
EdwardsGroupType::Constant(constant) => write!(f, "{:?}", constant),
|
||||
EdwardsGroupType::Allocated(allocated) => write!(f, "{:?}", allocated),
|
||||
EdwardsGroupType::Constant(constant) => write!(f, "({}, {})group", constant.x, constant.y),
|
||||
EdwardsGroupType::Allocated(allocated) => match (allocated.x.get_value(), allocated.y.get_value()) {
|
||||
(Some(x), Some(y)) => write!(f, "({}, {})group", x, y),
|
||||
allocated => write!(f, "{:?}", allocated),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,11 @@ impl Integer {
|
||||
if let InputValue::Integer(type_, number) = input {
|
||||
let asg_type = IntegerType::from(type_);
|
||||
if std::mem::discriminant(&asg_type) != std::mem::discriminant(integer_type) {
|
||||
return Err(IntegerError::integer_type_mismatch(integer_type, asg_type, span));
|
||||
return Err(IntegerError::integer_type_mismatch(
|
||||
integer_type.to_string(),
|
||||
asg_type.to_string(),
|
||||
span,
|
||||
));
|
||||
}
|
||||
Some(number)
|
||||
} else {
|
||||
|
@ -96,8 +96,8 @@ impl<'a, F: PrimeField, G: GroupType<F>> fmt::Display for ConstrainedValue<'a, F
|
||||
.unwrap_or_else(|| "[allocated]".to_string())
|
||||
),
|
||||
ConstrainedValue::Char(ref value) => write!(f, "{}", value),
|
||||
ConstrainedValue::Field(ref value) => write!(f, "{:?}", value),
|
||||
ConstrainedValue::Group(ref value) => write!(f, "{:?}", value),
|
||||
ConstrainedValue::Field(ref value) => write!(f, "{}", value),
|
||||
ConstrainedValue::Group(ref value) => write!(f, "{}", value),
|
||||
ConstrainedValue::Integer(ref value) => write!(f, "{}", value),
|
||||
|
||||
// Data type wrappers
|
||||
|
@ -38,6 +38,8 @@ use tracing::span::Span;
|
||||
/// require Build command output as their input.
|
||||
#[derive(StructOpt, Clone, Debug)]
|
||||
pub struct BuildOptions {
|
||||
#[structopt(long, help = "Disable canonicaliztion compiler optimization")]
|
||||
pub disable_canonicalization: bool,
|
||||
#[structopt(long, help = "Disable constant folding compiler optimization")]
|
||||
pub disable_constant_folding: bool,
|
||||
#[structopt(long, help = "Disable dead code elimination compiler optimization")]
|
||||
@ -57,6 +59,7 @@ pub struct BuildOptions {
|
||||
impl Default for BuildOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
disable_canonicalization: true,
|
||||
disable_constant_folding: true,
|
||||
disable_code_elimination: true,
|
||||
disable_all_optimizations: true,
|
||||
@ -78,7 +81,7 @@ impl From<BuildOptions> for CompilerOptions {
|
||||
}
|
||||
} else {
|
||||
CompilerOptions {
|
||||
canonicalization_enabled: true,
|
||||
canonicalization_enabled: !options.disable_canonicalization,
|
||||
constant_folding_enabled: !options.disable_constant_folding,
|
||||
dead_code_elimination_enabled: !options.disable_code_elimination,
|
||||
}
|
||||
@ -162,6 +165,12 @@ impl Command for Build {
|
||||
// Log compilation of files to console
|
||||
tracing::info!("Compiling main program... ({:?})", main_file_path);
|
||||
|
||||
if self.compiler_options.disable_canonicalization && self.compiler_options.enable_canonicalized_theorem {
|
||||
tracing::warn!(
|
||||
"Can not ask for canonicalization theorem without having canonicalization compiler feature enabled."
|
||||
);
|
||||
}
|
||||
|
||||
// Load the program at `main_file_path`
|
||||
let program = Compiler::<Fq, EdwardsGroupType>::parse_program_with_input(
|
||||
package_name.clone(),
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
use std::{fmt, sync::Once};
|
||||
|
||||
use anyhow::Result;
|
||||
use colored::Colorize;
|
||||
use tracing::{event::Event, subscriber::Subscriber};
|
||||
use tracing_subscriber::{
|
||||
@ -181,17 +182,23 @@ where
|
||||
|
||||
let mut message = "".to_string();
|
||||
|
||||
let scope = context.scope();
|
||||
for span in scope {
|
||||
message += span.metadata().name();
|
||||
match context.lookup_current() {
|
||||
Some(span_ref) => {
|
||||
let scope = span_ref.scope();
|
||||
|
||||
let ext = span.extensions();
|
||||
let fields = &ext
|
||||
.get::<FormattedFields<N>>()
|
||||
.expect("Unable to find FormattedFields in extensions; this is a bug");
|
||||
if !fields.is_empty() {
|
||||
message += &format!("{{{}}}", fields);
|
||||
for span in scope {
|
||||
message += span.metadata().name();
|
||||
|
||||
let ext = span.extensions();
|
||||
let fields = &ext
|
||||
.get::<FormattedFields<N>>()
|
||||
.expect("Unable to find FormattedFields in extensions; this is a bug");
|
||||
if !fields.is_empty() {
|
||||
message += &format!("{{{}}}", fields);
|
||||
}
|
||||
}
|
||||
}
|
||||
None => return Err(std::fmt::Error),
|
||||
}
|
||||
|
||||
write!(writer, "{:>10} ", colored_string(meta.level(), &message)).expect("Error writing event");
|
||||
@ -203,10 +210,13 @@ where
|
||||
}
|
||||
|
||||
/// Initialize logger with custom format and verbosity.
|
||||
pub fn init_logger(_app_name: &'static str, verbosity: usize) {
|
||||
pub fn init_logger(_app_name: &'static str, verbosity: usize) -> Result<()> {
|
||||
// This line enables Windows 10 ANSI coloring API.
|
||||
#[cfg(target_family = "windows")]
|
||||
ansi_term::enable_ansi_support();
|
||||
match ansi_term::enable_ansi_support() {
|
||||
Ok(_) => {}
|
||||
Err(_) => return Err(anyhow::anyhow!("Error: Failed to enable ansi_support")),
|
||||
};
|
||||
|
||||
let subscriber = FmtSubscriber::builder()
|
||||
// all spans/events with a level higher than TRACE (e.g, debug, info, warn, etc.)
|
||||
@ -226,4 +236,5 @@ pub fn init_logger(_app_name: &'static str, verbosity: usize) {
|
||||
START.call_once(|| {
|
||||
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
12
leo/main.rs
12
leo/main.rs
@ -38,7 +38,7 @@ use commands::{
|
||||
Watch,
|
||||
};
|
||||
|
||||
use anyhow::Error;
|
||||
use anyhow::Result;
|
||||
use std::{path::PathBuf, process::exit};
|
||||
use structopt::{clap::AppSettings, StructOpt};
|
||||
|
||||
@ -185,13 +185,13 @@ fn main() {
|
||||
}
|
||||
|
||||
/// Run command with custom build arguments.
|
||||
fn run_with_args(opt: Opt) -> Result<(), Error> {
|
||||
fn run_with_args(opt: Opt) -> Result<()> {
|
||||
if !opt.quiet {
|
||||
// Init logger with optional debug flag.
|
||||
logger::init_logger("leo", match opt.debug {
|
||||
false => 1,
|
||||
true => 2,
|
||||
});
|
||||
})?;
|
||||
}
|
||||
|
||||
// Get custom root folder and create context for it.
|
||||
@ -225,7 +225,7 @@ fn run_with_args(opt: Opt) -> Result<(), Error> {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_error<T>(res: Result<T, Error>) -> T {
|
||||
fn handle_error<T>(res: Result<T>) -> T {
|
||||
match res {
|
||||
Ok(t) => t,
|
||||
Err(err) => {
|
||||
@ -239,13 +239,13 @@ fn handle_error<T>(res: Result<T, Error>) -> T {
|
||||
mod cli_tests {
|
||||
use crate::{run_with_args, Opt};
|
||||
|
||||
use anyhow::Error;
|
||||
use anyhow::Result;
|
||||
use std::path::PathBuf;
|
||||
use structopt::StructOpt;
|
||||
use test_dir::{DirBuilder, FileType, TestDir};
|
||||
|
||||
// Runs Command from cmd-like argument "leo run --arg1 --arg2".
|
||||
fn run_cmd(args: &str, path: &Option<PathBuf>) -> Result<(), Error> {
|
||||
fn run_cmd(args: &str, path: &Option<PathBuf>) -> Result<()> {
|
||||
let args = args.split(' ').collect::<Vec<&str>>();
|
||||
let mut opts = Opt::from_iter_safe(args)?;
|
||||
|
||||
|
@ -36,6 +36,19 @@ use crate::{
|
||||
/// - relative to source dir - where Cargo.toml is located
|
||||
const PEDERSEN_HASH_PATH: &str = "./examples/pedersen-hash/";
|
||||
|
||||
#[test]
|
||||
pub fn init_logger() -> Result<()> {
|
||||
crate::logger::init_logger("test_init_logger", 1)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn format_event() -> Result<()> {
|
||||
crate::logger::init_logger("test_format_event", 1)?;
|
||||
tracing::info!("test");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn build_pedersen_hash() -> Result<()> {
|
||||
(Build {
|
||||
|
@ -0,0 +1,9 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
input_file: input/const_input_non_const.in
|
||||
*/
|
||||
|
||||
function main(a: u32) {
|
||||
let b = a * 2;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
input_file: input/var_in_both_sections_fail.in
|
||||
*/
|
||||
|
||||
function main(const a: u32) {
|
||||
let b = a * 2;
|
||||
}
|
@ -1,9 +1,7 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
input_file: input/different_types_signed_fail.in
|
||||
input_file: input/different_types_const_signed_fail.in
|
||||
input_file: input/main_fail_type.in
|
||||
*/
|
||||
|
||||
function main(const a: i32) {
|
@ -2,8 +2,6 @@
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
input_file: input/different_types_const_unsigned_fail.in
|
||||
input_file: input/different_types_unsigned_fail.in
|
||||
input_file: input/main_fail_type.in
|
||||
*/
|
||||
|
||||
function main(const a: u32) {
|
@ -1,9 +1,7 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
input_file: input/different_types_signed_fail.in
|
||||
input_file: input/different_types_const_signed_fail.in
|
||||
input_file: input/var_in_both_sections_fail.in
|
||||
input_file: input/different_types_fail_signed.in
|
||||
*/
|
||||
|
||||
function main(a: i32) {
|
||||
|
@ -1,9 +1,7 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
input_file: input/different_types_const_unsigned_fail.in
|
||||
input_file: input/different_types_unsigned_fail.in
|
||||
input_file: input/var_in_both_sections_fail.in
|
||||
*/
|
||||
|
||||
function main(a: u32) {
|
@ -0,0 +1,2 @@
|
||||
[constants]
|
||||
a: u32 = 2;
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: u32 = 2;
|
@ -0,0 +1,9 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
input_file: input/non_const_input_const.in
|
||||
*/
|
||||
|
||||
function main(aconst : u32) {
|
||||
let b = a * 2;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
input_file: input/var_in_both_sections_fail.in
|
||||
*/
|
||||
|
||||
function main(a: u32) {
|
||||
let b = a * 2;
|
||||
}
|
@ -2,4 +2,4 @@
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:21\n |\n 3 | function main(const a: i32) {\n | ^\n |\n = Expected input variable `a` to be constant. Move input variable `a` to [constants] section of input file"
|
||||
- aborting due to syntax error
|
||||
|
@ -2,4 +2,4 @@
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:21\n |\n 3 | function main(const a: u32) {\n | ^\n |\n = Expected input variable `a` to be constant. Move input variable `a` to [constants] section of input file"
|
||||
- aborting due to syntax error
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:15\n |\n 3 | function main(a: u32) {\n | ^\n |\n = Expected input variable `a` to be non-constant. Move input variable `a` to [main] section of input file"
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:21\n |\n 3 | function main(const a: u32) {\n | ^\n |\n = Input variable a declared twice"
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- aborting due to syntax error
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- aborting due to syntax error
|
@ -2,4 +2,4 @@
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:15\n |\n 3 | function main(a: i32) {\n | ^\n |\n = Input variable a declared twice"
|
||||
- aborting due to syntax error
|
||||
|
@ -2,4 +2,4 @@
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:15\n |\n 3 | function main(a: u32) {\n | ^\n |\n = Input variable a declared twice"
|
||||
- aborting due to syntax error
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- aborting due to syntax error
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:4:17\n |\n 4 | let b = a * 2;\n | ^\n |\n = failed to resolve type for variable definition 'unknown'"
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:15\n |\n 3 | function main(a: u32) {\n | ^\n |\n = Input variable a declared twice"
|
Loading…
Reference in New Issue
Block a user