fix storing self circuit variables inside circuit function bug

This commit is contained in:
collin 2020-09-07 15:06:52 -07:00
parent 17784ffb23
commit 09e209f5eb
3 changed files with 36 additions and 14 deletions

View File

@ -19,6 +19,7 @@
use crate::{
assignee::resolve_assignee,
errors::StatementError,
new_scope,
program::ConstrainedProgram,
value::ConstrainedValue,
GroupType,
@ -46,7 +47,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
span: Span,
) -> Result<(), StatementError> {
// Get the name of the variable we are assigning to
let mut variable_name = resolve_assignee(function_scope.clone(), assignee.clone());
let variable_name = resolve_assignee(function_scope.clone(), assignee.clone());
// Evaluate new value
let mut new_value =
@ -84,10 +85,30 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
// Mutate a circuit variable using the self keyword.
if let Assignee::Identifier(circuit_name) = *assignee {
if circuit_name.is_self() {
variable_name = declared_circuit_reference;
let self_circuit_variable_name = new_scope(circuit_name.name, circuit_variable.name.clone());
let self_variable_name = new_scope(file_scope, self_circuit_variable_name);
let value = self.mutate_circuit_variable(
cs,
indicator,
declared_circuit_reference,
circuit_variable,
new_value,
span,
)?;
self.store(self_variable_name, value);
} else {
let _value = self.mutate_circuit_variable(
cs,
indicator,
variable_name,
circuit_variable,
new_value,
span,
)?;
}
}
self.mutute_circuit_variable(cs, indicator, variable_name, circuit_variable, new_value, span)
Ok(())
}
}
}

View File

@ -28,7 +28,7 @@ use snarkos_models::{
};
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
pub fn mutute_circuit_variable<CS: ConstraintSystem<F>>(
pub fn mutate_circuit_variable<CS: ConstraintSystem<F>>(
&mut self,
cs: &mut CS,
indicator: Option<Boolean>,
@ -36,7 +36,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
variable_name: Identifier,
mut new_value: ConstrainedValue<F, G>,
span: Span,
) -> Result<(), StatementError> {
) -> Result<ConstrainedValue<F, G>, StatementError> {
let condition = indicator.unwrap_or(Boolean::Constant(true));
// Get the mutable circuit by name
@ -49,14 +49,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Some(member) => match &member.1 {
ConstrainedValue::Function(_circuit_identifier, function) => {
// Throw an error if we try to mutate a circuit function
return Err(StatementError::immutable_circuit_function(
Err(StatementError::immutable_circuit_function(
function.identifier.to_string(),
span,
));
))
}
ConstrainedValue::Static(_circuit_function) => {
// Throw an error if we try to mutate a static circuit function
return Err(StatementError::immutable_circuit_function("static".into(), span));
Err(StatementError::immutable_circuit_function("static".into(), span))
}
ConstrainedValue::Mutable(value) => {
// Mutate the circuit variable's value in place
@ -80,25 +80,25 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
selected_value = ConstrainedValue::Mutable(Box::new(selected_value));
member.1 = selected_value.to_owned();
Ok(selected_value.to_owned())
}
_ => {
// Throw an error if we try to mutate an immutable circuit variable
return Err(StatementError::immutable_circuit_variable(variable_name.name, span));
Err(StatementError::immutable_circuit_variable(variable_name.name, span))
}
},
None => {
// Throw an error if the circuit variable does not exist in the circuit
return Err(StatementError::undefined_circuit_variable(
Err(StatementError::undefined_circuit_variable(
variable_name.to_string(),
span,
));
))
}
}
}
// Throw an error if the circuit definition does not exist in the file
_ => return Err(StatementError::undefined_circuit(variable_name.to_string(), span)),
_ => Err(StatementError::undefined_circuit(variable_name.to_string(), span)),
}
Ok(())
}
}

View File

@ -3,6 +3,7 @@ circuit Foo {
function set_a(new: u8) {
self.a = new;
console.assert(self.a == new);
}
}