mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-24 07:48:04 +03:00
fix field namespaces and errors
This commit is contained in:
parent
2e02d0906c
commit
172ab78497
@ -51,7 +51,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
return Err(ExpressionError::undefined_identifier(unresolved_identifier));
|
||||
};
|
||||
|
||||
result_value.resolve_type(expected_types)?;
|
||||
result_value.resolve_type(expected_types, unresolved_identifier.span.clone())?;
|
||||
|
||||
Ok(result_value)
|
||||
}
|
||||
@ -69,17 +69,17 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(ConstrainedValue::Integer(num_1.add(cs, num_2, span)?))
|
||||
}
|
||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
||||
Ok(ConstrainedValue::Field(fe_1.add(cs, &fe_2)?))
|
||||
Ok(ConstrainedValue::Field(fe_1.add(cs, &fe_2, span)?))
|
||||
}
|
||||
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
||||
Ok(ConstrainedValue::Group(ge_1.add(cs, &ge_2)?))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
self.enforce_add_expression(cs, val_1, val_2, span)
|
||||
}
|
||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||
self.enforce_add_expression(cs, val_1, val_2, span)
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
||||
@ -101,17 +101,17 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(ConstrainedValue::Integer(num_1.sub(cs, num_2, span)?))
|
||||
}
|
||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
||||
Ok(ConstrainedValue::Field(fe_1.sub(cs, &fe_2)?))
|
||||
Ok(ConstrainedValue::Field(fe_1.sub(cs, &fe_2, span)?))
|
||||
}
|
||||
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
||||
Ok(ConstrainedValue::Group(ge_1.sub(cs, &ge_2)?))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
self.enforce_sub_expression(cs, val_1, val_2, span)
|
||||
}
|
||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||
self.enforce_sub_expression(cs, val_1, val_2, span)
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
||||
@ -133,14 +133,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(ConstrainedValue::Integer(num_1.mul(cs, num_2, span)?))
|
||||
}
|
||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
||||
Ok(ConstrainedValue::Field(fe_1.mul(cs, &fe_2)?))
|
||||
Ok(ConstrainedValue::Field(fe_1.mul(cs, &fe_2, span)?))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
self.enforce_mul_expression(cs, val_1, val_2, span)
|
||||
}
|
||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||
self.enforce_mul_expression(cs, val_1, val_2, span)
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
@ -164,14 +164,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(ConstrainedValue::Integer(num_1.div(cs, num_2, span)?))
|
||||
}
|
||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
||||
Ok(ConstrainedValue::Field(fe_1.div(cs, &fe_2)?))
|
||||
Ok(ConstrainedValue::Field(fe_1.div(cs, &fe_2, span)?))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
self.enforce_div_expression(cs, val_1, val_2, span)
|
||||
}
|
||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||
self.enforce_div_expression(cs, val_1, val_2, span)
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
@ -195,11 +195,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(ConstrainedValue::Integer(num_1.pow(cs, num_2, span)?))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
self.enforce_pow_expression(cs, val_1, val_2, span)
|
||||
}
|
||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||
self.enforce_pow_expression(cs, val_1, val_2, span)
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
||||
@ -232,11 +232,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
ge_1.evaluate_equal(expression_namespace, &ge_2)?
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
return self.evaluate_eq_expression(&mut expression_namespace, val_1, val_2, span);
|
||||
}
|
||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||
return self.evaluate_eq_expression(&mut expression_namespace, val_1, val_2, span);
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
@ -267,11 +267,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
self.evaluate_ge_expression(val_1, val_2, span)
|
||||
}
|
||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||
self.evaluate_ge_expression(val_1, val_2, span)
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
||||
@ -298,11 +298,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
self.evaluate_gt_expression(val_1, val_2, span)
|
||||
}
|
||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||
self.evaluate_gt_expression(val_1, val_2, span)
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
||||
@ -329,11 +329,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
self.evaluate_le_expression(val_1, val_2, span)
|
||||
}
|
||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||
self.evaluate_le_expression(val_1, val_2, span)
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
||||
@ -360,11 +360,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
self.evaluate_lt_expression(val_1, val_2, span)
|
||||
}
|
||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||
self.evaluate_lt_expression(val_1, val_2, span)
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
||||
@ -397,9 +397,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
value => return Err(ExpressionError::conditional_boolean(value.to_string(), span)),
|
||||
};
|
||||
|
||||
let resolved_second =
|
||||
self.enforce_expression_value(cs, file_scope.clone(), function_scope.clone(), expected_types, second)?;
|
||||
let resolved_third = self.enforce_expression_value(cs, file_scope, function_scope, expected_types, third)?;
|
||||
let resolved_second = self.enforce_expression_value(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
expected_types,
|
||||
second,
|
||||
span.clone(),
|
||||
)?;
|
||||
let resolved_third =
|
||||
self.enforce_expression_value(cs, file_scope, function_scope, expected_types, third, span.clone())?;
|
||||
|
||||
match (resolved_second, resolved_third) {
|
||||
(ConstrainedValue::Boolean(bool_2), ConstrainedValue::Boolean(bool_3)) => {
|
||||
@ -507,7 +514,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
span: Span,
|
||||
) -> Result<usize, ExpressionError> {
|
||||
let expected_types = vec![Type::IntegerType(IntegerType::U32)];
|
||||
match self.enforce_expression_value(cs, file_scope.clone(), function_scope.clone(), &expected_types, index)? {
|
||||
match self.enforce_expression_value(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
&expected_types,
|
||||
index,
|
||||
span.clone(),
|
||||
)? {
|
||||
ConstrainedValue::Integer(number) => Ok(number.to_usize()),
|
||||
value => Err(ExpressionError::invalid_index(value.to_string(), span)),
|
||||
}
|
||||
@ -529,6 +543,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
function_scope.clone(),
|
||||
expected_types,
|
||||
*array,
|
||||
span.clone(),
|
||||
)? {
|
||||
ConstrainedValue::Array(array) => array,
|
||||
value => return Err(ExpressionError::undefined_array(value.to_string(), span)),
|
||||
@ -633,6 +648,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
function_scope.clone(),
|
||||
expected_types,
|
||||
*circuit_identifier.clone(),
|
||||
span.clone(),
|
||||
)? {
|
||||
ConstrainedValue::CircuitExpression(name, members) => (name, members),
|
||||
value => return Err(ExpressionError::undefined_circuit(value.to_string(), span)),
|
||||
@ -773,9 +789,10 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub(crate) fn enforce_number_implicit(
|
||||
expected_types: &Vec<Type>,
|
||||
value: String,
|
||||
span: Span,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
if expected_types.len() == 1 {
|
||||
return Ok(ConstrainedValue::from_type(value, &expected_types[0])?);
|
||||
return Ok(ConstrainedValue::from_type(value, &expected_types[0], span)?);
|
||||
}
|
||||
|
||||
Ok(ConstrainedValue::Unresolved(value))
|
||||
@ -791,11 +808,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type>,
|
||||
expression: Expression,
|
||||
span: Span,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let mut branch = self.enforce_expression(cs, file_scope, function_scope, expected_types, expression)?;
|
||||
|
||||
branch.get_inner_mut();
|
||||
branch.resolve_type(expected_types)?;
|
||||
branch.resolve_type(expected_types, span)?;
|
||||
|
||||
Ok(branch)
|
||||
}
|
||||
@ -808,13 +826,26 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
expected_types: &Vec<Type>,
|
||||
left: Expression,
|
||||
right: Expression,
|
||||
span: Span,
|
||||
) -> Result<(ConstrainedValue<F, G>, ConstrainedValue<F, G>), ExpressionError> {
|
||||
let mut resolved_left =
|
||||
self.enforce_expression_value(cs, file_scope.clone(), function_scope.clone(), expected_types, left)?;
|
||||
let mut resolved_right =
|
||||
self.enforce_expression_value(cs, file_scope.clone(), function_scope.clone(), expected_types, right)?;
|
||||
let mut resolved_left = self.enforce_expression_value(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
expected_types,
|
||||
left,
|
||||
span.clone(),
|
||||
)?;
|
||||
let mut resolved_right = self.enforce_expression_value(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
expected_types,
|
||||
right,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
resolved_left.resolve_types(&mut resolved_right, expected_types)?;
|
||||
resolved_left.resolve_types(&mut resolved_right, expected_types, span)?;
|
||||
|
||||
Ok((resolved_left, resolved_right))
|
||||
}
|
||||
@ -835,10 +866,10 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
// Values
|
||||
Expression::Integer(integer) => Ok(ConstrainedValue::Integer(integer)),
|
||||
Expression::Field(field) => Ok(ConstrainedValue::Field(FieldType::constant(field)?)),
|
||||
Expression::Group(group_affine) => Ok(ConstrainedValue::Group(G::constant(group_affine)?)),
|
||||
Expression::Field(field, span) => Ok(ConstrainedValue::Field(FieldType::constant(field, span)?)),
|
||||
Expression::Group(group_affine, _span) => Ok(ConstrainedValue::Group(G::constant(group_affine)?)),
|
||||
Expression::Boolean(bool) => Ok(ConstrainedValue::Boolean(bool)),
|
||||
Expression::Implicit(value) => Self::enforce_number_implicit(expected_types, value),
|
||||
Expression::Implicit(value, span) => Self::enforce_number_implicit(expected_types, value, span),
|
||||
|
||||
// Binary operations
|
||||
Expression::Add(left, right, span) => {
|
||||
@ -849,6 +880,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
expected_types,
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
self.enforce_add_expression(cs, resolved_left, resolved_right, span)
|
||||
@ -861,6 +893,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
expected_types,
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
self.enforce_sub_expression(cs, resolved_left, resolved_right, span)
|
||||
@ -873,6 +906,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
expected_types,
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
self.enforce_mul_expression(cs, resolved_left, resolved_right, span)
|
||||
@ -885,6 +919,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
expected_types,
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
self.enforce_div_expression(cs, resolved_left, resolved_right, span)
|
||||
@ -897,6 +932,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
expected_types,
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
self.enforce_pow_expression(cs, resolved_left, resolved_right, span)
|
||||
@ -910,7 +946,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
expected_types,
|
||||
*expression,
|
||||
)?)?),
|
||||
Expression::Or(left, right, _span) => {
|
||||
Expression::Or(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
@ -918,11 +954,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
expected_types,
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
Ok(self.enforce_or(cs, resolved_left, resolved_right)?)
|
||||
}
|
||||
Expression::And(left, right, _span) => {
|
||||
Expression::And(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
@ -930,6 +967,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
expected_types,
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
Ok(self.enforce_and(cs, resolved_left, resolved_right)?)
|
||||
@ -942,6 +980,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
&vec![],
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
Ok(self.evaluate_eq_expression(cs, resolved_left, resolved_right, span)?)
|
||||
@ -954,6 +993,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
&vec![],
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
Ok(self.evaluate_ge_expression(resolved_left, resolved_right, span)?)
|
||||
@ -966,6 +1006,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
&vec![],
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
Ok(self.evaluate_gt_expression(resolved_left, resolved_right, span)?)
|
||||
@ -978,6 +1019,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
&vec![],
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
Ok(self.evaluate_le_expression(resolved_left, resolved_right, span)?)
|
||||
@ -990,6 +1032,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
&vec![],
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
Ok(self.evaluate_lt_expression(resolved_left, resolved_right, span)?)
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Methods to enforce constraints on field elements in a resolved Leo program.
|
||||
|
||||
use crate::{constraints::ConstrainedValue, errors::FieldError, FieldType, GroupType};
|
||||
use leo_types::InputValue;
|
||||
use leo_types::{InputValue, Span};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
@ -13,6 +13,7 @@ pub(crate) fn field_from_input<F: Field + PrimeField, G: GroupType<F>, CS: Const
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
input_value: Option<InputValue>,
|
||||
span: Span,
|
||||
) -> Result<ConstrainedValue<F, G>, FieldError> {
|
||||
// Check that the parameter value is the correct type
|
||||
let field_option = match input_value {
|
||||
@ -20,13 +21,18 @@ pub(crate) fn field_from_input<F: Field + PrimeField, G: GroupType<F>, CS: Const
|
||||
if let InputValue::Field(string) = input {
|
||||
Some(string)
|
||||
} else {
|
||||
return Err(FieldError::Invalid(input.to_string()));
|
||||
return Err(FieldError::invalid_field(input.to_string(), span));
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
let field_value = FieldType::alloc(cs.ns(|| name), || field_option.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
let field_name = format!("{}: field", name);
|
||||
let field_name_unique = format!("`{}` {}:{}", field_name, span.line, span.start);
|
||||
let field_value = FieldType::alloc(cs.ns(|| field_name_unique), || {
|
||||
field_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})
|
||||
.map_err(|_| FieldError::missing_field(field_name, span))?;
|
||||
|
||||
Ok(ConstrainedValue::Field(field_value))
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
input_value,
|
||||
span,
|
||||
)?)),
|
||||
Type::Field => Ok(field_from_input(cs, name, input_value)?),
|
||||
Type::Field => Ok(field_from_input(cs, name, input_value, span)?),
|
||||
Type::Group => Ok(group_from_input(cs, name, input_value)?),
|
||||
Type::Boolean => Ok(self.bool_from_input(cs, name, input_value)?),
|
||||
Type::Array(_type, dimensions) => self.allocate_array(cs, name, *_type, dimensions, input_value, span),
|
||||
|
@ -74,7 +74,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
// Modify the single value of the array in place
|
||||
match self.get_mutable_assignee(name, span.clone())? {
|
||||
ConstrainedValue::Array(old) => {
|
||||
new_value.resolve_type(&vec![old[index].to_type()])?;
|
||||
new_value.resolve_type(&vec![old[index].to_type()], span.clone())?;
|
||||
|
||||
let selected_value =
|
||||
ConstrainedValue::conditionally_select(cs, &condition, &new_value, &old[index]).map_err(
|
||||
@ -144,7 +144,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
return Err(StatementError::immutable_circuit_function("static".into(), span));
|
||||
}
|
||||
_ => {
|
||||
new_value.resolve_type(&vec![object.1.to_type()])?;
|
||||
new_value.resolve_type(&vec![object.1.to_type()], span.clone())?;
|
||||
|
||||
let selected_value =
|
||||
ConstrainedValue::conditionally_select(cs, &condition, &new_value, &object.1).map_err(
|
||||
@ -185,7 +185,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Assignee::Identifier(_identifier) => {
|
||||
let condition = indicator.unwrap_or(Boolean::Constant(true));
|
||||
let old_value = self.get_mutable_assignee(variable_name.clone(), span.clone())?;
|
||||
new_value.resolve_type(&vec![old_value.to_type()])?;
|
||||
new_value.resolve_type(&vec![old_value.to_type()], span.clone())?;
|
||||
let selected_value = ConstrainedValue::conditionally_select(cs, &condition, &new_value, old_value)
|
||||
.map_err(|_| StatementError::select_fail(new_value.to_string(), old_value.to_string(), span))?;
|
||||
|
||||
@ -325,6 +325,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
function_scope.clone(),
|
||||
&expected_types,
|
||||
expression,
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
returns.push(result);
|
||||
@ -556,7 +557,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
}
|
||||
Statement::AssertEq(left, right, span) => {
|
||||
let (resolved_left, resolved_right) =
|
||||
self.enforce_binary_expression(cs, file_scope, function_scope, &vec![], left, right)?;
|
||||
self.enforce_binary_expression(cs, file_scope, function_scope, &vec![], left, right, span.clone())?;
|
||||
|
||||
self.enforce_assert_eq_statement(cs, indicator, &resolved_left, &resolved_right, span)?;
|
||||
}
|
||||
|
@ -43,13 +43,13 @@ pub enum ConstrainedValue<F: Field + PrimeField, G: GroupType<F>> {
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
pub(crate) fn from_other(value: String, other: &ConstrainedValue<F, G>) -> Result<Self, ValueError> {
|
||||
pub(crate) fn from_other(value: String, other: &ConstrainedValue<F, G>, span: Span) -> Result<Self, ValueError> {
|
||||
let other_type = other.to_type();
|
||||
|
||||
ConstrainedValue::from_type(value, &other_type)
|
||||
ConstrainedValue::from_type(value, &other_type, span)
|
||||
}
|
||||
|
||||
pub(crate) fn from_type(value: String, _type: &Type) -> Result<Self, ValueError> {
|
||||
pub(crate) fn from_type(value: String, _type: &Type, span: Span) -> Result<Self, ValueError> {
|
||||
match _type {
|
||||
Type::IntegerType(integer_type) => Ok(ConstrainedValue::Integer(match integer_type {
|
||||
IntegerType::U8 => Integer::U8(UInt8::constant(value.parse::<u8>()?)),
|
||||
@ -58,10 +58,10 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
IntegerType::U64 => Integer::U64(UInt64::constant(value.parse::<u64>()?)),
|
||||
IntegerType::U128 => Integer::U128(UInt128::constant(value.parse::<u128>()?)),
|
||||
})),
|
||||
Type::Field => Ok(ConstrainedValue::Field(FieldType::constant(value)?)),
|
||||
Type::Field => Ok(ConstrainedValue::Field(FieldType::constant(value, span)?)),
|
||||
Type::Group => Ok(ConstrainedValue::Group(G::constant(value)?)),
|
||||
Type::Boolean => Ok(ConstrainedValue::Boolean(Boolean::Constant(value.parse::<bool>()?))),
|
||||
Type::Array(ref _type, _dimensions) => ConstrainedValue::from_type(value, _type),
|
||||
Type::Array(ref _type, _dimensions) => ConstrainedValue::from_type(value, _type, span),
|
||||
_ => Ok(ConstrainedValue::Unresolved(value)),
|
||||
}
|
||||
}
|
||||
@ -76,10 +76,10 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_type(&mut self, types: &Vec<Type>) -> Result<(), ValueError> {
|
||||
pub(crate) fn resolve_type(&mut self, types: &Vec<Type>, span: Span) -> Result<(), ValueError> {
|
||||
if let ConstrainedValue::Unresolved(ref string) = self {
|
||||
if !types.is_empty() {
|
||||
*self = ConstrainedValue::from_type(string.clone(), &types[0])?
|
||||
*self = ConstrainedValue::from_type(string.clone(), &types[0], span)?
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,16 +87,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
}
|
||||
|
||||
/// Expect both `self` and `other` to resolve to the same type
|
||||
pub(crate) fn resolve_types(&mut self, other: &mut Self, types: &Vec<Type>) -> Result<(), ValueError> {
|
||||
pub(crate) fn resolve_types(&mut self, other: &mut Self, types: &Vec<Type>, span: Span) -> Result<(), ValueError> {
|
||||
if !types.is_empty() {
|
||||
self.resolve_type(types)?;
|
||||
return other.resolve_type(types);
|
||||
self.resolve_type(types, span.clone())?;
|
||||
return other.resolve_type(types, span);
|
||||
}
|
||||
|
||||
match (&self, &other) {
|
||||
(ConstrainedValue::Unresolved(_), ConstrainedValue::Unresolved(_)) => Ok(()),
|
||||
(ConstrainedValue::Unresolved(_), _) => self.resolve_type(&vec![other.to_type()]),
|
||||
(_, ConstrainedValue::Unresolved(_)) => other.resolve_type(&vec![self.to_type()]),
|
||||
(ConstrainedValue::Unresolved(_), _) => self.resolve_type(&vec![other.to_type()], span),
|
||||
(_, ConstrainedValue::Unresolved(_)) => other.resolve_type(&vec![self.to_type()], span),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,44 @@
|
||||
use leo_types::{Error as FormattedError, Span};
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum FieldError {
|
||||
#[error("Expected field element parameter, got {}", _0)]
|
||||
Invalid(String),
|
||||
|
||||
#[error("No multiplicative inverse found for field {}", _0)]
|
||||
NoInverse(String),
|
||||
#[error("{}", _0)]
|
||||
Error(#[from] FormattedError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(#[from] SynthesisError),
|
||||
}
|
||||
|
||||
impl FieldError {
|
||||
fn new_from_span(message: String, span: Span) -> Self {
|
||||
FieldError::Error(FormattedError::new_from_span(message, span))
|
||||
}
|
||||
|
||||
pub fn cannot_enforce(operation: String, error: SynthesisError, span: Span) -> Self {
|
||||
let message = format!(
|
||||
"the field binary operation `{}` failed due to synthesis error `{}`",
|
||||
operation, error,
|
||||
);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_field(actual: String, span: Span) -> Self {
|
||||
let message = format!("expected field element input type, found `{}`", actual);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn missing_field(expected: String, span: Span) -> Self {
|
||||
let message = format!("expected integer input `{}` not found", expected);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn no_inverse(field: String, span: Span) -> Self {
|
||||
let message = format!("no multiplicative inverse found for field `{}`", field);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! A data type that represents a field value
|
||||
|
||||
use crate::errors::FieldError;
|
||||
use leo_types::Span;
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
@ -35,82 +36,100 @@ impl<F: Field + PrimeField> FieldType<F> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn constant(string: String) -> Result<Self, FieldError> {
|
||||
let value = F::from_str(&string).map_err(|_| FieldError::Invalid(string))?;
|
||||
pub fn constant(string: String, span: Span) -> Result<Self, FieldError> {
|
||||
let value = F::from_str(&string).map_err(|_| FieldError::invalid_field(string, span))?;
|
||||
|
||||
Ok(FieldType::Constant(value))
|
||||
}
|
||||
|
||||
pub fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, FieldError> {
|
||||
pub fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self, span: Span) -> Result<Self, FieldError> {
|
||||
match (self, other) {
|
||||
(FieldType::Constant(self_value), FieldType::Constant(other_value)) => {
|
||||
Ok(FieldType::Constant(self_value.add(other_value)))
|
||||
}
|
||||
|
||||
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
||||
let result = self_value.add(cs, other_value)?;
|
||||
|
||||
Ok(FieldType::Allocated(result))
|
||||
}
|
||||
|
||||
(FieldType::Constant(constant_value), FieldType::Allocated(allocated_value))
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => {
|
||||
Ok(FieldType::Allocated(allocated_value.add_constant(cs, constant_value)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sub<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, FieldError> {
|
||||
match (self, other) {
|
||||
(FieldType::Constant(self_value), FieldType::Constant(other_value)) => {
|
||||
Ok(FieldType::Constant(self_value.sub(other_value)))
|
||||
}
|
||||
|
||||
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
||||
let result = self_value.sub(cs, other_value)?;
|
||||
|
||||
Ok(FieldType::Allocated(result))
|
||||
}
|
||||
|
||||
(FieldType::Constant(constant_value), FieldType::Allocated(allocated_value))
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => {
|
||||
Ok(FieldType::Allocated(allocated_value.sub_constant(cs, constant_value)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mul<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, FieldError> {
|
||||
match (self, other) {
|
||||
(FieldType::Constant(self_value), FieldType::Constant(other_value)) => {
|
||||
Ok(FieldType::Constant(self_value.mul(other_value)))
|
||||
}
|
||||
|
||||
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
||||
let result = self_value.mul(cs, other_value)?;
|
||||
let result = self_value
|
||||
.add(cs, other_value)
|
||||
.map_err(|e| FieldError::cannot_enforce(format!("+"), e, span))?;
|
||||
|
||||
Ok(FieldType::Allocated(result))
|
||||
}
|
||||
|
||||
(FieldType::Constant(constant_value), FieldType::Allocated(allocated_value))
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
|
||||
allocated_value.mul_by_constant(cs, constant_value)?,
|
||||
allocated_value
|
||||
.add_constant(cs, constant_value)
|
||||
.map_err(|e| FieldError::cannot_enforce(format!("+"), e, span))?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn div<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Self, FieldError> {
|
||||
pub fn sub<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self, span: Span) -> Result<Self, FieldError> {
|
||||
match (self, other) {
|
||||
(FieldType::Constant(self_value), FieldType::Constant(other_value)) => {
|
||||
Ok(FieldType::Constant(self_value.sub(other_value)))
|
||||
}
|
||||
|
||||
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
||||
let result = self_value
|
||||
.sub(cs, other_value)
|
||||
.map_err(|e| FieldError::cannot_enforce(format!("-"), e, span))?;
|
||||
|
||||
Ok(FieldType::Allocated(result))
|
||||
}
|
||||
|
||||
(FieldType::Constant(constant_value), FieldType::Allocated(allocated_value))
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
|
||||
allocated_value
|
||||
.sub_constant(cs, constant_value)
|
||||
.map_err(|e| FieldError::cannot_enforce(format!("+"), e, span))?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mul<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self, span: Span) -> Result<Self, FieldError> {
|
||||
match (self, other) {
|
||||
(FieldType::Constant(self_value), FieldType::Constant(other_value)) => {
|
||||
Ok(FieldType::Constant(self_value.mul(other_value)))
|
||||
}
|
||||
|
||||
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
||||
let result = self_value
|
||||
.mul(cs, other_value)
|
||||
.map_err(|e| FieldError::cannot_enforce(format!("*"), e, span))?;
|
||||
|
||||
Ok(FieldType::Allocated(result))
|
||||
}
|
||||
|
||||
(FieldType::Constant(constant_value), FieldType::Allocated(allocated_value))
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
|
||||
allocated_value
|
||||
.mul_by_constant(cs, constant_value)
|
||||
.map_err(|e| FieldError::cannot_enforce(format!("*"), e, span))?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn div<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self, span: Span) -> Result<Self, FieldError> {
|
||||
let inverse = match other {
|
||||
FieldType::Constant(constant) => {
|
||||
let constant_inverse = constant.inverse().ok_or(FieldError::NoInverse(constant.to_string()))?;
|
||||
let constant_inverse = constant
|
||||
.inverse()
|
||||
.ok_or(FieldError::no_inverse(constant.to_string(), span.clone()))?;
|
||||
|
||||
FieldType::Constant(constant_inverse)
|
||||
}
|
||||
FieldType::Allocated(allocated) => {
|
||||
let allocated_inverse = allocated.inverse(&mut cs)?;
|
||||
let allocated_inverse = allocated
|
||||
.inverse(&mut cs)
|
||||
.map_err(|e| FieldError::cannot_enforce(format!("+"), e, span.clone()))?;
|
||||
|
||||
FieldType::Allocated(allocated_inverse)
|
||||
}
|
||||
};
|
||||
|
||||
self.mul(cs, &inverse)
|
||||
self.mul(cs, &inverse, span)
|
||||
}
|
||||
|
||||
pub fn alloc_helper<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>>(
|
||||
|
@ -54,18 +54,11 @@ fn output_one(program: EdwardsTestCompiler) {
|
||||
|
||||
fn fail_field(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::FieldError(FieldError::Invalid(_string))) => {}
|
||||
CompilerError::FunctionError(FunctionError::FieldError(FieldError::Error(_string))) => {}
|
||||
error => panic!("Expected invalid field error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_synthesis(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::FieldError(FieldError::SynthesisError(_string))) => {}
|
||||
error => panic!("Expected synthesis error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero() {
|
||||
let bytes = include_bytes!("zero.leo");
|
||||
@ -110,7 +103,7 @@ fn test_input_fail_none() {
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![None]);
|
||||
fail_synthesis(program);
|
||||
fail_field(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -16,12 +16,12 @@ impl<'ast> From<AstRangeOrExpression<'ast>> for RangeOrExpression {
|
||||
AstRangeOrExpression::Range(range) => {
|
||||
let from = range.from.map(|from| match Expression::from(from.0) {
|
||||
Expression::Integer(number) => number,
|
||||
Expression::Implicit(string) => Integer::from_implicit(string),
|
||||
Expression::Implicit(string, _span) => Integer::from_implicit(string),
|
||||
expression => unimplemented!("Range bounds should be integers, found {}", expression),
|
||||
});
|
||||
let to = range.to.map(|to| match Expression::from(to.0) {
|
||||
Expression::Integer(number) => number,
|
||||
Expression::Implicit(string) => Integer::from_implicit(string),
|
||||
Expression::Implicit(string, _span) => Integer::from_implicit(string),
|
||||
expression => unimplemented!("Range bounds should be integers, found {}", expression),
|
||||
});
|
||||
|
||||
|
@ -28,10 +28,10 @@ pub enum Expression {
|
||||
|
||||
// Values
|
||||
Integer(Integer),
|
||||
Field(String),
|
||||
Group(String),
|
||||
Field(String, Span),
|
||||
Group(String, Span),
|
||||
Boolean(Boolean),
|
||||
Implicit(String),
|
||||
Implicit(String, Span),
|
||||
|
||||
// Number operations
|
||||
Add(Box<Expression>, Box<Expression>, Span),
|
||||
@ -69,6 +69,9 @@ pub enum Expression {
|
||||
impl Expression {
|
||||
pub fn set_span(&mut self, new_span: &Span) {
|
||||
match self {
|
||||
Expression::Field(_, old_span) => *old_span = new_span.clone(),
|
||||
Expression::Group(_, old_span) => *old_span = new_span.clone(),
|
||||
|
||||
Expression::Add(_, _, old_span) => *old_span = new_span.clone(),
|
||||
Expression::Sub(_, _, old_span) => *old_span = new_span.clone(),
|
||||
Expression::Mul(_, _, old_span) => *old_span = new_span.clone(),
|
||||
@ -119,10 +122,10 @@ impl<'ast> fmt::Display for Expression {
|
||||
|
||||
// Values
|
||||
Expression::Integer(ref integer) => write!(f, "{}", integer),
|
||||
Expression::Field(ref field) => write!(f, "{}", field),
|
||||
Expression::Group(ref group) => write!(f, "{}", group),
|
||||
Expression::Field(ref field, ref _span) => write!(f, "{}", field),
|
||||
Expression::Group(ref group, ref _span) => write!(f, "{}", group),
|
||||
Expression::Boolean(ref bool) => write!(f, "{}", bool.get_value().unwrap()),
|
||||
Expression::Implicit(ref value) => write!(f, "{}", value),
|
||||
Expression::Implicit(ref value, ref _span) => write!(f, "{}", value),
|
||||
|
||||
// Number operations
|
||||
Expression::Add(ref left, ref right, ref _span) => write!(f, "{} + {}", left, right),
|
||||
@ -413,13 +416,13 @@ impl<'ast> From<NotExpression<'ast>> for Expression {
|
||||
|
||||
impl<'ast> From<FieldValue<'ast>> for Expression {
|
||||
fn from(field: FieldValue<'ast>) -> Self {
|
||||
Expression::Field(field.number.value)
|
||||
Expression::Field(field.number.value, Span::from(field.span))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<GroupValue<'ast>> for Expression {
|
||||
fn from(group: GroupValue<'ast>) -> Self {
|
||||
Expression::Group(group.to_string())
|
||||
Expression::Group(group.to_string(), Span::from(group.span))
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,7 +436,7 @@ impl<'ast> From<BooleanValue<'ast>> for Expression {
|
||||
|
||||
impl<'ast> From<NumberImplicitValue<'ast>> for Expression {
|
||||
fn from(number: NumberImplicitValue<'ast>) -> Self {
|
||||
Expression::Implicit(number.number.value)
|
||||
Expression::Implicit(number.number.value, Span::from(number.span))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,7 +392,7 @@ impl Integer {
|
||||
Ok(match (self, other) {
|
||||
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
|
||||
let unique_namespace = format!(
|
||||
"enforce {} / {} {}:{}",
|
||||
"enforce {} ÷ {} {}:{}",
|
||||
left_u8.value.unwrap(),
|
||||
right_u8.value.unwrap(),
|
||||
span.line,
|
||||
@ -404,7 +404,7 @@ impl Integer {
|
||||
}
|
||||
(Integer::U16(left_u16), Integer::U16(right_u16)) => {
|
||||
let unique_namespace = format!(
|
||||
"enforce {} / {} {}:{}",
|
||||
"enforce {} ÷ {} {}:{}",
|
||||
left_u16.value.unwrap(),
|
||||
right_u16.value.unwrap(),
|
||||
span.line,
|
||||
@ -416,7 +416,7 @@ impl Integer {
|
||||
}
|
||||
(Integer::U32(left_u32), Integer::U32(right_u32)) => {
|
||||
let unique_namespace = format!(
|
||||
"enforce {} / {} {}:{}",
|
||||
"enforce {} ÷ {} {}:{}",
|
||||
left_u32.value.unwrap(),
|
||||
right_u32.value.unwrap(),
|
||||
span.line,
|
||||
@ -428,7 +428,7 @@ impl Integer {
|
||||
}
|
||||
(Integer::U64(left_u64), Integer::U64(right_u64)) => {
|
||||
let unique_namespace = format!(
|
||||
"enforce {} / {} {}:{}",
|
||||
"enforce {} ÷ {} {}:{}",
|
||||
left_u64.value.unwrap(),
|
||||
right_u64.value.unwrap(),
|
||||
span.line,
|
||||
@ -440,7 +440,7 @@ impl Integer {
|
||||
}
|
||||
(Integer::U128(left_u128), Integer::U128(right_u128)) => {
|
||||
let unique_namespace = format!(
|
||||
"enforce {} / {} {}:{}",
|
||||
"enforce {} ÷ {} {}:{}",
|
||||
left_u128.value.unwrap(),
|
||||
right_u128.value.unwrap(),
|
||||
span.line,
|
||||
|
@ -151,12 +151,12 @@ impl<'ast> From<ForStatement<'ast>> for Statement {
|
||||
fn from(statement: ForStatement<'ast>) -> Self {
|
||||
let from = match Expression::from(statement.start) {
|
||||
Expression::Integer(number) => number,
|
||||
Expression::Implicit(string) => Integer::from_implicit(string),
|
||||
Expression::Implicit(string, _span) => Integer::from_implicit(string),
|
||||
expression => unimplemented!("Range bounds should be integers, found {}", expression),
|
||||
};
|
||||
let to = match Expression::from(statement.stop) {
|
||||
Expression::Integer(number) => number,
|
||||
Expression::Implicit(string) => Integer::from_implicit(string),
|
||||
Expression::Implicit(string, _span) => Integer::from_implicit(string),
|
||||
expression => unimplemented!("Range bounds should be integers, found {}", expression),
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user