From 88eda171570260f351ffe0826620393475665579 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 22 Oct 2024 21:16:20 -0300 Subject: [PATCH 01/15] feat: sort and merge imports --- tooling/nargo_fmt/src/config.rs | 1 + tooling/nargo_fmt/src/formatter.rs | 23 +- tooling/nargo_fmt/src/formatter/item.rs | 125 ++++- tooling/nargo_fmt/src/formatter/use_tree.rs | 58 +- .../nargo_fmt/src/formatter/use_tree_merge.rs | 515 ++++++++++++++++++ tooling/nargo_fmt/tests/expected/contract.nr | 18 +- 6 files changed, 717 insertions(+), 23 deletions(-) create mode 100644 tooling/nargo_fmt/src/formatter/use_tree_merge.rs diff --git a/tooling/nargo_fmt/src/config.rs b/tooling/nargo_fmt/src/config.rs index 6a1a019f18d..214ad610640 100644 --- a/tooling/nargo_fmt/src/config.rs +++ b/tooling/nargo_fmt/src/config.rs @@ -49,6 +49,7 @@ config! { array_width: usize, 100, "Maximum width of an array literal before falling back to vertical formatting"; fn_call_width: usize, 60, "Maximum width of the args of a function call before falling back to vertical formatting"; single_line_if_else_max_width: usize, 50, "Maximum line length for single line if-else expressions"; + merge_imports: bool, true, "Merge and sort groups of imports"; } impl Config { diff --git a/tooling/nargo_fmt/src/formatter.rs b/tooling/nargo_fmt/src/formatter.rs index 558dab2829e..4ae5443a2cc 100644 --- a/tooling/nargo_fmt/src/formatter.rs +++ b/tooling/nargo_fmt/src/formatter.rs @@ -31,6 +31,7 @@ mod traits; mod type_expression; mod types; mod use_tree; +mod use_tree_merge; mod visibility; mod where_clause; @@ -107,21 +108,12 @@ impl<'a> Formatter<'a> { self.format_parsed_module(parsed_module, self.ignore_next); } - pub(crate) fn format_parsed_module( - &mut self, - parsed_module: ParsedModule, - mut ignore_next: bool, - ) { + pub(crate) fn format_parsed_module(&mut self, parsed_module: ParsedModule, ignore_next: bool) { if !parsed_module.inner_doc_comments.is_empty() { self.format_inner_doc_comments(); } - for item in parsed_module.items { - self.format_item(item, ignore_next); - self.write_line(); - ignore_next = self.ignore_next; - } - + self.format_items(parsed_module.items, ignore_next); self.write_line(); } @@ -249,7 +241,14 @@ impl<'a> Formatter<'a> { pub(super) fn write_and_skip_span_without_formatting(&mut self, span: Span) { self.write_source_span(span); - while self.token_span.start() < span.end() { + while self.token_span.start() < span.end() && self.token != Token::EOF { + self.bump(); + } + } + + /// Advances the lexer until past the given span end without writing anything to the buffer. + pub(super) fn skip_past_span_end_without_formatting(&mut self, span_end: u32) { + while self.token_span.start() < span_end && self.token != Token::EOF { self.bump(); } } diff --git a/tooling/nargo_fmt/src/formatter/item.rs b/tooling/nargo_fmt/src/formatter/item.rs index 072f45278ee..cf7117c008e 100644 --- a/tooling/nargo_fmt/src/formatter/item.rs +++ b/tooling/nargo_fmt/src/formatter/item.rs @@ -1,8 +1,42 @@ -use noirc_frontend::parser::{Item, ItemKind}; +use noirc_frontend::{ + ast::{ItemVisibility, UseTree}, + hir::resolution::errors::Span, + parser::{Item, ItemKind}, +}; use super::Formatter; impl<'a> Formatter<'a> { + pub(super) fn format_items(&mut self, mut items: Vec, mut ignore_next: bool) { + // Reverse the items because we'll be processing them one by one, and it's a bit + // more efficient to pop than to shift. + items.reverse(); + + while !items.is_empty() { + // Format the next import group, if there is one. + if self.config.merge_imports { + let import_group = self.next_import_group(&mut items); + if let Some(import_group) = import_group { + self.merge_and_format_imports(import_group.imports, import_group.visibility); + self.skip_past_span_end_without_formatting(import_group.span_end); + self.write_line(); + ignore_next = self.ignore_next; + + // Continue from the top because the next thing that comes might be another import group + continue; + } + } + + if let Some(item) = items.pop() { + self.format_item(item, ignore_next); + self.write_line(); + ignore_next = self.ignore_next; + } else { + break; + } + } + } + pub(super) fn format_item(&mut self, item: Item, mut ignore_next: bool) { self.skip_comments_and_whitespace(); @@ -42,4 +76,93 @@ impl<'a> Formatter<'a> { ItemKind::InnerAttribute(..) => self.format_inner_attribute(), } } + + /// Returns the next import group, if there's is one. + /// + /// An import group is one or more `use` statements that all have the same visibility, + /// as long as exactly one newline separates them, and as long as there are no comments + /// in the `use` statements or trailing comments in them. + /// + /// Each import group will be sorted and merged, if the configuration is set to do so. + fn next_import_group(&self, items: &mut Vec) -> Option { + let mut imports = Vec::new(); + + let item = items.last()?; + if self.span_has_comments(item.span) { + return None; + } + + let ItemKind::Import(..) = item.kind else { + return None; + }; + + let item = items.pop().unwrap(); + let ItemKind::Import(use_tree, visibility) = item.kind else { + panic!("Expected import, got {:?}", item.kind); + }; + + imports.push(use_tree); + let mut span_end = item.span.end(); + + while let Some(item) = items.last() { + if self.span_is_import_group_separator(Span::from(span_end..item.span.start())) { + break; + } + + let next_item_start = if items.len() > 1 { + if let Some(next_item) = items.get(items.len() - 2) { + next_item.span.start() + } else { + self.source.len() as u32 + } + } else { + self.source.len() as u32 + }; + + if self.span_starts_with_trailing_comment(Span::from(item.span.end()..next_item_start)) + { + break; + } + + let ItemKind::Import(_, next_visibility) = &item.kind else { + break; + }; + + if visibility != *next_visibility { + break; + } + + let item = items.pop().unwrap(); + let ItemKind::Import(use_tree, _) = item.kind else { + panic!("Expected import, got {:?}", item.kind); + }; + imports.push(use_tree); + span_end = item.span.end(); + } + + Some(ImportGroup { imports, visibility, span_end }) + } + + fn span_has_comments(&self, span: Span) -> bool { + let slice = &self.source[span.start() as usize..span.end() as usize]; + slice.contains("/*") || slice.contains("//") + } + + fn span_starts_with_trailing_comment(&self, span: Span) -> bool { + let slice = &self.source[span.start() as usize..span.end() as usize]; + slice.trim_start_matches(' ').starts_with("//") + } + + /// Returns true if there at most one newline in the given span and it contains no comments. + fn span_is_import_group_separator(&self, span: Span) -> bool { + let slice = &self.source[span.start() as usize..span.end() as usize]; + let number_of_newlines = slice.chars().filter(|char| *char == '\n').count(); + number_of_newlines > 1 || slice.contains("//") || slice.contains("/*") + } +} + +struct ImportGroup { + imports: Vec, + visibility: ItemVisibility, + span_end: u32, } diff --git a/tooling/nargo_fmt/src/formatter/use_tree.rs b/tooling/nargo_fmt/src/formatter/use_tree.rs index 0c99bc7ee79..3a6b750cf65 100644 --- a/tooling/nargo_fmt/src/formatter/use_tree.rs +++ b/tooling/nargo_fmt/src/formatter/use_tree.rs @@ -68,6 +68,11 @@ impl<'a, 'b> ChunkFormatter<'a, 'b> { })); } UseTreeKind::List(use_trees) => { + // We check if there are nested lists. If yes, then each item will be on a separate line + // (it reads better, and this is what rustfmt seems to do too) + let has_nested_list = + use_trees.iter().any(|use_tree| matches!(use_tree.kind, UseTreeKind::List(..))); + let use_trees_len = use_trees.len(); let left_brace_chunk = self.chunk(|formatter| { @@ -99,6 +104,10 @@ impl<'a, 'b> ChunkFormatter<'a, 'b> { items_chunk.chunks.into_iter().filter_map(Chunk::group).next().unwrap(); group.chunks.extend(single_group.chunks); } else { + if has_nested_list { + group.one_chunk_per_line = true; + } + group.text(left_brace_chunk); group.chunks.extend(items_chunk.chunks); group.text(right_brace_chunk); @@ -112,10 +121,20 @@ impl<'a, 'b> ChunkFormatter<'a, 'b> { #[cfg(test)] mod tests { - use crate::{assert_format, assert_format_with_max_width}; + use crate::{assert_format_with_config, Config}; + + fn assert_format(src: &str, expected: &str) { + let config = Config { merge_imports: false, ..Config::default() }; + assert_format_with_config(src, expected, config); + } + + fn assert_format_with_max_width(src: &str, expected: &str, max_width: usize) { + let config = Config { merge_imports: false, max_width, ..Config::default() }; + assert_format_with_config(src, expected, config); + } #[test] - fn format_simple_use() { + fn format_simple_use_without_alias() { let src = " mod moo { pub use foo ; }"; let expected = "mod moo { pub use foo; @@ -152,7 +171,9 @@ mod tests { fn format_use_trees_with_max_width() { let src = " use foo::{ bar, baz , qux , one::{two, three} };"; let expected = "use foo::{ - bar, baz, qux, + bar, + baz, + qux, one::{ two, three, }, @@ -175,7 +196,7 @@ mod tests { four, five, }; "; - assert_format_with_max_width(src, expected, 20); + assert_format_with_max_width(src, expected, 25); } #[test] @@ -201,4 +222,33 @@ mod tests { "; assert_format_with_max_width(src, expected, "use crate::hash::{Hash, Hasher}".len()); } + + #[test] + fn do_not_merge_and_sort_imports() { + let src = " +use aztec::{ + context::Context, log::emit_unencrypted_log, note::{ + note_getter_options::NoteGetterOptions, note_header::NoteHeader, + }, state_vars::{ + Map, PrivateSet, PublicMutable, + }, types::{ + address::AztecAddress, type_serialization::field_serialization::{ + FIELD_SERIALIZED_LEN, FieldSerializationMethods, + }, + }, +}; + "; + let expected = "use aztec::{ + context::Context, + log::emit_unencrypted_log, + note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader}, + state_vars::{Map, PrivateSet, PublicMutable}, + types::{ + address::AztecAddress, + type_serialization::field_serialization::{FIELD_SERIALIZED_LEN, FieldSerializationMethods}, + }, +}; +"; + assert_format(src, expected); + } } diff --git a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs new file mode 100644 index 00000000000..804785250c2 --- /dev/null +++ b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs @@ -0,0 +1,515 @@ +use std::{ + cmp::Ordering, + collections::BTreeMap, + fmt::{self, Display}, +}; + +use noirc_frontend::ast::{ItemVisibility, PathKind, UseTree, UseTreeKind}; + +use crate::chunks::{ChunkGroup, TextChunk}; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn merge_and_format_imports( + &mut self, + imports: Vec, + visibility: ItemVisibility, + ) { + let merged_import = merge_imports(imports); + + for (index, (segment, segment_tree)) in merged_import.tree.into_iter().enumerate() { + if index > 0 { + self.write_line_without_skipping_whitespace_and_comments(); + } + + let tree = ImportTree::single(segment, *segment_tree); + let tree = tree.simplify(); + + let group = format_merged_import_with_visibility(tree, visibility); + self.write_indentation(); + self.format_chunk_group(group); + } + } +} + +// The logic here is similar to that of `use_tree.rs`, except that it works with ImportTree +// instead of UseTree and we never check or advance the lexer. + +fn format_merged_import_with_visibility( + mut import_tree: ImportTree, + visibility: ItemVisibility, +) -> ChunkGroup { + let mut group = ChunkGroup::new(); + match visibility { + ItemVisibility::Private => (), + ItemVisibility::PublicCrate => { + group.text(TextChunk::new("pub(crate) ".to_string())); + } + ItemVisibility::Public => { + group.text(TextChunk::new("pub ".to_string())); + } + } + group.text(TextChunk::new("use ".to_string())); + + let (segment, tree) = import_tree.tree.pop_first().unwrap(); + assert!(import_tree.tree.is_empty()); + + group.group(format_merged_import(segment, *tree)); + group.text_attached_to_last_group(TextChunk::new(";".to_string())); + group +} + +fn format_merged_import(segment: Segment, import_tree: ImportTree) -> ChunkGroup { + let mut group = ChunkGroup::new(); + + group.text(TextChunk::new(segment.to_string())); + + if import_tree.tree.is_empty() { + return group; + } + + // We check if there are nested lists. If yes, then each item will be on a separate line + // (it reads better, and this is what rustfmt seems to do too) + if import_tree.tree.values().all(|tree| tree.tree.is_empty()) { + group.one_chunk_per_line = false; + } + + group.text(TextChunk::new("::{".to_string())); + group.increase_indentation(); + group.line(); + + for (index, (segment, import_tree)) in import_tree.tree.into_iter().enumerate() { + if index > 0 { + group.text_attached_to_last_group(TextChunk::new(",".to_string())); + group.space_or_line(); + } + + group.group(format_merged_import(segment, *import_tree)); + } + + group.trailing_comma(); + group.decrease_indentation(); + group.line(); + group.text(TextChunk::new("}".to_string())); + + group +} + +/// We keep Crate, Super and Dep as special segments so that they are ordered in that way +/// (they'll come in that order before any plain segment). +#[derive(Debug, PartialEq, Eq)] +enum Segment { + Crate, + Super, + Dep, + Plain(String), +} + +impl Segment { + /// Combines two segments into a single one, by joining them with "::". + fn combine(&self, other: Segment) -> Segment { + Segment::Plain(format!("{}::{}", self, other)) + } +} + +impl Display for Segment { + fn fmt(&self, f: &mut std::fmt::Formatter) -> fmt::Result { + match self { + Segment::Crate => write!(f, "crate"), + Segment::Super => write!(f, "super"), + Segment::Dep => write!(f, "dep"), + Segment::Plain(s) => write!(f, "{}", s), + } + } +} + +impl PartialOrd for Segment { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Segment { + fn cmp(&self, other: &Self) -> Ordering { + match (self, other) { + (Segment::Crate, Segment::Crate) => Ordering::Equal, + (Segment::Crate, _) => Ordering::Less, + (Segment::Super, Segment::Crate) => Ordering::Greater, + (Segment::Super, Segment::Super) => Ordering::Equal, + (Segment::Super, _) => Ordering::Less, + (Segment::Dep, Segment::Crate) | (Segment::Dep, Segment::Super) => Ordering::Less, + (Segment::Dep, Segment::Dep) => Ordering::Equal, + (Segment::Dep, _) => Ordering::Greater, + (Segment::Plain(self_string), Segment::Plain(other_string)) => { + // Case-insensitive comparison for plain segments + self_string.to_lowercase().cmp(&other_string.to_lowercase()) + } + (Segment::Plain(_), _) => Ordering::Greater, + } + } +} + +/// An import tree to represent merged imports. +/// For example for the given imports: +/// +/// use foo::bar::{baz, qux}; +/// use foo::another; +/// +/// an ImportTree that represents the merged imports would be: +/// +/// { +/// "foo" => { +/// "another" => {} +/// "bar" => {"baz", "qux"}, +/// } +/// } +#[derive(Debug, Default)] +struct ImportTree { + tree: BTreeMap>, +} + +impl ImportTree { + fn new() -> Self { + Self { tree: BTreeMap::new() } + } + + /// Creates an import tree that has `segment` as the only element with `tree` as its value. + fn single(segment: Segment, tree: ImportTree) -> Self { + let mut tree_map = BTreeMap::new(); + tree_map.insert(segment, Box::new(tree)); + Self { tree: tree_map } + } + + /// Inserts a segment to the tree, creating the necessary empty children if they don't exist yet. + fn insert(&mut self, segment: Segment) -> &mut ImportTree { + self.tree.entry(segment).or_default() + } + + /// Simplifies a tree by combining segments that only have one child. + /// + /// For example, this tree: + /// + /// { + /// "foo" => { + /// "bar" => {"baz", "qux"} + /// } + /// } + /// + /// will be simplified to: + /// + /// { + /// "foo::bar" => {"baz", "qux"} + /// } + fn simplify(self) -> ImportTree { + let mut new_tree = ImportTree::new(); + for (segment, tree) in self.tree.into_iter() { + let mut tree = tree.simplify(); + if tree.tree.len() == 1 { + let (first_segment, first_tree) = tree.tree.pop_first().unwrap(); + let new_segment = segment.combine(first_segment); + new_tree.tree.insert(new_segment, first_tree); + } else { + new_tree.tree.insert(segment, Box::new(tree)); + } + } + new_tree + } +} + +/// Combines all use trees to form a single ImportTree. +fn merge_imports(imports: Vec) -> ImportTree { + let mut tree = ImportTree::new(); + merge_imports_in_tree(imports, &mut tree); + tree +} + +fn merge_imports_in_tree(imports: Vec, mut tree: &mut ImportTree) { + for import in imports { + let mut tree = match import.prefix.kind { + PathKind::Crate => tree.insert(Segment::Crate), + PathKind::Super => tree.insert(Segment::Super), + PathKind::Dep => tree.insert(Segment::Dep), + PathKind::Plain => &mut tree, + }; + + for segment in import.prefix.segments { + tree = tree.insert(Segment::Plain(segment.ident.to_string())); + } + + match import.kind { + UseTreeKind::Path(ident, alias) => { + if let Some(alias) = alias { + tree.insert(Segment::Plain(format!("{} as {}", ident, alias))); + } else { + tree.insert(Segment::Plain(ident.to_string())); + } + } + UseTreeKind::List(trees) => { + merge_imports_in_tree(trees, tree); + } + } + } +} + +#[cfg(test)] +mod tests { + use crate::{assert_format, assert_format_with_max_width}; + + #[test] + fn format_simple_use_without_alias() { + let src = " mod moo { pub use foo ; }"; + let expected = "mod moo { + pub use foo; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_simple_use_with_alias() { + let src = " mod moo { use foo :: bar as baz ; }"; + let expected = "mod moo { + use foo::bar as baz; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_simple_use_with_path_kind() { + let src = "use super :: foo ;"; + let expected = "use super::foo;\n"; + assert_format(src, expected); + } + + #[test] + fn format_use_list_two_items() { + let src = " use foo::{ bar, baz };"; + let expected = "use foo::{bar, baz};\n"; + assert_format(src, expected); + } + + #[test] + fn format_use_trees_with_max_width() { + let src = " use foo::{ bar, baz , qux , one::{two, three} };"; + let expected = "use foo::{ + bar, + baz, + one::{ + three, two, + }, + qux, +}; +"; + assert_format_with_max_width(src, expected, 20); + } + + #[test] + fn format_use_list_one_item() { + let src = " use foo::{ bar, };"; + let expected = "use foo::bar;\n"; + assert_format(src, expected); + } + + #[test] + fn format_long_use_list_one_item() { + let src = "use one::two::{three::{four, five}};"; + let expected = "use one::two::three::{ + five, four, +}; +"; + assert_format_with_max_width(src, expected, 25); + } + + #[test] + fn format_use_list_one_item_with_comments() { + let src = " use foo::{ /* do not remove me */ bar, };"; + let expected = "use foo::{ /* do not remove me */ bar};\n"; + assert_format(src, expected); + } + + #[test] + fn format_use_crate_with_list() { + let src = " use crate :: hash :: { Hash, Hasher }; "; + let expected = "use crate::hash::{Hash, Hasher};\n"; + assert_format(src, expected); + } + + #[test] + fn attaches_semicolon_to_last_group() { + let src = " use crate::hash::{Hash, Hasher}; "; + let expected = "use crate::hash::{ + Hash, Hasher, +}; +"; + assert_format_with_max_width(src, expected, "use crate::hash::{Hash, Hasher}".len()); + } + + #[test] + fn does_not_merge_imports_if_they_are_separated_by_two_lines() { + let src = " + use foo::baz; + + use foo::{def, abc}; +"; + let expected = "use foo::baz; + +use foo::{abc, def}; +"; + assert_format(src, expected); + } + + #[test] + fn does_not_merge_imports_if_they_have_different_visibilities() { + let src = " + pub use foo::baz; + use foo::{def, abc}; +"; + let expected = "pub use foo::baz; +use foo::{abc, def}; +"; + assert_format(src, expected); + } + + #[test] + fn does_not_merge_imports_if_they_have_trailing_comments_on_the_first_use() { + let src = " + use foo; // trailing + use bar; + + fn foo() {} +"; + let expected = "use foo; // trailing +use bar; + +fn foo() {} +"; + assert_format(src, expected); + } + + #[test] + fn does_not_merge_imports_if_they_have_trailing_comments_followed_by_item() { + let src = " + use foo; + use bar; // trailing + + fn foo() {} +"; + let expected = "use foo; +use bar; // trailing + +fn foo() {} +"; + assert_format(src, expected); + } + + #[test] + fn does_not_merge_imports_if_they_have_trailing_comments_followed_by_nothing() { + let src = " + use foo; + use bar; // trailing +"; + let expected = "use foo; +use bar; // trailing +"; + assert_format(src, expected); + } + + #[test] + fn merges_and_sorts_imports() { + let src = " + use foo::baz; + use foo::bar; + "; + let expected = "use foo::{bar, baz};\n"; + assert_format(src, expected); + } + + #[test] + fn merges_and_sorts_imports_2() { + let src = " +use aztec::{ + context::Context, log::emit_unencrypted_log, note::{ + note_getter_options::NoteGetterOptions, note_header::NoteHeader, + }, state_vars::{ + Map, PrivateSet, PublicMutable, + }, types::{ + address::AztecAddress, type_serialization::field_serialization::{ + FIELD_SERIALIZED_LEN, FieldSerializationMethods, + }, + }, +}; + "; + let expected = "use aztec::{ + context::Context, + log::emit_unencrypted_log, + note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader}, + state_vars::{Map, PrivateSet, PublicMutable}, + types::{ + address::AztecAddress, + type_serialization::field_serialization::{FIELD_SERIALIZED_LEN, FieldSerializationMethods}, + }, +}; +"; + assert_format(src, expected); + } + + #[test] + fn merges_and_sorts_imports_with_different_path_kinds() { + let src = " + use bar::baz; + use foo::bar; + use crate::foo; + "; + let expected = "use crate::foo; +use bar::baz; +use foo::bar; +"; + assert_format(src, expected); + } + + #[test] + fn sorts_import() { + let src = " + use value_note::{ + utils::{increment, decrement}, value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, + }; + "; + let expected = "use value_note::{ + utils::{decrement, increment}, + value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, +}; +"; + assert_format(src, expected); + } + + #[test] + fn sorts_import_ignoring_case() { + let src = " + use foo::{def, ZETA, ABC, efg}; + use BAR; + "; + let expected = "use BAR; +use foo::{ABC, def, efg, ZETA}; +"; + assert_format(src, expected); + } + + #[test] + fn idempotent_test_check_next_test() { + let src = " + use std::as_witness; +use std::merkle::compute_merkle_root; + "; + let expected = "use std::{as_witness, merkle::compute_merkle_root};\n"; + assert_format(src, expected); + } + + #[test] + fn idempotent_test_check_previous_test() { + let src = "use std::{as_witness, merkle::compute_merkle_root};"; + let expected = "use std::{as_witness, merkle::compute_merkle_root};\n"; + assert_format(src, expected); + } +} diff --git a/tooling/nargo_fmt/tests/expected/contract.nr b/tooling/nargo_fmt/tests/expected/contract.nr index 28e4ccd8ffe..ad53e61c911 100644 --- a/tooling/nargo_fmt/tests/expected/contract.nr +++ b/tooling/nargo_fmt/tests/expected/contract.nr @@ -6,15 +6,21 @@ contract Benchmarking { use aztec::protocol_types::abis::function_selector::FunctionSelector; use value_note::{ - utils::{increment, decrement}, value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, + utils::{decrement, increment}, + value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, }; use aztec::{ - context::Context, note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader}, - log::emit_unencrypted_log, state_vars::{Map, PublicMutable, PrivateSet}, - types::type_serialization::field_serialization::{ - FieldSerializationMethods, FIELD_SERIALIZED_LEN, - }, types::address::AztecAddress, + context::Context, + log::emit_unencrypted_log, + note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader}, + state_vars::{Map, PrivateSet, PublicMutable}, + types::{ + address::AztecAddress, + type_serialization::field_serialization::{ + FIELD_SERIALIZED_LEN, FieldSerializationMethods, + }, + }, }; struct Storage { From a7d58de7165f3e4ca7e6abfb253d1893ff406b83 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 23 Oct 2024 10:40:44 -0300 Subject: [PATCH 02/15] There's a need for `self` in imports --- .../nargo_fmt/src/formatter/use_tree_merge.rs | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs index 804785250c2..1c3d0326a6e 100644 --- a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs +++ b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs @@ -104,12 +104,17 @@ enum Segment { Super, Dep, Plain(String), + Terminal, } impl Segment { /// Combines two segments into a single one, by joining them with "::". - fn combine(&self, other: Segment) -> Segment { - Segment::Plain(format!("{}::{}", self, other)) + fn combine(self, other: Segment) -> Segment { + if other == Segment::Terminal { + self + } else { + Segment::Plain(format!("{}::{}", self, other)) + } } } @@ -120,6 +125,7 @@ impl Display for Segment { Segment::Super => write!(f, "super"), Segment::Dep => write!(f, "dep"), Segment::Plain(s) => write!(f, "{}", s), + Segment::Terminal => write!(f, "self"), } } } @@ -145,7 +151,9 @@ impl Ord for Segment { // Case-insensitive comparison for plain segments self_string.to_lowercase().cmp(&other_string.to_lowercase()) } + (Segment::Plain(_), Segment::Terminal) => Ordering::Less, (Segment::Plain(_), _) => Ordering::Greater, + (Segment::Terminal, _) => Ordering::Greater, } } } @@ -186,6 +194,12 @@ impl ImportTree { self.tree.entry(segment).or_default() } + /// Inserts a segment that's the final segment in an import path. + fn insert_terminal(&mut self, segment: Segment) { + let tree = self.insert(segment); + tree.insert(Segment::Terminal); + } + /// Simplifies a tree by combining segments that only have one child. /// /// For example, this tree: @@ -240,9 +254,9 @@ fn merge_imports_in_tree(imports: Vec, mut tree: &mut ImportTree) { match import.kind { UseTreeKind::Path(ident, alias) => { if let Some(alias) = alias { - tree.insert(Segment::Plain(format!("{} as {}", ident, alias))); + tree.insert_terminal(Segment::Plain(format!("{} as {}", ident, alias))); } else { - tree.insert(Segment::Plain(ident.to_string())); + tree.insert_terminal(Segment::Plain(ident.to_string())); } } UseTreeKind::List(trees) => { @@ -417,7 +431,7 @@ use bar; // trailing } #[test] - fn merges_and_sorts_imports() { + fn merges_and_sorts_imports_just_two() { let src = " use foo::baz; use foo::bar; @@ -496,6 +510,16 @@ use foo::{ABC, def, efg, ZETA}; assert_format(src, expected); } + #[test] + fn merges_nested_import() { + let src = " + use foo::bar; + use foo; + "; + let expected = "use foo::{bar, self};\n"; + assert_format(src, expected); + } + #[test] fn idempotent_test_check_next_test() { let src = " From f30b438cd3629bbe97c8deb22a460b8c1e0ff239 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 23 Oct 2024 11:07:18 -0300 Subject: [PATCH 03/15] Allow self in use statements --- compiler/noirc_frontend/src/ast/statement.rs | 4 +++- .../src/parser/parser/use_tree.rs | 15 +++++++++++++ compiler/noirc_frontend/src/tests.rs | 22 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/ast/statement.rs b/compiler/noirc_frontend/src/ast/statement.rs index 441eff99d9e..038a7b76bac 100644 --- a/compiler/noirc_frontend/src/ast/statement.rs +++ b/compiler/noirc_frontend/src/ast/statement.rs @@ -373,7 +373,9 @@ impl UseTree { match self.kind { UseTreeKind::Path(name, alias) => { - vec![ImportStatement { visibility, path: prefix.join(name), alias }] + // Desugar `use foo::{self}` to `use foo` + let path = if name.0.contents == "self" { prefix } else { prefix.join(name) }; + vec![ImportStatement { visibility, path, alias }] } UseTreeKind::List(trees) => { let trees = trees.into_iter(); diff --git a/compiler/noirc_frontend/src/parser/parser/use_tree.rs b/compiler/noirc_frontend/src/parser/parser/use_tree.rs index 1c43732c94f..bc95c04d46b 100644 --- a/compiler/noirc_frontend/src/parser/parser/use_tree.rs +++ b/compiler/noirc_frontend/src/parser/parser/use_tree.rs @@ -66,6 +66,14 @@ impl<'a> Parser<'a> { fn parse_use_tree_in_list(&mut self) -> Option { let start_span = self.current_token_span; + // Special case: "self" cannot be followed by anything else + if self.eat_self() { + return Some(UseTree { + prefix: Path { segments: Vec::new(), kind: PathKind::Plain, span: start_span }, + kind: UseTreeKind::Path(Ident::new("self".to_string(), start_span), None), + }); + } + let use_tree = self.parse_use_tree_without_kind( start_span, PathKind::Plain, @@ -250,4 +258,11 @@ mod tests { let (_, errors) = parse_program(src); assert!(!errors.is_empty()); } + + #[test] + fn errors_on_double_colon_after_self() { + let src = "use foo::{self::bar};"; + let (_, errors) = parse_program(src); + assert!(!errors.is_empty()); + } } diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index 17acd17dcc9..86a486a0de5 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -3389,3 +3389,25 @@ fn arithmetic_generics_rounding_fail() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); } + +#[test] +fn uses_self_in_import() { + let src = r#" + mod moo { + pub mod bar { + pub fn foo() -> i32 { + 1 + } + } + } + + use moo::bar::{self}; + + pub fn baz() -> i32 { + bar::foo() + } + + fn main() {} + "#; + assert_no_errors(src); +} From d05702c3dfabca56e2918dffce46f6b4bd804e50 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 23 Oct 2024 11:11:11 -0300 Subject: [PATCH 04/15] Merge imports in the standard library and test programs --- noir_stdlib/src/array/check_shuffle.nr | 2 +- noir_stdlib/src/array/mod.nr | 4 +-- noir_stdlib/src/bigint.nr | 3 +- noir_stdlib/src/cmp.nr | 2 +- noir_stdlib/src/collections/map.nr | 12 ++++--- noir_stdlib/src/collections/umap.nr | 5 +-- noir_stdlib/src/ec/consts/te.nr | 3 +- noir_stdlib/src/ec/montcurve.nr | 36 ++++++++++--------- noir_stdlib/src/ec/swcurve.nr | 9 ++--- noir_stdlib/src/ec/tecurve.nr | 28 ++++++++------- noir_stdlib/src/eddsa.nr | 10 +++--- noir_stdlib/src/embedded_curve_ops.nr | 3 +- noir_stdlib/src/field/bn254.nr | 2 +- noir_stdlib/src/field/mod.nr | 2 +- noir_stdlib/src/hash/keccak.nr | 3 +- noir_stdlib/src/hash/mimc.nr | 3 +- noir_stdlib/src/hash/mod.nr | 12 ++++--- noir_stdlib/src/hash/poseidon/bn254/consts.nr | 3 +- noir_stdlib/src/hash/poseidon/bn254/perm.nr | 3 +- noir_stdlib/src/hash/poseidon/mod.nr | 3 +- noir_stdlib/src/hash/poseidon2.nr | 3 +- noir_stdlib/src/meta/expr.nr | 4 +-- noir_stdlib/src/meta/mod.nr | 4 +-- noir_stdlib/src/meta/quoted.nr | 3 +- noir_stdlib/src/meta/trait_constraint.nr | 3 +- noir_stdlib/src/meta/trait_def.nr | 3 +- noir_stdlib/src/meta/typ.nr | 3 +- noir_stdlib/src/ops/mod.nr | 4 +-- noir_stdlib/src/option.nr | 4 +-- noir_stdlib/src/prelude.nr | 23 ++++++------ noir_stdlib/src/string.nr | 3 +- noir_stdlib/src/uint128.nr | 8 +++-- .../ec_baby_jubjub/src/main.nr | 11 ++---- .../macros_in_comptime/src/main.nr | 6 ++-- .../mod_nr_entrypoint/src/main.nr | 4 +-- .../reexports/src/main.nr | 2 +- .../regression_2099/src/main.nr | 3 +- .../trait_call_full_path/src/main.nr | 3 +- .../trait_method_mut_self/src/main.nr | 3 +- .../trait_multi_module_test/src/module3.nr | 3 +- .../trait_where_clause/src/main.nr | 3 +- .../src/main.nr | 4 +-- .../execution_success/bigint/src/main.nr | 3 +- .../binary_operator_overloading/src/main.nr | 3 +- .../brillig_oracle/src/main.nr | 3 +- .../diamond_deps_0/src/main.nr | 3 +- .../execution_success/eddsa/src/main.nr | 12 +++---- .../execution_success/hashmap/src/main.nr | 4 +-- .../execution_success/prelude/src/main.nr | 3 +- .../regression_3889/src/main.nr | 6 ++-- .../regression_5045/src/main.nr | 3 +- .../regression_5615/src/main.nr | 4 +-- .../execution_success/uhashmap/src/main.nr | 4 +-- 53 files changed, 130 insertions(+), 173 deletions(-) diff --git a/noir_stdlib/src/array/check_shuffle.nr b/noir_stdlib/src/array/check_shuffle.nr index 82028d487c7..2e8c227feee 100644 --- a/noir_stdlib/src/array/check_shuffle.nr +++ b/noir_stdlib/src/array/check_shuffle.nr @@ -59,8 +59,8 @@ where } mod test { - use super::check_shuffle; use crate::cmp::Eq; + use super::check_shuffle; struct CompoundStruct { a: bool, diff --git a/noir_stdlib/src/array/mod.nr b/noir_stdlib/src/array/mod.nr index 8bb425854f2..16a27757c63 100644 --- a/noir_stdlib/src/array/mod.nr +++ b/noir_stdlib/src/array/mod.nr @@ -1,6 +1,4 @@ -use crate::cmp::{Eq, Ord}; -use crate::convert::From; -use crate::runtime::is_unconstrained; +use crate::{cmp::{Eq, Ord}, convert::From, runtime::is_unconstrained}; mod check_shuffle; mod quicksort; diff --git a/noir_stdlib/src/bigint.nr b/noir_stdlib/src/bigint.nr index 203ff90d444..63fca63a515 100644 --- a/noir_stdlib/src/bigint.nr +++ b/noir_stdlib/src/bigint.nr @@ -1,5 +1,4 @@ -use crate::ops::{Add, Sub, Mul, Div}; -use crate::cmp::Eq; +use crate::{cmp::Eq, ops::{Add, Div, Mul, Sub}}; global bn254_fq = &[ 0x47, 0xFD, 0x7C, 0xD8, 0x16, 0x8C, 0x20, 0x3C, 0x8d, 0xca, 0x71, 0x68, 0x91, 0x6a, 0x81, 0x97, diff --git a/noir_stdlib/src/cmp.nr b/noir_stdlib/src/cmp.nr index 10be6e7b867..ae515150a4d 100644 --- a/noir_stdlib/src/cmp.nr +++ b/noir_stdlib/src/cmp.nr @@ -537,7 +537,7 @@ where } mod cmp_tests { - use crate::cmp::{min, max}; + use crate::cmp::{max, min}; #[test] fn sanity_check_min() { diff --git a/noir_stdlib/src/collections/map.nr b/noir_stdlib/src/collections/map.nr index cd203c43ad3..a83557c41ca 100644 --- a/noir_stdlib/src/collections/map.nr +++ b/noir_stdlib/src/collections/map.nr @@ -1,8 +1,10 @@ -use crate::cmp::Eq; -use crate::option::Option; -use crate::default::Default; -use crate::hash::{Hash, Hasher, BuildHasher}; -use crate::collections::bounded_vec::BoundedVec; +use crate::{ + cmp::Eq, + collections::bounded_vec::BoundedVec, + default::Default, + hash::{BuildHasher, Hash, Hasher}, + option::Option, +}; // We use load factor alpha_max = 0.75. // Upon exceeding it, assert will fail in order to inform the user diff --git a/noir_stdlib/src/collections/umap.nr b/noir_stdlib/src/collections/umap.nr index 9b72b6173ca..bdcbc7c7094 100644 --- a/noir_stdlib/src/collections/umap.nr +++ b/noir_stdlib/src/collections/umap.nr @@ -1,7 +1,4 @@ -use crate::cmp::Eq; -use crate::option::Option; -use crate::default::Default; -use crate::hash::{Hash, Hasher, BuildHasher}; +use crate::{cmp::Eq, default::Default, hash::{BuildHasher, Hash, Hasher}, option::Option}; // An unconstrained hash table with open addressing and quadratic probing. // Note that "unconstrained" here means that almost all operations on this diff --git a/noir_stdlib/src/ec/consts/te.nr b/noir_stdlib/src/ec/consts/te.nr index 561c16e846a..9bc2626acdf 100644 --- a/noir_stdlib/src/ec/consts/te.nr +++ b/noir_stdlib/src/ec/consts/te.nr @@ -1,5 +1,4 @@ -use crate::ec::tecurve::affine::Point as TEPoint; -use crate::ec::tecurve::affine::Curve as TECurve; +use crate::ec::tecurve::affine::{Curve as TECurve, Point as TEPoint}; pub struct BabyJubjub { pub curve: TECurve, diff --git a/noir_stdlib/src/ec/montcurve.nr b/noir_stdlib/src/ec/montcurve.nr index 6c83feb1607..cc854ef7cbe 100644 --- a/noir_stdlib/src/ec/montcurve.nr +++ b/noir_stdlib/src/ec/montcurve.nr @@ -3,16 +3,18 @@ pub mod affine { // Points are represented by two-dimensional Cartesian coordinates. // All group operations are induced by those of the corresponding Twisted Edwards curve. // See e.g. for details on the correspondences. - use crate::ec::montcurve::curvegroup; - use crate::ec::swcurve::affine::Curve as SWCurve; - use crate::ec::swcurve::affine::Point as SWPoint; - use crate::ec::tecurve::affine::Curve as TECurve; - use crate::ec::tecurve::affine::Point as TEPoint; - use crate::ec::is_square; - use crate::ec::safe_inverse; - use crate::ec::sqrt; - use crate::ec::ZETA; - use crate::cmp::Eq; + use crate::{ + cmp::Eq, + ec::{ + is_square, + montcurve::curvegroup, + safe_inverse, + sqrt, + swcurve::affine::{Curve as SWCurve, Point as SWPoint}, + tecurve::affine::{Curve as TECurve, Point as TEPoint}, + ZETA, + }, + }; // Curve specification pub struct Curve { // Montgomery Curve configuration (ky^2 = x^3 + j*x^2 + x) @@ -222,12 +224,14 @@ pub mod curvegroup { // Points are represented by three-dimensional projective (homogeneous) coordinates. // All group operations are induced by those of the corresponding Twisted Edwards curve. // See e.g. for details on the correspondences. - use crate::ec::montcurve::affine; - use crate::ec::swcurve::curvegroup::Curve as SWCurve; - use crate::ec::swcurve::curvegroup::Point as SWPoint; - use crate::ec::tecurve::curvegroup::Curve as TECurve; - use crate::ec::tecurve::curvegroup::Point as TEPoint; - use crate::cmp::Eq; + use crate::{ + cmp::Eq, + ec::{ + montcurve::affine, + swcurve::curvegroup::{Curve as SWCurve, Point as SWPoint}, + tecurve::curvegroup::{Curve as TECurve, Point as TEPoint}, + }, + }; pub struct Curve { // Montgomery Curve configuration (ky^2 z = x*(x^2 + j*x*z + z*z)) pub j: Field, diff --git a/noir_stdlib/src/ec/swcurve.nr b/noir_stdlib/src/ec/swcurve.nr index 145b2506f73..1e43285b8b1 100644 --- a/noir_stdlib/src/ec/swcurve.nr +++ b/noir_stdlib/src/ec/swcurve.nr @@ -3,11 +3,7 @@ pub mod affine { // Points are represented by two-dimensional Cartesian coordinates. // Group operations are implemented in terms of those in CurveGroup (in this case, extended Twisted Edwards) coordinates // for reasons of efficiency, cf. . - use crate::ec::swcurve::curvegroup; - use crate::ec::safe_inverse; - use crate::ec::is_square; - use crate::ec::sqrt; - use crate::cmp::Eq; + use crate::{cmp::Eq, ec::{is_square, safe_inverse, sqrt, swcurve::curvegroup}}; // Curve specification pub struct Curve { // Short Weierstrass curve @@ -190,8 +186,7 @@ pub mod curvegroup { // CurveGroup representation of Weierstrass curves // Points are represented by three-dimensional Jacobian coordinates. // See for details. - use crate::ec::swcurve::affine; - use crate::cmp::Eq; + use crate::{cmp::Eq, ec::swcurve::affine}; // Curve specification pub struct Curve { // Short Weierstrass curve diff --git a/noir_stdlib/src/ec/tecurve.nr b/noir_stdlib/src/ec/tecurve.nr index 0088896015d..5a4a9b4149c 100644 --- a/noir_stdlib/src/ec/tecurve.nr +++ b/noir_stdlib/src/ec/tecurve.nr @@ -4,12 +4,14 @@ pub mod affine { // Group operations are implemented in terms of those in CurveGroup (in this case, extended Twisted Edwards) coordinates // for reasons of efficiency. // See for details. - use crate::ec::tecurve::curvegroup; - use crate::ec::montcurve::affine::Curve as MCurve; - use crate::ec::montcurve::affine::Point as MPoint; - use crate::ec::swcurve::affine::Curve as SWCurve; - use crate::ec::swcurve::affine::Point as SWPoint; - use crate::cmp::Eq; + use crate::{ + cmp::Eq, + ec::{ + montcurve::affine::{Curve as MCurve, Point as MPoint}, + swcurve::affine::{Curve as SWCurve, Point as SWPoint}, + tecurve::curvegroup, + }, + }; // Curve specification pub struct Curve { // Twisted Edwards curve @@ -197,12 +199,14 @@ pub mod curvegroup { // CurveGroup coordinate representation of Twisted Edwards curves // Points are represented by four-dimensional projective coordinates, viz. extended Twisted Edwards coordinates. // See section 3 of for details. - use crate::ec::tecurve::affine; - use crate::ec::montcurve::curvegroup::Curve as MCurve; - use crate::ec::montcurve::curvegroup::Point as MPoint; - use crate::ec::swcurve::curvegroup::Curve as SWCurve; - use crate::ec::swcurve::curvegroup::Point as SWPoint; - use crate::cmp::Eq; + use crate::{ + cmp::Eq, + ec::{ + montcurve::curvegroup::{Curve as MCurve, Point as MPoint}, + swcurve::curvegroup::{Curve as SWCurve, Point as SWPoint}, + tecurve::affine, + }, + }; // Curve specification pub struct Curve { // Twisted Edwards curve diff --git a/noir_stdlib/src/eddsa.nr b/noir_stdlib/src/eddsa.nr index 89a0b05b072..c9df59def8e 100644 --- a/noir_stdlib/src/eddsa.nr +++ b/noir_stdlib/src/eddsa.nr @@ -1,8 +1,8 @@ -use crate::ec::consts::te::baby_jubjub; -use crate::ec::tecurve::affine::Point as TEPoint; -use crate::hash::Hasher; -use crate::hash::poseidon::PoseidonHasher; -use crate::default::Default; +use crate::{ + default::Default, + ec::{consts::te::baby_jubjub, tecurve::affine::Point as TEPoint}, + hash::{Hasher, poseidon::PoseidonHasher}, +}; // Returns true if signature is valid pub fn eddsa_poseidon_verify( diff --git a/noir_stdlib/src/embedded_curve_ops.nr b/noir_stdlib/src/embedded_curve_ops.nr index dd5e4285c00..edabcf7ad36 100644 --- a/noir_stdlib/src/embedded_curve_ops.nr +++ b/noir_stdlib/src/embedded_curve_ops.nr @@ -1,5 +1,4 @@ -use crate::ops::arith::{Add, Sub, Neg}; -use crate::cmp::Eq; +use crate::{cmp::Eq, ops::arith::{Add, Neg, Sub}}; /// A point on the embedded elliptic curve /// By definition, the base field of the embedded curve is the scalar field of the proof system curve, i.e the Noir Field. diff --git a/noir_stdlib/src/field/bn254.nr b/noir_stdlib/src/field/bn254.nr index 356b47e63cf..9642c2aa1b8 100644 --- a/noir_stdlib/src/field/bn254.nr +++ b/noir_stdlib/src/field/bn254.nr @@ -141,7 +141,7 @@ pub fn lt(a: Field, b: Field) -> bool { mod tests { // TODO: Allow imports from "super" use crate::field::bn254::{ - decompose, compute_lt, assert_gt, gt, TWO_POW_128, compute_lte, PLO, PHI, + assert_gt, compute_lt, compute_lte, decompose, gt, PHI, PLO, TWO_POW_128, }; #[test] diff --git a/noir_stdlib/src/field/mod.nr b/noir_stdlib/src/field/mod.nr index 915ea8f939e..b632cf1f7a2 100644 --- a/noir_stdlib/src/field/mod.nr +++ b/noir_stdlib/src/field/mod.nr @@ -1,6 +1,6 @@ pub mod bn254; -use bn254::lt as bn254_lt; use crate::runtime::is_unconstrained; +use bn254::lt as bn254_lt; impl Field { /// Asserts that `self` can be represented in `bit_size` bits. diff --git a/noir_stdlib/src/hash/keccak.nr b/noir_stdlib/src/hash/keccak.nr index 50fbab8a416..a539086331e 100644 --- a/noir_stdlib/src/hash/keccak.nr +++ b/noir_stdlib/src/hash/keccak.nr @@ -1,5 +1,4 @@ -use crate::collections::vec::Vec; -use crate::runtime::is_unconstrained; +use crate::{collections::vec::Vec, runtime::is_unconstrained}; global BLOCK_SIZE_IN_BYTES: u32 = 136; //(1600 - BITS * 2) / WORD_SIZE; global WORD_SIZE: u32 = 8; // Limbs are made up of u64s so 8 bytes each. diff --git a/noir_stdlib/src/hash/mimc.nr b/noir_stdlib/src/hash/mimc.nr index 6045ae3dbdb..73e62d95a03 100644 --- a/noir_stdlib/src/hash/mimc.nr +++ b/noir_stdlib/src/hash/mimc.nr @@ -1,5 +1,4 @@ -use crate::hash::Hasher; -use crate::default::Default; +use crate::{default::Default, hash::Hasher}; // mimc-p/p implementation // constants are (publicly generated) random numbers, for instance using keccak as a ROM. diff --git a/noir_stdlib/src/hash/mod.nr b/noir_stdlib/src/hash/mod.nr index 609017d70aa..550ee0412f8 100644 --- a/noir_stdlib/src/hash/mod.nr +++ b/noir_stdlib/src/hash/mod.nr @@ -5,12 +5,14 @@ pub mod keccak; pub mod sha256; pub mod sha512; -use crate::default::Default; -use crate::uint128::U128; -use crate::embedded_curve_ops::{ - EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return, +use crate::{ + default::Default, + embedded_curve_ops::{ + EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return, + }, + meta::derive_via, + uint128::U128, }; -use crate::meta::derive_via; // Kept for backwards compatibility pub use sha256::{digest, sha256, sha256_compression, sha256_var}; diff --git a/noir_stdlib/src/hash/poseidon/bn254/consts.nr b/noir_stdlib/src/hash/poseidon/bn254/consts.nr index 835ed3ea476..4c27dfc6ad5 100644 --- a/noir_stdlib/src/hash/poseidon/bn254/consts.nr +++ b/noir_stdlib/src/hash/poseidon/bn254/consts.nr @@ -2,8 +2,7 @@ // Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 // Constants for various Poseidon instances in the case of the prime field of the same order as BN254. // Consistent with https://github.com/iden3/circomlib/blob/master/circuits/poseidon.circom and https://github.com/iden3/circomlib/blob/master/circuits/poseidon_constants.circom -use crate::hash::poseidon::PoseidonConfig; -use crate::hash::poseidon::config; +use crate::hash::poseidon::{config, PoseidonConfig}; // S-box power fn alpha() -> Field { 5 diff --git a/noir_stdlib/src/hash/poseidon/bn254/perm.nr b/noir_stdlib/src/hash/poseidon/bn254/perm.nr index 3a12f59fe77..61e629e4db1 100644 --- a/noir_stdlib/src/hash/poseidon/bn254/perm.nr +++ b/noir_stdlib/src/hash/poseidon/bn254/perm.nr @@ -1,6 +1,5 @@ // Instantiations of Poseidon permutation for the prime field of the same order as BN254 -use crate::hash::poseidon::bn254::consts; -use crate::hash::poseidon::permute; +use crate::hash::poseidon::{bn254::consts, permute}; #[field(bn254)] pub fn x5_2(mut state: [Field; 2]) -> [Field; 2] { diff --git a/noir_stdlib/src/hash/poseidon/mod.nr b/noir_stdlib/src/hash/poseidon/mod.nr index 0af7951b8dc..8c75b9a3662 100644 --- a/noir_stdlib/src/hash/poseidon/mod.nr +++ b/noir_stdlib/src/hash/poseidon/mod.nr @@ -1,6 +1,5 @@ pub mod bn254; // Instantiations of Poseidon for prime field of the same order as BN254 -use crate::hash::Hasher; -use crate::default::Default; +use crate::{default::Default, hash::Hasher}; // A config struct defining the parameters of the Poseidon instance to use. // diff --git a/noir_stdlib/src/hash/poseidon2.nr b/noir_stdlib/src/hash/poseidon2.nr index 517c2cd8f5f..2fd2f09e65c 100644 --- a/noir_stdlib/src/hash/poseidon2.nr +++ b/noir_stdlib/src/hash/poseidon2.nr @@ -1,5 +1,4 @@ -use crate::hash::Hasher; -use crate::default::Default; +use crate::{default::Default, hash::Hasher}; comptime global RATE: u32 = 3; diff --git a/noir_stdlib/src/meta/expr.nr b/noir_stdlib/src/meta/expr.nr index 1b04a97ab15..46c65638527 100644 --- a/noir_stdlib/src/meta/expr.nr +++ b/noir_stdlib/src/meta/expr.nr @@ -1,8 +1,6 @@ //! Contains methods on the built-in `Expr` type for quoted, syntactically valid expressions. -use crate::option::Option; -use crate::meta::op::UnaryOp; -use crate::meta::op::BinaryOp; +use crate::{meta::op::{BinaryOp, UnaryOp}, option::Option}; impl Expr { /// If this expression is an array literal `[elem1, ..., elemN]`, this returns a slice of each element in the array. diff --git a/noir_stdlib/src/meta/mod.nr b/noir_stdlib/src/meta/mod.nr index ff662b878ec..eb7a59634bc 100644 --- a/noir_stdlib/src/meta/mod.nr +++ b/noir_stdlib/src/meta/mod.nr @@ -30,9 +30,7 @@ pub comptime fn type_of(x: T) -> Type {} // docs:start:derive_example // These are needed for the unconstrained hashmap we're using to store derive functions -use crate::collections::umap::UHashMap; -use crate::hash::BuildHasherDefault; -use crate::hash::poseidon2::Poseidon2Hasher; +use crate::{collections::umap::UHashMap, hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher}}; // A derive function is one that given a struct definition can // create us a quoted trait impl from it. diff --git a/noir_stdlib/src/meta/quoted.nr b/noir_stdlib/src/meta/quoted.nr index d67174d7829..c4f2b095766 100644 --- a/noir_stdlib/src/meta/quoted.nr +++ b/noir_stdlib/src/meta/quoted.nr @@ -1,5 +1,4 @@ -use crate::cmp::Eq; -use crate::option::Option; +use crate::{cmp::Eq, option::Option}; impl Quoted { #[builtin(quoted_as_expr)] diff --git a/noir_stdlib/src/meta/trait_constraint.nr b/noir_stdlib/src/meta/trait_constraint.nr index bf22f454448..91dd1168116 100644 --- a/noir_stdlib/src/meta/trait_constraint.nr +++ b/noir_stdlib/src/meta/trait_constraint.nr @@ -1,5 +1,4 @@ -use crate::hash::{Hash, Hasher}; -use crate::cmp::Eq; +use crate::{cmp::Eq, hash::{Hash, Hasher}}; impl Eq for TraitConstraint { comptime fn eq(self, other: Self) -> bool { diff --git a/noir_stdlib/src/meta/trait_def.nr b/noir_stdlib/src/meta/trait_def.nr index cc448b2eae5..d889fdd1591 100644 --- a/noir_stdlib/src/meta/trait_def.nr +++ b/noir_stdlib/src/meta/trait_def.nr @@ -1,5 +1,4 @@ -use crate::hash::{Hash, Hasher}; -use crate::cmp::Eq; +use crate::{cmp::Eq, hash::{Hash, Hasher}}; impl TraitDefinition { #[builtin(trait_def_as_trait_constraint)] diff --git a/noir_stdlib/src/meta/typ.nr b/noir_stdlib/src/meta/typ.nr index 8076c692ca5..f722c3d0a5c 100644 --- a/noir_stdlib/src/meta/typ.nr +++ b/noir_stdlib/src/meta/typ.nr @@ -1,7 +1,6 @@ //! Contains methods on the built-in `Type` type used for representing a type in the source program. -use crate::cmp::Eq; -use crate::option::Option; +use crate::{cmp::Eq, option::Option}; /// Creates and returns an unbound type variable. This is a special kind of type internal /// to type checking which will type check with any other type. When it is type checked diff --git a/noir_stdlib/src/ops/mod.nr b/noir_stdlib/src/ops/mod.nr index bf908ea4b27..0e3a2467c60 100644 --- a/noir_stdlib/src/ops/mod.nr +++ b/noir_stdlib/src/ops/mod.nr @@ -1,5 +1,5 @@ pub(crate) mod arith; pub(crate) mod bit; -pub use arith::{Add, Sub, Mul, Div, Rem, Neg}; -pub use bit::{Not, BitOr, BitAnd, BitXor, Shl, Shr}; +pub use arith::{Add, Div, Mul, Neg, Rem, Sub}; +pub use bit::{BitAnd, BitOr, BitXor, Not, Shl, Shr}; diff --git a/noir_stdlib/src/option.nr b/noir_stdlib/src/option.nr index 5db2ce84efd..b045a3d7612 100644 --- a/noir_stdlib/src/option.nr +++ b/noir_stdlib/src/option.nr @@ -1,6 +1,4 @@ -use crate::hash::{Hash, Hasher}; -use crate::cmp::{Ordering, Ord, Eq}; -use crate::default::Default; +use crate::{cmp::{Eq, Ord, Ordering}, default::Default, hash::{Hash, Hasher}}; pub struct Option { _is_some: bool, diff --git a/noir_stdlib/src/prelude.nr b/noir_stdlib/src/prelude.nr index b6e54eaae60..f56fd888f76 100644 --- a/noir_stdlib/src/prelude.nr +++ b/noir_stdlib/src/prelude.nr @@ -1,10 +1,13 @@ -pub use crate::collections::vec::Vec; -pub use crate::collections::bounded_vec::BoundedVec; -pub use crate::option::Option; -pub use crate::{print, println, assert_constant}; -pub use crate::uint128::U128; -pub use crate::cmp::{Eq, Ord}; -pub use crate::default::Default; -pub use crate::convert::{From, Into}; -pub use crate::meta::{derive, derive_via}; -pub use crate::panic::panic; +pub use crate::{ + assert_constant, + cmp::{Eq, Ord}, + collections::{bounded_vec::BoundedVec, vec::Vec}, + convert::{From, Into}, + default::Default, + meta::{derive, derive_via}, + option::Option, + panic::panic, + print, + println, + uint128::U128, +}; diff --git a/noir_stdlib/src/string.nr b/noir_stdlib/src/string.nr index 18fb449626a..017b4ff649b 100644 --- a/noir_stdlib/src/string.nr +++ b/noir_stdlib/src/string.nr @@ -1,5 +1,4 @@ -use crate::collections::vec::Vec; -use crate::convert::From; +use crate::{collections::vec::Vec, convert::From}; impl str { /// Converts the given string into a byte array diff --git a/noir_stdlib/src/uint128.nr b/noir_stdlib/src/uint128.nr index a4e20859604..95ae3362385 100644 --- a/noir_stdlib/src/uint128.nr +++ b/noir_stdlib/src/uint128.nr @@ -1,5 +1,7 @@ -use crate::ops::{Add, Sub, Mul, Div, Rem, Not, BitOr, BitAnd, BitXor, Shl, Shr}; -use crate::cmp::{Eq, Ord, Ordering}; +use crate::{ + cmp::{Eq, Ord, Ordering}, + ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Rem, Shl, Shr, Sub}, +}; global pow64: Field = 18446744073709551616; //2^64; global pow63: Field = 9223372036854775808; // 2^63; @@ -313,7 +315,7 @@ impl Shr for U128 { } mod tests { - use crate::uint128::{U128, pow64, pow63}; + use crate::uint128::{pow63, pow64, U128}; #[test] fn test_not(lo: u64, hi: u64) { diff --git a/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr b/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr index 935b1c613ad..3f46eb10034 100644 --- a/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr +++ b/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr @@ -1,14 +1,9 @@ // Tests may be checked against https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/tree/main/poc -use std::ec::tecurve::affine::Curve as AffineCurve; -use std::ec::tecurve::affine::Point as Gaffine; -use std::ec::tecurve::curvegroup::Point as G; +use std::ec::tecurve::{affine::{Curve as AffineCurve, Point as Gaffine}, curvegroup::Point as G}; -use std::ec::swcurve::affine::Point as SWGaffine; -use std::ec::swcurve::curvegroup::Point as SWG; +use std::ec::swcurve::{affine::Point as SWGaffine, curvegroup::Point as SWG}; -use std::ec::montcurve::affine::Point as MGaffine; -use std::ec::montcurve::curvegroup::Point as MG; -use std::compat; +use std::{compat, ec::montcurve::{affine::Point as MGaffine, curvegroup::Point as MG}}; fn main() { // This test only makes sense if Field is the right prime field. diff --git a/test_programs/compile_success_empty/macros_in_comptime/src/main.nr b/test_programs/compile_success_empty/macros_in_comptime/src/main.nr index 799091fca09..1764f28ae6f 100644 --- a/test_programs/compile_success_empty/macros_in_comptime/src/main.nr +++ b/test_programs/compile_success_empty/macros_in_comptime/src/main.nr @@ -1,5 +1,4 @@ -use std::field::modulus_num_bits; -use std::meta::unquote; +use std::{field::modulus_num_bits, meta::unquote}; // Numeric generics default to u32 global three_field: Field = 3; @@ -38,8 +37,7 @@ comptime fn foo(x: Field) { } mod submodule { - use std::field::modulus_be_bytes; - use std::meta::unquote; + use std::{field::modulus_be_bytes, meta::unquote}; pub comptime fn bar() { // Use a function only in scope in this module diff --git a/test_programs/compile_success_empty/mod_nr_entrypoint/src/main.nr b/test_programs/compile_success_empty/mod_nr_entrypoint/src/main.nr index 620fd99f6ec..7fa8b1426ab 100644 --- a/test_programs/compile_success_empty/mod_nr_entrypoint/src/main.nr +++ b/test_programs/compile_success_empty/mod_nr_entrypoint/src/main.nr @@ -1,6 +1,4 @@ -use crate::foo::in_foo_mod; -use crate::foo::bar::in_bar_mod; -use crate::baz::in_baz_mod; +use crate::{baz::in_baz_mod, foo::{bar::in_bar_mod, in_foo_mod}}; mod foo; mod baz; diff --git a/test_programs/compile_success_empty/reexports/src/main.nr b/test_programs/compile_success_empty/reexports/src/main.nr index 0fd65a33564..6b568bea682 100644 --- a/test_programs/compile_success_empty/reexports/src/main.nr +++ b/test_programs/compile_success_empty/reexports/src/main.nr @@ -1,4 +1,4 @@ -use reexporting_lib::{FooStruct, MyStruct, lib}; +use reexporting_lib::{FooStruct, lib, MyStruct}; fn main() { let x: FooStruct = MyStruct { inner: 0 }; diff --git a/test_programs/compile_success_empty/regression_2099/src/main.nr b/test_programs/compile_success_empty/regression_2099/src/main.nr index 3fe3cdaf39a..2ca8b4ccc9e 100644 --- a/test_programs/compile_success_empty/regression_2099/src/main.nr +++ b/test_programs/compile_success_empty/regression_2099/src/main.nr @@ -1,5 +1,4 @@ -use std::ec::tecurve::affine::Curve as AffineCurve; -use std::ec::tecurve::affine::Point as Gaffine; +use std::ec::tecurve::affine::{Curve as AffineCurve, Point as Gaffine}; fn main() { // Define Baby Jubjub (ERC-2494) parameters in affine representation diff --git a/test_programs/compile_success_empty/trait_call_full_path/src/main.nr b/test_programs/compile_success_empty/trait_call_full_path/src/main.nr index aea0f436dce..29cf1b2e167 100644 --- a/test_programs/compile_success_empty/trait_call_full_path/src/main.nr +++ b/test_programs/compile_success_empty/trait_call_full_path/src/main.nr @@ -10,8 +10,7 @@ mod foo { } } -use foo::Trait; -use foo::Trait::me; +use foo::Trait::{me, self}; fn main(x: Field) { let _ = foo::Trait::me(x); diff --git a/test_programs/compile_success_empty/trait_method_mut_self/src/main.nr b/test_programs/compile_success_empty/trait_method_mut_self/src/main.nr index aa0baab7f89..cd67ec48f8d 100644 --- a/test_programs/compile_success_empty/trait_method_mut_self/src/main.nr +++ b/test_programs/compile_success_empty/trait_method_mut_self/src/main.nr @@ -1,5 +1,4 @@ -use std::hash::Hasher; -use std::hash::poseidon2::Poseidon2Hasher; +use std::hash::{Hasher, poseidon2::Poseidon2Hasher}; fn main(x: Field, y: pub Field) { let mut a_mut_ref = AType { x }; diff --git a/test_programs/compile_success_empty/trait_multi_module_test/src/module3.nr b/test_programs/compile_success_empty/trait_multi_module_test/src/module3.nr index 2485a2ba7a1..d9df949a465 100644 --- a/test_programs/compile_success_empty/trait_multi_module_test/src/module3.nr +++ b/test_programs/compile_success_empty/trait_multi_module_test/src/module3.nr @@ -1,4 +1,3 @@ -use crate::module1::MyTrait; -use crate::module2::MyStruct; +use crate::{module1::MyTrait, module2::MyStruct}; // ensure we can implement traits that are imported with the `use` syntax impl MyTrait for MyStruct {} diff --git a/test_programs/compile_success_empty/trait_where_clause/src/main.nr b/test_programs/compile_success_empty/trait_where_clause/src/main.nr index 8dc00be622d..88f2cafffde 100644 --- a/test_programs/compile_success_empty/trait_where_clause/src/main.nr +++ b/test_programs/compile_success_empty/trait_where_clause/src/main.nr @@ -4,8 +4,7 @@ // - structs (struct Foo where T: ...) // import the traits from another module to ensure the where clauses are ok with that mod the_trait; -use crate::the_trait::Asd; -use crate::the_trait::StaticTrait; +use crate::the_trait::{Asd, StaticTrait}; struct Add10 { x: Field, diff --git a/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr b/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr index 535d7b18137..a755e492a81 100644 --- a/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr +++ b/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr @@ -1,6 +1,4 @@ -use std::hash::Hasher; -use std::hash::poseidon2::Poseidon2Hasher; -use std::hash::poseidon::PoseidonHasher; +use std::hash::{Hasher, poseidon2::Poseidon2Hasher, poseidon::PoseidonHasher}; fn main(x: Field, y: pub Field) { let mut hasher = PoseidonHasher::default(); diff --git a/test_programs/execution_success/bigint/src/main.nr b/test_programs/execution_success/bigint/src/main.nr index 5a8b9fb67ef..5514b44e7e9 100644 --- a/test_programs/execution_success/bigint/src/main.nr +++ b/test_programs/execution_success/bigint/src/main.nr @@ -1,5 +1,4 @@ -use std::bigint; -use std::{bigint::Secpk1Fq, println}; +use std::{bigint::{Secpk1Fq, self}, println}; fn main(mut x: [u8; 5], y: [u8; 5]) { let a = bigint::Secpk1Fq::from_le_bytes(&[x[0], x[1], x[2], x[3], x[4]]); diff --git a/test_programs/execution_success/binary_operator_overloading/src/main.nr b/test_programs/execution_success/binary_operator_overloading/src/main.nr index a5e12fd5da9..e6739e6f4d6 100644 --- a/test_programs/execution_success/binary_operator_overloading/src/main.nr +++ b/test_programs/execution_success/binary_operator_overloading/src/main.nr @@ -1,5 +1,4 @@ -use std::ops::{Add, Sub, Mul, Div, Rem, BitAnd, BitOr, BitXor, Shl, Shr}; -use std::cmp::Ordering; +use std::{cmp::Ordering, ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub}}; // x = 3, y = 9 fn main(x: u32, y: u32) { diff --git a/test_programs/execution_success/brillig_oracle/src/main.nr b/test_programs/execution_success/brillig_oracle/src/main.nr index 8f5b2fa7566..0f10749c485 100644 --- a/test_programs/execution_success/brillig_oracle/src/main.nr +++ b/test_programs/execution_success/brillig_oracle/src/main.nr @@ -1,5 +1,4 @@ -use std::slice; -use std::test::OracleMock; +use std::{slice, test::OracleMock}; // Tests oracle usage in brillig/unconstrained functions fn main(_x: Field) { diff --git a/test_programs/execution_success/diamond_deps_0/src/main.nr b/test_programs/execution_success/diamond_deps_0/src/main.nr index 690d6fc9fc8..1fff8a5f583 100644 --- a/test_programs/execution_success/diamond_deps_0/src/main.nr +++ b/test_programs/execution_success/diamond_deps_0/src/main.nr @@ -1,6 +1,5 @@ use dep1::call_dep1_then_dep2; -use dep2::call_dep2; -use dep2::RESOLVE_THIS; +use dep2::{call_dep2, RESOLVE_THIS}; fn main(x: Field, y: pub Field) -> pub Field { call_dep1_then_dep2(x, y) + call_dep2(x, y) + RESOLVE_THIS diff --git a/test_programs/execution_success/eddsa/src/main.nr b/test_programs/execution_success/eddsa/src/main.nr index d0ce8e70053..028dd8bd950 100644 --- a/test_programs/execution_success/eddsa/src/main.nr +++ b/test_programs/execution_success/eddsa/src/main.nr @@ -1,9 +1,9 @@ -use std::compat; -use std::ec::consts::te::baby_jubjub; -use std::ec::tecurve::affine::Point as TEPoint; -use std::hash; -use std::eddsa::{eddsa_to_pub, eddsa_poseidon_verify, eddsa_verify}; -use std::hash::poseidon2::Poseidon2Hasher; +use std::{ + compat, + ec::{consts::te::baby_jubjub, tecurve::affine::Point as TEPoint}, + eddsa::{eddsa_poseidon_verify, eddsa_to_pub, eddsa_verify}, + hash::{poseidon2::Poseidon2Hasher, self}, +}; fn main(msg: pub Field, _priv_key_a: Field, _priv_key_b: Field) { // Skip this test for non-bn254 backends diff --git a/test_programs/execution_success/hashmap/src/main.nr b/test_programs/execution_success/hashmap/src/main.nr index 964b900dce5..6e71d3fb010 100644 --- a/test_programs/execution_success/hashmap/src/main.nr +++ b/test_programs/execution_success/hashmap/src/main.nr @@ -1,8 +1,6 @@ mod utils; -use std::collections::map::HashMap; -use std::hash::BuildHasherDefault; -use std::hash::poseidon2::Poseidon2Hasher; +use std::{collections::map::HashMap, hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher}}; use utils::cut; diff --git a/test_programs/execution_success/prelude/src/main.nr b/test_programs/execution_success/prelude/src/main.nr index 4fe6080222e..cc0180ff1fe 100644 --- a/test_programs/execution_success/prelude/src/main.nr +++ b/test_programs/execution_success/prelude/src/main.nr @@ -8,8 +8,7 @@ fn main() { mod a { // We don't want to give an error due to re-importing elements that are already in the prelude. - use std::collections::vec::Vec; - use std::option::Option; + use std::{collections::vec::Vec, option::Option}; fn main() { let _xs = Vec::new(); diff --git a/test_programs/execution_success/regression_3889/src/main.nr b/test_programs/execution_success/regression_3889/src/main.nr index 2b54ae54418..ed7aefa5c80 100644 --- a/test_programs/execution_success/regression_3889/src/main.nr +++ b/test_programs/execution_success/regression_3889/src/main.nr @@ -5,16 +5,14 @@ mod Foo { } mod Bar { - use crate::Foo::NewType as BarStruct; - use crate::Foo::NewType; + use crate::Foo::{NewType, NewType as BarStruct}; } mod Baz { struct Works { a: Field, } - use crate::Bar::BarStruct; - use crate::Bar::NewType; + use crate::Bar::{BarStruct, NewType}; } fn main(works: Baz::Works, fails: Baz::BarStruct, also_fails: Bar::NewType) -> pub Field { diff --git a/test_programs/execution_success/regression_5045/src/main.nr b/test_programs/execution_success/regression_5045/src/main.nr index 545694368fd..aa9a45f7c11 100644 --- a/test_programs/execution_success/regression_5045/src/main.nr +++ b/test_programs/execution_success/regression_5045/src/main.nr @@ -1,5 +1,4 @@ -use std::embedded_curve_ops::EmbeddedCurvePoint; -use std::embedded_curve_ops::EmbeddedCurveScalar; +use std::embedded_curve_ops::{EmbeddedCurvePoint, EmbeddedCurveScalar}; fn main(is_active: bool) { let a = EmbeddedCurvePoint { diff --git a/test_programs/execution_success/regression_5615/src/main.nr b/test_programs/execution_success/regression_5615/src/main.nr index 1d8e0a045cd..186d8362009 100644 --- a/test_programs/execution_success/regression_5615/src/main.nr +++ b/test_programs/execution_success/regression_5615/src/main.nr @@ -1,6 +1,4 @@ -use std::collections::umap::UHashMap; -use std::hash::BuildHasherDefault; -use std::hash::poseidon2::Poseidon2Hasher; +use std::{collections::umap::UHashMap, hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher}}; unconstrained fn main() { comptime { diff --git a/test_programs/execution_success/uhashmap/src/main.nr b/test_programs/execution_success/uhashmap/src/main.nr index e917a83c5fd..7fc2efa95e5 100644 --- a/test_programs/execution_success/uhashmap/src/main.nr +++ b/test_programs/execution_success/uhashmap/src/main.nr @@ -1,6 +1,4 @@ -use std::collections::umap::UHashMap; -use std::hash::BuildHasherDefault; -use std::hash::poseidon2::Poseidon2Hasher; +use std::{collections::umap::UHashMap, hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher}}; type K = Field; type V = Field; From 3d5f90b7be4f4df031d926ff883a47ed65cdc0e3 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 23 Oct 2024 11:30:25 -0300 Subject: [PATCH 05/15] Add a comment --- tooling/nargo_fmt/src/formatter/use_tree_merge.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs index 1c3d0326a6e..b4598b6f4ea 100644 --- a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs +++ b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs @@ -104,6 +104,11 @@ enum Segment { Super, Dep, Plain(String), + /// Represents the end of a path. + /// This is needed because we have want to merge "foo" and "foo::bar", + /// we need to know that "foo" is the end of a path, and "foo::bar" is another one. + /// If we don't, merging "foo" and "foo::bar" will result in just "foo::bar", loosing "foo", + /// when we actually want "foo::{self, bar}". Terminal, } From a74554f2554428aa6c999ca1e137491227b692a8 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 23 Oct 2024 11:42:43 -0300 Subject: [PATCH 06/15] Put `self` before other segments --- .../nargo_fmt/src/formatter/use_tree_merge.rs | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs index b4598b6f4ea..552bf7e71dc 100644 --- a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs +++ b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs @@ -100,16 +100,16 @@ fn format_merged_import(segment: Segment, import_tree: ImportTree) -> ChunkGroup /// (they'll come in that order before any plain segment). #[derive(Debug, PartialEq, Eq)] enum Segment { - Crate, - Super, - Dep, - Plain(String), /// Represents the end of a path. /// This is needed because we have want to merge "foo" and "foo::bar", /// we need to know that "foo" is the end of a path, and "foo::bar" is another one. /// If we don't, merging "foo" and "foo::bar" will result in just "foo::bar", loosing "foo", /// when we actually want "foo::{self, bar}". Terminal, + Crate, + Super, + Dep, + Plain(String), } impl Segment { @@ -121,6 +121,16 @@ impl Segment { Segment::Plain(format!("{}::{}", self, other)) } } + + fn order_number(&self) -> usize { + match self { + Segment::Terminal => 0, + Segment::Crate => 1, + Segment::Super => 2, + Segment::Dep => 3, + Segment::Plain(_) => 4, + } + } } impl Display for Segment { @@ -143,22 +153,16 @@ impl PartialOrd for Segment { impl Ord for Segment { fn cmp(&self, other: &Self) -> Ordering { - match (self, other) { - (Segment::Crate, Segment::Crate) => Ordering::Equal, - (Segment::Crate, _) => Ordering::Less, - (Segment::Super, Segment::Crate) => Ordering::Greater, - (Segment::Super, Segment::Super) => Ordering::Equal, - (Segment::Super, _) => Ordering::Less, - (Segment::Dep, Segment::Crate) | (Segment::Dep, Segment::Super) => Ordering::Less, - (Segment::Dep, Segment::Dep) => Ordering::Equal, - (Segment::Dep, _) => Ordering::Greater, - (Segment::Plain(self_string), Segment::Plain(other_string)) => { - // Case-insensitive comparison for plain segments - self_string.to_lowercase().cmp(&other_string.to_lowercase()) - } - (Segment::Plain(_), Segment::Terminal) => Ordering::Less, - (Segment::Plain(_), _) => Ordering::Greater, - (Segment::Terminal, _) => Ordering::Greater, + let order_number_ordering = self.order_number().cmp(&other.order_number()); + if order_number_ordering != Ordering::Equal { + return order_number_ordering; + } + + if let (Segment::Plain(self_string), Segment::Plain(other_string)) = (self, other) { + // Case-insensitive comparison for plain segments + self_string.to_lowercase().cmp(&other_string.to_lowercase()) + } else { + order_number_ordering } } } @@ -199,12 +203,6 @@ impl ImportTree { self.tree.entry(segment).or_default() } - /// Inserts a segment that's the final segment in an import path. - fn insert_terminal(&mut self, segment: Segment) { - let tree = self.insert(segment); - tree.insert(Segment::Terminal); - } - /// Simplifies a tree by combining segments that only have one child. /// /// For example, this tree: @@ -259,9 +257,13 @@ fn merge_imports_in_tree(imports: Vec, mut tree: &mut ImportTree) { match import.kind { UseTreeKind::Path(ident, alias) => { if let Some(alias) = alias { - tree.insert_terminal(Segment::Plain(format!("{} as {}", ident, alias))); + tree = tree.insert(Segment::Plain(format!("{} as {}", ident, alias))); + tree.insert(Segment::Terminal); + } else if ident.0.contents == "self" { + tree.insert(Segment::Terminal); } else { - tree.insert_terminal(Segment::Plain(ident.to_string())); + tree = tree.insert(Segment::Plain(ident.to_string())); + tree.insert(Segment::Terminal); } } UseTreeKind::List(trees) => { @@ -521,7 +523,7 @@ use foo::{ABC, def, efg, ZETA}; use foo::bar; use foo; "; - let expected = "use foo::{bar, self};\n"; + let expected = "use foo::{self, bar};\n"; assert_format(src, expected); } From 7e6736e206080e7f4bda9e54946191e1e3757c5b Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 23 Oct 2024 11:43:06 -0300 Subject: [PATCH 07/15] Rename Terminal to SelfReference --- tooling/nargo_fmt/src/formatter/use_tree_merge.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs index 552bf7e71dc..3bdaa65c3df 100644 --- a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs +++ b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs @@ -105,7 +105,7 @@ enum Segment { /// we need to know that "foo" is the end of a path, and "foo::bar" is another one. /// If we don't, merging "foo" and "foo::bar" will result in just "foo::bar", loosing "foo", /// when we actually want "foo::{self, bar}". - Terminal, + SelfReference, Crate, Super, Dep, @@ -115,7 +115,7 @@ enum Segment { impl Segment { /// Combines two segments into a single one, by joining them with "::". fn combine(self, other: Segment) -> Segment { - if other == Segment::Terminal { + if other == Segment::SelfReference { self } else { Segment::Plain(format!("{}::{}", self, other)) @@ -124,7 +124,7 @@ impl Segment { fn order_number(&self) -> usize { match self { - Segment::Terminal => 0, + Segment::SelfReference => 0, Segment::Crate => 1, Segment::Super => 2, Segment::Dep => 3, @@ -140,7 +140,7 @@ impl Display for Segment { Segment::Super => write!(f, "super"), Segment::Dep => write!(f, "dep"), Segment::Plain(s) => write!(f, "{}", s), - Segment::Terminal => write!(f, "self"), + Segment::SelfReference => write!(f, "self"), } } } @@ -258,12 +258,12 @@ fn merge_imports_in_tree(imports: Vec, mut tree: &mut ImportTree) { UseTreeKind::Path(ident, alias) => { if let Some(alias) = alias { tree = tree.insert(Segment::Plain(format!("{} as {}", ident, alias))); - tree.insert(Segment::Terminal); + tree.insert(Segment::SelfReference); } else if ident.0.contents == "self" { - tree.insert(Segment::Terminal); + tree.insert(Segment::SelfReference); } else { tree = tree.insert(Segment::Plain(ident.to_string())); - tree.insert(Segment::Terminal); + tree.insert(Segment::SelfReference); } } UseTreeKind::List(trees) => { From afe7029ab0a580e2581f7226c5467e078dbd0862 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 23 Oct 2024 11:43:36 -0300 Subject: [PATCH 08/15] Reformat --- .../compile_success_empty/trait_call_full_path/src/main.nr | 2 +- test_programs/execution_success/bigint/src/main.nr | 2 +- test_programs/execution_success/eddsa/src/main.nr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test_programs/compile_success_empty/trait_call_full_path/src/main.nr b/test_programs/compile_success_empty/trait_call_full_path/src/main.nr index 29cf1b2e167..f3e818a162a 100644 --- a/test_programs/compile_success_empty/trait_call_full_path/src/main.nr +++ b/test_programs/compile_success_empty/trait_call_full_path/src/main.nr @@ -10,7 +10,7 @@ mod foo { } } -use foo::Trait::{me, self}; +use foo::Trait::{self, me}; fn main(x: Field) { let _ = foo::Trait::me(x); diff --git a/test_programs/execution_success/bigint/src/main.nr b/test_programs/execution_success/bigint/src/main.nr index 5514b44e7e9..ca7a7fbc3eb 100644 --- a/test_programs/execution_success/bigint/src/main.nr +++ b/test_programs/execution_success/bigint/src/main.nr @@ -1,4 +1,4 @@ -use std::{bigint::{Secpk1Fq, self}, println}; +use std::{bigint::{self, Secpk1Fq}, println}; fn main(mut x: [u8; 5], y: [u8; 5]) { let a = bigint::Secpk1Fq::from_le_bytes(&[x[0], x[1], x[2], x[3], x[4]]); diff --git a/test_programs/execution_success/eddsa/src/main.nr b/test_programs/execution_success/eddsa/src/main.nr index 028dd8bd950..edf761407f6 100644 --- a/test_programs/execution_success/eddsa/src/main.nr +++ b/test_programs/execution_success/eddsa/src/main.nr @@ -2,7 +2,7 @@ use std::{ compat, ec::{consts::te::baby_jubjub, tecurve::affine::Point as TEPoint}, eddsa::{eddsa_poseidon_verify, eddsa_to_pub, eddsa_verify}, - hash::{poseidon2::Poseidon2Hasher, self}, + hash::{self, poseidon2::Poseidon2Hasher}, }; fn main(msg: pub Field, _priv_key_a: Field, _priv_key_b: Field) { From 60a25ef76bd0c1bea2317d7dcc965cad54aeee36 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 23 Oct 2024 15:12:42 -0300 Subject: [PATCH 09/15] Revert "Reformat" This reverts commit afe7029ab0a580e2581f7226c5467e078dbd0862. --- .../compile_success_empty/trait_call_full_path/src/main.nr | 2 +- test_programs/execution_success/bigint/src/main.nr | 2 +- test_programs/execution_success/eddsa/src/main.nr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test_programs/compile_success_empty/trait_call_full_path/src/main.nr b/test_programs/compile_success_empty/trait_call_full_path/src/main.nr index f3e818a162a..29cf1b2e167 100644 --- a/test_programs/compile_success_empty/trait_call_full_path/src/main.nr +++ b/test_programs/compile_success_empty/trait_call_full_path/src/main.nr @@ -10,7 +10,7 @@ mod foo { } } -use foo::Trait::{self, me}; +use foo::Trait::{me, self}; fn main(x: Field) { let _ = foo::Trait::me(x); diff --git a/test_programs/execution_success/bigint/src/main.nr b/test_programs/execution_success/bigint/src/main.nr index ca7a7fbc3eb..5514b44e7e9 100644 --- a/test_programs/execution_success/bigint/src/main.nr +++ b/test_programs/execution_success/bigint/src/main.nr @@ -1,4 +1,4 @@ -use std::{bigint::{self, Secpk1Fq}, println}; +use std::{bigint::{Secpk1Fq, self}, println}; fn main(mut x: [u8; 5], y: [u8; 5]) { let a = bigint::Secpk1Fq::from_le_bytes(&[x[0], x[1], x[2], x[3], x[4]]); diff --git a/test_programs/execution_success/eddsa/src/main.nr b/test_programs/execution_success/eddsa/src/main.nr index edf761407f6..028dd8bd950 100644 --- a/test_programs/execution_success/eddsa/src/main.nr +++ b/test_programs/execution_success/eddsa/src/main.nr @@ -2,7 +2,7 @@ use std::{ compat, ec::{consts::te::baby_jubjub, tecurve::affine::Point as TEPoint}, eddsa::{eddsa_poseidon_verify, eddsa_to_pub, eddsa_verify}, - hash::{self, poseidon2::Poseidon2Hasher}, + hash::{poseidon2::Poseidon2Hasher, self}, }; fn main(msg: pub Field, _priv_key_a: Field, _priv_key_b: Field) { From 0e468385d80ea8b1d8fe0a6f7b0b14d07c659e72 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 23 Oct 2024 15:12:51 -0300 Subject: [PATCH 10/15] Revert "Merge imports in the standard library and test programs" This reverts commit d05702c3dfabca56e2918dffce46f6b4bd804e50. --- noir_stdlib/src/array/check_shuffle.nr | 2 +- noir_stdlib/src/array/mod.nr | 4 ++- noir_stdlib/src/bigint.nr | 3 +- noir_stdlib/src/cmp.nr | 2 +- noir_stdlib/src/collections/map.nr | 12 +++---- noir_stdlib/src/collections/umap.nr | 5 ++- noir_stdlib/src/ec/consts/te.nr | 3 +- noir_stdlib/src/ec/montcurve.nr | 36 +++++++++---------- noir_stdlib/src/ec/swcurve.nr | 9 +++-- noir_stdlib/src/ec/tecurve.nr | 28 +++++++-------- noir_stdlib/src/eddsa.nr | 10 +++--- noir_stdlib/src/embedded_curve_ops.nr | 3 +- noir_stdlib/src/field/bn254.nr | 2 +- noir_stdlib/src/field/mod.nr | 2 +- noir_stdlib/src/hash/keccak.nr | 3 +- noir_stdlib/src/hash/mimc.nr | 3 +- noir_stdlib/src/hash/mod.nr | 12 +++---- noir_stdlib/src/hash/poseidon/bn254/consts.nr | 3 +- noir_stdlib/src/hash/poseidon/bn254/perm.nr | 3 +- noir_stdlib/src/hash/poseidon/mod.nr | 3 +- noir_stdlib/src/hash/poseidon2.nr | 3 +- noir_stdlib/src/meta/expr.nr | 4 ++- noir_stdlib/src/meta/mod.nr | 4 ++- noir_stdlib/src/meta/quoted.nr | 3 +- noir_stdlib/src/meta/trait_constraint.nr | 3 +- noir_stdlib/src/meta/trait_def.nr | 3 +- noir_stdlib/src/meta/typ.nr | 3 +- noir_stdlib/src/ops/mod.nr | 4 +-- noir_stdlib/src/option.nr | 4 ++- noir_stdlib/src/prelude.nr | 23 ++++++------ noir_stdlib/src/string.nr | 3 +- noir_stdlib/src/uint128.nr | 8 ++--- .../ec_baby_jubjub/src/main.nr | 11 ++++-- .../macros_in_comptime/src/main.nr | 6 ++-- .../mod_nr_entrypoint/src/main.nr | 4 ++- .../reexports/src/main.nr | 2 +- .../regression_2099/src/main.nr | 3 +- .../trait_call_full_path/src/main.nr | 3 +- .../trait_method_mut_self/src/main.nr | 3 +- .../trait_multi_module_test/src/module3.nr | 3 +- .../trait_where_clause/src/main.nr | 3 +- .../src/main.nr | 4 ++- .../execution_success/bigint/src/main.nr | 3 +- .../binary_operator_overloading/src/main.nr | 3 +- .../brillig_oracle/src/main.nr | 3 +- .../diamond_deps_0/src/main.nr | 3 +- .../execution_success/eddsa/src/main.nr | 12 +++---- .../execution_success/hashmap/src/main.nr | 4 ++- .../execution_success/prelude/src/main.nr | 3 +- .../regression_3889/src/main.nr | 6 ++-- .../regression_5045/src/main.nr | 3 +- .../regression_5615/src/main.nr | 4 ++- .../execution_success/uhashmap/src/main.nr | 4 ++- 53 files changed, 173 insertions(+), 130 deletions(-) diff --git a/noir_stdlib/src/array/check_shuffle.nr b/noir_stdlib/src/array/check_shuffle.nr index 2e8c227feee..82028d487c7 100644 --- a/noir_stdlib/src/array/check_shuffle.nr +++ b/noir_stdlib/src/array/check_shuffle.nr @@ -59,8 +59,8 @@ where } mod test { - use crate::cmp::Eq; use super::check_shuffle; + use crate::cmp::Eq; struct CompoundStruct { a: bool, diff --git a/noir_stdlib/src/array/mod.nr b/noir_stdlib/src/array/mod.nr index 16a27757c63..8bb425854f2 100644 --- a/noir_stdlib/src/array/mod.nr +++ b/noir_stdlib/src/array/mod.nr @@ -1,4 +1,6 @@ -use crate::{cmp::{Eq, Ord}, convert::From, runtime::is_unconstrained}; +use crate::cmp::{Eq, Ord}; +use crate::convert::From; +use crate::runtime::is_unconstrained; mod check_shuffle; mod quicksort; diff --git a/noir_stdlib/src/bigint.nr b/noir_stdlib/src/bigint.nr index 63fca63a515..203ff90d444 100644 --- a/noir_stdlib/src/bigint.nr +++ b/noir_stdlib/src/bigint.nr @@ -1,4 +1,5 @@ -use crate::{cmp::Eq, ops::{Add, Div, Mul, Sub}}; +use crate::ops::{Add, Sub, Mul, Div}; +use crate::cmp::Eq; global bn254_fq = &[ 0x47, 0xFD, 0x7C, 0xD8, 0x16, 0x8C, 0x20, 0x3C, 0x8d, 0xca, 0x71, 0x68, 0x91, 0x6a, 0x81, 0x97, diff --git a/noir_stdlib/src/cmp.nr b/noir_stdlib/src/cmp.nr index ae515150a4d..10be6e7b867 100644 --- a/noir_stdlib/src/cmp.nr +++ b/noir_stdlib/src/cmp.nr @@ -537,7 +537,7 @@ where } mod cmp_tests { - use crate::cmp::{max, min}; + use crate::cmp::{min, max}; #[test] fn sanity_check_min() { diff --git a/noir_stdlib/src/collections/map.nr b/noir_stdlib/src/collections/map.nr index a83557c41ca..cd203c43ad3 100644 --- a/noir_stdlib/src/collections/map.nr +++ b/noir_stdlib/src/collections/map.nr @@ -1,10 +1,8 @@ -use crate::{ - cmp::Eq, - collections::bounded_vec::BoundedVec, - default::Default, - hash::{BuildHasher, Hash, Hasher}, - option::Option, -}; +use crate::cmp::Eq; +use crate::option::Option; +use crate::default::Default; +use crate::hash::{Hash, Hasher, BuildHasher}; +use crate::collections::bounded_vec::BoundedVec; // We use load factor alpha_max = 0.75. // Upon exceeding it, assert will fail in order to inform the user diff --git a/noir_stdlib/src/collections/umap.nr b/noir_stdlib/src/collections/umap.nr index bdcbc7c7094..9b72b6173ca 100644 --- a/noir_stdlib/src/collections/umap.nr +++ b/noir_stdlib/src/collections/umap.nr @@ -1,4 +1,7 @@ -use crate::{cmp::Eq, default::Default, hash::{BuildHasher, Hash, Hasher}, option::Option}; +use crate::cmp::Eq; +use crate::option::Option; +use crate::default::Default; +use crate::hash::{Hash, Hasher, BuildHasher}; // An unconstrained hash table with open addressing and quadratic probing. // Note that "unconstrained" here means that almost all operations on this diff --git a/noir_stdlib/src/ec/consts/te.nr b/noir_stdlib/src/ec/consts/te.nr index 9bc2626acdf..561c16e846a 100644 --- a/noir_stdlib/src/ec/consts/te.nr +++ b/noir_stdlib/src/ec/consts/te.nr @@ -1,4 +1,5 @@ -use crate::ec::tecurve::affine::{Curve as TECurve, Point as TEPoint}; +use crate::ec::tecurve::affine::Point as TEPoint; +use crate::ec::tecurve::affine::Curve as TECurve; pub struct BabyJubjub { pub curve: TECurve, diff --git a/noir_stdlib/src/ec/montcurve.nr b/noir_stdlib/src/ec/montcurve.nr index cc854ef7cbe..6c83feb1607 100644 --- a/noir_stdlib/src/ec/montcurve.nr +++ b/noir_stdlib/src/ec/montcurve.nr @@ -3,18 +3,16 @@ pub mod affine { // Points are represented by two-dimensional Cartesian coordinates. // All group operations are induced by those of the corresponding Twisted Edwards curve. // See e.g. for details on the correspondences. - use crate::{ - cmp::Eq, - ec::{ - is_square, - montcurve::curvegroup, - safe_inverse, - sqrt, - swcurve::affine::{Curve as SWCurve, Point as SWPoint}, - tecurve::affine::{Curve as TECurve, Point as TEPoint}, - ZETA, - }, - }; + use crate::ec::montcurve::curvegroup; + use crate::ec::swcurve::affine::Curve as SWCurve; + use crate::ec::swcurve::affine::Point as SWPoint; + use crate::ec::tecurve::affine::Curve as TECurve; + use crate::ec::tecurve::affine::Point as TEPoint; + use crate::ec::is_square; + use crate::ec::safe_inverse; + use crate::ec::sqrt; + use crate::ec::ZETA; + use crate::cmp::Eq; // Curve specification pub struct Curve { // Montgomery Curve configuration (ky^2 = x^3 + j*x^2 + x) @@ -224,14 +222,12 @@ pub mod curvegroup { // Points are represented by three-dimensional projective (homogeneous) coordinates. // All group operations are induced by those of the corresponding Twisted Edwards curve. // See e.g. for details on the correspondences. - use crate::{ - cmp::Eq, - ec::{ - montcurve::affine, - swcurve::curvegroup::{Curve as SWCurve, Point as SWPoint}, - tecurve::curvegroup::{Curve as TECurve, Point as TEPoint}, - }, - }; + use crate::ec::montcurve::affine; + use crate::ec::swcurve::curvegroup::Curve as SWCurve; + use crate::ec::swcurve::curvegroup::Point as SWPoint; + use crate::ec::tecurve::curvegroup::Curve as TECurve; + use crate::ec::tecurve::curvegroup::Point as TEPoint; + use crate::cmp::Eq; pub struct Curve { // Montgomery Curve configuration (ky^2 z = x*(x^2 + j*x*z + z*z)) pub j: Field, diff --git a/noir_stdlib/src/ec/swcurve.nr b/noir_stdlib/src/ec/swcurve.nr index 1e43285b8b1..145b2506f73 100644 --- a/noir_stdlib/src/ec/swcurve.nr +++ b/noir_stdlib/src/ec/swcurve.nr @@ -3,7 +3,11 @@ pub mod affine { // Points are represented by two-dimensional Cartesian coordinates. // Group operations are implemented in terms of those in CurveGroup (in this case, extended Twisted Edwards) coordinates // for reasons of efficiency, cf. . - use crate::{cmp::Eq, ec::{is_square, safe_inverse, sqrt, swcurve::curvegroup}}; + use crate::ec::swcurve::curvegroup; + use crate::ec::safe_inverse; + use crate::ec::is_square; + use crate::ec::sqrt; + use crate::cmp::Eq; // Curve specification pub struct Curve { // Short Weierstrass curve @@ -186,7 +190,8 @@ pub mod curvegroup { // CurveGroup representation of Weierstrass curves // Points are represented by three-dimensional Jacobian coordinates. // See for details. - use crate::{cmp::Eq, ec::swcurve::affine}; + use crate::ec::swcurve::affine; + use crate::cmp::Eq; // Curve specification pub struct Curve { // Short Weierstrass curve diff --git a/noir_stdlib/src/ec/tecurve.nr b/noir_stdlib/src/ec/tecurve.nr index 5a4a9b4149c..0088896015d 100644 --- a/noir_stdlib/src/ec/tecurve.nr +++ b/noir_stdlib/src/ec/tecurve.nr @@ -4,14 +4,12 @@ pub mod affine { // Group operations are implemented in terms of those in CurveGroup (in this case, extended Twisted Edwards) coordinates // for reasons of efficiency. // See for details. - use crate::{ - cmp::Eq, - ec::{ - montcurve::affine::{Curve as MCurve, Point as MPoint}, - swcurve::affine::{Curve as SWCurve, Point as SWPoint}, - tecurve::curvegroup, - }, - }; + use crate::ec::tecurve::curvegroup; + use crate::ec::montcurve::affine::Curve as MCurve; + use crate::ec::montcurve::affine::Point as MPoint; + use crate::ec::swcurve::affine::Curve as SWCurve; + use crate::ec::swcurve::affine::Point as SWPoint; + use crate::cmp::Eq; // Curve specification pub struct Curve { // Twisted Edwards curve @@ -199,14 +197,12 @@ pub mod curvegroup { // CurveGroup coordinate representation of Twisted Edwards curves // Points are represented by four-dimensional projective coordinates, viz. extended Twisted Edwards coordinates. // See section 3 of for details. - use crate::{ - cmp::Eq, - ec::{ - montcurve::curvegroup::{Curve as MCurve, Point as MPoint}, - swcurve::curvegroup::{Curve as SWCurve, Point as SWPoint}, - tecurve::affine, - }, - }; + use crate::ec::tecurve::affine; + use crate::ec::montcurve::curvegroup::Curve as MCurve; + use crate::ec::montcurve::curvegroup::Point as MPoint; + use crate::ec::swcurve::curvegroup::Curve as SWCurve; + use crate::ec::swcurve::curvegroup::Point as SWPoint; + use crate::cmp::Eq; // Curve specification pub struct Curve { // Twisted Edwards curve diff --git a/noir_stdlib/src/eddsa.nr b/noir_stdlib/src/eddsa.nr index c9df59def8e..89a0b05b072 100644 --- a/noir_stdlib/src/eddsa.nr +++ b/noir_stdlib/src/eddsa.nr @@ -1,8 +1,8 @@ -use crate::{ - default::Default, - ec::{consts::te::baby_jubjub, tecurve::affine::Point as TEPoint}, - hash::{Hasher, poseidon::PoseidonHasher}, -}; +use crate::ec::consts::te::baby_jubjub; +use crate::ec::tecurve::affine::Point as TEPoint; +use crate::hash::Hasher; +use crate::hash::poseidon::PoseidonHasher; +use crate::default::Default; // Returns true if signature is valid pub fn eddsa_poseidon_verify( diff --git a/noir_stdlib/src/embedded_curve_ops.nr b/noir_stdlib/src/embedded_curve_ops.nr index edabcf7ad36..dd5e4285c00 100644 --- a/noir_stdlib/src/embedded_curve_ops.nr +++ b/noir_stdlib/src/embedded_curve_ops.nr @@ -1,4 +1,5 @@ -use crate::{cmp::Eq, ops::arith::{Add, Neg, Sub}}; +use crate::ops::arith::{Add, Sub, Neg}; +use crate::cmp::Eq; /// A point on the embedded elliptic curve /// By definition, the base field of the embedded curve is the scalar field of the proof system curve, i.e the Noir Field. diff --git a/noir_stdlib/src/field/bn254.nr b/noir_stdlib/src/field/bn254.nr index 9642c2aa1b8..356b47e63cf 100644 --- a/noir_stdlib/src/field/bn254.nr +++ b/noir_stdlib/src/field/bn254.nr @@ -141,7 +141,7 @@ pub fn lt(a: Field, b: Field) -> bool { mod tests { // TODO: Allow imports from "super" use crate::field::bn254::{ - assert_gt, compute_lt, compute_lte, decompose, gt, PHI, PLO, TWO_POW_128, + decompose, compute_lt, assert_gt, gt, TWO_POW_128, compute_lte, PLO, PHI, }; #[test] diff --git a/noir_stdlib/src/field/mod.nr b/noir_stdlib/src/field/mod.nr index b632cf1f7a2..915ea8f939e 100644 --- a/noir_stdlib/src/field/mod.nr +++ b/noir_stdlib/src/field/mod.nr @@ -1,6 +1,6 @@ pub mod bn254; -use crate::runtime::is_unconstrained; use bn254::lt as bn254_lt; +use crate::runtime::is_unconstrained; impl Field { /// Asserts that `self` can be represented in `bit_size` bits. diff --git a/noir_stdlib/src/hash/keccak.nr b/noir_stdlib/src/hash/keccak.nr index a539086331e..50fbab8a416 100644 --- a/noir_stdlib/src/hash/keccak.nr +++ b/noir_stdlib/src/hash/keccak.nr @@ -1,4 +1,5 @@ -use crate::{collections::vec::Vec, runtime::is_unconstrained}; +use crate::collections::vec::Vec; +use crate::runtime::is_unconstrained; global BLOCK_SIZE_IN_BYTES: u32 = 136; //(1600 - BITS * 2) / WORD_SIZE; global WORD_SIZE: u32 = 8; // Limbs are made up of u64s so 8 bytes each. diff --git a/noir_stdlib/src/hash/mimc.nr b/noir_stdlib/src/hash/mimc.nr index 73e62d95a03..6045ae3dbdb 100644 --- a/noir_stdlib/src/hash/mimc.nr +++ b/noir_stdlib/src/hash/mimc.nr @@ -1,4 +1,5 @@ -use crate::{default::Default, hash::Hasher}; +use crate::hash::Hasher; +use crate::default::Default; // mimc-p/p implementation // constants are (publicly generated) random numbers, for instance using keccak as a ROM. diff --git a/noir_stdlib/src/hash/mod.nr b/noir_stdlib/src/hash/mod.nr index 550ee0412f8..609017d70aa 100644 --- a/noir_stdlib/src/hash/mod.nr +++ b/noir_stdlib/src/hash/mod.nr @@ -5,14 +5,12 @@ pub mod keccak; pub mod sha256; pub mod sha512; -use crate::{ - default::Default, - embedded_curve_ops::{ - EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return, - }, - meta::derive_via, - uint128::U128, +use crate::default::Default; +use crate::uint128::U128; +use crate::embedded_curve_ops::{ + EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return, }; +use crate::meta::derive_via; // Kept for backwards compatibility pub use sha256::{digest, sha256, sha256_compression, sha256_var}; diff --git a/noir_stdlib/src/hash/poseidon/bn254/consts.nr b/noir_stdlib/src/hash/poseidon/bn254/consts.nr index 4c27dfc6ad5..835ed3ea476 100644 --- a/noir_stdlib/src/hash/poseidon/bn254/consts.nr +++ b/noir_stdlib/src/hash/poseidon/bn254/consts.nr @@ -2,7 +2,8 @@ // Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 // Constants for various Poseidon instances in the case of the prime field of the same order as BN254. // Consistent with https://github.com/iden3/circomlib/blob/master/circuits/poseidon.circom and https://github.com/iden3/circomlib/blob/master/circuits/poseidon_constants.circom -use crate::hash::poseidon::{config, PoseidonConfig}; +use crate::hash::poseidon::PoseidonConfig; +use crate::hash::poseidon::config; // S-box power fn alpha() -> Field { 5 diff --git a/noir_stdlib/src/hash/poseidon/bn254/perm.nr b/noir_stdlib/src/hash/poseidon/bn254/perm.nr index 61e629e4db1..3a12f59fe77 100644 --- a/noir_stdlib/src/hash/poseidon/bn254/perm.nr +++ b/noir_stdlib/src/hash/poseidon/bn254/perm.nr @@ -1,5 +1,6 @@ // Instantiations of Poseidon permutation for the prime field of the same order as BN254 -use crate::hash::poseidon::{bn254::consts, permute}; +use crate::hash::poseidon::bn254::consts; +use crate::hash::poseidon::permute; #[field(bn254)] pub fn x5_2(mut state: [Field; 2]) -> [Field; 2] { diff --git a/noir_stdlib/src/hash/poseidon/mod.nr b/noir_stdlib/src/hash/poseidon/mod.nr index 8c75b9a3662..0af7951b8dc 100644 --- a/noir_stdlib/src/hash/poseidon/mod.nr +++ b/noir_stdlib/src/hash/poseidon/mod.nr @@ -1,5 +1,6 @@ pub mod bn254; // Instantiations of Poseidon for prime field of the same order as BN254 -use crate::{default::Default, hash::Hasher}; +use crate::hash::Hasher; +use crate::default::Default; // A config struct defining the parameters of the Poseidon instance to use. // diff --git a/noir_stdlib/src/hash/poseidon2.nr b/noir_stdlib/src/hash/poseidon2.nr index 2fd2f09e65c..517c2cd8f5f 100644 --- a/noir_stdlib/src/hash/poseidon2.nr +++ b/noir_stdlib/src/hash/poseidon2.nr @@ -1,4 +1,5 @@ -use crate::{default::Default, hash::Hasher}; +use crate::hash::Hasher; +use crate::default::Default; comptime global RATE: u32 = 3; diff --git a/noir_stdlib/src/meta/expr.nr b/noir_stdlib/src/meta/expr.nr index 46c65638527..1b04a97ab15 100644 --- a/noir_stdlib/src/meta/expr.nr +++ b/noir_stdlib/src/meta/expr.nr @@ -1,6 +1,8 @@ //! Contains methods on the built-in `Expr` type for quoted, syntactically valid expressions. -use crate::{meta::op::{BinaryOp, UnaryOp}, option::Option}; +use crate::option::Option; +use crate::meta::op::UnaryOp; +use crate::meta::op::BinaryOp; impl Expr { /// If this expression is an array literal `[elem1, ..., elemN]`, this returns a slice of each element in the array. diff --git a/noir_stdlib/src/meta/mod.nr b/noir_stdlib/src/meta/mod.nr index eb7a59634bc..ff662b878ec 100644 --- a/noir_stdlib/src/meta/mod.nr +++ b/noir_stdlib/src/meta/mod.nr @@ -30,7 +30,9 @@ pub comptime fn type_of(x: T) -> Type {} // docs:start:derive_example // These are needed for the unconstrained hashmap we're using to store derive functions -use crate::{collections::umap::UHashMap, hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher}}; +use crate::collections::umap::UHashMap; +use crate::hash::BuildHasherDefault; +use crate::hash::poseidon2::Poseidon2Hasher; // A derive function is one that given a struct definition can // create us a quoted trait impl from it. diff --git a/noir_stdlib/src/meta/quoted.nr b/noir_stdlib/src/meta/quoted.nr index c4f2b095766..d67174d7829 100644 --- a/noir_stdlib/src/meta/quoted.nr +++ b/noir_stdlib/src/meta/quoted.nr @@ -1,4 +1,5 @@ -use crate::{cmp::Eq, option::Option}; +use crate::cmp::Eq; +use crate::option::Option; impl Quoted { #[builtin(quoted_as_expr)] diff --git a/noir_stdlib/src/meta/trait_constraint.nr b/noir_stdlib/src/meta/trait_constraint.nr index 91dd1168116..bf22f454448 100644 --- a/noir_stdlib/src/meta/trait_constraint.nr +++ b/noir_stdlib/src/meta/trait_constraint.nr @@ -1,4 +1,5 @@ -use crate::{cmp::Eq, hash::{Hash, Hasher}}; +use crate::hash::{Hash, Hasher}; +use crate::cmp::Eq; impl Eq for TraitConstraint { comptime fn eq(self, other: Self) -> bool { diff --git a/noir_stdlib/src/meta/trait_def.nr b/noir_stdlib/src/meta/trait_def.nr index d889fdd1591..cc448b2eae5 100644 --- a/noir_stdlib/src/meta/trait_def.nr +++ b/noir_stdlib/src/meta/trait_def.nr @@ -1,4 +1,5 @@ -use crate::{cmp::Eq, hash::{Hash, Hasher}}; +use crate::hash::{Hash, Hasher}; +use crate::cmp::Eq; impl TraitDefinition { #[builtin(trait_def_as_trait_constraint)] diff --git a/noir_stdlib/src/meta/typ.nr b/noir_stdlib/src/meta/typ.nr index f722c3d0a5c..8076c692ca5 100644 --- a/noir_stdlib/src/meta/typ.nr +++ b/noir_stdlib/src/meta/typ.nr @@ -1,6 +1,7 @@ //! Contains methods on the built-in `Type` type used for representing a type in the source program. -use crate::{cmp::Eq, option::Option}; +use crate::cmp::Eq; +use crate::option::Option; /// Creates and returns an unbound type variable. This is a special kind of type internal /// to type checking which will type check with any other type. When it is type checked diff --git a/noir_stdlib/src/ops/mod.nr b/noir_stdlib/src/ops/mod.nr index 0e3a2467c60..bf908ea4b27 100644 --- a/noir_stdlib/src/ops/mod.nr +++ b/noir_stdlib/src/ops/mod.nr @@ -1,5 +1,5 @@ pub(crate) mod arith; pub(crate) mod bit; -pub use arith::{Add, Div, Mul, Neg, Rem, Sub}; -pub use bit::{BitAnd, BitOr, BitXor, Not, Shl, Shr}; +pub use arith::{Add, Sub, Mul, Div, Rem, Neg}; +pub use bit::{Not, BitOr, BitAnd, BitXor, Shl, Shr}; diff --git a/noir_stdlib/src/option.nr b/noir_stdlib/src/option.nr index b045a3d7612..5db2ce84efd 100644 --- a/noir_stdlib/src/option.nr +++ b/noir_stdlib/src/option.nr @@ -1,4 +1,6 @@ -use crate::{cmp::{Eq, Ord, Ordering}, default::Default, hash::{Hash, Hasher}}; +use crate::hash::{Hash, Hasher}; +use crate::cmp::{Ordering, Ord, Eq}; +use crate::default::Default; pub struct Option { _is_some: bool, diff --git a/noir_stdlib/src/prelude.nr b/noir_stdlib/src/prelude.nr index f56fd888f76..b6e54eaae60 100644 --- a/noir_stdlib/src/prelude.nr +++ b/noir_stdlib/src/prelude.nr @@ -1,13 +1,10 @@ -pub use crate::{ - assert_constant, - cmp::{Eq, Ord}, - collections::{bounded_vec::BoundedVec, vec::Vec}, - convert::{From, Into}, - default::Default, - meta::{derive, derive_via}, - option::Option, - panic::panic, - print, - println, - uint128::U128, -}; +pub use crate::collections::vec::Vec; +pub use crate::collections::bounded_vec::BoundedVec; +pub use crate::option::Option; +pub use crate::{print, println, assert_constant}; +pub use crate::uint128::U128; +pub use crate::cmp::{Eq, Ord}; +pub use crate::default::Default; +pub use crate::convert::{From, Into}; +pub use crate::meta::{derive, derive_via}; +pub use crate::panic::panic; diff --git a/noir_stdlib/src/string.nr b/noir_stdlib/src/string.nr index 017b4ff649b..18fb449626a 100644 --- a/noir_stdlib/src/string.nr +++ b/noir_stdlib/src/string.nr @@ -1,4 +1,5 @@ -use crate::{collections::vec::Vec, convert::From}; +use crate::collections::vec::Vec; +use crate::convert::From; impl str { /// Converts the given string into a byte array diff --git a/noir_stdlib/src/uint128.nr b/noir_stdlib/src/uint128.nr index 95ae3362385..a4e20859604 100644 --- a/noir_stdlib/src/uint128.nr +++ b/noir_stdlib/src/uint128.nr @@ -1,7 +1,5 @@ -use crate::{ - cmp::{Eq, Ord, Ordering}, - ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Rem, Shl, Shr, Sub}, -}; +use crate::ops::{Add, Sub, Mul, Div, Rem, Not, BitOr, BitAnd, BitXor, Shl, Shr}; +use crate::cmp::{Eq, Ord, Ordering}; global pow64: Field = 18446744073709551616; //2^64; global pow63: Field = 9223372036854775808; // 2^63; @@ -315,7 +313,7 @@ impl Shr for U128 { } mod tests { - use crate::uint128::{pow63, pow64, U128}; + use crate::uint128::{U128, pow64, pow63}; #[test] fn test_not(lo: u64, hi: u64) { diff --git a/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr b/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr index 3f46eb10034..935b1c613ad 100644 --- a/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr +++ b/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr @@ -1,9 +1,14 @@ // Tests may be checked against https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/tree/main/poc -use std::ec::tecurve::{affine::{Curve as AffineCurve, Point as Gaffine}, curvegroup::Point as G}; +use std::ec::tecurve::affine::Curve as AffineCurve; +use std::ec::tecurve::affine::Point as Gaffine; +use std::ec::tecurve::curvegroup::Point as G; -use std::ec::swcurve::{affine::Point as SWGaffine, curvegroup::Point as SWG}; +use std::ec::swcurve::affine::Point as SWGaffine; +use std::ec::swcurve::curvegroup::Point as SWG; -use std::{compat, ec::montcurve::{affine::Point as MGaffine, curvegroup::Point as MG}}; +use std::ec::montcurve::affine::Point as MGaffine; +use std::ec::montcurve::curvegroup::Point as MG; +use std::compat; fn main() { // This test only makes sense if Field is the right prime field. diff --git a/test_programs/compile_success_empty/macros_in_comptime/src/main.nr b/test_programs/compile_success_empty/macros_in_comptime/src/main.nr index 1764f28ae6f..799091fca09 100644 --- a/test_programs/compile_success_empty/macros_in_comptime/src/main.nr +++ b/test_programs/compile_success_empty/macros_in_comptime/src/main.nr @@ -1,4 +1,5 @@ -use std::{field::modulus_num_bits, meta::unquote}; +use std::field::modulus_num_bits; +use std::meta::unquote; // Numeric generics default to u32 global three_field: Field = 3; @@ -37,7 +38,8 @@ comptime fn foo(x: Field) { } mod submodule { - use std::{field::modulus_be_bytes, meta::unquote}; + use std::field::modulus_be_bytes; + use std::meta::unquote; pub comptime fn bar() { // Use a function only in scope in this module diff --git a/test_programs/compile_success_empty/mod_nr_entrypoint/src/main.nr b/test_programs/compile_success_empty/mod_nr_entrypoint/src/main.nr index 7fa8b1426ab..620fd99f6ec 100644 --- a/test_programs/compile_success_empty/mod_nr_entrypoint/src/main.nr +++ b/test_programs/compile_success_empty/mod_nr_entrypoint/src/main.nr @@ -1,4 +1,6 @@ -use crate::{baz::in_baz_mod, foo::{bar::in_bar_mod, in_foo_mod}}; +use crate::foo::in_foo_mod; +use crate::foo::bar::in_bar_mod; +use crate::baz::in_baz_mod; mod foo; mod baz; diff --git a/test_programs/compile_success_empty/reexports/src/main.nr b/test_programs/compile_success_empty/reexports/src/main.nr index 6b568bea682..0fd65a33564 100644 --- a/test_programs/compile_success_empty/reexports/src/main.nr +++ b/test_programs/compile_success_empty/reexports/src/main.nr @@ -1,4 +1,4 @@ -use reexporting_lib::{FooStruct, lib, MyStruct}; +use reexporting_lib::{FooStruct, MyStruct, lib}; fn main() { let x: FooStruct = MyStruct { inner: 0 }; diff --git a/test_programs/compile_success_empty/regression_2099/src/main.nr b/test_programs/compile_success_empty/regression_2099/src/main.nr index 2ca8b4ccc9e..3fe3cdaf39a 100644 --- a/test_programs/compile_success_empty/regression_2099/src/main.nr +++ b/test_programs/compile_success_empty/regression_2099/src/main.nr @@ -1,4 +1,5 @@ -use std::ec::tecurve::affine::{Curve as AffineCurve, Point as Gaffine}; +use std::ec::tecurve::affine::Curve as AffineCurve; +use std::ec::tecurve::affine::Point as Gaffine; fn main() { // Define Baby Jubjub (ERC-2494) parameters in affine representation diff --git a/test_programs/compile_success_empty/trait_call_full_path/src/main.nr b/test_programs/compile_success_empty/trait_call_full_path/src/main.nr index 29cf1b2e167..aea0f436dce 100644 --- a/test_programs/compile_success_empty/trait_call_full_path/src/main.nr +++ b/test_programs/compile_success_empty/trait_call_full_path/src/main.nr @@ -10,7 +10,8 @@ mod foo { } } -use foo::Trait::{me, self}; +use foo::Trait; +use foo::Trait::me; fn main(x: Field) { let _ = foo::Trait::me(x); diff --git a/test_programs/compile_success_empty/trait_method_mut_self/src/main.nr b/test_programs/compile_success_empty/trait_method_mut_self/src/main.nr index cd67ec48f8d..aa0baab7f89 100644 --- a/test_programs/compile_success_empty/trait_method_mut_self/src/main.nr +++ b/test_programs/compile_success_empty/trait_method_mut_self/src/main.nr @@ -1,4 +1,5 @@ -use std::hash::{Hasher, poseidon2::Poseidon2Hasher}; +use std::hash::Hasher; +use std::hash::poseidon2::Poseidon2Hasher; fn main(x: Field, y: pub Field) { let mut a_mut_ref = AType { x }; diff --git a/test_programs/compile_success_empty/trait_multi_module_test/src/module3.nr b/test_programs/compile_success_empty/trait_multi_module_test/src/module3.nr index d9df949a465..2485a2ba7a1 100644 --- a/test_programs/compile_success_empty/trait_multi_module_test/src/module3.nr +++ b/test_programs/compile_success_empty/trait_multi_module_test/src/module3.nr @@ -1,3 +1,4 @@ -use crate::{module1::MyTrait, module2::MyStruct}; +use crate::module1::MyTrait; +use crate::module2::MyStruct; // ensure we can implement traits that are imported with the `use` syntax impl MyTrait for MyStruct {} diff --git a/test_programs/compile_success_empty/trait_where_clause/src/main.nr b/test_programs/compile_success_empty/trait_where_clause/src/main.nr index 88f2cafffde..8dc00be622d 100644 --- a/test_programs/compile_success_empty/trait_where_clause/src/main.nr +++ b/test_programs/compile_success_empty/trait_where_clause/src/main.nr @@ -4,7 +4,8 @@ // - structs (struct Foo where T: ...) // import the traits from another module to ensure the where clauses are ok with that mod the_trait; -use crate::the_trait::{Asd, StaticTrait}; +use crate::the_trait::Asd; +use crate::the_trait::StaticTrait; struct Add10 { x: Field, diff --git a/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr b/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr index a755e492a81..535d7b18137 100644 --- a/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr +++ b/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr @@ -1,4 +1,6 @@ -use std::hash::{Hasher, poseidon2::Poseidon2Hasher, poseidon::PoseidonHasher}; +use std::hash::Hasher; +use std::hash::poseidon2::Poseidon2Hasher; +use std::hash::poseidon::PoseidonHasher; fn main(x: Field, y: pub Field) { let mut hasher = PoseidonHasher::default(); diff --git a/test_programs/execution_success/bigint/src/main.nr b/test_programs/execution_success/bigint/src/main.nr index 5514b44e7e9..5a8b9fb67ef 100644 --- a/test_programs/execution_success/bigint/src/main.nr +++ b/test_programs/execution_success/bigint/src/main.nr @@ -1,4 +1,5 @@ -use std::{bigint::{Secpk1Fq, self}, println}; +use std::bigint; +use std::{bigint::Secpk1Fq, println}; fn main(mut x: [u8; 5], y: [u8; 5]) { let a = bigint::Secpk1Fq::from_le_bytes(&[x[0], x[1], x[2], x[3], x[4]]); diff --git a/test_programs/execution_success/binary_operator_overloading/src/main.nr b/test_programs/execution_success/binary_operator_overloading/src/main.nr index e6739e6f4d6..a5e12fd5da9 100644 --- a/test_programs/execution_success/binary_operator_overloading/src/main.nr +++ b/test_programs/execution_success/binary_operator_overloading/src/main.nr @@ -1,4 +1,5 @@ -use std::{cmp::Ordering, ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub}}; +use std::ops::{Add, Sub, Mul, Div, Rem, BitAnd, BitOr, BitXor, Shl, Shr}; +use std::cmp::Ordering; // x = 3, y = 9 fn main(x: u32, y: u32) { diff --git a/test_programs/execution_success/brillig_oracle/src/main.nr b/test_programs/execution_success/brillig_oracle/src/main.nr index 0f10749c485..8f5b2fa7566 100644 --- a/test_programs/execution_success/brillig_oracle/src/main.nr +++ b/test_programs/execution_success/brillig_oracle/src/main.nr @@ -1,4 +1,5 @@ -use std::{slice, test::OracleMock}; +use std::slice; +use std::test::OracleMock; // Tests oracle usage in brillig/unconstrained functions fn main(_x: Field) { diff --git a/test_programs/execution_success/diamond_deps_0/src/main.nr b/test_programs/execution_success/diamond_deps_0/src/main.nr index 1fff8a5f583..690d6fc9fc8 100644 --- a/test_programs/execution_success/diamond_deps_0/src/main.nr +++ b/test_programs/execution_success/diamond_deps_0/src/main.nr @@ -1,5 +1,6 @@ use dep1::call_dep1_then_dep2; -use dep2::{call_dep2, RESOLVE_THIS}; +use dep2::call_dep2; +use dep2::RESOLVE_THIS; fn main(x: Field, y: pub Field) -> pub Field { call_dep1_then_dep2(x, y) + call_dep2(x, y) + RESOLVE_THIS diff --git a/test_programs/execution_success/eddsa/src/main.nr b/test_programs/execution_success/eddsa/src/main.nr index 028dd8bd950..d0ce8e70053 100644 --- a/test_programs/execution_success/eddsa/src/main.nr +++ b/test_programs/execution_success/eddsa/src/main.nr @@ -1,9 +1,9 @@ -use std::{ - compat, - ec::{consts::te::baby_jubjub, tecurve::affine::Point as TEPoint}, - eddsa::{eddsa_poseidon_verify, eddsa_to_pub, eddsa_verify}, - hash::{poseidon2::Poseidon2Hasher, self}, -}; +use std::compat; +use std::ec::consts::te::baby_jubjub; +use std::ec::tecurve::affine::Point as TEPoint; +use std::hash; +use std::eddsa::{eddsa_to_pub, eddsa_poseidon_verify, eddsa_verify}; +use std::hash::poseidon2::Poseidon2Hasher; fn main(msg: pub Field, _priv_key_a: Field, _priv_key_b: Field) { // Skip this test for non-bn254 backends diff --git a/test_programs/execution_success/hashmap/src/main.nr b/test_programs/execution_success/hashmap/src/main.nr index 6e71d3fb010..964b900dce5 100644 --- a/test_programs/execution_success/hashmap/src/main.nr +++ b/test_programs/execution_success/hashmap/src/main.nr @@ -1,6 +1,8 @@ mod utils; -use std::{collections::map::HashMap, hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher}}; +use std::collections::map::HashMap; +use std::hash::BuildHasherDefault; +use std::hash::poseidon2::Poseidon2Hasher; use utils::cut; diff --git a/test_programs/execution_success/prelude/src/main.nr b/test_programs/execution_success/prelude/src/main.nr index cc0180ff1fe..4fe6080222e 100644 --- a/test_programs/execution_success/prelude/src/main.nr +++ b/test_programs/execution_success/prelude/src/main.nr @@ -8,7 +8,8 @@ fn main() { mod a { // We don't want to give an error due to re-importing elements that are already in the prelude. - use std::{collections::vec::Vec, option::Option}; + use std::collections::vec::Vec; + use std::option::Option; fn main() { let _xs = Vec::new(); diff --git a/test_programs/execution_success/regression_3889/src/main.nr b/test_programs/execution_success/regression_3889/src/main.nr index ed7aefa5c80..2b54ae54418 100644 --- a/test_programs/execution_success/regression_3889/src/main.nr +++ b/test_programs/execution_success/regression_3889/src/main.nr @@ -5,14 +5,16 @@ mod Foo { } mod Bar { - use crate::Foo::{NewType, NewType as BarStruct}; + use crate::Foo::NewType as BarStruct; + use crate::Foo::NewType; } mod Baz { struct Works { a: Field, } - use crate::Bar::{BarStruct, NewType}; + use crate::Bar::BarStruct; + use crate::Bar::NewType; } fn main(works: Baz::Works, fails: Baz::BarStruct, also_fails: Bar::NewType) -> pub Field { diff --git a/test_programs/execution_success/regression_5045/src/main.nr b/test_programs/execution_success/regression_5045/src/main.nr index aa9a45f7c11..545694368fd 100644 --- a/test_programs/execution_success/regression_5045/src/main.nr +++ b/test_programs/execution_success/regression_5045/src/main.nr @@ -1,4 +1,5 @@ -use std::embedded_curve_ops::{EmbeddedCurvePoint, EmbeddedCurveScalar}; +use std::embedded_curve_ops::EmbeddedCurvePoint; +use std::embedded_curve_ops::EmbeddedCurveScalar; fn main(is_active: bool) { let a = EmbeddedCurvePoint { diff --git a/test_programs/execution_success/regression_5615/src/main.nr b/test_programs/execution_success/regression_5615/src/main.nr index 186d8362009..1d8e0a045cd 100644 --- a/test_programs/execution_success/regression_5615/src/main.nr +++ b/test_programs/execution_success/regression_5615/src/main.nr @@ -1,4 +1,6 @@ -use std::{collections::umap::UHashMap, hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher}}; +use std::collections::umap::UHashMap; +use std::hash::BuildHasherDefault; +use std::hash::poseidon2::Poseidon2Hasher; unconstrained fn main() { comptime { diff --git a/test_programs/execution_success/uhashmap/src/main.nr b/test_programs/execution_success/uhashmap/src/main.nr index 7fc2efa95e5..e917a83c5fd 100644 --- a/test_programs/execution_success/uhashmap/src/main.nr +++ b/test_programs/execution_success/uhashmap/src/main.nr @@ -1,4 +1,6 @@ -use std::{collections::umap::UHashMap, hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher}}; +use std::collections::umap::UHashMap; +use std::hash::BuildHasherDefault; +use std::hash::poseidon2::Poseidon2Hasher; type K = Field; type V = Field; From 69089b9a3e23feecb0ed0f521795d927704ca07d Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 23 Oct 2024 15:14:49 -0300 Subject: [PATCH 11/15] Don't merge imports by default --- tooling/nargo_fmt/src/config.rs | 2 +- tooling/nargo_fmt/src/formatter/use_tree_merge.rs | 12 +++++++++++- tooling/nargo_fmt/tests/expected/contract.nr | 14 ++++++-------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/tooling/nargo_fmt/src/config.rs b/tooling/nargo_fmt/src/config.rs index 214ad610640..6f863393c42 100644 --- a/tooling/nargo_fmt/src/config.rs +++ b/tooling/nargo_fmt/src/config.rs @@ -49,7 +49,7 @@ config! { array_width: usize, 100, "Maximum width of an array literal before falling back to vertical formatting"; fn_call_width: usize, 60, "Maximum width of the args of a function call before falling back to vertical formatting"; single_line_if_else_max_width: usize, 50, "Maximum line length for single line if-else expressions"; - merge_imports: bool, true, "Merge and sort groups of imports"; + merge_imports: bool, false, "Merge and sort groups of imports"; } impl Config { diff --git a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs index 3bdaa65c3df..602e314be41 100644 --- a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs +++ b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs @@ -275,7 +275,17 @@ fn merge_imports_in_tree(imports: Vec, mut tree: &mut ImportTree) { #[cfg(test)] mod tests { - use crate::{assert_format, assert_format_with_max_width}; + use crate::{assert_format_with_config, Config}; + + fn assert_format(src: &str, expected: &str) { + let config = Config { merge_imports: true, ..Config::default() }; + assert_format_with_config(src, expected, config); + } + + fn assert_format_with_max_width(src: &str, expected: &str, max_width: usize) { + let config = Config { merge_imports: true, max_width, ..Config::default() }; + assert_format_with_config(src, expected, config); + } #[test] fn format_simple_use_without_alias() { diff --git a/tooling/nargo_fmt/tests/expected/contract.nr b/tooling/nargo_fmt/tests/expected/contract.nr index ad53e61c911..c3648bb37d4 100644 --- a/tooling/nargo_fmt/tests/expected/contract.nr +++ b/tooling/nargo_fmt/tests/expected/contract.nr @@ -6,21 +6,19 @@ contract Benchmarking { use aztec::protocol_types::abis::function_selector::FunctionSelector; use value_note::{ - utils::{decrement, increment}, + utils::{increment, decrement}, value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, }; use aztec::{ context::Context, - log::emit_unencrypted_log, note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader}, - state_vars::{Map, PrivateSet, PublicMutable}, - types::{ - address::AztecAddress, - type_serialization::field_serialization::{ - FIELD_SERIALIZED_LEN, FieldSerializationMethods, - }, + log::emit_unencrypted_log, + state_vars::{Map, PublicMutable, PrivateSet}, + types::type_serialization::field_serialization::{ + FieldSerializationMethods, FIELD_SERIALIZED_LEN, }, + types::address::AztecAddress, }; struct Storage { From 4c67212996a4c011f57867581aafd6537643cef3 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 23 Oct 2024 15:37:34 -0300 Subject: [PATCH 12/15] Add `reorder_imports` option, true by default --- tooling/nargo_fmt/src/config.rs | 1 + tooling/nargo_fmt/src/formatter/item.rs | 25 +++++----- tooling/nargo_fmt/src/formatter/use_tree.rs | 5 +- .../nargo_fmt/src/formatter/use_tree_merge.rs | 47 +++++++++++++++++-- tooling/nargo_fmt/tests/expected/contract.nr | 14 +++--- 5 files changed, 68 insertions(+), 24 deletions(-) diff --git a/tooling/nargo_fmt/src/config.rs b/tooling/nargo_fmt/src/config.rs index 6f863393c42..44562715721 100644 --- a/tooling/nargo_fmt/src/config.rs +++ b/tooling/nargo_fmt/src/config.rs @@ -50,6 +50,7 @@ config! { fn_call_width: usize, 60, "Maximum width of the args of a function call before falling back to vertical formatting"; single_line_if_else_max_width: usize, 50, "Maximum line length for single line if-else expressions"; merge_imports: bool, false, "Merge and sort groups of imports"; + reorder_imports: bool, true, "Reorder imports alphabetically"; } impl Config { diff --git a/tooling/nargo_fmt/src/formatter/item.rs b/tooling/nargo_fmt/src/formatter/item.rs index cf7117c008e..7fb58e4e026 100644 --- a/tooling/nargo_fmt/src/formatter/item.rs +++ b/tooling/nargo_fmt/src/formatter/item.rs @@ -14,17 +14,15 @@ impl<'a> Formatter<'a> { while !items.is_empty() { // Format the next import group, if there is one. - if self.config.merge_imports { - let import_group = self.next_import_group(&mut items); - if let Some(import_group) = import_group { - self.merge_and_format_imports(import_group.imports, import_group.visibility); - self.skip_past_span_end_without_formatting(import_group.span_end); - self.write_line(); - ignore_next = self.ignore_next; - - // Continue from the top because the next thing that comes might be another import group - continue; - } + let import_group = self.next_import_group(&mut items); + if let Some(import_group) = import_group { + self.merge_and_format_imports(import_group.imports, import_group.visibility); + self.skip_past_span_end_without_formatting(import_group.span_end); + self.write_line(); + ignore_next = self.ignore_next; + + // Continue from the top because the next thing that comes might be another import group + continue; } if let Some(item) = items.pop() { @@ -85,6 +83,10 @@ impl<'a> Formatter<'a> { /// /// Each import group will be sorted and merged, if the configuration is set to do so. fn next_import_group(&self, items: &mut Vec) -> Option { + if !self.config.merge_imports && !self.config.reorder_imports { + return None; + } + let mut imports = Vec::new(); let item = items.last()?; @@ -161,6 +163,7 @@ impl<'a> Formatter<'a> { } } +#[derive(Debug)] struct ImportGroup { imports: Vec, visibility: ItemVisibility, diff --git a/tooling/nargo_fmt/src/formatter/use_tree.rs b/tooling/nargo_fmt/src/formatter/use_tree.rs index 3a6b750cf65..3c293b5bd14 100644 --- a/tooling/nargo_fmt/src/formatter/use_tree.rs +++ b/tooling/nargo_fmt/src/formatter/use_tree.rs @@ -124,12 +124,13 @@ mod tests { use crate::{assert_format_with_config, Config}; fn assert_format(src: &str, expected: &str) { - let config = Config { merge_imports: false, ..Config::default() }; + let config = Config { merge_imports: false, reorder_imports: false, ..Config::default() }; assert_format_with_config(src, expected, config); } fn assert_format_with_max_width(src: &str, expected: &str, max_width: usize) { - let config = Config { merge_imports: false, max_width, ..Config::default() }; + let config = + Config { merge_imports: false, reorder_imports: false, max_width, ..Config::default() }; assert_format_with_config(src, expected, config); } diff --git a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs index 602e314be41..bb48d586f4a 100644 --- a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs +++ b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs @@ -16,9 +16,26 @@ impl<'a> Formatter<'a> { imports: Vec, visibility: ItemVisibility, ) { - let merged_import = merge_imports(imports); + if self.config.merge_imports { + let import_tree = merge_imports(imports); + self.format_import_tree(import_tree, visibility); + } else { + let mut import_trees: Vec = + imports.into_iter().map(|import| merge_imports(vec![import])).collect(); + import_trees.sort(); + + for (index, import_tree) in import_trees.into_iter().enumerate() { + if index > 0 { + self.write_line_without_skipping_whitespace_and_comments(); + } - for (index, (segment, segment_tree)) in merged_import.tree.into_iter().enumerate() { + self.format_import_tree(import_tree, visibility); + } + } + } + + fn format_import_tree(&mut self, import_tree: ImportTree, visibility: ItemVisibility) { + for (index, (segment, segment_tree)) in import_tree.tree.into_iter().enumerate() { if index > 0 { self.write_line_without_skipping_whitespace_and_comments(); } @@ -181,7 +198,7 @@ impl Ord for Segment { /// "bar" => {"baz", "qux"}, /// } /// } -#[derive(Debug, Default)] +#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord)] struct ImportTree { tree: BTreeMap>, } @@ -278,12 +295,18 @@ mod tests { use crate::{assert_format_with_config, Config}; fn assert_format(src: &str, expected: &str) { - let config = Config { merge_imports: true, ..Config::default() }; + let config = Config { merge_imports: true, reorder_imports: true, ..Config::default() }; assert_format_with_config(src, expected, config); } fn assert_format_with_max_width(src: &str, expected: &str, max_width: usize) { - let config = Config { merge_imports: true, max_width, ..Config::default() }; + let config = + Config { merge_imports: true, reorder_imports: true, max_width, ..Config::default() }; + assert_format_with_config(src, expected, config); + } + + fn assert_format_without_merge(src: &str, expected: &str) { + let config = Config { merge_imports: false, reorder_imports: true, ..Config::default() }; assert_format_with_config(src, expected, config); } @@ -457,6 +480,20 @@ use bar; // trailing assert_format(src, expected); } + #[test] + fn sorts_but_not_merges_if_not_told_so() { + let src = " + use foo::baz; + use foo::{qux, bar}; + use bar; + "; + let expected = "use bar; +use foo::{bar, qux}; +use foo::baz; +"; + assert_format_without_merge(src, expected); + } + #[test] fn merges_and_sorts_imports_2() { let src = " diff --git a/tooling/nargo_fmt/tests/expected/contract.nr b/tooling/nargo_fmt/tests/expected/contract.nr index c3648bb37d4..ad53e61c911 100644 --- a/tooling/nargo_fmt/tests/expected/contract.nr +++ b/tooling/nargo_fmt/tests/expected/contract.nr @@ -6,19 +6,21 @@ contract Benchmarking { use aztec::protocol_types::abis::function_selector::FunctionSelector; use value_note::{ - utils::{increment, decrement}, + utils::{decrement, increment}, value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, }; use aztec::{ context::Context, - note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader}, log::emit_unencrypted_log, - state_vars::{Map, PublicMutable, PrivateSet}, - types::type_serialization::field_serialization::{ - FieldSerializationMethods, FIELD_SERIALIZED_LEN, + note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader}, + state_vars::{Map, PrivateSet, PublicMutable}, + types::{ + address::AztecAddress, + type_serialization::field_serialization::{ + FIELD_SERIALIZED_LEN, FieldSerializationMethods, + }, }, - types::address::AztecAddress, }; struct Storage { From 5a57f2cade885f93ef6945fcdfea26646bbe545d Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 23 Oct 2024 15:40:04 -0300 Subject: [PATCH 13/15] Reorder imports in the std and test programs --- noir_stdlib/src/array/check_shuffle.nr | 2 +- noir_stdlib/src/bigint.nr | 2 +- noir_stdlib/src/cmp.nr | 2 +- noir_stdlib/src/collections/map.nr | 6 +++--- noir_stdlib/src/collections/umap.nr | 4 ++-- noir_stdlib/src/ec/consts/te.nr | 2 +- noir_stdlib/src/ec/montcurve.nr | 10 +++++----- noir_stdlib/src/ec/swcurve.nr | 8 ++++---- noir_stdlib/src/ec/tecurve.nr | 8 ++++---- noir_stdlib/src/eddsa.nr | 2 +- noir_stdlib/src/embedded_curve_ops.nr | 2 +- noir_stdlib/src/field/bn254.nr | 2 +- noir_stdlib/src/field/mod.nr | 2 +- noir_stdlib/src/hash/mimc.nr | 2 +- noir_stdlib/src/hash/mod.nr | 2 +- noir_stdlib/src/hash/poseidon/bn254/consts.nr | 2 +- noir_stdlib/src/hash/poseidon/mod.nr | 2 +- noir_stdlib/src/hash/poseidon2.nr | 2 +- noir_stdlib/src/meta/expr.nr | 4 ++-- noir_stdlib/src/meta/trait_constraint.nr | 2 +- noir_stdlib/src/meta/trait_def.nr | 2 +- noir_stdlib/src/ops/mod.nr | 4 ++-- noir_stdlib/src/option.nr | 4 ++-- noir_stdlib/src/prelude.nr | 12 ++++++------ noir_stdlib/src/uint128.nr | 4 ++-- .../compile_success_empty/ec_baby_jubjub/src/main.nr | 2 +- .../mod_nr_entrypoint/src/main.nr | 4 ++-- .../compile_success_empty/reexports/src/main.nr | 2 +- .../turbofish_call_func_diff_types/src/main.nr | 2 +- .../binary_operator_overloading/src/main.nr | 2 +- test_programs/execution_success/eddsa/src/main.nr | 2 +- .../execution_success/regression_3889/src/main.nr | 2 +- 32 files changed, 55 insertions(+), 55 deletions(-) diff --git a/noir_stdlib/src/array/check_shuffle.nr b/noir_stdlib/src/array/check_shuffle.nr index 82028d487c7..2e8c227feee 100644 --- a/noir_stdlib/src/array/check_shuffle.nr +++ b/noir_stdlib/src/array/check_shuffle.nr @@ -59,8 +59,8 @@ where } mod test { - use super::check_shuffle; use crate::cmp::Eq; + use super::check_shuffle; struct CompoundStruct { a: bool, diff --git a/noir_stdlib/src/bigint.nr b/noir_stdlib/src/bigint.nr index 203ff90d444..be072257be3 100644 --- a/noir_stdlib/src/bigint.nr +++ b/noir_stdlib/src/bigint.nr @@ -1,5 +1,5 @@ -use crate::ops::{Add, Sub, Mul, Div}; use crate::cmp::Eq; +use crate::ops::{Add, Div, Mul, Sub}; global bn254_fq = &[ 0x47, 0xFD, 0x7C, 0xD8, 0x16, 0x8C, 0x20, 0x3C, 0x8d, 0xca, 0x71, 0x68, 0x91, 0x6a, 0x81, 0x97, diff --git a/noir_stdlib/src/cmp.nr b/noir_stdlib/src/cmp.nr index 10be6e7b867..ae515150a4d 100644 --- a/noir_stdlib/src/cmp.nr +++ b/noir_stdlib/src/cmp.nr @@ -537,7 +537,7 @@ where } mod cmp_tests { - use crate::cmp::{min, max}; + use crate::cmp::{max, min}; #[test] fn sanity_check_min() { diff --git a/noir_stdlib/src/collections/map.nr b/noir_stdlib/src/collections/map.nr index cd203c43ad3..b46bfa837fb 100644 --- a/noir_stdlib/src/collections/map.nr +++ b/noir_stdlib/src/collections/map.nr @@ -1,8 +1,8 @@ use crate::cmp::Eq; -use crate::option::Option; -use crate::default::Default; -use crate::hash::{Hash, Hasher, BuildHasher}; use crate::collections::bounded_vec::BoundedVec; +use crate::default::Default; +use crate::hash::{BuildHasher, Hash, Hasher}; +use crate::option::Option; // We use load factor alpha_max = 0.75. // Upon exceeding it, assert will fail in order to inform the user diff --git a/noir_stdlib/src/collections/umap.nr b/noir_stdlib/src/collections/umap.nr index 9b72b6173ca..3e074551e9d 100644 --- a/noir_stdlib/src/collections/umap.nr +++ b/noir_stdlib/src/collections/umap.nr @@ -1,7 +1,7 @@ use crate::cmp::Eq; -use crate::option::Option; use crate::default::Default; -use crate::hash::{Hash, Hasher, BuildHasher}; +use crate::hash::{BuildHasher, Hash, Hasher}; +use crate::option::Option; // An unconstrained hash table with open addressing and quadratic probing. // Note that "unconstrained" here means that almost all operations on this diff --git a/noir_stdlib/src/ec/consts/te.nr b/noir_stdlib/src/ec/consts/te.nr index 561c16e846a..150eb849947 100644 --- a/noir_stdlib/src/ec/consts/te.nr +++ b/noir_stdlib/src/ec/consts/te.nr @@ -1,5 +1,5 @@ -use crate::ec::tecurve::affine::Point as TEPoint; use crate::ec::tecurve::affine::Curve as TECurve; +use crate::ec::tecurve::affine::Point as TEPoint; pub struct BabyJubjub { pub curve: TECurve, diff --git a/noir_stdlib/src/ec/montcurve.nr b/noir_stdlib/src/ec/montcurve.nr index 6c83feb1607..239585ba13f 100644 --- a/noir_stdlib/src/ec/montcurve.nr +++ b/noir_stdlib/src/ec/montcurve.nr @@ -3,16 +3,16 @@ pub mod affine { // Points are represented by two-dimensional Cartesian coordinates. // All group operations are induced by those of the corresponding Twisted Edwards curve. // See e.g. for details on the correspondences. + use crate::cmp::Eq; + use crate::ec::is_square; use crate::ec::montcurve::curvegroup; + use crate::ec::safe_inverse; + use crate::ec::sqrt; use crate::ec::swcurve::affine::Curve as SWCurve; use crate::ec::swcurve::affine::Point as SWPoint; use crate::ec::tecurve::affine::Curve as TECurve; use crate::ec::tecurve::affine::Point as TEPoint; - use crate::ec::is_square; - use crate::ec::safe_inverse; - use crate::ec::sqrt; use crate::ec::ZETA; - use crate::cmp::Eq; // Curve specification pub struct Curve { // Montgomery Curve configuration (ky^2 = x^3 + j*x^2 + x) @@ -222,12 +222,12 @@ pub mod curvegroup { // Points are represented by three-dimensional projective (homogeneous) coordinates. // All group operations are induced by those of the corresponding Twisted Edwards curve. // See e.g. for details on the correspondences. + use crate::cmp::Eq; use crate::ec::montcurve::affine; use crate::ec::swcurve::curvegroup::Curve as SWCurve; use crate::ec::swcurve::curvegroup::Point as SWPoint; use crate::ec::tecurve::curvegroup::Curve as TECurve; use crate::ec::tecurve::curvegroup::Point as TEPoint; - use crate::cmp::Eq; pub struct Curve { // Montgomery Curve configuration (ky^2 z = x*(x^2 + j*x*z + z*z)) pub j: Field, diff --git a/noir_stdlib/src/ec/swcurve.nr b/noir_stdlib/src/ec/swcurve.nr index 145b2506f73..d9c1cf8c8c7 100644 --- a/noir_stdlib/src/ec/swcurve.nr +++ b/noir_stdlib/src/ec/swcurve.nr @@ -3,11 +3,11 @@ pub mod affine { // Points are represented by two-dimensional Cartesian coordinates. // Group operations are implemented in terms of those in CurveGroup (in this case, extended Twisted Edwards) coordinates // for reasons of efficiency, cf. . - use crate::ec::swcurve::curvegroup; - use crate::ec::safe_inverse; + use crate::cmp::Eq; use crate::ec::is_square; + use crate::ec::safe_inverse; use crate::ec::sqrt; - use crate::cmp::Eq; + use crate::ec::swcurve::curvegroup; // Curve specification pub struct Curve { // Short Weierstrass curve @@ -190,8 +190,8 @@ pub mod curvegroup { // CurveGroup representation of Weierstrass curves // Points are represented by three-dimensional Jacobian coordinates. // See for details. - use crate::ec::swcurve::affine; use crate::cmp::Eq; + use crate::ec::swcurve::affine; // Curve specification pub struct Curve { // Short Weierstrass curve diff --git a/noir_stdlib/src/ec/tecurve.nr b/noir_stdlib/src/ec/tecurve.nr index 0088896015d..8512413c831 100644 --- a/noir_stdlib/src/ec/tecurve.nr +++ b/noir_stdlib/src/ec/tecurve.nr @@ -4,12 +4,12 @@ pub mod affine { // Group operations are implemented in terms of those in CurveGroup (in this case, extended Twisted Edwards) coordinates // for reasons of efficiency. // See for details. - use crate::ec::tecurve::curvegroup; + use crate::cmp::Eq; use crate::ec::montcurve::affine::Curve as MCurve; use crate::ec::montcurve::affine::Point as MPoint; use crate::ec::swcurve::affine::Curve as SWCurve; use crate::ec::swcurve::affine::Point as SWPoint; - use crate::cmp::Eq; + use crate::ec::tecurve::curvegroup; // Curve specification pub struct Curve { // Twisted Edwards curve @@ -197,12 +197,12 @@ pub mod curvegroup { // CurveGroup coordinate representation of Twisted Edwards curves // Points are represented by four-dimensional projective coordinates, viz. extended Twisted Edwards coordinates. // See section 3 of for details. - use crate::ec::tecurve::affine; + use crate::cmp::Eq; use crate::ec::montcurve::curvegroup::Curve as MCurve; use crate::ec::montcurve::curvegroup::Point as MPoint; use crate::ec::swcurve::curvegroup::Curve as SWCurve; use crate::ec::swcurve::curvegroup::Point as SWPoint; - use crate::cmp::Eq; + use crate::ec::tecurve::affine; // Curve specification pub struct Curve { // Twisted Edwards curve diff --git a/noir_stdlib/src/eddsa.nr b/noir_stdlib/src/eddsa.nr index 89a0b05b072..c049b7abbb5 100644 --- a/noir_stdlib/src/eddsa.nr +++ b/noir_stdlib/src/eddsa.nr @@ -1,8 +1,8 @@ +use crate::default::Default; use crate::ec::consts::te::baby_jubjub; use crate::ec::tecurve::affine::Point as TEPoint; use crate::hash::Hasher; use crate::hash::poseidon::PoseidonHasher; -use crate::default::Default; // Returns true if signature is valid pub fn eddsa_poseidon_verify( diff --git a/noir_stdlib/src/embedded_curve_ops.nr b/noir_stdlib/src/embedded_curve_ops.nr index dd5e4285c00..6b225ee18b2 100644 --- a/noir_stdlib/src/embedded_curve_ops.nr +++ b/noir_stdlib/src/embedded_curve_ops.nr @@ -1,5 +1,5 @@ -use crate::ops::arith::{Add, Sub, Neg}; use crate::cmp::Eq; +use crate::ops::arith::{Add, Neg, Sub}; /// A point on the embedded elliptic curve /// By definition, the base field of the embedded curve is the scalar field of the proof system curve, i.e the Noir Field. diff --git a/noir_stdlib/src/field/bn254.nr b/noir_stdlib/src/field/bn254.nr index 356b47e63cf..9642c2aa1b8 100644 --- a/noir_stdlib/src/field/bn254.nr +++ b/noir_stdlib/src/field/bn254.nr @@ -141,7 +141,7 @@ pub fn lt(a: Field, b: Field) -> bool { mod tests { // TODO: Allow imports from "super" use crate::field::bn254::{ - decompose, compute_lt, assert_gt, gt, TWO_POW_128, compute_lte, PLO, PHI, + assert_gt, compute_lt, compute_lte, decompose, gt, PHI, PLO, TWO_POW_128, }; #[test] diff --git a/noir_stdlib/src/field/mod.nr b/noir_stdlib/src/field/mod.nr index 915ea8f939e..b632cf1f7a2 100644 --- a/noir_stdlib/src/field/mod.nr +++ b/noir_stdlib/src/field/mod.nr @@ -1,6 +1,6 @@ pub mod bn254; -use bn254::lt as bn254_lt; use crate::runtime::is_unconstrained; +use bn254::lt as bn254_lt; impl Field { /// Asserts that `self` can be represented in `bit_size` bits. diff --git a/noir_stdlib/src/hash/mimc.nr b/noir_stdlib/src/hash/mimc.nr index 6045ae3dbdb..55c06964122 100644 --- a/noir_stdlib/src/hash/mimc.nr +++ b/noir_stdlib/src/hash/mimc.nr @@ -1,5 +1,5 @@ -use crate::hash::Hasher; use crate::default::Default; +use crate::hash::Hasher; // mimc-p/p implementation // constants are (publicly generated) random numbers, for instance using keccak as a ROM. diff --git a/noir_stdlib/src/hash/mod.nr b/noir_stdlib/src/hash/mod.nr index 609017d70aa..15112757312 100644 --- a/noir_stdlib/src/hash/mod.nr +++ b/noir_stdlib/src/hash/mod.nr @@ -6,11 +6,11 @@ pub mod sha256; pub mod sha512; use crate::default::Default; -use crate::uint128::U128; use crate::embedded_curve_ops::{ EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return, }; use crate::meta::derive_via; +use crate::uint128::U128; // Kept for backwards compatibility pub use sha256::{digest, sha256, sha256_compression, sha256_var}; diff --git a/noir_stdlib/src/hash/poseidon/bn254/consts.nr b/noir_stdlib/src/hash/poseidon/bn254/consts.nr index 835ed3ea476..42df0ef662f 100644 --- a/noir_stdlib/src/hash/poseidon/bn254/consts.nr +++ b/noir_stdlib/src/hash/poseidon/bn254/consts.nr @@ -2,8 +2,8 @@ // Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 // Constants for various Poseidon instances in the case of the prime field of the same order as BN254. // Consistent with https://github.com/iden3/circomlib/blob/master/circuits/poseidon.circom and https://github.com/iden3/circomlib/blob/master/circuits/poseidon_constants.circom -use crate::hash::poseidon::PoseidonConfig; use crate::hash::poseidon::config; +use crate::hash::poseidon::PoseidonConfig; // S-box power fn alpha() -> Field { 5 diff --git a/noir_stdlib/src/hash/poseidon/mod.nr b/noir_stdlib/src/hash/poseidon/mod.nr index 0af7951b8dc..6f0e461a610 100644 --- a/noir_stdlib/src/hash/poseidon/mod.nr +++ b/noir_stdlib/src/hash/poseidon/mod.nr @@ -1,6 +1,6 @@ pub mod bn254; // Instantiations of Poseidon for prime field of the same order as BN254 -use crate::hash::Hasher; use crate::default::Default; +use crate::hash::Hasher; // A config struct defining the parameters of the Poseidon instance to use. // diff --git a/noir_stdlib/src/hash/poseidon2.nr b/noir_stdlib/src/hash/poseidon2.nr index 517c2cd8f5f..f2167c43c2c 100644 --- a/noir_stdlib/src/hash/poseidon2.nr +++ b/noir_stdlib/src/hash/poseidon2.nr @@ -1,5 +1,5 @@ -use crate::hash::Hasher; use crate::default::Default; +use crate::hash::Hasher; comptime global RATE: u32 = 3; diff --git a/noir_stdlib/src/meta/expr.nr b/noir_stdlib/src/meta/expr.nr index 1b04a97ab15..bb795a520d3 100644 --- a/noir_stdlib/src/meta/expr.nr +++ b/noir_stdlib/src/meta/expr.nr @@ -1,8 +1,8 @@ //! Contains methods on the built-in `Expr` type for quoted, syntactically valid expressions. -use crate::option::Option; -use crate::meta::op::UnaryOp; use crate::meta::op::BinaryOp; +use crate::meta::op::UnaryOp; +use crate::option::Option; impl Expr { /// If this expression is an array literal `[elem1, ..., elemN]`, this returns a slice of each element in the array. diff --git a/noir_stdlib/src/meta/trait_constraint.nr b/noir_stdlib/src/meta/trait_constraint.nr index bf22f454448..2d9c6639dbd 100644 --- a/noir_stdlib/src/meta/trait_constraint.nr +++ b/noir_stdlib/src/meta/trait_constraint.nr @@ -1,5 +1,5 @@ -use crate::hash::{Hash, Hasher}; use crate::cmp::Eq; +use crate::hash::{Hash, Hasher}; impl Eq for TraitConstraint { comptime fn eq(self, other: Self) -> bool { diff --git a/noir_stdlib/src/meta/trait_def.nr b/noir_stdlib/src/meta/trait_def.nr index cc448b2eae5..75f746337d4 100644 --- a/noir_stdlib/src/meta/trait_def.nr +++ b/noir_stdlib/src/meta/trait_def.nr @@ -1,5 +1,5 @@ -use crate::hash::{Hash, Hasher}; use crate::cmp::Eq; +use crate::hash::{Hash, Hasher}; impl TraitDefinition { #[builtin(trait_def_as_trait_constraint)] diff --git a/noir_stdlib/src/ops/mod.nr b/noir_stdlib/src/ops/mod.nr index bf908ea4b27..0e3a2467c60 100644 --- a/noir_stdlib/src/ops/mod.nr +++ b/noir_stdlib/src/ops/mod.nr @@ -1,5 +1,5 @@ pub(crate) mod arith; pub(crate) mod bit; -pub use arith::{Add, Sub, Mul, Div, Rem, Neg}; -pub use bit::{Not, BitOr, BitAnd, BitXor, Shl, Shr}; +pub use arith::{Add, Div, Mul, Neg, Rem, Sub}; +pub use bit::{BitAnd, BitOr, BitXor, Not, Shl, Shr}; diff --git a/noir_stdlib/src/option.nr b/noir_stdlib/src/option.nr index 5db2ce84efd..0a62e412849 100644 --- a/noir_stdlib/src/option.nr +++ b/noir_stdlib/src/option.nr @@ -1,6 +1,6 @@ -use crate::hash::{Hash, Hasher}; -use crate::cmp::{Ordering, Ord, Eq}; +use crate::cmp::{Eq, Ord, Ordering}; use crate::default::Default; +use crate::hash::{Hash, Hasher}; pub struct Option { _is_some: bool, diff --git a/noir_stdlib/src/prelude.nr b/noir_stdlib/src/prelude.nr index b6e54eaae60..a4a6c35b615 100644 --- a/noir_stdlib/src/prelude.nr +++ b/noir_stdlib/src/prelude.nr @@ -1,10 +1,10 @@ -pub use crate::collections::vec::Vec; -pub use crate::collections::bounded_vec::BoundedVec; -pub use crate::option::Option; -pub use crate::{print, println, assert_constant}; -pub use crate::uint128::U128; +pub use crate::{assert_constant, print, println}; pub use crate::cmp::{Eq, Ord}; -pub use crate::default::Default; +pub use crate::collections::bounded_vec::BoundedVec; +pub use crate::collections::vec::Vec; pub use crate::convert::{From, Into}; +pub use crate::default::Default; pub use crate::meta::{derive, derive_via}; +pub use crate::option::Option; pub use crate::panic::panic; +pub use crate::uint128::U128; diff --git a/noir_stdlib/src/uint128.nr b/noir_stdlib/src/uint128.nr index a4e20859604..06febb3ee00 100644 --- a/noir_stdlib/src/uint128.nr +++ b/noir_stdlib/src/uint128.nr @@ -1,5 +1,5 @@ -use crate::ops::{Add, Sub, Mul, Div, Rem, Not, BitOr, BitAnd, BitXor, Shl, Shr}; use crate::cmp::{Eq, Ord, Ordering}; +use crate::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Rem, Shl, Shr, Sub}; global pow64: Field = 18446744073709551616; //2^64; global pow63: Field = 9223372036854775808; // 2^63; @@ -313,7 +313,7 @@ impl Shr for U128 { } mod tests { - use crate::uint128::{U128, pow64, pow63}; + use crate::uint128::{pow63, pow64, U128}; #[test] fn test_not(lo: u64, hi: u64) { diff --git a/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr b/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr index 935b1c613ad..caaa51d84f0 100644 --- a/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr +++ b/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr @@ -6,9 +6,9 @@ use std::ec::tecurve::curvegroup::Point as G; use std::ec::swcurve::affine::Point as SWGaffine; use std::ec::swcurve::curvegroup::Point as SWG; +use std::compat; use std::ec::montcurve::affine::Point as MGaffine; use std::ec::montcurve::curvegroup::Point as MG; -use std::compat; fn main() { // This test only makes sense if Field is the right prime field. diff --git a/test_programs/compile_success_empty/mod_nr_entrypoint/src/main.nr b/test_programs/compile_success_empty/mod_nr_entrypoint/src/main.nr index 620fd99f6ec..972a64bfeb9 100644 --- a/test_programs/compile_success_empty/mod_nr_entrypoint/src/main.nr +++ b/test_programs/compile_success_empty/mod_nr_entrypoint/src/main.nr @@ -1,6 +1,6 @@ -use crate::foo::in_foo_mod; -use crate::foo::bar::in_bar_mod; use crate::baz::in_baz_mod; +use crate::foo::bar::in_bar_mod; +use crate::foo::in_foo_mod; mod foo; mod baz; diff --git a/test_programs/compile_success_empty/reexports/src/main.nr b/test_programs/compile_success_empty/reexports/src/main.nr index 0fd65a33564..6b568bea682 100644 --- a/test_programs/compile_success_empty/reexports/src/main.nr +++ b/test_programs/compile_success_empty/reexports/src/main.nr @@ -1,4 +1,4 @@ -use reexporting_lib::{FooStruct, MyStruct, lib}; +use reexporting_lib::{FooStruct, lib, MyStruct}; fn main() { let x: FooStruct = MyStruct { inner: 0 }; diff --git a/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr b/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr index 535d7b18137..e44df34a193 100644 --- a/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr +++ b/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr @@ -1,6 +1,6 @@ use std::hash::Hasher; -use std::hash::poseidon2::Poseidon2Hasher; use std::hash::poseidon::PoseidonHasher; +use std::hash::poseidon2::Poseidon2Hasher; fn main(x: Field, y: pub Field) { let mut hasher = PoseidonHasher::default(); diff --git a/test_programs/execution_success/binary_operator_overloading/src/main.nr b/test_programs/execution_success/binary_operator_overloading/src/main.nr index a5e12fd5da9..03a4e1ed22f 100644 --- a/test_programs/execution_success/binary_operator_overloading/src/main.nr +++ b/test_programs/execution_success/binary_operator_overloading/src/main.nr @@ -1,5 +1,5 @@ -use std::ops::{Add, Sub, Mul, Div, Rem, BitAnd, BitOr, BitXor, Shl, Shr}; use std::cmp::Ordering; +use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub}; // x = 3, y = 9 fn main(x: u32, y: u32) { diff --git a/test_programs/execution_success/eddsa/src/main.nr b/test_programs/execution_success/eddsa/src/main.nr index d0ce8e70053..48e1e4af9fb 100644 --- a/test_programs/execution_success/eddsa/src/main.nr +++ b/test_programs/execution_success/eddsa/src/main.nr @@ -1,8 +1,8 @@ use std::compat; use std::ec::consts::te::baby_jubjub; use std::ec::tecurve::affine::Point as TEPoint; +use std::eddsa::{eddsa_poseidon_verify, eddsa_to_pub, eddsa_verify}; use std::hash; -use std::eddsa::{eddsa_to_pub, eddsa_poseidon_verify, eddsa_verify}; use std::hash::poseidon2::Poseidon2Hasher; fn main(msg: pub Field, _priv_key_a: Field, _priv_key_b: Field) { diff --git a/test_programs/execution_success/regression_3889/src/main.nr b/test_programs/execution_success/regression_3889/src/main.nr index 2b54ae54418..dfd9e8c2c85 100644 --- a/test_programs/execution_success/regression_3889/src/main.nr +++ b/test_programs/execution_success/regression_3889/src/main.nr @@ -5,8 +5,8 @@ mod Foo { } mod Bar { - use crate::Foo::NewType as BarStruct; use crate::Foo::NewType; + use crate::Foo::NewType as BarStruct; } mod Baz { From 11834276bda51241913a940fed1dfc4c5a697825 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Wed, 23 Oct 2024 15:47:58 -0300 Subject: [PATCH 14/15] Rename merge_imports to imports_granularity --- tooling/nargo_fmt/src/config.rs | 14 ++++- tooling/nargo_fmt/src/formatter/item.rs | 6 +- tooling/nargo_fmt/src/formatter/use_tree.rs | 16 +++-- .../nargo_fmt/src/formatter/use_tree_merge.rs | 58 ++++++++++++------- 4 files changed, 68 insertions(+), 26 deletions(-) diff --git a/tooling/nargo_fmt/src/config.rs b/tooling/nargo_fmt/src/config.rs index 44562715721..488647c0b39 100644 --- a/tooling/nargo_fmt/src/config.rs +++ b/tooling/nargo_fmt/src/config.rs @@ -1,5 +1,7 @@ use std::path::Path; +use serde::{Deserialize, Serialize}; + use crate::errors::ConfigError; macro_rules! config { @@ -49,7 +51,7 @@ config! { array_width: usize, 100, "Maximum width of an array literal before falling back to vertical formatting"; fn_call_width: usize, 60, "Maximum width of the args of a function call before falling back to vertical formatting"; single_line_if_else_max_width: usize, 50, "Maximum line length for single line if-else expressions"; - merge_imports: bool, false, "Merge and sort groups of imports"; + imports_granularity: ImportsGranularity, ImportsGranularity::Preserve, "How imports should be grouped into use statements."; reorder_imports: bool, true, "Reorder imports alphabetically"; } @@ -73,3 +75,13 @@ impl Config { Ok(config) } } + +/// How imports should be grouped into use statements. +/// Imports will be merged or split to the configured level of granularity. +#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq)] +pub enum ImportsGranularity { + /// Do not change the granularity of any imports and preserve the original structure written by the developer. + Preserve, + /// Merge imports from the same crate into a single use statement. + Crate, +} diff --git a/tooling/nargo_fmt/src/formatter/item.rs b/tooling/nargo_fmt/src/formatter/item.rs index 7fb58e4e026..77f1cd10cbc 100644 --- a/tooling/nargo_fmt/src/formatter/item.rs +++ b/tooling/nargo_fmt/src/formatter/item.rs @@ -4,6 +4,8 @@ use noirc_frontend::{ parser::{Item, ItemKind}, }; +use crate::config::ImportsGranularity; + use super::Formatter; impl<'a> Formatter<'a> { @@ -83,7 +85,9 @@ impl<'a> Formatter<'a> { /// /// Each import group will be sorted and merged, if the configuration is set to do so. fn next_import_group(&self, items: &mut Vec) -> Option { - if !self.config.merge_imports && !self.config.reorder_imports { + if self.config.imports_granularity == ImportsGranularity::Preserve + && !self.config.reorder_imports + { return None; } diff --git a/tooling/nargo_fmt/src/formatter/use_tree.rs b/tooling/nargo_fmt/src/formatter/use_tree.rs index 3c293b5bd14..bc8dc3fcabb 100644 --- a/tooling/nargo_fmt/src/formatter/use_tree.rs +++ b/tooling/nargo_fmt/src/formatter/use_tree.rs @@ -121,16 +121,24 @@ impl<'a, 'b> ChunkFormatter<'a, 'b> { #[cfg(test)] mod tests { - use crate::{assert_format_with_config, Config}; + use crate::{assert_format_with_config, config::ImportsGranularity, Config}; fn assert_format(src: &str, expected: &str) { - let config = Config { merge_imports: false, reorder_imports: false, ..Config::default() }; + let config = Config { + imports_granularity: ImportsGranularity::Preserve, + reorder_imports: false, + ..Config::default() + }; assert_format_with_config(src, expected, config); } fn assert_format_with_max_width(src: &str, expected: &str, max_width: usize) { - let config = - Config { merge_imports: false, reorder_imports: false, max_width, ..Config::default() }; + let config = Config { + imports_granularity: ImportsGranularity::Preserve, + reorder_imports: false, + max_width, + ..Config::default() + }; assert_format_with_config(src, expected, config); } diff --git a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs index bb48d586f4a..c71078033cd 100644 --- a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs +++ b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs @@ -6,7 +6,10 @@ use std::{ use noirc_frontend::ast::{ItemVisibility, PathKind, UseTree, UseTreeKind}; -use crate::chunks::{ChunkGroup, TextChunk}; +use crate::{ + chunks::{ChunkGroup, TextChunk}, + config::ImportsGranularity, +}; use super::Formatter; @@ -16,19 +19,22 @@ impl<'a> Formatter<'a> { imports: Vec, visibility: ItemVisibility, ) { - if self.config.merge_imports { - let import_tree = merge_imports(imports); - self.format_import_tree(import_tree, visibility); - } else { - let mut import_trees: Vec = - imports.into_iter().map(|import| merge_imports(vec![import])).collect(); - import_trees.sort(); - - for (index, import_tree) in import_trees.into_iter().enumerate() { - if index > 0 { - self.write_line_without_skipping_whitespace_and_comments(); + match self.config.imports_granularity { + ImportsGranularity::Preserve => { + let mut import_trees: Vec = + imports.into_iter().map(|import| merge_imports(vec![import])).collect(); + import_trees.sort(); + + for (index, import_tree) in import_trees.into_iter().enumerate() { + if index > 0 { + self.write_line_without_skipping_whitespace_and_comments(); + } + + self.format_import_tree(import_tree, visibility); } - + } + ImportsGranularity::Crate => { + let import_tree = merge_imports(imports); self.format_import_tree(import_tree, visibility); } } @@ -292,21 +298,33 @@ fn merge_imports_in_tree(imports: Vec, mut tree: &mut ImportTree) { #[cfg(test)] mod tests { - use crate::{assert_format_with_config, Config}; + use crate::{assert_format_with_config, config::ImportsGranularity, Config}; fn assert_format(src: &str, expected: &str) { - let config = Config { merge_imports: true, reorder_imports: true, ..Config::default() }; + let config = Config { + imports_granularity: ImportsGranularity::Crate, + reorder_imports: true, + ..Config::default() + }; assert_format_with_config(src, expected, config); } fn assert_format_with_max_width(src: &str, expected: &str, max_width: usize) { - let config = - Config { merge_imports: true, reorder_imports: true, max_width, ..Config::default() }; + let config = Config { + imports_granularity: ImportsGranularity::Crate, + reorder_imports: true, + max_width, + ..Config::default() + }; assert_format_with_config(src, expected, config); } - fn assert_format_without_merge(src: &str, expected: &str) { - let config = Config { merge_imports: false, reorder_imports: true, ..Config::default() }; + fn assert_format_preserving_granularity(src: &str, expected: &str) { + let config = Config { + imports_granularity: ImportsGranularity::Preserve, + reorder_imports: true, + ..Config::default() + }; assert_format_with_config(src, expected, config); } @@ -491,7 +509,7 @@ use bar; // trailing use foo::{bar, qux}; use foo::baz; "; - assert_format_without_merge(src, expected); + assert_format_preserving_granularity(src, expected); } #[test] From 22011e8c80c0277cabf7457c570f9ed723f4264c Mon Sep 17 00:00:00 2001 From: Tom French Date: Wed, 23 Oct 2024 21:05:05 +0100 Subject: [PATCH 15/15] chore: add test for imports in separate not being sorted --- .../nargo_fmt/src/formatter/use_tree_merge.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs index c71078033cd..e24b7b8cbf6 100644 --- a/tooling/nargo_fmt/src/formatter/use_tree_merge.rs +++ b/tooling/nargo_fmt/src/formatter/use_tree_merge.rs @@ -512,6 +512,22 @@ use foo::baz; assert_format_preserving_granularity(src, expected); } + #[test] + fn does_not_sort_imports_in_separate_groups() { + let src = " + use foo::baz; + use foo::{qux, bar}; + + use bar; + "; + let expected = "use foo::{bar, qux}; +use foo::baz; + +use bar; +"; + assert_format_preserving_granularity(src, expected); + } + #[test] fn merges_and_sorts_imports_2() { let src = "