From 6e066f869cfaab199c8997f210b15e764e589289 Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 15 Sep 2021 12:38:26 +0200 Subject: [PATCH 1/7] keep original declaration type intact and specialize on the fly --- zokrates_core/src/compile.rs | 2 + zokrates_core/src/semantics.rs | 27 +++----- zokrates_core/src/typed_absy/types.rs | 99 ++++++++++++++++++--------- 3 files changed, 77 insertions(+), 51 deletions(-) diff --git a/zokrates_core/src/compile.rs b/zokrates_core/src/compile.rs index 172ad747..de33ea26 100644 --- a/zokrates_core/src/compile.rs +++ b/zokrates_core/src/compile.rs @@ -247,6 +247,8 @@ fn check_with_arena<'ast, T: Field, E: Into>( let typed_ast = Checker::check(compiled) .map_err(|errors| CompileErrors(errors.into_iter().map(CompileError::from).collect()))?; + log::trace!("\n{}", typed_ast); + let main_module = typed_ast.main.clone(); log::debug!("Run static analysis"); diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 2572dc65..ce4a97a8 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -1600,24 +1600,9 @@ impl<'ast, T: Field> Checker<'ast, T> { _ => unreachable!("generic on declaration struct types must be generic identifiers") })); - // generate actual type based on generic type and concrete generics - let members = declared_struct_ty - .members - .into_iter() - .map(|m| { - Ok(DeclarationStructMember { - ty: box specialize_declaration_type(*m.ty, &assignment) - .unwrap(), - ..m - }) - }) - .collect::, _>>()?; - Ok(DeclarationType::Struct(DeclarationStructType { - canonical_location: declared_struct_ty.canonical_location, - location: declared_struct_ty.location, generics: checked_generics, - members, + ..declared_struct_ty })) } false => Err(ErrorInner { @@ -3113,11 +3098,19 @@ impl<'ast, T: Field> Checker<'ast, T> { Some(ty) => Ok(ty), }?; - let declared_struct_type = match ty { + let mut declared_struct_type = match ty { DeclarationType::Struct(struct_type) => struct_type, _ => unreachable!(), }; + declared_struct_type.generics = (0..declared_struct_type.generics.len()) + .map(|index| { + Some(DeclarationConstant::Generic( + GenericIdentifier::with_name("DUMMY").index(index), + )) + }) + .collect(); + // check that we provided the required number of values if declared_struct_type.members_count() != inline_members.len() { return Err(ErrorInner { diff --git a/zokrates_core/src/typed_absy/types.rs b/zokrates_core/src/typed_absy/types.rs index 24d125c4..4cdf41f2 100644 --- a/zokrates_core/src/typed_absy/types.rs +++ b/zokrates_core/src/typed_absy/types.rs @@ -57,7 +57,7 @@ impl<'ast, T> Types<'ast, T> { } } -#[derive(Debug, Clone, Eq, Ord)] +#[derive(Debug, Clone, Eq)] pub struct GenericIdentifier<'ast> { pub name: &'ast str, pub index: usize, @@ -86,6 +86,12 @@ impl<'ast> PartialOrd for GenericIdentifier<'ast> { } } +impl<'ast> Ord for GenericIdentifier<'ast> { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.partial_cmp(other).unwrap() + } +} + impl<'ast> Hash for GenericIdentifier<'ast> { fn hash(&self, state: &mut H) { self.index.hash(state); @@ -995,9 +1001,8 @@ pub fn specialize_declaration_type< Ok(match decl_ty { DeclarationType::Int => unreachable!(), DeclarationType::Array(t0) => { - // let s1 = t1.size.clone(); - let ty = box specialize_declaration_type(*t0.ty, &generics)?; + let size = match t0.size { DeclarationConstant::Generic(s) => generics.0.get(&s).cloned().ok_or(s), DeclarationConstant::Concrete(s) => Ok(s.into()), @@ -1009,37 +1014,63 @@ pub fn specialize_declaration_type< DeclarationType::FieldElement => GType::FieldElement, DeclarationType::Boolean => GType::Boolean, DeclarationType::Uint(b0) => GType::Uint(b0), - DeclarationType::Struct(s0) => GType::Struct(GStructType { - members: s0 - .members - .into_iter() - .map(|m| { - let id = m.id; - specialize_declaration_type(*m.ty, generics) - .map(|ty| GStructMember { ty: box ty, id }) - }) - .collect::>()?, - generics: s0 - .generics - .into_iter() - .map(|g| match g { - Some(constant) => match constant { - DeclarationConstant::Generic(s) => { - generics.0.get(&s).cloned().ok_or(s).map(Some) - } - DeclarationConstant::Concrete(s) => Ok(Some(s.into())), - DeclarationConstant::Constant(..) => { - unreachable!( - "identifiers should have been removed in constant inlining" - ) - } - }, - _ => Ok(None), - }) - .collect::>()?, - canonical_location: s0.canonical_location, - location: s0.location, - }), + DeclarationType::Struct(s0) => { + // here we specialize Foo {FooDef} with some values for Generics + // we need to remap these values for InsideGenerics to then visit the members + + let inside_generics = GGenericsAssignment( + s0.generics + .clone() + .into_iter() + .enumerate() + .map(|(index, g)| { + ( + GenericIdentifier::with_name("dummy").index(index), + g.map(|g| match g { + DeclarationConstant::Generic(s) => { + generics.0.get(&s).cloned().unwrap() + } + DeclarationConstant::Concrete(s) => s.into(), + DeclarationConstant::Constant(c) => c.into(), + }) + .unwrap(), + ) + }) + .collect(), + ); + + GType::Struct(GStructType { + members: s0 + .members + .into_iter() + .map(|m| { + let id = m.id; + specialize_declaration_type(*m.ty, &inside_generics) + .map(|ty| GStructMember { ty: box ty, id }) + }) + .collect::>()?, + generics: s0 + .generics + .into_iter() + .map(|g| match g { + Some(constant) => match constant { + DeclarationConstant::Generic(s) => { + generics.0.get(&s).cloned().ok_or(s).map(Some) + } + DeclarationConstant::Concrete(s) => Ok(Some(s.into())), + DeclarationConstant::Constant(..) => { + unreachable!( + "identifiers should have been removed in constant inlining" + ) + } + }, + _ => Ok(None), + }) + .collect::>()?, + canonical_location: s0.canonical_location, + location: s0.location, + }) + } }) } From 6f8b73ab0f4e00e3617880421bea117699891c25 Mon Sep 17 00:00:00 2001 From: schaeff Date: Thu, 16 Sep 2021 18:36:17 +0300 Subject: [PATCH 2/7] fix abi with concretization, fix StructType --- zokrates_core/src/semantics.rs | 32 +++++-- .../static_analysis/flatten_complex_types.rs | 2 + zokrates_core/src/static_analysis/mod.rs | 10 ++ .../src/static_analysis/propagation.rs | 18 ++-- .../src/static_analysis/struct_concretizer.rs | 96 +++++++++++++++++++ zokrates_core/src/typed_absy/mod.rs | 14 ++- zokrates_core/src/typed_absy/types.rs | 3 +- 7 files changed, 153 insertions(+), 22 deletions(-) create mode 100644 zokrates_core/src/static_analysis/struct_concretizer.rs diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index ce4a97a8..85421404 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -6,7 +6,7 @@ use crate::absy::Identifier; use crate::absy::*; -use crate::typed_absy::types::GGenericsAssignment; +use crate::typed_absy::types::{GGenericsAssignment, GenericsAssignment}; use crate::typed_absy::*; use crate::typed_absy::{DeclarationParameter, DeclarationVariable, Variable}; use num_bigint::BigUint; @@ -1032,17 +1032,28 @@ impl<'ast, T: Field> Checker<'ast, T> { match self.check_signature(funct.signature, module_id, state) { Ok(s) => { + // initialise generics map + let mut generics: GenericsAssignment<'ast, T> = GGenericsAssignment::default(); + // define variables for the constants for generic in &s.generics { - let generic = generic.clone().unwrap(); // for declaration signatures, generics cannot be ignored + let generic = match generic.clone().unwrap() { + DeclarationConstant::Generic(g) => g, + _ => unreachable!(), + }; + + // for declaration signatures, generics cannot be ignored let v = Variable::with_id_and_type( - match generic { - DeclarationConstant::Generic(g) => g.name, - _ => unreachable!(), - }, + generic.name.clone(), Type::Uint(UBitwidth::B32), ); + + generics.0.insert( + generic.clone(), + UExpressionInner::Identifier(generic.name.into()).annotate(UBitwidth::B32), + ); + // we don't have to check for conflicts here, because this was done when checking the signature self.insert_into_scope(v.clone()); } @@ -1055,9 +1066,12 @@ impl<'ast, T: Field> Checker<'ast, T> { let decl_v = DeclarationVariable::with_id_and_type(arg.id.value.id, decl_ty.clone()); - match self.insert_into_scope( - crate::typed_absy::variable::try_from_g_variable(decl_v.clone()).unwrap(), - ) { + let ty = specialize_declaration_type(decl_v.clone()._type, &generics).unwrap(); + + match self.insert_into_scope(crate::typed_absy::variable::Variable { + id: decl_v.clone().id, + _type: ty, + }) { true => {} false => { errors.push(ErrorInner { diff --git a/zokrates_core/src/static_analysis/flatten_complex_types.rs b/zokrates_core/src/static_analysis/flatten_complex_types.rs index f3973297..db213ca6 100644 --- a/zokrates_core/src/static_analysis/flatten_complex_types.rs +++ b/zokrates_core/src/static_analysis/flatten_complex_types.rs @@ -1125,6 +1125,8 @@ fn fold_struct_expression<'ast, T: Field>( statements_buffer: &mut Vec>, e: typed_absy::StructExpression<'ast, T>, ) -> Vec> { + println!("{:#?}", e.ty()); + f.fold_struct_expression_inner( statements_buffer, &typed_absy::types::ConcreteStructType::try_from(e.ty().clone()).unwrap(), diff --git a/zokrates_core/src/static_analysis/mod.rs b/zokrates_core/src/static_analysis/mod.rs index 2285115b..ae46821f 100644 --- a/zokrates_core/src/static_analysis/mod.rs +++ b/zokrates_core/src/static_analysis/mod.rs @@ -11,6 +11,7 @@ mod flat_propagation; mod flatten_complex_types; mod propagation; mod reducer; +mod struct_concretizer; mod uint_optimizer; mod unconstrained_vars; mod variable_write_remover; @@ -20,6 +21,7 @@ use self::constant_argument_checker::ConstantArgumentChecker; use self::flatten_complex_types::Flattener; use self::propagation::Propagator; use self::reducer::reduce_program; +use self::struct_concretizer::StructConcretizer; use self::uint_optimizer::UintOptimizer; use self::unconstrained_vars::UnconstrainedVariableDetector; use self::variable_write_remover::VariableWriteRemover; @@ -101,6 +103,14 @@ impl<'ast, T: Field> TypedProgram<'ast, T> { let r = reduce_program(r).map_err(Error::from)?; log::trace!("\n{}", r); + log::debug!("Static analyser: Propagate"); + let r = Propagator::propagate(r)?; + log::trace!("\n{}", r); + + log::debug!("Static analyser: Concretize structs"); + let r = StructConcretizer::concretize(r); + log::trace!("\n{}", r); + // generate abi log::debug!("Static analyser: Generate abi"); let abi = r.abi(); diff --git a/zokrates_core/src/static_analysis/propagation.rs b/zokrates_core/src/static_analysis/propagation.rs index b90fc99d..1450e077 100644 --- a/zokrates_core/src/static_analysis/propagation.rs +++ b/zokrates_core/src/static_analysis/propagation.rs @@ -1194,16 +1194,14 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { let e1 = self.fold_struct_expression(e1)?; let e2 = self.fold_struct_expression(e2)?; - if let (Ok(t1), Ok(t2)) = ( - ConcreteType::try_from(e1.get_type()), - ConcreteType::try_from(e2.get_type()), - ) { - if t1 != t2 { - return Err(Error::Type(format!( - "Cannot compare {} of type {} to {} of type {}", - e1, t1, e2, t2 - ))); - } + let t1 = e1.get_type(); + let t2 = e2.get_type(); + + if t1 != t2 { + return Err(Error::Type(format!( + "Cannot compare {} of type {} to {} of type {}", + e1, t1, e2, t2 + ))); }; Ok(BooleanExpression::StructEq(box e1, box e2)) diff --git a/zokrates_core/src/static_analysis/struct_concretizer.rs b/zokrates_core/src/static_analysis/struct_concretizer.rs new file mode 100644 index 00000000..874a4b36 --- /dev/null +++ b/zokrates_core/src/static_analysis/struct_concretizer.rs @@ -0,0 +1,96 @@ +// After all generics are inlined, a program should be completely "concrete", which means that all types must only contain +// litterals for array sizes. This is especially important to generate the ABI of the program. +// It is direct to ensure that with most types, however the way structs are implemented requires a slightly different process: +// Where for an array, `field[N]` ends up being propagated to `field[42]` which is direct to turn into a concrete type, +// for structs, `Foo { field[N] a }` is propagated to `Foo<42> { field[N] a }`. The missing step is replacing `N` by `42` +// *inside* the canonical type, so that it can be concretized in the same way arrays are. +// We apply this transformation only to the main function. + +use crate::typed_absy::folder::*; +use crate::typed_absy::{ + types::{ + ConcreteGenericsAssignment, DeclarationArrayType, DeclarationConstant, + DeclarationStructMember, GGenericsAssignment, + }, + DeclarationStructType, GenericIdentifier, TypedProgram, +}; +use zokrates_field::Field; + +#[derive(Default)] +pub struct StructConcretizer<'ast> { + generics: ConcreteGenericsAssignment<'ast>, +} + +impl<'ast> StructConcretizer<'ast> { + pub fn concretize(p: TypedProgram<'ast, T>) -> TypedProgram<'ast, T> { + StructConcretizer::default().fold_program(p) + } + + pub fn with_generics(generics: ConcreteGenericsAssignment<'ast>) -> Self { + Self { generics } + } +} + +impl<'ast, T: Field> Folder<'ast, T> for StructConcretizer<'ast> { + fn fold_declaration_struct_type( + &mut self, + ty: DeclarationStructType<'ast>, + ) -> DeclarationStructType<'ast> { + let concrete_generics: Vec<_> = ty + .generics + .iter() + .map(|g| match g.as_ref().unwrap() { + DeclarationConstant::Generic(s) => self.generics.0.get(&s).cloned().unwrap(), + DeclarationConstant::Concrete(s) => *s as usize, + DeclarationConstant::Constant(..) => unreachable!(), + }) + .collect(); + + let concrete_generics_map: ConcreteGenericsAssignment = GGenericsAssignment( + concrete_generics + .iter() + .enumerate() + .map(|(index, g)| (GenericIdentifier::with_name("DUMMY").index(index), *g)) + .collect(), + ); + + let mut internal_concretizer = StructConcretizer::with_generics(concrete_generics_map); + + DeclarationStructType { + members: ty + .members + .into_iter() + .map(|member| { + DeclarationStructMember::new( + member.id, + >::fold_declaration_type( + &mut internal_concretizer, + *member.ty, + ), + ) + }) + .collect(), + generics: concrete_generics + .into_iter() + .map(|g| Some(DeclarationConstant::Concrete(g as u32))) + .collect(), + ..ty + } + } + + fn fold_declaration_array_type( + &mut self, + ty: DeclarationArrayType<'ast>, + ) -> DeclarationArrayType<'ast> { + let size = match ty.size { + DeclarationConstant::Generic(s) => self.generics.0.get(&s).cloned().unwrap() as u32, + DeclarationConstant::Concrete(s) => s, + DeclarationConstant::Constant(..) => unreachable!(), + }; + + DeclarationArrayType { + size: DeclarationConstant::Concrete(size), + ty: box >::fold_declaration_type(self, *ty.ty), + } + } +} diff --git a/zokrates_core/src/typed_absy/mod.rs b/zokrates_core/src/typed_absy/mod.rs index b31dfeee..29a8dfb6 100644 --- a/zokrates_core/src/typed_absy/mod.rs +++ b/zokrates_core/src/typed_absy/mod.rs @@ -663,7 +663,19 @@ impl<'ast, T: fmt::Display> fmt::Display for StructExpression<'ast, T> { StructExpressionInner::IfElse(ref c) => write!(f, "{}", c), StructExpressionInner::Member(ref m) => write!(f, "{}", m), StructExpressionInner::Select(ref select) => write!(f, "{}", select), - } + }?; + + write!( + f, + "/* {} {{{}}} */", + self.ty, + self.ty + .members + .iter() + .map(|m| format!("{}: {}", m.id, m.ty)) + .collect::>() + .join(", ") + ) } } diff --git a/zokrates_core/src/typed_absy/types.rs b/zokrates_core/src/typed_absy/types.rs index 4cdf41f2..94a6acc1 100644 --- a/zokrates_core/src/typed_absy/types.rs +++ b/zokrates_core/src/typed_absy/types.rs @@ -371,8 +371,7 @@ impl<'ast, S, R: PartialEq> PartialEq> for GStructType { .zip(other.generics.iter()) .all(|(a, b)| match (a, b) { (Some(a), Some(b)) => a == b, - (None, None) => true, - _ => false, + _ => true, }) } } From a3bfa9f6d6573fc55ab70a779de5b3895e03d728 Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 17 Sep 2021 16:21:52 +0300 Subject: [PATCH 3/7] clippy --- zokrates_core/src/semantics.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 85421404..213a69a7 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -1044,10 +1044,7 @@ impl<'ast, T: Field> Checker<'ast, T> { // for declaration signatures, generics cannot be ignored - let v = Variable::with_id_and_type( - generic.name.clone(), - Type::Uint(UBitwidth::B32), - ); + let v = Variable::with_id_and_type(generic.name, Type::Uint(UBitwidth::B32)); generics.0.insert( generic.clone(), From ae825b7f36334974d57b298c182c1aed326ac86d Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 21 Sep 2021 14:01:49 +0300 Subject: [PATCH 4/7] update highlighters --- zokrates_parser/src/ace_mode/index.js | 2 +- .../src/textmate/zokrates.tmLanguage.yaml | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/zokrates_parser/src/ace_mode/index.js b/zokrates_parser/src/ace_mode/index.js index 9778609b..b576695f 100644 --- a/zokrates_parser/src/ace_mode/index.js +++ b/zokrates_parser/src/ace_mode/index.js @@ -37,7 +37,7 @@ ace.define("ace/mode/zokrates_highlight_rules",["require","exports","module","ac var ZoKratesHighlightRules = function () { var keywords = ( - "assert|as|bool|byte|const|def|do|else|endfor|export|false|field|for|if|then|fi|import|from|in|private|public|return|struct|true|u8|u16|u32|u64" + "assert|as|bool|byte|const|def|do|else|endfor|export|false|field|for|if|then|fi|import|from|in|private|public|return|struct|true|type|u8|u16|u32|u64" ); var keywordMapper = this.createKeywordMapper({ diff --git a/zokrates_parser/src/textmate/zokrates.tmLanguage.yaml b/zokrates_parser/src/textmate/zokrates.tmLanguage.yaml index 2a2e9fb6..bb200057 100644 --- a/zokrates_parser/src/textmate/zokrates.tmLanguage.yaml +++ b/zokrates_parser/src/textmate/zokrates.tmLanguage.yaml @@ -202,19 +202,23 @@ repository: - comment: 'control flow keywords' name: keyword.control.zokrates - match: \b(do|else|for|do|endfor|if|then|fi|return|assert)\b + match: \b(for|in|do|endfor|if|then|else|fi|return|assert)\b - comment: 'storage keywords' name: storage.type.zokrates match: \b(struct)\b - - comment: const + comment: 'const keyword' name: keyword.other.const.zokrates - match: \bconst\b + match: \b(const)\b - - comment: def + comment: 'type keyword' + name: keyword.other.type.zokrates + match: \b(type)\b + - + comment: 'def keyword' name: keyword.other.def.zokrates - match: \bdef\b + match: \b(def)\b - comment: 'import keywords' name: keyword.other.import.zokrates From fad1b2fa3773e8b3952d683904f2f34e77b5021d Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 21 Sep 2021 15:14:26 +0300 Subject: [PATCH 5/7] clean, use u32 for concrete array sizes, introduce functions to map using generic assignments --- zokrates_core/src/embed.rs | 24 ++-- .../static_analysis/flatten_complex_types.rs | 15 +-- .../src/static_analysis/struct_concretizer.rs | 11 +- .../static_analysis/variable_write_remover.rs | 7 +- zokrates_core/src/typed_absy/mod.rs | 14 +-- zokrates_core/src/typed_absy/types.rs | 112 ++++++++---------- zokrates_core/src/typed_absy/uint.rs | 10 +- zokrates_core/src/typed_absy/variable.rs | 2 +- zokrates_core/src/zir/identifier.rs | 2 +- 9 files changed, 80 insertions(+), 117 deletions(-) diff --git a/zokrates_core/src/embed.rs b/zokrates_core/src/embed.rs index 3ee07660..88f0604c 100644 --- a/zokrates_core/src/embed.rs +++ b/zokrates_core/src/embed.rs @@ -94,59 +94,59 @@ impl FlatEmbed { .inputs(vec![DeclarationType::uint(8)]) .outputs(vec![DeclarationType::array(( DeclarationType::Boolean, - 8usize, + 8u32, ))]), FlatEmbed::U16ToBits => DeclarationSignature::new() .inputs(vec![DeclarationType::uint(16)]) .outputs(vec![DeclarationType::array(( DeclarationType::Boolean, - 16usize, + 16u32, ))]), FlatEmbed::U32ToBits => DeclarationSignature::new() .inputs(vec![DeclarationType::uint(32)]) .outputs(vec![DeclarationType::array(( DeclarationType::Boolean, - 32usize, + 32u32, ))]), FlatEmbed::U64ToBits => DeclarationSignature::new() .inputs(vec![DeclarationType::uint(64)]) .outputs(vec![DeclarationType::array(( DeclarationType::Boolean, - 64usize, + 64u32, ))]), FlatEmbed::U8FromBits => DeclarationSignature::new() .outputs(vec![DeclarationType::uint(8)]) .inputs(vec![DeclarationType::array(( DeclarationType::Boolean, - 8usize, + 8u32, ))]), FlatEmbed::U16FromBits => DeclarationSignature::new() .outputs(vec![DeclarationType::uint(16)]) .inputs(vec![DeclarationType::array(( DeclarationType::Boolean, - 16usize, + 16u32, ))]), FlatEmbed::U32FromBits => DeclarationSignature::new() .outputs(vec![DeclarationType::uint(32)]) .inputs(vec![DeclarationType::array(( DeclarationType::Boolean, - 32usize, + 32u32, ))]), FlatEmbed::U64FromBits => DeclarationSignature::new() .outputs(vec![DeclarationType::uint(64)]) .inputs(vec![DeclarationType::array(( DeclarationType::Boolean, - 64usize, + 64u32, ))]), #[cfg(feature = "bellman")] FlatEmbed::Sha256Round => DeclarationSignature::new() .inputs(vec![ - DeclarationType::array((DeclarationType::Boolean, 512usize)), - DeclarationType::array((DeclarationType::Boolean, 256usize)), + DeclarationType::array((DeclarationType::Boolean, 512u32)), + DeclarationType::array((DeclarationType::Boolean, 256u32)), ]) .outputs(vec![DeclarationType::array(( DeclarationType::Boolean, - 256usize, + 256u32, ))]), #[cfg(feature = "ark")] FlatEmbed::SnarkVerifyBls12377 => DeclarationSignature::new() @@ -168,7 +168,7 @@ impl FlatEmbed { index: 0, }, )), // inputs - DeclarationType::array((DeclarationType::FieldElement, 8usize)), // proof + DeclarationType::array((DeclarationType::FieldElement, 8u32)), // proof DeclarationType::array(( DeclarationType::FieldElement, GenericIdentifier { diff --git a/zokrates_core/src/static_analysis/flatten_complex_types.rs b/zokrates_core/src/static_analysis/flatten_complex_types.rs index db213ca6..c9fcfea3 100644 --- a/zokrates_core/src/static_analysis/flatten_complex_types.rs +++ b/zokrates_core/src/static_analysis/flatten_complex_types.rs @@ -340,7 +340,7 @@ impl<'ast, T: Field> Flattener { &mut self, statements_buffer: &mut Vec>, ty: &typed_absy::types::ConcreteType, - size: usize, + size: u32, e: typed_absy::ArrayExpressionInner<'ast, T>, ) -> Vec> { fold_array_expression_inner(self, statements_buffer, ty, size, e) @@ -404,7 +404,7 @@ fn fold_array_expression_inner<'ast, T: Field>( f: &mut Flattener, statements_buffer: &mut Vec>, ty: &typed_absy::types::ConcreteType, - size: usize, + size: u32, array: typed_absy::ArrayExpressionInner<'ast, T>, ) -> Vec> { match array { @@ -437,7 +437,7 @@ fn fold_array_expression_inner<'ast, T: Field>( .flat_map(|e| f.fold_expression_or_spread(statements_buffer, e)) .collect(); - assert_eq!(exprs.len(), size * ty.get_primitive_count()); + assert_eq!(exprs.len(), size as usize * ty.get_primitive_count()); exprs } @@ -458,7 +458,7 @@ fn fold_array_expression_inner<'ast, T: Field>( match (from.into_inner(), to.into_inner()) { (zir::UExpressionInner::Value(from), zir::UExpressionInner::Value(to)) => { - assert_eq!(size, to.saturating_sub(from) as usize); + assert_eq!(size, to.saturating_sub(from) as u32); let element_size = ty.get_primitive_count(); let start = from as usize * element_size; @@ -1108,10 +1108,7 @@ fn fold_array_expression<'ast, T: Field>( statements_buffer: &mut Vec>, e: typed_absy::ArrayExpression<'ast, T>, ) -> Vec> { - let size = match e.size().into_inner() { - typed_absy::UExpressionInner::Value(v) => v, - _ => unreachable!(), - } as usize; + let size: u32 = e.size().try_into().unwrap(); f.fold_array_expression_inner( statements_buffer, &typed_absy::types::ConcreteType::try_from(e.inner_type().clone()).unwrap(), @@ -1125,8 +1122,6 @@ fn fold_struct_expression<'ast, T: Field>( statements_buffer: &mut Vec>, e: typed_absy::StructExpression<'ast, T>, ) -> Vec> { - println!("{:#?}", e.ty()); - f.fold_struct_expression_inner( statements_buffer, &typed_absy::types::ConcreteStructType::try_from(e.ty().clone()).unwrap(), diff --git a/zokrates_core/src/static_analysis/struct_concretizer.rs b/zokrates_core/src/static_analysis/struct_concretizer.rs index 874a4b36..2b137357 100644 --- a/zokrates_core/src/static_analysis/struct_concretizer.rs +++ b/zokrates_core/src/static_analysis/struct_concretizer.rs @@ -36,14 +36,11 @@ impl<'ast, T: Field> Folder<'ast, T> for StructConcretizer<'ast> { &mut self, ty: DeclarationStructType<'ast>, ) -> DeclarationStructType<'ast> { - let concrete_generics: Vec<_> = ty + let concrete_generics: Vec = ty .generics - .iter() - .map(|g| match g.as_ref().unwrap() { - DeclarationConstant::Generic(s) => self.generics.0.get(&s).cloned().unwrap(), - DeclarationConstant::Concrete(s) => *s as usize, - DeclarationConstant::Constant(..) => unreachable!(), - }) + .clone() + .into_iter() + .map(|g| g.unwrap().map_concrete(&self.generics).unwrap()) .collect(); let concrete_generics_map: ConcreteGenericsAssignment = GGenericsAssignment( diff --git a/zokrates_core/src/static_analysis/variable_write_remover.rs b/zokrates_core/src/static_analysis/variable_write_remover.rs index 82cc206e..e66a4461 100644 --- a/zokrates_core/src/static_analysis/variable_write_remover.rs +++ b/zokrates_core/src/static_analysis/variable_write_remover.rs @@ -37,10 +37,9 @@ impl<'ast> VariableWriteRemover { let inner_ty = base.inner_type(); let size = base.size(); - let size = match size.as_inner() { - UExpressionInner::Value(v) => *v as u32, - _ => unreachable!(), - }; + use std::convert::TryInto; + + let size: u32 = size.try_into().unwrap(); let head = indices.remove(0); let tail = indices; diff --git a/zokrates_core/src/typed_absy/mod.rs b/zokrates_core/src/typed_absy/mod.rs index 29a8dfb6..b31dfeee 100644 --- a/zokrates_core/src/typed_absy/mod.rs +++ b/zokrates_core/src/typed_absy/mod.rs @@ -663,19 +663,7 @@ impl<'ast, T: fmt::Display> fmt::Display for StructExpression<'ast, T> { StructExpressionInner::IfElse(ref c) => write!(f, "{}", c), StructExpressionInner::Member(ref m) => write!(f, "{}", m), StructExpressionInner::Select(ref select) => write!(f, "{}", select), - }?; - - write!( - f, - "/* {} {{{}}} */", - self.ty, - self.ty - .members - .iter() - .map(|m| format!("{}: {}", m.id, m.ty)) - .collect::>() - .join(", ") - ) + } } } diff --git a/zokrates_core/src/typed_absy/types.rs b/zokrates_core/src/typed_absy/types.rs index 94a6acc1..608cdb88 100644 --- a/zokrates_core/src/typed_absy/types.rs +++ b/zokrates_core/src/typed_absy/types.rs @@ -137,6 +137,32 @@ pub enum DeclarationConstant<'ast> { Constant(CanonicalConstantIdentifier<'ast>), } +impl<'ast> DeclarationConstant<'ast> { + pub fn map> + From + Clone>( + self, + generics: &GGenericsAssignment<'ast, S>, + ) -> Result> { + match self { + DeclarationConstant::Generic(g) => generics.0.get(&g).cloned().ok_or(g), + DeclarationConstant::Concrete(v) => Ok(v.into()), + DeclarationConstant::Constant(c) => Ok(c.into()), + } + } + + pub fn map_concrete + Clone>( + self, + generics: &GGenericsAssignment<'ast, S>, + ) -> Result> { + match self { + DeclarationConstant::Constant(_) => unreachable!( + "called map_concrete on a constant, it should have been resolved before" + ), + DeclarationConstant::Generic(g) => generics.0.get(&g).cloned().ok_or(g), + DeclarationConstant::Concrete(v) => Ok(v.into()), + } + } +} + impl<'ast, T> PartialEq> for DeclarationConstant<'ast> { fn eq(&self, other: &UExpression<'ast, T>) -> bool { match (self, other.as_inner()) { @@ -158,12 +184,6 @@ impl<'ast> From for DeclarationConstant<'ast> { } } -impl<'ast> From for DeclarationConstant<'ast> { - fn from(e: usize) -> Self { - DeclarationConstant::Concrete(e as u32) - } -} - impl<'ast> From> for DeclarationConstant<'ast> { fn from(e: GenericIdentifier<'ast>) -> Self { DeclarationConstant::Generic(e) @@ -180,8 +200,8 @@ impl<'ast> fmt::Display for DeclarationConstant<'ast> { } } -impl<'ast, T> From for UExpression<'ast, T> { - fn from(i: usize) -> Self { +impl<'ast, T> From for UExpression<'ast, T> { + fn from(i: u32) -> Self { UExpressionInner::Value(i as u128).annotate(UBitwidth::B32) } } @@ -202,25 +222,14 @@ impl<'ast, T> From> for UExpression<'ast, T> { } } -impl<'ast, T> TryInto for UExpression<'ast, T> { +impl<'ast, T> TryInto for UExpression<'ast, T> { type Error = SpecializationError; - fn try_into(self) -> Result { + fn try_into(self) -> Result { assert_eq!(self.bitwidth, UBitwidth::B32); match self.into_inner() { - UExpressionInner::Value(v) => Ok(v as usize), - _ => Err(SpecializationError), - } - } -} - -impl<'ast> TryInto for DeclarationConstant<'ast> { - type Error = SpecializationError; - - fn try_into(self) -> Result { - match self { - DeclarationConstant::Concrete(v) => Ok(v as usize), + UExpressionInner::Value(v) => Ok(v as u32), _ => Err(SpecializationError), } } @@ -237,7 +246,7 @@ pub struct GStructMember { } pub type DeclarationStructMember<'ast> = GStructMember>; -pub type ConcreteStructMember = GStructMember; +pub type ConcreteStructMember = GStructMember; pub type StructMember<'ast, T> = GStructMember>; impl<'ast, S, R: PartialEq> PartialEq> for GStructMember { @@ -277,7 +286,7 @@ pub struct GArrayType { } pub type DeclarationArrayType<'ast> = GArrayType>; -pub type ConcreteArrayType = GArrayType; +pub type ConcreteArrayType = GArrayType; pub type ArrayType<'ast, T> = GArrayType>; impl<'ast, S, R: PartialEq> PartialEq> for GArrayType { @@ -359,7 +368,7 @@ pub struct GStructType { } pub type DeclarationStructType<'ast> = GStructType>; -pub type ConcreteStructType = GStructType; +pub type ConcreteStructType = GStructType; pub type StructType<'ast, T> = GStructType>; impl<'ast, S, R: PartialEq> PartialEq> for GStructType { @@ -615,7 +624,7 @@ impl<'de, S: Deserialize<'de>> Deserialize<'de> for GType { } pub type DeclarationType<'ast> = GType>; -pub type ConcreteType = GType; +pub type ConcreteType = GType; pub type Type<'ast, T> = GType>; impl<'ast, S, R: PartialEq> PartialEq> for GType { @@ -804,7 +813,9 @@ impl ConcreteType { GType::FieldElement => 1, GType::Boolean => 1, GType::Uint(_) => 1, - GType::Array(array_type) => array_type.size * array_type.ty.get_primitive_count(), + GType::Array(array_type) => { + array_type.size as usize * array_type.ty.get_primitive_count() + } GType::Int => unreachable!(), GType::Struct(struct_type) => struct_type .iter() @@ -824,7 +835,7 @@ pub struct GFunctionKey<'ast, S> { } pub type DeclarationFunctionKey<'ast> = GFunctionKey<'ast, DeclarationConstant<'ast>>; -pub type ConcreteFunctionKey<'ast> = GFunctionKey<'ast, usize>; +pub type ConcreteFunctionKey<'ast> = GFunctionKey<'ast, u32>; pub type FunctionKey<'ast, T> = GFunctionKey<'ast, UExpression<'ast, T>>; impl<'ast, S: fmt::Display> fmt::Display for GFunctionKey<'ast, S> { @@ -836,7 +847,7 @@ impl<'ast, S: fmt::Display> fmt::Display for GFunctionKey<'ast, S> { #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub struct GGenericsAssignment<'ast, S>(pub BTreeMap, S>); -pub type ConcreteGenericsAssignment<'ast> = GGenericsAssignment<'ast, usize>; +pub type ConcreteGenericsAssignment<'ast> = GGenericsAssignment<'ast, u32>; pub type GenericsAssignment<'ast, T> = GGenericsAssignment<'ast, UExpression<'ast, T>>; impl<'ast, S> Default for GGenericsAssignment<'ast, S> { @@ -936,7 +947,7 @@ impl<'ast> ConcreteFunctionKey<'ast> { use std::collections::btree_map::Entry; -pub fn check_type<'ast, S: Clone + PartialEq + PartialEq>( +pub fn check_type<'ast, S: Clone + PartialEq + PartialEq>( decl_ty: &DeclarationType<'ast>, ty: >ype, constants: &mut GGenericsAssignment<'ast, S>, @@ -957,7 +968,7 @@ pub fn check_type<'ast, S: Clone + PartialEq + PartialEq>( true } }, - DeclarationConstant::Concrete(s0) => s1 == *s0 as usize, + DeclarationConstant::Concrete(s0) => s1 == *s0 as u32, // in the case of a constant, we do not know the value yet, so we optimistically assume it's correct // if it does not match, it will be caught during inlining DeclarationConstant::Constant(..) => true, @@ -1002,11 +1013,7 @@ pub fn specialize_declaration_type< DeclarationType::Array(t0) => { let ty = box specialize_declaration_type(*t0.ty, &generics)?; - let size = match t0.size { - DeclarationConstant::Generic(s) => generics.0.get(&s).cloned().ok_or(s), - DeclarationConstant::Concrete(s) => Ok(s.into()), - DeclarationConstant::Constant(c) => Ok(c.into()), - }?; + let size = t0.size.map(generics)?; GType::Array(GArrayType { size, ty }) } @@ -1025,14 +1032,7 @@ pub fn specialize_declaration_type< .map(|(index, g)| { ( GenericIdentifier::with_name("dummy").index(index), - g.map(|g| match g { - DeclarationConstant::Generic(s) => { - generics.0.get(&s).cloned().unwrap() - } - DeclarationConstant::Concrete(s) => s.into(), - DeclarationConstant::Constant(c) => c.into(), - }) - .unwrap(), + g.map(|g| g.map(generics).unwrap()).unwrap(), ) }) .collect(), @@ -1052,17 +1052,7 @@ pub fn specialize_declaration_type< .generics .into_iter() .map(|g| match g { - Some(constant) => match constant { - DeclarationConstant::Generic(s) => { - generics.0.get(&s).cloned().ok_or(s).map(Some) - } - DeclarationConstant::Concrete(s) => Ok(Some(s.into())), - DeclarationConstant::Constant(..) => { - unreachable!( - "identifiers should have been removed in constant inlining" - ) - } - }, + Some(constant) => constant.map(generics).map(Some), _ => Ok(None), }) .collect::>()?, @@ -1127,7 +1117,7 @@ pub mod signature { } pub type DeclarationSignature<'ast> = GSignature>; - pub type ConcreteSignature = GSignature; + pub type ConcreteSignature = GSignature; pub type Signature<'ast, T> = GSignature>; impl<'ast> PartialEq> for ConcreteSignature { @@ -1140,7 +1130,7 @@ pub mod signature { .iter() .chain(other.outputs.iter()) .zip(self.inputs.iter().chain(self.outputs.iter())) - .all(|(decl_ty, ty)| check_type::(decl_ty, ty, &mut constants)) + .all(|(decl_ty, ty)| check_type::(decl_ty, ty, &mut constants)) } } @@ -1165,7 +1155,7 @@ pub mod signature { constants.0.extend( decl_generics .zip(values.into_iter()) - .filter_map(|(g, v)| v.map(|v| (g, v as usize))), + .filter_map(|(g, v)| v.map(|v| (g, v))), ); let condition = self @@ -1488,8 +1478,8 @@ pub mod signature { fn array_slug() { let s = ConcreteSignature::new() .inputs(vec![ - ConcreteType::array((ConcreteType::FieldElement, 42usize)), - ConcreteType::array((ConcreteType::FieldElement, 21usize)), + ConcreteType::array((ConcreteType::FieldElement, 42u32)), + ConcreteType::array((ConcreteType::FieldElement, 21u32)), ]) .outputs(vec![]); @@ -1512,7 +1502,7 @@ mod tests { fn array_display() { // field[1][2] let t = ConcreteType::Array(ConcreteArrayType::new( - ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 2usize)), + ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 2u32)), 1usize, )); assert_eq!(format!("{}", t), "field[1][2]"); diff --git a/zokrates_core/src/typed_absy/uint.rs b/zokrates_core/src/typed_absy/uint.rs index 4620dd7c..3fab93a8 100644 --- a/zokrates_core/src/typed_absy/uint.rs +++ b/zokrates_core/src/typed_absy/uint.rs @@ -146,12 +146,6 @@ pub struct UExpression<'ast, T> { pub inner: UExpressionInner<'ast, T>, } -impl<'ast, T> From for UExpression<'ast, T> { - fn from(u: u32) -> Self { - UExpressionInner::Value(u as u128).annotate(UBitwidth::B32) - } -} - impl<'ast, T> From for UExpression<'ast, T> { fn from(u: u16) -> Self { UExpressionInner::Value(u as u128).annotate(UBitwidth::B16) @@ -164,8 +158,8 @@ impl<'ast, T> From for UExpression<'ast, T> { } } -impl<'ast, T> PartialEq for UExpression<'ast, T> { - fn eq(&self, other: &usize) -> bool { +impl<'ast, T> PartialEq for UExpression<'ast, T> { + fn eq(&self, other: &u32) -> bool { match self.as_inner() { UExpressionInner::Value(v) => *v == *other as u128, _ => true, diff --git a/zokrates_core/src/typed_absy/variable.rs b/zokrates_core/src/typed_absy/variable.rs index 2d19a95e..281b9a49 100644 --- a/zokrates_core/src/typed_absy/variable.rs +++ b/zokrates_core/src/typed_absy/variable.rs @@ -12,7 +12,7 @@ pub struct GVariable<'ast, S> { } pub type DeclarationVariable<'ast> = GVariable<'ast, DeclarationConstant<'ast>>; -pub type ConcreteVariable<'ast> = GVariable<'ast, usize>; +pub type ConcreteVariable<'ast> = GVariable<'ast, u32>; pub type Variable<'ast, T> = GVariable<'ast, UExpression<'ast, T>>; impl<'ast, T> TryFrom> for ConcreteVariable<'ast> { diff --git a/zokrates_core/src/zir/identifier.rs b/zokrates_core/src/zir/identifier.rs index 87eea34d..9f7b6a9e 100644 --- a/zokrates_core/src/zir/identifier.rs +++ b/zokrates_core/src/zir/identifier.rs @@ -11,7 +11,7 @@ pub enum Identifier<'ast> { #[derive(Debug, PartialEq, Clone, Hash, Eq)] pub enum SourceIdentifier<'ast> { Basic(CoreIdentifier<'ast>), - Select(Box>, usize), + Select(Box>, u32), Member(Box>, MemberId), } From 2e589796d7404232a9267b413eb70147d447bd3b Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 21 Sep 2021 15:34:51 +0300 Subject: [PATCH 6/7] refactor GenericIdentifier to avoid dummy names --- zokrates_core/src/embed.rs | 49 +++++-------------- zokrates_core/src/semantics.rs | 44 ++++++++--------- .../static_analysis/reducer/shallow_ssa.rs | 2 +- .../src/static_analysis/struct_concretizer.rs | 36 +++++++------- zokrates_core/src/typed_absy/types.rs | 34 ++++++++++--- 5 files changed, 78 insertions(+), 87 deletions(-) diff --git a/zokrates_core/src/embed.rs b/zokrates_core/src/embed.rs index 88f0604c..496ceaa8 100644 --- a/zokrates_core/src/embed.rs +++ b/zokrates_core/src/embed.rs @@ -50,25 +50,16 @@ impl FlatEmbed { match self { FlatEmbed::BitArrayLe => DeclarationSignature::new() .generics(vec![Some(DeclarationConstant::Generic( - GenericIdentifier { - name: "N", - index: 0, - }, + GenericIdentifier::with_name("N").with_index(0), ))]) .inputs(vec![ DeclarationType::array(( DeclarationType::Boolean, - GenericIdentifier { - name: "N", - index: 0, - }, + GenericIdentifier::with_name("N").with_index(0), )), DeclarationType::array(( DeclarationType::Boolean, - GenericIdentifier { - name: "N", - index: 0, - }, + GenericIdentifier::with_name("N").with_index(0), )), ]) .outputs(vec![DeclarationType::Boolean]), @@ -77,18 +68,12 @@ impl FlatEmbed { .outputs(vec![DeclarationType::FieldElement]), FlatEmbed::Unpack => DeclarationSignature::new() .generics(vec![Some(DeclarationConstant::Generic( - GenericIdentifier { - name: "N", - index: 0, - }, + GenericIdentifier::with_name("N").with_index(0), ))]) .inputs(vec![DeclarationType::FieldElement]) .outputs(vec![DeclarationType::array(( DeclarationType::Boolean, - GenericIdentifier { - name: "N", - index: 0, - }, + GenericIdentifier::with_name("N").with_index(0), ))]), FlatEmbed::U8ToBits => DeclarationSignature::new() .inputs(vec![DeclarationType::uint(8)]) @@ -151,30 +136,22 @@ impl FlatEmbed { #[cfg(feature = "ark")] FlatEmbed::SnarkVerifyBls12377 => DeclarationSignature::new() .generics(vec![ - Some(DeclarationConstant::Generic(GenericIdentifier { - name: "N", - index: 0, - })), - Some(DeclarationConstant::Generic(GenericIdentifier { - name: "V", - index: 1, - })), + Some(DeclarationConstant::Generic( + GenericIdentifier::with_name("N").with_index(0), + )), + Some(DeclarationConstant::Generic( + GenericIdentifier::with_name("V").with_index(1), + )), ]) .inputs(vec![ DeclarationType::array(( DeclarationType::FieldElement, - GenericIdentifier { - name: "N", - index: 0, - }, + GenericIdentifier::with_name("N").with_index(0), )), // inputs DeclarationType::array((DeclarationType::FieldElement, 8u32)), // proof DeclarationType::array(( DeclarationType::FieldElement, - GenericIdentifier { - name: "V", - index: 1, - }, + GenericIdentifier::with_name("V").with_index(1), )), // 18 + (2 * n) // vk ]) .outputs(vec![DeclarationType::Boolean]), diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 213a69a7..ff019481 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -382,10 +382,9 @@ impl<'ast, T: Field> Checker<'ast, T> { } else { match generics_map.insert(g.value, index).is_none() { true => { - generics.push(Some(DeclarationConstant::Generic(GenericIdentifier { - name: g.value, - index, - }))); + generics.push(Some(DeclarationConstant::Generic( + GenericIdentifier::with_name(g.value).with_index(index), + ))); } false => { errors.push(ErrorInner { @@ -515,10 +514,9 @@ impl<'ast, T: Field> Checker<'ast, T> { } else { match generics_map.insert(g.value, index).is_none() { true => { - generics.push(Some(DeclarationConstant::Generic(GenericIdentifier { - name: g.value, - index, - }))); + generics.push(Some(DeclarationConstant::Generic( + GenericIdentifier::with_name(g.value).with_index(index), + ))); } false => { errors.push(ErrorInner { @@ -1044,11 +1042,12 @@ impl<'ast, T: Field> Checker<'ast, T> { // for declaration signatures, generics cannot be ignored - let v = Variable::with_id_and_type(generic.name, Type::Uint(UBitwidth::B32)); + let v = Variable::with_id_and_type(generic.name(), Type::Uint(UBitwidth::B32)); generics.0.insert( generic.clone(), - UExpressionInner::Identifier(generic.name.into()).annotate(UBitwidth::B32), + UExpressionInner::Identifier(generic.name().into()) + .annotate(UBitwidth::B32), ); // we don't have to check for conflicts here, because this was done when checking the signature @@ -1191,10 +1190,9 @@ impl<'ast, T: Field> Checker<'ast, T> { } else { match generics_map.insert(g.value, index).is_none() { true => { - generics.push(Some(DeclarationConstant::Generic(GenericIdentifier { - name: g.value, - index, - }))); + generics.push(Some(DeclarationConstant::Generic( + GenericIdentifier::with_name(g.value).with_index(index), + ))); } false => { errors.push(ErrorInner { @@ -1482,7 +1480,7 @@ impl<'ast, T: Field> Checker<'ast, T> { }) } } - (None, Some(index)) => Ok(DeclarationConstant::Generic(GenericIdentifier { name, index: *index })), + (None, Some(index)) => Ok(DeclarationConstant::Generic(GenericIdentifier::with_name(name).with_index(*index))), _ => Err(ErrorInner { pos: Some(pos), message: format!("Undeclared symbol `{}`", name) @@ -3117,7 +3115,7 @@ impl<'ast, T: Field> Checker<'ast, T> { declared_struct_type.generics = (0..declared_struct_type.generics.len()) .map(|index| { Some(DeclarationConstant::Generic( - GenericIdentifier::with_name("DUMMY").index(index), + GenericIdentifier::without_name().with_index(index), )) }) .collect(); @@ -3676,7 +3674,7 @@ mod tests { "bar", DeclarationSignature::new() .generics(vec![Some( - GenericIdentifier::with_name("K").index(0).into() + GenericIdentifier::with_name("K").with_index(0).into() )]) .inputs(vec![DeclarationType::FieldElement]) )); @@ -3685,11 +3683,11 @@ mod tests { "bar", DeclarationSignature::new() .generics(vec![Some( - GenericIdentifier::with_name("K").index(0).into() + GenericIdentifier::with_name("K").with_index(0).into() )]) .inputs(vec![DeclarationType::array(( DeclarationType::FieldElement, - GenericIdentifier::with_name("K").index(0) + GenericIdentifier::with_name("K").with_index(0) ))]) )); // a `bar` function with an equivalent signature, just renaming generic parameters @@ -3697,11 +3695,11 @@ mod tests { "bar", DeclarationSignature::new() .generics(vec![Some( - GenericIdentifier::with_name("L").index(0).into() + GenericIdentifier::with_name("L").with_index(0).into() )]) .inputs(vec![DeclarationType::array(( DeclarationType::FieldElement, - GenericIdentifier::with_name("L").index(0) + GenericIdentifier::with_name("L").with_index(0) ))]) )); // a `bar` type isn't allowed as the name is already taken by at least one function @@ -4265,7 +4263,7 @@ mod tests { .inputs(vec![DeclarationType::array(( DeclarationType::array(( DeclarationType::FieldElement, - GenericIdentifier::with_name("K").index(0) + GenericIdentifier::with_name("K").with_index(0) )), GenericIdentifier::with_name("L").index(1) ))]) @@ -4274,7 +4272,7 @@ mod tests { DeclarationType::FieldElement, GenericIdentifier::with_name("L").index(1) )), - GenericIdentifier::with_name("K").index(0) + GenericIdentifier::with_name("K").with_index(0) ))])) ); } diff --git a/zokrates_core/src/static_analysis/reducer/shallow_ssa.rs b/zokrates_core/src/static_analysis/reducer/shallow_ssa.rs index 5ae603bc..a06453b7 100644 --- a/zokrates_core/src/static_analysis/reducer/shallow_ssa.rs +++ b/zokrates_core/src/static_analysis/reducer/shallow_ssa.rs @@ -105,7 +105,7 @@ impl<'ast, 'a> ShallowTransformer<'ast, 'a> { .map(|(g, v)| { TypedStatement::Definition( TypedAssignee::Identifier(Variable::with_id_and_type( - g.name, + g.name(), Type::Uint(UBitwidth::B32), )), UExpression::from(*v as u32).into(), diff --git a/zokrates_core/src/static_analysis/struct_concretizer.rs b/zokrates_core/src/static_analysis/struct_concretizer.rs index 2b137357..b5fb5407 100644 --- a/zokrates_core/src/static_analysis/struct_concretizer.rs +++ b/zokrates_core/src/static_analysis/struct_concretizer.rs @@ -14,24 +14,28 @@ use crate::typed_absy::{ }, DeclarationStructType, GenericIdentifier, TypedProgram, }; +use std::marker::PhantomData; use zokrates_field::Field; -#[derive(Default)] -pub struct StructConcretizer<'ast> { +pub struct StructConcretizer<'ast, T> { generics: ConcreteGenericsAssignment<'ast>, + marker: PhantomData, } -impl<'ast> StructConcretizer<'ast> { - pub fn concretize(p: TypedProgram<'ast, T>) -> TypedProgram<'ast, T> { - StructConcretizer::default().fold_program(p) +impl<'ast, T: Field> StructConcretizer<'ast, T> { + pub fn concretize(p: TypedProgram<'ast, T>) -> TypedProgram<'ast, T> { + StructConcretizer::with_generics(ConcreteGenericsAssignment::default()).fold_program(p) } pub fn with_generics(generics: ConcreteGenericsAssignment<'ast>) -> Self { - Self { generics } + Self { + generics, + marker: PhantomData, + } } } -impl<'ast, T: Field> Folder<'ast, T> for StructConcretizer<'ast> { +impl<'ast, T: Field> Folder<'ast, T> for StructConcretizer<'ast, T> { fn fold_declaration_struct_type( &mut self, ty: DeclarationStructType<'ast>, @@ -47,11 +51,12 @@ impl<'ast, T: Field> Folder<'ast, T> for StructConcretizer<'ast> { concrete_generics .iter() .enumerate() - .map(|(index, g)| (GenericIdentifier::with_name("DUMMY").index(index), *g)) + .map(|(index, g)| (GenericIdentifier::without_name().with_index(index), *g)) .collect(), ); - let mut internal_concretizer = StructConcretizer::with_generics(concrete_generics_map); + let mut internal_concretizer: StructConcretizer<'ast, T> = + StructConcretizer::with_generics(concrete_generics_map); DeclarationStructType { members: ty @@ -60,10 +65,7 @@ impl<'ast, T: Field> Folder<'ast, T> for StructConcretizer<'ast> { .map(|member| { DeclarationStructMember::new( member.id, - >::fold_declaration_type( - &mut internal_concretizer, - *member.ty, - ), + internal_concretizer.fold_declaration_type(*member.ty), ) }) .collect(), @@ -79,15 +81,11 @@ impl<'ast, T: Field> Folder<'ast, T> for StructConcretizer<'ast> { &mut self, ty: DeclarationArrayType<'ast>, ) -> DeclarationArrayType<'ast> { - let size = match ty.size { - DeclarationConstant::Generic(s) => self.generics.0.get(&s).cloned().unwrap() as u32, - DeclarationConstant::Concrete(s) => s, - DeclarationConstant::Constant(..) => unreachable!(), - }; + let size = ty.size.map_concrete(&self.generics).unwrap(); DeclarationArrayType { size: DeclarationConstant::Concrete(size), - ty: box >::fold_declaration_type(self, *ty.ty), + ty: box self.fold_declaration_type(*ty.ty), } } } diff --git a/zokrates_core/src/typed_absy/types.rs b/zokrates_core/src/typed_absy/types.rs index 608cdb88..44c6b2e5 100644 --- a/zokrates_core/src/typed_absy/types.rs +++ b/zokrates_core/src/typed_absy/types.rs @@ -59,19 +59,37 @@ impl<'ast, T> Types<'ast, T> { #[derive(Debug, Clone, Eq)] pub struct GenericIdentifier<'ast> { - pub name: &'ast str, - pub index: usize, + name: Option<&'ast str>, + index: usize, } impl<'ast> GenericIdentifier<'ast> { - pub fn with_name(name: &'ast str) -> Self { - Self { name, index: 0 } + pub fn without_name() -> Self { + Self { + name: None, + index: 0, + } } - pub fn index(mut self, index: usize) -> Self { + pub fn with_name(name: &'ast str) -> Self { + Self { + name: Some(name), + index: 0, + } + } + + pub fn with_index(mut self, index: usize) -> Self { self.index = index; self } + + pub fn name(&self) -> &'ast str { + self.name.unwrap() + } + + pub fn index(&self) -> usize { + self.index + } } impl<'ast> PartialEq for GenericIdentifier<'ast> { @@ -100,7 +118,7 @@ impl<'ast> Hash for GenericIdentifier<'ast> { impl<'ast> fmt::Display for GenericIdentifier<'ast> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.name) + write!(f, "{}", self.name()) } } @@ -210,7 +228,7 @@ impl<'ast, T> From> for UExpression<'ast, T> { fn from(c: DeclarationConstant<'ast>) -> Self { match c { DeclarationConstant::Generic(i) => { - UExpressionInner::Identifier(i.name.into()).annotate(UBitwidth::B32) + UExpressionInner::Identifier(i.name().into()).annotate(UBitwidth::B32) } DeclarationConstant::Concrete(v) => { UExpressionInner::Value(v as u128).annotate(UBitwidth::B32) @@ -1031,7 +1049,7 @@ pub fn specialize_declaration_type< .enumerate() .map(|(index, g)| { ( - GenericIdentifier::with_name("dummy").index(index), + GenericIdentifier::without_name().with_index(index), g.map(|g| g.map(generics).unwrap()).unwrap(), ) }) From 1ffbc024b2a751dd010ed88ea1fbd78547682ea8 Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 21 Sep 2021 17:39:13 +0300 Subject: [PATCH 7/7] fix tests --- zokrates_abi/src/lib.rs | 7 +--- zokrates_core/src/semantics.rs | 4 +- .../src/static_analysis/constant_inliner.rs | 10 ++--- .../src/static_analysis/propagation.rs | 2 +- .../src/static_analysis/reducer/mod.rs | 42 +++++++++---------- .../static_analysis/reducer/shallow_ssa.rs | 12 +++--- zokrates_core/src/typed_absy/abi.rs | 10 ++--- zokrates_core/src/typed_absy/types.rs | 26 +++--------- 8 files changed, 48 insertions(+), 65 deletions(-) diff --git a/zokrates_abi/src/lib.rs b/zokrates_abi/src/lib.rs index 6c07891e..16cdca31 100644 --- a/zokrates_abi/src/lib.rs +++ b/zokrates_abi/src/lib.rs @@ -413,11 +413,8 @@ mod tests { fn array() { let s = "[[true, false]]"; assert_eq!( - parse_strict::( - s, - vec![ConcreteType::array((ConcreteType::Boolean, 2usize))] - ) - .unwrap(), + parse_strict::(s, vec![ConcreteType::array((ConcreteType::Boolean, 2u32))]) + .unwrap(), Values(vec![Value::Array(vec![ Value::Boolean(true), Value::Boolean(false) diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index ff019481..36f7af1d 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -4265,12 +4265,12 @@ mod tests { DeclarationType::FieldElement, GenericIdentifier::with_name("K").with_index(0) )), - GenericIdentifier::with_name("L").index(1) + GenericIdentifier::with_name("L").with_index(1) ))]) .outputs(vec![DeclarationType::array(( DeclarationType::array(( DeclarationType::FieldElement, - GenericIdentifier::with_name("L").index(1) + GenericIdentifier::with_name("L").with_index(1) )), GenericIdentifier::with_name("K").with_index(0) ))])) diff --git a/zokrates_core/src/static_analysis/constant_inliner.rs b/zokrates_core/src/static_analysis/constant_inliner.rs index 589ace6f..d2b803e8 100644 --- a/zokrates_core/src/static_analysis/constant_inliner.rs +++ b/zokrates_core/src/static_analysis/constant_inliner.rs @@ -574,13 +574,13 @@ mod tests { statements: vec![TypedStatement::Return(vec![FieldElementExpression::Add( FieldElementExpression::select( ArrayExpressionInner::Identifier(Identifier::from(const_id)) - .annotate(GType::FieldElement, 2usize), + .annotate(GType::FieldElement, 2u32), UExpressionInner::Value(0u128).annotate(UBitwidth::B32), ) .into(), FieldElementExpression::select( ArrayExpressionInner::Identifier(Identifier::from(const_id)) - .annotate(GType::FieldElement, 2usize), + .annotate(GType::FieldElement, 2u32), UExpressionInner::Value(1u128).annotate(UBitwidth::B32), ) .into(), @@ -608,7 +608,7 @@ mod tests { ] .into(), ) - .annotate(GType::FieldElement, 2usize), + .annotate(GType::FieldElement, 2u32), ))), )] .into_iter() @@ -649,7 +649,7 @@ mod tests { ] .into(), ) - .annotate(GType::FieldElement, 2usize), + .annotate(GType::FieldElement, 2u32), UExpressionInner::Value(0u128).annotate(UBitwidth::B32), ) .into(), @@ -661,7 +661,7 @@ mod tests { ] .into(), ) - .annotate(GType::FieldElement, 2usize), + .annotate(GType::FieldElement, 2u32), UExpressionInner::Value(1u128).annotate(UBitwidth::B32), ) .into(), diff --git a/zokrates_core/src/static_analysis/propagation.rs b/zokrates_core/src/static_analysis/propagation.rs index 1450e077..9424ee35 100644 --- a/zokrates_core/src/static_analysis/propagation.rs +++ b/zokrates_core/src/static_analysis/propagation.rs @@ -1463,7 +1463,7 @@ mod tests { ] .into(), ) - .annotate(Type::FieldElement, 3usize), + .annotate(Type::FieldElement, 3u32), UExpressionInner::Add(box 1u32.into(), box 1u32.into()) .annotate(UBitwidth::B32), ); diff --git a/zokrates_core/src/static_analysis/reducer/mod.rs b/zokrates_core/src/static_analysis/reducer/mod.rs index 84790f29..b5b8fd24 100644 --- a/zokrates_core/src/static_analysis/reducer/mod.rs +++ b/zokrates_core/src/static_analysis/reducer/mod.rs @@ -830,22 +830,22 @@ mod tests { let foo_signature = DeclarationSignature::new() .generics(vec![Some( - GenericIdentifier::with_name("K").index(0).into(), + GenericIdentifier::with_name("K").with_index(0).into(), )]) .inputs(vec![DeclarationType::array(( DeclarationType::FieldElement, - DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)), + DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)), ))]) .outputs(vec![DeclarationType::array(( DeclarationType::FieldElement, - DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)), + DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)), ))]); let foo: TypedFunction = TypedFunction { arguments: vec![DeclarationVariable::array( "a", DeclarationType::FieldElement, - GenericIdentifier::with_name("K").index(0), + GenericIdentifier::with_name("K").with_index(0), ) .into()], statements: vec![TypedStatement::Return(vec![ @@ -954,7 +954,7 @@ mod tests { DeclarationFunctionKey::with_location("main", "foo") .signature(foo_signature.clone()), GGenericsAssignment( - vec![(GenericIdentifier::with_name("K").index(0), 1)] + vec![(GenericIdentifier::with_name("K").with_index(0), 1)] .into_iter() .collect(), ), @@ -1049,22 +1049,22 @@ mod tests { let foo_signature = DeclarationSignature::new() .generics(vec![Some( - GenericIdentifier::with_name("K").index(0).into(), + GenericIdentifier::with_name("K").with_index(0).into(), )]) .inputs(vec![DeclarationType::array(( DeclarationType::FieldElement, - DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)), + DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)), ))]) .outputs(vec![DeclarationType::array(( DeclarationType::FieldElement, - DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)), + DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)), ))]); let foo: TypedFunction = TypedFunction { arguments: vec![DeclarationVariable::array( "a", DeclarationType::FieldElement, - GenericIdentifier::with_name("K").index(0), + GenericIdentifier::with_name("K").with_index(0), ) .into()], statements: vec![TypedStatement::Return(vec![ @@ -1182,7 +1182,7 @@ mod tests { DeclarationFunctionKey::with_location("main", "foo") .signature(foo_signature.clone()), GGenericsAssignment( - vec![(GenericIdentifier::with_name("K").index(0), 1)] + vec![(GenericIdentifier::with_name("K").with_index(0), 1)] .into_iter() .collect(), ), @@ -1280,21 +1280,21 @@ mod tests { let foo_signature = DeclarationSignature::new() .inputs(vec![DeclarationType::array(( DeclarationType::FieldElement, - DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)), + DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)), ))]) .outputs(vec![DeclarationType::array(( DeclarationType::FieldElement, - DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)), + DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)), ))]) .generics(vec![Some( - GenericIdentifier::with_name("K").index(0).into(), + GenericIdentifier::with_name("K").with_index(0).into(), )]); let foo: TypedFunction = TypedFunction { arguments: vec![DeclarationVariable::array( "a", DeclarationType::FieldElement, - DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)), + DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)), ) .into()], statements: vec![ @@ -1358,7 +1358,7 @@ mod tests { arguments: vec![DeclarationVariable::array( "a", DeclarationType::FieldElement, - DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)), + DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)), ) .into()], statements: vec![TypedStatement::Return(vec![ @@ -1433,7 +1433,7 @@ mod tests { DeclarationFunctionKey::with_location("main", "foo") .signature(foo_signature.clone()), GGenericsAssignment( - vec![(GenericIdentifier::with_name("K").index(0), 1)] + vec![(GenericIdentifier::with_name("K").with_index(0), 1)] .into_iter() .collect(), ), @@ -1442,7 +1442,7 @@ mod tests { DeclarationFunctionKey::with_location("main", "bar") .signature(foo_signature.clone()), GGenericsAssignment( - vec![(GenericIdentifier::with_name("K").index(0), 2)] + vec![(GenericIdentifier::with_name("K").with_index(0), 2)] .into_iter() .collect(), ), @@ -1489,22 +1489,22 @@ mod tests { let foo_signature = DeclarationSignature::new() .generics(vec![Some( - GenericIdentifier::with_name("K").index(0).into(), + GenericIdentifier::with_name("K").with_index(0).into(), )]) .inputs(vec![DeclarationType::array(( DeclarationType::FieldElement, - GenericIdentifier::with_name("K").index(0), + GenericIdentifier::with_name("K").with_index(0), ))]) .outputs(vec![DeclarationType::array(( DeclarationType::FieldElement, - GenericIdentifier::with_name("K").index(0), + GenericIdentifier::with_name("K").with_index(0), ))]); let foo: TypedFunction = TypedFunction { arguments: vec![DeclarationVariable::array( "a", DeclarationType::FieldElement, - GenericIdentifier::with_name("K").index(0), + GenericIdentifier::with_name("K").with_index(0), ) .into()], statements: vec![TypedStatement::Return(vec![ diff --git a/zokrates_core/src/static_analysis/reducer/shallow_ssa.rs b/zokrates_core/src/static_analysis/reducer/shallow_ssa.rs index a06453b7..aa744e8d 100644 --- a/zokrates_core/src/static_analysis/reducer/shallow_ssa.rs +++ b/zokrates_core/src/static_analysis/reducer/shallow_ssa.rs @@ -662,7 +662,7 @@ mod tests { ], signature: DeclarationSignature::new() .generics(vec![Some( - GenericIdentifier::with_name("K").index(0).into(), + GenericIdentifier::with_name("K").with_index(0).into(), )]) .inputs(vec![DeclarationType::FieldElement]) .outputs(vec![DeclarationType::FieldElement]), @@ -673,7 +673,7 @@ mod tests { let ssa = ShallowTransformer::transform( f, &GGenericsAssignment( - vec![(GenericIdentifier::with_name("K").index(0), 1)] + vec![(GenericIdentifier::with_name("K").with_index(0), 1)] .into_iter() .collect(), ), @@ -742,7 +742,7 @@ mod tests { ], signature: DeclarationSignature::new() .generics(vec![Some( - GenericIdentifier::with_name("K").index(0).into(), + GenericIdentifier::with_name("K").with_index(0).into(), )]) .inputs(vec![DeclarationType::FieldElement]) .outputs(vec![DeclarationType::FieldElement]), @@ -851,7 +851,7 @@ mod tests { ], signature: DeclarationSignature::new() .generics(vec![Some( - GenericIdentifier::with_name("K").index(0).into(), + GenericIdentifier::with_name("K").with_index(0).into(), )]) .inputs(vec![DeclarationType::FieldElement]) .outputs(vec![DeclarationType::FieldElement]), @@ -862,7 +862,7 @@ mod tests { let ssa = ShallowTransformer::transform( f, &GGenericsAssignment( - vec![(GenericIdentifier::with_name("K").index(0), 1)] + vec![(GenericIdentifier::with_name("K").with_index(0), 1)] .into_iter() .collect(), ), @@ -934,7 +934,7 @@ mod tests { ], signature: DeclarationSignature::new() .generics(vec![Some( - GenericIdentifier::with_name("K").index(0).into(), + GenericIdentifier::with_name("K").with_index(0).into(), )]) .inputs(vec![DeclarationType::FieldElement]) .outputs(vec![DeclarationType::FieldElement]), diff --git a/zokrates_core/src/typed_absy/abi.rs b/zokrates_core/src/typed_absy/abi.rs index 15554a73..0dfbfade 100644 --- a/zokrates_core/src/typed_absy/abi.rs +++ b/zokrates_core/src/typed_absy/abi.rs @@ -231,12 +231,12 @@ mod tests { ty: ConcreteType::Struct(ConcreteStructType::new( "".into(), "Bar".into(), - vec![Some(1usize)], + vec![Some(1u32)], vec![ConcreteStructMember::new( String::from("a"), ConcreteType::Array(ConcreteArrayType::new( ConcreteType::FieldElement, - 1usize, + 1u32, )), )], )), @@ -400,7 +400,7 @@ mod tests { ConcreteStructMember::new(String::from("c"), ConcreteType::Boolean), ], )), - 2usize, + 2u32, )), }], outputs: vec![ConcreteType::Boolean], @@ -454,8 +454,8 @@ mod tests { name: String::from("a"), public: false, ty: ConcreteType::Array(ConcreteArrayType::new( - ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 2usize)), - 2usize, + ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 2u32)), + 2u32, )), }], outputs: vec![ConcreteType::FieldElement], diff --git a/zokrates_core/src/typed_absy/types.rs b/zokrates_core/src/typed_absy/types.rs index 44c6b2e5..750de024 100644 --- a/zokrates_core/src/typed_absy/types.rs +++ b/zokrates_core/src/typed_absy/types.rs @@ -1405,33 +1405,19 @@ pub mod signature { let generic1 = DeclarationSignature::new() .generics(vec![Some( - GenericIdentifier { - name: "P", - index: 0, - } - .into(), + GenericIdentifier::with_name("P").with_index(0).into(), )]) .inputs(vec![DeclarationType::array(DeclarationArrayType::new( DeclarationType::FieldElement, - GenericIdentifier { - name: "P", - index: 0, - }, + GenericIdentifier::with_name("P").with_index(0), ))]); let generic2 = DeclarationSignature::new() .generics(vec![Some( - GenericIdentifier { - name: "Q", - index: 0, - } - .into(), + GenericIdentifier::with_name("Q").with_index(0).into(), )]) .inputs(vec![DeclarationType::array(DeclarationArrayType::new( DeclarationType::FieldElement, - GenericIdentifier { - name: "Q", - index: 0, - }, + GenericIdentifier::with_name("Q").with_index(0), ))]); assert_eq!(generic1, generic2); @@ -1512,7 +1498,7 @@ mod tests { #[test] fn array() { - let t = ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 42usize)); + let t = ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 42u32)); assert_eq!(t.get_primitive_count(), 42); } @@ -1521,7 +1507,7 @@ mod tests { // field[1][2] let t = ConcreteType::Array(ConcreteArrayType::new( ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 2u32)), - 1usize, + 1u32, )); assert_eq!(format!("{}", t), "field[1][2]"); }