1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

Merge pull request #845 from Zokrates/fix-nested-struct-flattening

Fix nested struct flattening
This commit is contained in:
Thibaut Schaeffer 2021-05-05 16:24:17 +02:00 committed by GitHub
commit 6156b33dfd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 369 deletions

12
Cargo.lock generated
View file

@ -2269,7 +2269,7 @@ dependencies = [
[[package]]
name = "zokrates_cli"
version = "0.7.0"
version = "0.7.1"
dependencies = [
"assert_cli",
"bincode",
@ -2294,7 +2294,7 @@ version = "0.1.0"
[[package]]
name = "zokrates_core"
version = "0.6.0"
version = "0.6.1"
dependencies = [
"ark-bls12-377",
"ark-bn254",
@ -2335,7 +2335,7 @@ dependencies = [
[[package]]
name = "zokrates_core_test"
version = "0.2.0"
version = "0.2.1"
dependencies = [
"zokrates_test",
"zokrates_test_derive",
@ -2381,7 +2381,7 @@ dependencies = [
[[package]]
name = "zokrates_parser"
version = "0.2.0"
version = "0.2.1"
dependencies = [
"glob 0.2.11",
"pest",
@ -2390,7 +2390,7 @@ dependencies = [
[[package]]
name = "zokrates_pest_ast"
version = "0.2.0"
version = "0.2.1"
dependencies = [
"from-pest",
"glob 0.2.11",
@ -2402,7 +2402,7 @@ dependencies = [
[[package]]
name = "zokrates_stdlib"
version = "0.2.0"
version = "0.2.1"
dependencies = [
"fs_extra",
"zokrates_test",

View file

@ -0,0 +1 @@
Fix nested struct access crash

View file

@ -0,0 +1,11 @@
struct Foo {
field a
}
struct Bar {
Foo foo
}
def main(Bar b):
field a = b.foo.a
return

View file

@ -479,22 +479,19 @@ pub fn fold_struct_expression_inner<'ast, T: Field>(
.collect()
}
typed_absy::StructExpressionInner::Member(box s, id) => {
let members = s.ty().clone();
// get the concrete struct type, which must be available now
let struct_ty: typed_absy::types::ConcreteStructType =
s.ty().clone().try_into().unwrap();
let s = f.fold_struct_expression(s);
let offset: usize = members
// get the offset at which this member starts
let offset: usize = struct_ty
.iter()
.take_while(|member| member.id != id)
.map(|member| {
typed_absy::types::ConcreteType::try_from(*member.ty.clone())
.unwrap()
.get_primitive_count()
})
.map(|member| member.ty.get_primitive_count())
.sum();
// we also need the size of this member
let size = ty
// get the size of this member
let size = struct_ty
.iter()
.find(|member| member.id == id)
.cloned()
@ -502,6 +499,10 @@ pub fn fold_struct_expression_inner<'ast, T: Field>(
.ty
.get_primitive_count();
// flatten the full struct
let s = f.fold_struct_expression(s);
// extract the member
s[offset..offset + size].to_vec()
}
typed_absy::StructExpressionInner::Select(box array, box index) => {

View file

@ -148,7 +148,7 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedProgram<'ast, T> {
}
/// A typed module as a collection of functions. Types have been resolved during semantic checking.
#[derive(PartialEq, Clone)]
#[derive(PartialEq, Debug, Clone)]
pub struct TypedModule<'ast, T> {
/// Functions of the module
pub functions: TypedFunctionSymbols<'ast, T>,
@ -156,24 +156,13 @@ pub struct TypedModule<'ast, T> {
pub constants: TypedConstantSymbols<'ast, T>,
}
#[derive(Clone, PartialEq)]
#[derive(Clone, PartialEq, Debug)]
pub enum TypedFunctionSymbol<'ast, T> {
Here(TypedFunction<'ast, T>),
There(DeclarationFunctionKey<'ast>),
Flat(FlatEmbed),
}
// this should be deriveable but it seems like the bounds are not infered correctly
impl<'ast, T: fmt::Debug> fmt::Debug for TypedFunctionSymbol<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TypedFunctionSymbol::Here(s) => write!(f, "Here({:?})", s),
TypedFunctionSymbol::There(key) => write!(f, "There({:?})", key),
TypedFunctionSymbol::Flat(s) => write!(f, "Flat({:?})", s),
}
}
}
impl<'ast, T: Field> TypedFunctionSymbol<'ast, T> {
pub fn signature<'a>(
&'a self,
@ -225,27 +214,8 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedModule<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for TypedModule<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"TypedModule(\n\tFunctions:\n\t\t{:?}\n\tConstants:\n\t\t{:?}\n)",
self.functions
.iter()
.map(|x| format!("{:?}", x))
.collect::<Vec<_>>()
.join("\n\t\t"),
self.constants
.iter()
.map(|x| format!("{:?}", x))
.collect::<Vec<_>>()
.join("\n\t\t")
)
}
}
/// A typed function
#[derive(Clone, PartialEq, Hash)]
#[derive(Clone, PartialEq, Debug, Hash)]
pub struct TypedFunction<'ast, T> {
/// Arguments of the function
pub arguments: Vec<DeclarationParameter<'ast>>,
@ -318,23 +288,7 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedFunction<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for TypedFunction<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"TypedFunction(signature: {:?}, arguments: {:?}, ...):\n{}",
self.signature,
self.arguments,
self.statements
.iter()
.map(|x| format!("\t{:?}", x))
.collect::<Vec<_>>()
.join("\n")
)
}
}
#[derive(Clone, PartialEq)]
#[derive(Clone, PartialEq, Debug)]
pub struct TypedConstant<'ast, T> {
ty: Type<'ast, T>,
expression: TypedExpression<'ast, T>,
@ -346,12 +300,6 @@ impl<'ast, T> TypedConstant<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for TypedConstant<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "TypedConstant({:?}, {:?})", self.ty, self.expression)
}
}
impl<'ast, T: fmt::Display> fmt::Display for TypedConstant<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "const {}({})", self.ty, self.expression)
@ -365,7 +313,7 @@ impl<'ast, T: Clone> Typed<'ast, T> for TypedConstant<'ast, T> {
}
/// Something we can assign to.
#[derive(Clone, PartialEq, Hash, Eq)]
#[derive(Clone, PartialEq, Debug, Hash, Eq)]
pub enum TypedAssignee<'ast, T> {
Identifier(Variable<'ast, T>),
Select(Box<TypedAssignee<'ast, T>>, Box<UExpression<'ast, T>>),
@ -389,7 +337,7 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedSpread<'ast, T> {
}
}
#[derive(Clone, PartialEq, Hash, Eq, Debug)]
#[derive(Clone, PartialEq, Debug, Hash, Eq)]
pub enum TypedExpressionOrSpread<'ast, T> {
Expression(TypedExpression<'ast, T>),
Spread(TypedSpread<'ast, T>),
@ -475,16 +423,6 @@ impl<'ast, T: Clone> Typed<'ast, T> for TypedAssignee<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for TypedAssignee<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TypedAssignee::Identifier(ref s) => write!(f, "{:?}", s.id),
TypedAssignee::Select(ref a, ref e) => write!(f, "Select({:?}, {:?})", a, e),
TypedAssignee::Member(ref s, ref m) => write!(f, "Member({:?}, {:?})", s, m),
}
}
}
impl<'ast, T: fmt::Display> fmt::Display for TypedAssignee<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
@ -497,7 +435,7 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedAssignee<'ast, T> {
/// A statement in a `TypedFunction`
#[allow(clippy::large_enum_variant)]
#[derive(Clone, PartialEq, Hash, Eq)]
#[derive(Clone, PartialEq, Debug, Hash, Eq)]
pub enum TypedStatement<'ast, T> {
Return(Vec<TypedExpression<'ast, T>>),
Definition(TypedAssignee<'ast, T>, TypedExpression<'ast, T>),
@ -518,42 +456,6 @@ pub enum TypedStatement<'ast, T> {
PopCallLog,
}
impl<'ast, T: fmt::Debug> fmt::Debug for TypedStatement<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TypedStatement::Return(ref exprs) => {
write!(f, "Return(")?;
for (i, expr) in exprs.iter().enumerate() {
write!(f, "{:?}", expr)?;
if i < exprs.len() - 1 {
write!(f, ", ")?;
}
}
write!(f, ")")
}
TypedStatement::Declaration(ref var) => write!(f, "({:?})", var),
TypedStatement::Definition(ref lhs, ref rhs) => {
write!(f, "Definition({:?}, {:?})", lhs, rhs)
}
TypedStatement::Assertion(ref e) => write!(f, "Assertion({:?})", e),
TypedStatement::For(ref var, ref start, ref stop, ref list) => {
writeln!(f, "for {:?} in {:?}..{:?} do", var, start, stop)?;
for l in list {
writeln!(f, "\t\t{:?}", l)?;
}
write!(f, "\tendfor")
}
TypedStatement::MultipleDefinition(ref lhs, ref rhs) => {
write!(f, "MultipleDefinition({:?}, {:?})", lhs, rhs)
}
TypedStatement::PushCallLog(ref key, ref generics) => {
write!(f, "PushCallLog({:?}, {:?})", key, generics)
}
TypedStatement::PopCallLog => write!(f, "PopCallLog"),
}
}
}
impl<'ast, T: fmt::Display> TypedStatement<'ast, T> {
fn fmt_indented(&self, f: &mut fmt::Formatter, depth: usize) -> fmt::Result {
match self {
@ -621,7 +523,7 @@ pub trait Typed<'ast, T> {
/// A typed expression
#[allow(clippy::large_enum_variant)]
#[derive(Clone, PartialEq, Hash, Eq)]
#[derive(Clone, PartialEq, Debug, Hash, Eq)]
pub enum TypedExpression<'ast, T> {
Boolean(BooleanExpression<'ast, T>),
FieldElement(FieldElementExpression<'ast, T>),
@ -680,31 +582,12 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedExpression<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for TypedExpression<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TypedExpression::Boolean(ref e) => write!(f, "{:?}", e),
TypedExpression::FieldElement(ref e) => write!(f, "{:?}", e),
TypedExpression::Uint(ref e) => write!(f, "{:?}", e),
TypedExpression::Array(ref e) => write!(f, "{:?}", e),
TypedExpression::Struct(ref s) => write!(f, "{:?}", s),
TypedExpression::Int(ref s) => write!(f, "{:?}", s),
}
}
}
impl<'ast, T: fmt::Display> fmt::Display for ArrayExpression<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.inner)
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for ArrayExpression<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.inner)
}
}
impl<'ast, T: fmt::Display> fmt::Display for StructExpression<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.inner {
@ -759,12 +642,6 @@ impl<'ast, T: fmt::Display> fmt::Display for StructExpression<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for StructExpression<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.inner)
}
}
impl<'ast, T: Clone> Typed<'ast, T> for TypedExpression<'ast, T> {
fn get_type(&self) -> Type<'ast, T> {
match *self {
@ -812,7 +689,7 @@ pub trait MultiTyped<'ast, T> {
fn get_types(&self) -> &Vec<Type<'ast, T>>;
}
#[derive(Clone, PartialEq, Hash, Eq)]
#[derive(Clone, PartialEq, Debug, Hash, Eq)]
pub enum TypedExpressionList<'ast, T> {
FunctionCall(
DeclarationFunctionKey<'ast>,
@ -838,7 +715,7 @@ impl<'ast, T> MultiTyped<'ast, T> for TypedExpressionList<'ast, T> {
}
/// An expression of type `field`
#[derive(Clone, PartialEq, Hash, Eq)]
#[derive(Clone, PartialEq, Debug, Hash, Eq)]
pub enum FieldElementExpression<'ast, T> {
Number(T),
Identifier(Identifier<'ast>),
@ -922,7 +799,7 @@ impl<'ast, T> From<T> for FieldElementExpression<'ast, T> {
}
/// An expression of type `bool`
#[derive(Clone, PartialEq, Hash, Eq)]
#[derive(Clone, PartialEq, Debug, Hash, Eq)]
pub enum BooleanExpression<'ast, T> {
Identifier(Identifier<'ast>),
Value(bool),
@ -994,7 +871,7 @@ impl<'ast, T> From<bool> for BooleanExpression<'ast, T> {
/// * Contrary to basic types which are represented as enums, we wrap an enum `ArrayExpressionInner` in a struct in order to keep track of the type (content and size)
/// of the array. Only using an enum would require generics, which would propagate up to TypedExpression which we want to keep simple, hence this "runtime"
/// type checking
#[derive(Clone, PartialEq, Hash, Eq)]
#[derive(Clone, PartialEq, Debug, Hash, Eq)]
pub struct ArrayExpression<'ast, T> {
ty: Box<ArrayType<'ast, T>>,
inner: ArrayExpressionInner<'ast, T>,
@ -1078,7 +955,7 @@ impl<'ast, T> std::iter::FromIterator<TypedExpressionOrSpread<'ast, T>> for Arra
}
}
#[derive(Clone, PartialEq, Hash, Eq)]
#[derive(Clone, PartialEq, Debug, Hash, Eq)]
pub enum ArrayExpressionInner<'ast, T> {
Identifier(Identifier<'ast>),
Value(ArrayValue<'ast, T>),
@ -1144,7 +1021,7 @@ impl<'ast, T: Clone> ArrayExpression<'ast, T> {
}
}
#[derive(Clone, PartialEq, Hash, Eq)]
#[derive(Clone, PartialEq, Debug, Hash, Eq)]
pub struct StructExpression<'ast, T> {
ty: StructType<'ast, T>,
inner: StructExpressionInner<'ast, T>,
@ -1186,7 +1063,7 @@ impl<'ast, T> StructExpression<'ast, T> {
}
}
#[derive(Clone, PartialEq, Hash, Eq)]
#[derive(Clone, PartialEq, Debug, Hash, Eq)]
pub enum StructExpressionInner<'ast, T> {
Identifier(Identifier<'ast>),
Value(Vec<TypedExpression<'ast, T>>),
@ -1551,167 +1428,6 @@ impl<'ast, T: fmt::Display> fmt::Display for ArrayExpressionInner<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for BooleanExpression<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
BooleanExpression::Identifier(ref var) => write!(f, "Ide({})", var),
BooleanExpression::Value(b) => write!(f, "Value({})", b),
BooleanExpression::IfElse(ref condition, ref consequent, ref alternative) => write!(
f,
"IfElse({:?}, {:?}, {:?})",
condition, consequent, alternative
),
BooleanExpression::FieldLt(ref lhs, ref rhs) => {
write!(f, "FieldLt({:?}, {:?})", lhs, rhs)
}
BooleanExpression::FieldLe(ref lhs, ref rhs) => {
write!(f, "FieldLe({:?}, {:?})", lhs, rhs)
}
BooleanExpression::FieldGe(ref lhs, ref rhs) => {
write!(f, "FieldGe({:?}, {:?})", lhs, rhs)
}
BooleanExpression::FieldGt(ref lhs, ref rhs) => {
write!(f, "FieldGt({:?}, {:?})", lhs, rhs)
}
BooleanExpression::UintLt(ref lhs, ref rhs) => {
write!(f, "UintLt({:?}, {:?})", lhs, rhs)
}
BooleanExpression::UintLe(ref lhs, ref rhs) => {
write!(f, "UintLe({:?}, {:?})", lhs, rhs)
}
BooleanExpression::UintGe(ref lhs, ref rhs) => {
write!(f, "UintGe({:?}, {:?})", lhs, rhs)
}
BooleanExpression::UintGt(ref lhs, ref rhs) => {
write!(f, "UintGt({:?}, {:?})", lhs, rhs)
}
BooleanExpression::FieldEq(ref lhs, ref rhs) => {
write!(f, "FieldEq({:?}, {:?})", lhs, rhs)
}
BooleanExpression::BoolEq(ref lhs, ref rhs) => {
write!(f, "BoolEq({:?}, {:?})", lhs, rhs)
}
BooleanExpression::ArrayEq(ref lhs, ref rhs) => {
write!(f, "ArrayEq({:?}, {:?})", lhs, rhs)
}
BooleanExpression::StructEq(ref lhs, ref rhs) => {
write!(f, "StructEq({:?}, {:?})", lhs, rhs)
}
BooleanExpression::UintEq(ref lhs, ref rhs) => {
write!(f, "UintEq({:?}, {:?})", lhs, rhs)
}
BooleanExpression::And(ref lhs, ref rhs) => write!(f, "And({:?}, {:?})", lhs, rhs),
BooleanExpression::Not(ref exp) => write!(f, "Not({:?})", exp),
BooleanExpression::FunctionCall(ref i, ref g, ref p) => {
write!(f, "FunctionCall({:?}, {:?}, (", g, i)?;
f.debug_list().entries(p.iter()).finish()?;
write!(f, ")")
}
BooleanExpression::Select(ref array, ref index) => {
write!(f, "Select({:?}, {:?})", array, index)
}
BooleanExpression::Member(ref struc, ref id) => {
write!(f, "Access({:?}, {:?})", struc, id)
}
BooleanExpression::Or(ref lhs, ref rhs) => write!(f, "Or({:?}, {:?})", lhs, rhs),
}
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for FieldElementExpression<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
FieldElementExpression::Number(ref i) => write!(f, "Num({:?})", i),
FieldElementExpression::Identifier(ref var) => write!(f, "Ide({:?})", var),
FieldElementExpression::Add(ref lhs, ref rhs) => write!(f, "Add({:?}, {:?})", lhs, rhs),
FieldElementExpression::Sub(ref lhs, ref rhs) => write!(f, "Sub({:?}, {:?})", lhs, rhs),
FieldElementExpression::Mult(ref lhs, ref rhs) => {
write!(f, "Mult({:?}, {:?})", lhs, rhs)
}
FieldElementExpression::Div(ref lhs, ref rhs) => write!(f, "Div({:?}, {:?})", lhs, rhs),
FieldElementExpression::Pow(ref lhs, ref rhs) => write!(f, "Pow({:?}, {:?})", lhs, rhs),
FieldElementExpression::Neg(ref e) => write!(f, "Neg({:?})", e),
FieldElementExpression::Pos(ref e) => write!(f, "Pos({:?})", e),
FieldElementExpression::IfElse(ref condition, ref consequent, ref alternative) => {
write!(
f,
"IfElse({:?}, {:?}, {:?})",
condition, consequent, alternative
)
}
FieldElementExpression::FunctionCall(ref i, ref g, ref p) => {
write!(f, "FunctionCall({:?}, {:?}, (", g, i)?;
f.debug_list().entries(p.iter()).finish()?;
write!(f, ")")
}
FieldElementExpression::Member(ref struc, ref id) => {
write!(f, "Member({:?}, {:?})", struc, id)
}
FieldElementExpression::Select(ref id, ref index) => {
write!(f, "Select({:?}, {:?})", id, index)
}
}
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for ArrayExpressionInner<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ArrayExpressionInner::Identifier(ref var) => write!(f, "Identifier({:?})", var),
ArrayExpressionInner::Value(ref values) => write!(f, "Value({:?})", values),
ArrayExpressionInner::FunctionCall(ref i, ref g, ref p) => {
write!(f, "FunctionCall({:?}, {:?}, (", g, i)?;
f.debug_list().entries(p.iter()).finish()?;
write!(f, ")")
}
ArrayExpressionInner::IfElse(ref condition, ref consequent, ref alternative) => write!(
f,
"IfElse({:?}, {:?}, {:?})",
condition, consequent, alternative
),
ArrayExpressionInner::Member(ref struc, ref id) => {
write!(f, "Member({:?}, {:?})", struc, id)
}
ArrayExpressionInner::Select(ref array, ref index) => {
write!(f, "Select({:?}, {:?})", array, index)
}
ArrayExpressionInner::Slice(ref array, ref from, ref to) => {
write!(f, "Slice({:?}, {:?}, {:?})", array, from, to)
}
ArrayExpressionInner::Repeat(ref e, ref count) => {
write!(f, "Repeat({:?}, {:?})", e, count)
}
}
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for StructExpressionInner<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
StructExpressionInner::Identifier(ref var) => write!(f, "{:?}", var),
StructExpressionInner::Value(ref values) => write!(f, "{:?}", values),
StructExpressionInner::FunctionCall(ref i, ref g, ref p) => {
write!(f, "FunctionCall({:?}, {:?}, (", g, i)?;
f.debug_list().entries(p.iter()).finish()?;
write!(f, ")")
}
StructExpressionInner::IfElse(ref condition, ref consequent, ref alternative) => {
write!(
f,
"IfElse({:?}, {:?}, {:?})",
condition, consequent, alternative
)
}
StructExpressionInner::Member(ref struc, ref id) => {
write!(f, "Member({:?}, {:?})", struc, id)
}
StructExpressionInner::Select(ref id, ref index) => {
write!(f, "Select({:?}, {:?})", id, index)
}
}
}
}
impl<'ast, T: fmt::Display> fmt::Display for TypedExpressionList<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
@ -1766,23 +1482,6 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedExpressionList<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for TypedExpressionList<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TypedExpressionList::FunctionCall(ref i, ref g, ref p, _) => {
write!(f, "FunctionCall({:?}, {:?}, (", g, i)?;
f.debug_list().entries(p.iter()).finish()?;
write!(f, ")")
}
TypedExpressionList::EmbedCall(ref embed, ref g, ref p, _) => {
write!(f, "EmbedCall({:?}, {:?}, (", g, embed)?;
f.debug_list().entries(p.iter()).finish()?;
write!(f, ")")
}
}
}
}
// Variable to TypedExpression conversion
impl<'ast, T: Field> From<Variable<'ast, T>> for TypedExpression<'ast, T> {

View file

@ -179,7 +179,7 @@ impl<'ast, T> From<DeclarationStructMember<'ast>> for StructMember<'ast, T> {
}
}
#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord, Debug)]
pub struct GArrayType<S> {
pub size: S,
#[serde(flatten)]
@ -426,7 +426,7 @@ impl fmt::Display for UBitwidth {
}
}
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub enum GType<S> {
FieldElement,
Boolean,
@ -627,29 +627,6 @@ impl<S: fmt::Display> fmt::Display for GType<S> {
}
}
impl<S: fmt::Debug> fmt::Debug for GType<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
GType::FieldElement => write!(f, "field"),
GType::Boolean => write!(f, "bool"),
GType::Int => write!(f, "integer"),
GType::Uint(ref bitwidth) => write!(f, "u{:?}", bitwidth),
GType::Array(ref array_type) => write!(f, "{:?}[{:?}]", array_type.ty, array_type.size),
GType::Struct(ref struct_type) => write!(
f,
"{:?} {{{:?}}}",
struct_type.name(),
struct_type
.members
.iter()
.map(|member| format!("{:?}: {:?}", member.id, member.ty))
.collect::<Vec<_>>()
.join(", ")
),
}
}
}
impl<S> GType<S> {
pub fn array<U: Into<GArrayType<S>>>(array_ty: U) -> Self {
GType::Array(array_ty.into())
@ -870,7 +847,7 @@ pub mod signature {
use super::*;
use std::fmt;
#[derive(Clone, Serialize, Deserialize, Eq)]
#[derive(Clone, Serialize, Deserialize, Eq, Debug)]
pub struct GSignature<S> {
pub generics: Vec<Option<S>>,
pub inputs: Vec<GType<S>>,
@ -1136,16 +1113,6 @@ pub mod signature {
}
}
impl<S: fmt::Debug> fmt::Debug for GSignature<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"Signature(generics: {:?}, inputs: {:?}, outputs: {:?})",
self.generics, self.inputs, self.outputs
)
}
}
impl<S: fmt::Display> fmt::Display for GSignature<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if !self.generics.is_empty() {