mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-24 10:52:29 +03:00
Merge pull request #1054 from AleoHQ/bugs/1040-1041-input-bugs
input bugs fixes
This commit is contained in:
commit
214c5b21c9
@ -26,6 +26,7 @@ use leo_input::{
|
||||
CharValue as InputCharValue,
|
||||
FieldValue,
|
||||
GroupValue as InputGroupValue,
|
||||
IntegerValue,
|
||||
NumberValue,
|
||||
Value,
|
||||
},
|
||||
@ -102,6 +103,32 @@ impl InputValue {
|
||||
(DataType::Boolean(_), Value::Boolean(boolean)) => InputValue::from_boolean(boolean),
|
||||
(DataType::Char(_), Value::Char(character)) => InputValue::from_char(character),
|
||||
(DataType::Integer(integer_type), Value::Integer(integer)) => {
|
||||
match integer.clone() {
|
||||
IntegerValue::Signed(signed) => {
|
||||
if let IntegerType::Signed(inner) = integer_type.clone() {
|
||||
let singed_type = signed.clone().type_;
|
||||
if std::mem::discriminant(&inner) != std::mem::discriminant(&singed_type) {
|
||||
return Err(InputParserError::integer_type_mismatch(
|
||||
integer_type,
|
||||
IntegerType::Signed(singed_type),
|
||||
integer.span(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
IntegerValue::Unsigned(unsigned) => {
|
||||
if let IntegerType::Unsigned(inner) = integer_type.clone() {
|
||||
let unsinged_type = unsigned.clone().type_;
|
||||
if std::mem::discriminant(&inner) != std::mem::discriminant(&unsinged_type) {
|
||||
return Err(InputParserError::integer_type_mismatch(
|
||||
integer_type,
|
||||
IntegerType::Unsigned(unsinged_type),
|
||||
integer.span(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(InputValue::from_number(integer_type, integer.to_string()))
|
||||
}
|
||||
(DataType::Group(_), Value::Group(group)) => Ok(InputValue::from_group(group)),
|
||||
|
@ -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, LeoError, Span};
|
||||
use leo_ast::{FormattedError, IntegerType, LeoError, Span};
|
||||
|
||||
use snarkvm_gadgets::errors::{SignedIntegerError, UnsignedIntegerError};
|
||||
use snarkvm_r1cs::SynthesisError;
|
||||
@ -68,6 +68,12 @@ impl IntegerError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn integer_type_mismatch(expected: &IntegerType, received: IntegerType, span: &Span) -> Self {
|
||||
let message = format!("expected data type `{}`, found `{}`", expected, received);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_integer(actual: String, span: &Span) -> Self {
|
||||
let message = format!("failed to parse `{}` as expected integer type", actual);
|
||||
|
||||
|
@ -67,7 +67,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
(_, Some(_), Some(_)) => {
|
||||
return Err(FunctionError::double_input_declaration(
|
||||
name.to_string(),
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
&input_variable.name.span,
|
||||
));
|
||||
}
|
||||
// If input option is found in [main] section and input is not const.
|
||||
@ -76,7 +76,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
&input_variable.type_.clone(),
|
||||
&name,
|
||||
input_option,
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
&input_variable.name.span,
|
||||
)?,
|
||||
// If input option is found in [constants] section and function argument is const.
|
||||
(true, _, Some(input_option)) => self.constant_main_function_input(
|
||||
@ -84,27 +84,27 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
&input_variable.type_.clone(),
|
||||
&name,
|
||||
input_option,
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
&input_variable.name.span,
|
||||
)?,
|
||||
// Function argument is const, input is not.
|
||||
(true, Some(_), None) => {
|
||||
return Err(FunctionError::expected_const_input(
|
||||
name.to_string(),
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
&input_variable.name.span,
|
||||
));
|
||||
}
|
||||
// Input is const, function argument is not.
|
||||
(false, None, Some(_)) => {
|
||||
return Err(FunctionError::expected_non_const_input(
|
||||
name.to_string(),
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
&input_variable.name.span,
|
||||
));
|
||||
}
|
||||
// When not found - Error out.
|
||||
(_, _, _) => {
|
||||
return Err(FunctionError::input_not_found(
|
||||
name.to_string(),
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
&input_variable.name.span,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
@ -157,7 +157,11 @@ impl Integer {
|
||||
// Check that the input value is the correct type
|
||||
let option = match integer_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Integer(_type_, number) = input {
|
||||
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));
|
||||
}
|
||||
Some(number)
|
||||
} else {
|
||||
return Err(IntegerError::invalid_integer(input.to_string(), span));
|
||||
|
@ -128,11 +128,12 @@ macro_rules! match_integers_span {
|
||||
|
||||
macro_rules! allocate_type {
|
||||
($rust_ty:ty, $gadget_ty:ty, $leo_ty:path, $cs:expr, $name:expr, $option:expr, $span:expr) => {{
|
||||
let option = $option.map(|s| {
|
||||
s.parse::<$rust_ty>()
|
||||
.map_err(|_| IntegerError::invalid_integer(s, $span))
|
||||
.unwrap()
|
||||
});
|
||||
let option = $option
|
||||
.map(|s| {
|
||||
s.parse::<$rust_ty>()
|
||||
.map_err(|_| IntegerError::invalid_integer(s, $span))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let result = <$gadget_ty>::alloc(
|
||||
$cs.ns(|| {
|
||||
|
@ -20,7 +20,7 @@ use crate::{
|
||||
expressions::{ArrayInlineExpression, Expression},
|
||||
sections::Header,
|
||||
tables::Table,
|
||||
types::{DataType, Type},
|
||||
types::{DataType, IntegerType, Type},
|
||||
values::{NumberValue, Value},
|
||||
};
|
||||
|
||||
@ -83,6 +83,12 @@ impl InputParserError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn integer_type_mismatch(expected: IntegerType, received: IntegerType, span: &Span) -> Self {
|
||||
let message = format!("expected data type `{}`, found `{}`", expected, received);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_char(character: String, span: &Span) -> Self {
|
||||
let message = format!("Expected valid character found `{}`", character);
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
/*
|
||||
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) {
|
||||
let b = a * 2;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
/*
|
||||
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) {
|
||||
let b = a * 2;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
function main(a: i32) {
|
||||
let b = a * 2;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
/*
|
||||
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) {
|
||||
let b = a * 2;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
[constants]
|
||||
a: i32 = 2i8;
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: i32 = 2i8;
|
@ -0,0 +1,2 @@
|
||||
[constants]
|
||||
a: u32 = 2u8;
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: u32 = 2u8;
|
@ -0,0 +1,5 @@
|
||||
[main]
|
||||
a: u32 = 2u32;
|
||||
|
||||
[constants]
|
||||
a: u32 = 2u32;
|
@ -1,5 +1,5 @@
|
||||
[main]
|
||||
a: [[u8; 4]; 2] = [[0u64, 0u64, 0u64, 0u64], [0u64, 0u64, 0u64, 0u64]];
|
||||
a: [[u8; 4]; 2] = [[0u8, 0u8, 0u8, 0u8], [0u8, 0u8, 0u8, 0u8]];
|
||||
|
||||
[registers]
|
||||
r2: [[u8; 4]; 2] = [[0u64, 0u64, 0u64, 0u64], [0u64, 0u64, 0u64, 0u64]];
|
||||
r2: [[u8; 4]; 2] = [[0u8, 0u8, 0u8, 0u8], [0u8, 0u8, 0u8, 0u8]];
|
||||
|
10
tests/compiler/integers/u128/negative_input_fail.leo
Normal file
10
tests/compiler/integers/u128/negative_input_fail.leo
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
inputs:
|
||||
- u128.in: |
|
||||
[main]
|
||||
a: u128 = -2;
|
||||
*/
|
||||
|
||||
function main(a: u128) {}
|
10
tests/compiler/integers/u16/negative_input_fail.leo
Normal file
10
tests/compiler/integers/u16/negative_input_fail.leo
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
inputs:
|
||||
- u16.in: |
|
||||
[main]
|
||||
a: u16 = -2;
|
||||
*/
|
||||
|
||||
function main(a: u16) {}
|
10
tests/compiler/integers/u32/negative_input_fail.leo
Normal file
10
tests/compiler/integers/u32/negative_input_fail.leo
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
inputs:
|
||||
- u32.in: |
|
||||
[main]
|
||||
a: u32 = -2;
|
||||
*/
|
||||
|
||||
function main(a: u32) {}
|
10
tests/compiler/integers/u64/negative_input_fail.leo
Normal file
10
tests/compiler/integers/u64/negative_input_fail.leo
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
inputs:
|
||||
- u64.in: |
|
||||
[main]
|
||||
a: u64 = -2;
|
||||
*/
|
||||
|
||||
function main(a: u64) {}
|
10
tests/compiler/integers/u8/negative_input_fail.leo
Normal file
10
tests/compiler/integers/u8/negative_input_fail.leo
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
inputs:
|
||||
- u8.in: |
|
||||
[main]
|
||||
a: u8 = -2;
|
||||
*/
|
||||
|
||||
function main(a: u8) {}
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
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"
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
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"
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:15\n |\n 3 | function main(a: u32) {\n | ^\n |\n = expected data type `u32`, found `u8`"
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:15\n |\n 3 | function main(a: i32) {\n | ^\n |\n = Input variable a declared twice"
|
@ -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"
|
@ -2,4 +2,4 @@
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:1\n |\n 3 | function main(x: [i16; 2]) {\n 4 | ...\n 5 | }\n | ^\n |\n = Input array dimensions mismatch expected 1, found array dimensions 2"
|
||||
- " --> compiler-test:3:15\n |\n 3 | function main(x: [i16; 2]) {\n | ^\n |\n = Input array dimensions mismatch expected 1, found array dimensions 2"
|
||||
|
@ -2,4 +2,4 @@
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:1\n |\n 3 | function main(x: (u8, bool, u8)) {\n 4 | ...\n 5 | }\n | ^\n |\n = Input tuple size mismatch expected 3, found tuple with length 2"
|
||||
- " --> compiler-test:3:15\n |\n 3 | function main(x: (u8, bool, u8)) {\n | ^\n |\n = Input tuple size mismatch expected 3, found tuple with length 2"
|
||||
|
@ -2,4 +2,4 @@
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:1\n |\n 3 | function main(const x: [i16; 2]) {\n 4 | ...\n 5 | }\n | ^\n |\n = Input array dimensions mismatch expected 2, found array dimensions 1"
|
||||
- " --> compiler-test:3:21\n |\n 3 | function main(const x: [i16; 2]) {\n | ^\n |\n = Input array dimensions mismatch expected 2, found array dimensions 1"
|
||||
|
@ -2,4 +2,4 @@
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:1\n |\n 3 | function main(const x: (u8, bool, u8)) {\n 4 | ...\n 5 | }\n | ^\n |\n = Input tuple size mismatch expected 3, found tuple with length 2"
|
||||
- " --> compiler-test:3:21\n |\n 3 | function main(const x: (u8, bool, u8)) {\n | ^\n |\n = Input tuple size mismatch expected 3, found tuple with length 2"
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:15\n |\n 3 | function main(a: u128) {}\n | ^\n |\n = failed to parse `-2` as expected integer type"
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:15\n |\n 3 | function main(a: u16) {}\n | ^\n |\n = failed to parse `-2` as expected integer type"
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:15\n |\n 3 | function main(a: u32) {}\n | ^\n |\n = failed to parse `-2` as expected integer type"
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:15\n |\n 3 | function main(a: u64) {}\n | ^\n |\n = failed to parse `-2` as expected integer type"
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- " --> compiler-test:3:15\n |\n 3 | function main(a: u8) {}\n | ^\n |\n = failed to parse `-2` as expected integer type"
|
Loading…
Reference in New Issue
Block a user