Skip to content

Commit 07ab515

Browse files
asteriteTomAFrench
andauthored
feat: merge and sort imports (#6322)
# Description ## Problem Manually arranging imports is time consuming. ## Summary Added two new configurations, `reorder_imports` (true by default) and `imports_granularity` (`Preserve` by default), similar to the ones found in rustfmt. With the default configuration imports are reorganized alphabetically but not merged. While implementing this I bumped into one code in the test programs like this: ```noir use foo; use foo::bar; ``` Merging those in Rust ends up like this: ```noir use foo::{bar, self}; ``` We don't have `self` in imports, so I had two choices: 1. Try to leave the above unmodified. 2. Implement `self` in imports. It turned out that implement `self` in imports is very easy: when we desugar imports, if the last segment is "self" we just remove it. Then `use foo::self` is desugared into `use foo`. ## Additional Context None. ## Documentation Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Tom French <[email protected]>
1 parent 5a6dae9 commit 07ab515

41 files changed

Lines changed: 953 additions & 79 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/noirc_frontend/src/ast/statement.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,9 @@ impl UseTree {
373373

374374
match self.kind {
375375
UseTreeKind::Path(name, alias) => {
376-
vec![ImportStatement { visibility, path: prefix.join(name), alias }]
376+
// Desugar `use foo::{self}` to `use foo`
377+
let path = if name.0.contents == "self" { prefix } else { prefix.join(name) };
378+
vec![ImportStatement { visibility, path, alias }]
377379
}
378380
UseTreeKind::List(trees) => {
379381
let trees = trees.into_iter();

compiler/noirc_frontend/src/parser/parser/use_tree.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ impl<'a> Parser<'a> {
6666
fn parse_use_tree_in_list(&mut self) -> Option<UseTree> {
6767
let start_span = self.current_token_span;
6868

69+
// Special case: "self" cannot be followed by anything else
70+
if self.eat_self() {
71+
return Some(UseTree {
72+
prefix: Path { segments: Vec::new(), kind: PathKind::Plain, span: start_span },
73+
kind: UseTreeKind::Path(Ident::new("self".to_string(), start_span), None),
74+
});
75+
}
76+
6977
let use_tree = self.parse_use_tree_without_kind(
7078
start_span,
7179
PathKind::Plain,
@@ -250,4 +258,11 @@ mod tests {
250258
let (_, errors) = parse_program(src);
251259
assert!(!errors.is_empty());
252260
}
261+
262+
#[test]
263+
fn errors_on_double_colon_after_self() {
264+
let src = "use foo::{self::bar};";
265+
let (_, errors) = parse_program(src);
266+
assert!(!errors.is_empty());
267+
}
253268
}

compiler/noirc_frontend/src/tests.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3389,3 +3389,25 @@ fn arithmetic_generics_rounding_fail() {
33893389
let errors = get_program_errors(src);
33903390
assert_eq!(errors.len(), 1);
33913391
}
3392+
3393+
#[test]
3394+
fn uses_self_in_import() {
3395+
let src = r#"
3396+
mod moo {
3397+
pub mod bar {
3398+
pub fn foo() -> i32 {
3399+
1
3400+
}
3401+
}
3402+
}
3403+
3404+
use moo::bar::{self};
3405+
3406+
pub fn baz() -> i32 {
3407+
bar::foo()
3408+
}
3409+
3410+
fn main() {}
3411+
"#;
3412+
assert_no_errors(src);
3413+
}

noir_stdlib/src/array/check_shuffle.nr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ where
5959
}
6060

6161
mod test {
62-
use super::check_shuffle;
6362
use crate::cmp::Eq;
63+
use super::check_shuffle;
6464

6565
struct CompoundStruct {
6666
a: bool,

noir_stdlib/src/bigint.nr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::ops::{Add, Sub, Mul, Div};
21
use crate::cmp::Eq;
2+
use crate::ops::{Add, Div, Mul, Sub};
33

44
global bn254_fq = &[
55
0x47, 0xFD, 0x7C, 0xD8, 0x16, 0x8C, 0x20, 0x3C, 0x8d, 0xca, 0x71, 0x68, 0x91, 0x6a, 0x81, 0x97,

noir_stdlib/src/cmp.nr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ where
537537
}
538538

539539
mod cmp_tests {
540-
use crate::cmp::{min, max};
540+
use crate::cmp::{max, min};
541541

542542
#[test]
543543
fn sanity_check_min() {

noir_stdlib/src/collections/map.nr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::cmp::Eq;
2-
use crate::option::Option;
3-
use crate::default::Default;
4-
use crate::hash::{Hash, Hasher, BuildHasher};
52
use crate::collections::bounded_vec::BoundedVec;
3+
use crate::default::Default;
4+
use crate::hash::{BuildHasher, Hash, Hasher};
5+
use crate::option::Option;
66

77
// We use load factor alpha_max = 0.75.
88
// Upon exceeding it, assert will fail in order to inform the user

noir_stdlib/src/collections/umap.nr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::cmp::Eq;
2-
use crate::option::Option;
32
use crate::default::Default;
4-
use crate::hash::{Hash, Hasher, BuildHasher};
3+
use crate::hash::{BuildHasher, Hash, Hasher};
4+
use crate::option::Option;
55

66
// An unconstrained hash table with open addressing and quadratic probing.
77
// Note that "unconstrained" here means that almost all operations on this

noir_stdlib/src/ec/consts/te.nr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::ec::tecurve::affine::Point as TEPoint;
21
use crate::ec::tecurve::affine::Curve as TECurve;
2+
use crate::ec::tecurve::affine::Point as TEPoint;
33

44
pub struct BabyJubjub {
55
pub curve: TECurve,

noir_stdlib/src/ec/montcurve.nr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ pub mod affine {
33
// Points are represented by two-dimensional Cartesian coordinates.
44
// All group operations are induced by those of the corresponding Twisted Edwards curve.
55
// See e.g. <https://eprint.iacr.org/2017/212.pdf> for details on the correspondences.
6+
use crate::cmp::Eq;
7+
use crate::ec::is_square;
68
use crate::ec::montcurve::curvegroup;
9+
use crate::ec::safe_inverse;
10+
use crate::ec::sqrt;
711
use crate::ec::swcurve::affine::Curve as SWCurve;
812
use crate::ec::swcurve::affine::Point as SWPoint;
913
use crate::ec::tecurve::affine::Curve as TECurve;
1014
use crate::ec::tecurve::affine::Point as TEPoint;
11-
use crate::ec::is_square;
12-
use crate::ec::safe_inverse;
13-
use crate::ec::sqrt;
1415
use crate::ec::ZETA;
15-
use crate::cmp::Eq;
1616

1717
// Curve specification
1818
pub struct Curve { // Montgomery Curve configuration (ky^2 = x^3 + j*x^2 + x)
@@ -222,12 +222,12 @@ pub mod curvegroup {
222222
// Points are represented by three-dimensional projective (homogeneous) coordinates.
223223
// All group operations are induced by those of the corresponding Twisted Edwards curve.
224224
// See e.g. <https://eprint.iacr.org/2017/212.pdf> for details on the correspondences.
225+
use crate::cmp::Eq;
225226
use crate::ec::montcurve::affine;
226227
use crate::ec::swcurve::curvegroup::Curve as SWCurve;
227228
use crate::ec::swcurve::curvegroup::Point as SWPoint;
228229
use crate::ec::tecurve::curvegroup::Curve as TECurve;
229230
use crate::ec::tecurve::curvegroup::Point as TEPoint;
230-
use crate::cmp::Eq;
231231

232232
pub struct Curve { // Montgomery Curve configuration (ky^2 z = x*(x^2 + j*x*z + z*z))
233233
pub j: Field,

0 commit comments

Comments
 (0)