Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5aaa6fe
feat: catch imports of private definitions in def collection
TomAFrench Feb 25, 2024
166dc3f
feat: fully resolve private items while returning warning
TomAFrench Mar 14, 2024
04c7203
chore: fix warning for unused result
TomAFrench Mar 14, 2024
6285007
chore: cleanup
TomAFrench Mar 14, 2024
557f9e3
Merge branch 'master' into tf/def-collection-visiblity
TomAFrench Mar 14, 2024
e6bb6b7
chore: replace placeholder error messages
TomAFrench Mar 15, 2024
bb95692
chore: remove private modules test
TomAFrench Mar 15, 2024
a08090c
chore: formatting
TomAFrench Mar 15, 2024
bf3a540
chore: nit
TomAFrench Mar 15, 2024
16048c9
chore: refactoring
TomAFrench Mar 15, 2024
424fbee
chore: refactor display of `ItemVisibility`
TomAFrench Mar 15, 2024
8633239
Merge branch 'master' into tf/def-collection-visiblity
TomAFrench Mar 15, 2024
0e21701
Update compiler/noirc_frontend/src/parser/parser.rs
TomAFrench Mar 19, 2024
352cfa6
Update compiler/noirc_frontend/src/parser/parser.rs
TomAFrench Mar 19, 2024
564a067
Update compiler/noirc_frontend/src/lexer/token.rs
TomAFrench Mar 19, 2024
5deda19
Update compiler/noirc_frontend/src/ast/statement.rs
TomAFrench Mar 23, 2024
72151b8
chore: remove duplicated code
TomAFrench Mar 23, 2024
83198ac
chore: simplify return types
TomAFrench Mar 23, 2024
b7d57bf
chore: make fn more private
TomAFrench Mar 23, 2024
c389a55
chore: make `PathResolution` actually contain a resolved path rather …
TomAFrench Mar 23, 2024
90ee97a
chore: cargo fmt
TomAFrench Mar 23, 2024
32f5246
Merge branch 'master' into tf/def-collection-visiblity
TomAFrench Apr 2, 2024
b2d1f77
Merge branch 'master' into tf/def-collection-visiblity
TomAFrench Jun 19, 2024
bd04dc4
Merge branch 'master' into tf/def-collection-visiblity
TomAFrench Jul 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions compiler/noirc_frontend/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,18 @@ pub enum ItemVisibility {
Public,
Private,
PublicCrate,
PublicSuper,
}

impl std::fmt::Display for ItemVisibility {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Public => write!(f, "pub"),
Self::Private => write!(f, "priv"),
Self::PublicCrate => write!(f, "pub(crate)"),
Self::PublicSuper => write!(f, "pub(super)"),
}
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
Expand Down
5 changes: 5 additions & 0 deletions compiler/noirc_frontend/src/ast/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,15 @@ pub trait Recoverable {
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ModuleDeclaration {
pub ident: Ident,
pub visibility: ItemVisibility,
}

impl std::fmt::Display for ModuleDeclaration {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.visibility != ItemVisibility::Private {
write!(f, "{} ", self.visibility)?;
};

write!(f, "mod {}", self.ident)
}
}
Expand Down
13 changes: 10 additions & 3 deletions compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ impl<'a> ModCollector<'a> {
let id = match self.push_child_module(
context,
&name,
ItemVisibility::Public,
Location::new(name.span(), self.file_id),
false,
false,
Expand Down Expand Up @@ -386,6 +387,7 @@ impl<'a> ModCollector<'a> {
let trait_id = match self.push_child_module(
context,
&name,
ItemVisibility::Public,
Location::new(name.span(), self.file_id),
false,
false,
Expand Down Expand Up @@ -552,6 +554,7 @@ impl<'a> ModCollector<'a> {
match self.push_child_module(
context,
&submodule.name,
ItemVisibility::Public,
Location::new(submodule.name.span(), file_id),
true,
submodule.is_contract,
Expand Down Expand Up @@ -643,6 +646,7 @@ impl<'a> ModCollector<'a> {
match self.push_child_module(
context,
&mod_decl.ident,
ItemVisibility::Public,
Location::new(Span::empty(0), child_file_id),
true,
false,
Expand Down Expand Up @@ -676,6 +680,7 @@ impl<'a> ModCollector<'a> {
&mut self,
context: &mut Context,
mod_name: &Ident,
visibility: ItemVisibility,
mod_location: Location,
add_to_parent_scope: bool,
is_contract: bool,
Expand Down Expand Up @@ -711,9 +716,11 @@ impl<'a> ModCollector<'a> {
// to a child module containing its methods) since the module name should not shadow
// the struct name.
if add_to_parent_scope {
if let Err((first_def, second_def)) =
modules[self.module_id.0].declare_child_module(mod_name.to_owned(), mod_id)
{
if let Err((first_def, second_def)) = modules[self.module_id.0].declare_child_module(
mod_name.to_owned(),
visibility,
mod_id,
) {
let err = DefCollectorErrorKind::Duplicate {
typ: DuplicateType::Module,
first_def,
Expand Down
3 changes: 2 additions & 1 deletion compiler/noirc_frontend/src/hir/def_map/module_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,10 @@ impl ModuleData {
pub fn declare_child_module(
&mut self,
name: Ident,
visibility: ItemVisibility,
child_id: ModuleId,
) -> Result<(), (Ident, Ident)> {
self.declare(name, ItemVisibility::Public, child_id.into(), None)
self.declare(name, visibility, child_id.into(), None)
}

pub fn find_func_with_name(&self, name: &Ident) -> Option<FuncId> {
Expand Down
21 changes: 21 additions & 0 deletions compiler/noirc_frontend/src/hir/resolution/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,18 @@ fn can_reference_module_id(
match visibility {
ItemVisibility::Public => true,
ItemVisibility::PublicCrate => same_crate,
ItemVisibility::PublicSuper => {
same_crate
&& (module_descendent_of_target(
target_crate_def_map,
target_module.local_id,
current_module,
) || module_parent_of_target(
target_crate_def_map,
target_module.local_id,
current_module,
))
}
ItemVisibility::Private => {
same_crate
&& module_descendent_of_target(
Expand All @@ -385,3 +397,12 @@ fn module_descendent_of_target(
.parent
.map_or(false, |parent| module_descendent_of_target(def_map, target, parent))
}

// Returns true if `target` is a direct child module of `current`.
fn module_parent_of_target(
def_map: &CrateDefMap,
target: LocalModuleId,
current: LocalModuleId,
) -> bool {
def_map.modules[target.0].parent.map_or(false, |parent| parent == current)
}
33 changes: 30 additions & 3 deletions compiler/noirc_frontend/src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,10 +461,37 @@ fn optional_type_annotation<'a>() -> impl NoirParser<UnresolvedType> + 'a {
.map(|r#type| r#type.unwrap_or_else(UnresolvedType::unspecified))
}

/// import_visibility: 'pub(crate)' | 'pub' | %empty
fn import_visibility() -> impl NoirParser<ItemVisibility> {
let is_pub_crate = (keyword(Keyword::Pub)
.then_ignore(just(Token::LeftParen))
.then_ignore(keyword(Keyword::Crate))
.then_ignore(just(Token::RightParen)))
.map(|_| ItemVisibility::PublicCrate);

let is_pub_super = (keyword(Keyword::Pub)
.then_ignore(just(Token::LeftParen))
.then_ignore(keyword(Keyword::Super))
.then_ignore(just(Token::RightParen)))
.map(|_| ItemVisibility::PublicSuper);

let is_pub = keyword(Keyword::Pub).map(|_| ItemVisibility::Public);

let is_private = empty().map(|_| ItemVisibility::Private);

choice((is_pub_crate, is_pub_super, is_pub, is_private))
}
Comment on lines +465 to +483
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit confusing as we're overloading pub for both zk visibiilty and standard programming language visibility.

An alternative would be to rename this to export so we'd have export(super) and export(crate) to avoid this overloading.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a break from rust but a relatively weak one as it's just a keyword change.

Copy link
Collaborator

@Savio-Sou Savio-Sou Mar 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a break from rust

pub for ZK is a break anyway; the benefits of more intuitive keywords almost always outweigh the costs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jfecher what are your thoughts on this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds like using pub is a compromise either way. pub for item visibility is much more common within Noir while pub for zk is only used on entry-point function parameters. Changing either would be breaking but changing pub visibility may be less so just because it is newer. Using export fn, export(crate) fn, etc would make Noir less rust-like which could be a stumbling block. I'm fine with both uses of pub for now but if there's ever a future scenario where we could want to apply pub (zk) to a function somehow then things would get confusing real fast.


fn module_declaration() -> impl NoirParser<TopLevelStatement> {
keyword(Keyword::Mod)
.ignore_then(ident())
.map(|ident| TopLevelStatement::Module(ModuleDeclaration { ident }))
import_visibility().then_ignore(keyword(Keyword::Mod)).then(ident()).map(
|(mut visibility, ident)| {
// A module's contents are visible to the parent module unless they themselves are marked private.
if visibility == ItemVisibility::Private {
visibility = ItemVisibility::PublicSuper;
}
TopLevelStatement::Module(ModuleDeclaration { ident, visibility })
},
)
}

fn use_statement() -> impl NoirParser<TopLevelStatement> {
Expand Down
17 changes: 1 addition & 16 deletions compiler/noirc_frontend/src/parser/parser/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,28 +51,13 @@ pub(super) fn function_definition(allow_self: bool) -> impl NoirParser<NoirFunct
})
}

/// visibility_modifier: 'pub(crate)'? 'pub'? ''
fn visibility_modifier() -> impl NoirParser<ItemVisibility> {
let is_pub_crate = (keyword(Keyword::Pub)
.then_ignore(just(Token::LeftParen))
.then_ignore(keyword(Keyword::Crate))
.then_ignore(just(Token::RightParen)))
.map(|_| ItemVisibility::PublicCrate);

let is_pub = keyword(Keyword::Pub).map(|_| ItemVisibility::Public);

let is_private = empty().map(|_| ItemVisibility::Private);

choice((is_pub_crate, is_pub, is_private))
}

/// function_modifiers: 'unconstrained'? (visibility)?
///
/// returns (is_unconstrained, visibility) for whether each keyword was present
fn function_modifiers() -> impl NoirParser<(bool, ItemVisibility, bool)> {
keyword(Keyword::Unconstrained)
.or_not()
.then(visibility_modifier())
.then(import_visibility())
.then(maybe_comp_time())
.map(|((unconstrained, visibility), comptime)| {
(unconstrained.is_some(), visibility, comptime)
Expand Down
2 changes: 1 addition & 1 deletion compiler/wasm/test/fixtures/deps/lib-c/src/lib.nr
Original file line number Diff line number Diff line change
@@ -1 +1 @@
mod module;
pub mod module;
2 changes: 1 addition & 1 deletion compiler/wasm/test/fixtures/deps/lib-c/src/module.nr
Original file line number Diff line number Diff line change
@@ -1 +1 @@
mod foo;
pub mod foo;
6 changes: 3 additions & 3 deletions noir_stdlib/src/collections/mod.nr
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
mod vec;
mod bounded_vec;
mod map;
pub mod vec;
pub mod bounded_vec;
pub mod map;
2 changes: 1 addition & 1 deletion noir_stdlib/src/ec/consts/mod.nr
Original file line number Diff line number Diff line change
@@ -1 +1 @@
mod te;
pub mod te;
8 changes: 4 additions & 4 deletions noir_stdlib/src/ec/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
// Overview
// ========
// The following three elliptic curve representations are admissible:
mod tecurve; // Twisted Edwards curves
mod swcurve; // Elliptic curves in Short Weierstraß form
mod montcurve; // Montgomery curves
mod consts; // Commonly used curve presets
pub mod tecurve; // Twisted Edwards curves
pub mod swcurve; // Elliptic curves in Short Weierstraß form
pub mod montcurve; // Montgomery curves
pub mod consts; // Commonly used curve presets
//
// Note that Twisted Edwards and Montgomery curves are (birationally) equivalent, so that
// they may be freely converted between one another, whereas Short Weierstraß curves are
Expand Down
2 changes: 1 addition & 1 deletion noir_stdlib/src/field/mod.nr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod bn254;
pub mod bn254;
use bn254::lt as bn254_lt;

impl Field {
Expand Down
7 changes: 4 additions & 3 deletions noir_stdlib/src/hash/mod.nr
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod poseidon;
mod mimc;
mod poseidon2;
pub mod poseidon;
pub mod mimc;
pub mod poseidon2;
pub mod pedersen;

use crate::default::Default;
use crate::uint128::U128;
Expand Down
4 changes: 2 additions & 2 deletions noir_stdlib/src/hash/poseidon/bn254.nr
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Instantiations of Poseidon constants, permutations and sponge for prime field of the same order as BN254
mod perm;
mod consts;
pub mod perm;
pub mod consts;

use crate::hash::poseidon::{PoseidonConfig, absorb};

Expand Down
2 changes: 1 addition & 1 deletion noir_stdlib/src/hash/poseidon/mod.nr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod bn254; // Instantiations of Poseidon for prime field of the same order as BN254
pub mod bn254; // Instantiations of Poseidon for prime field of the same order as BN254
use crate::field::modulus_num_bits;
use crate::hash::Hasher;
use crate::default::Default;
Expand Down
60 changes: 30 additions & 30 deletions noir_stdlib/src/lib.nr
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
mod hash;
mod aes128;
mod array;
mod slice;
mod merkle;
mod schnorr;
mod ecdsa_secp256k1;
mod ecdsa_secp256r1;
mod eddsa;
mod embedded_curve_ops;
mod sha256;
mod sha512;
mod field;
mod ec;
mod unsafe;
mod collections;
mod compat;
mod convert;
mod option;
mod string;
mod test;
mod cmp;
mod ops;
mod default;
mod prelude;
mod uint128;
mod bigint;
mod runtime;
mod meta;
mod append;
pub mod hash;
pub mod aes128;
pub mod array;
pub mod slice;
pub mod merkle;
pub mod schnorr;
pub mod ecdsa_secp256k1;
pub mod ecdsa_secp256r1;
pub mod eddsa;
pub mod embedded_curve_ops;
pub mod sha256;
pub mod sha512;
pub mod field;
pub mod ec;
pub mod unsafe;
pub mod collections;
pub mod compat;
pub(crate) mod convert;
pub mod option;
pub mod string;
pub mod test;
pub mod cmp;
pub mod ops;
pub(crate) mod default;
pub mod prelude;
pub mod uint128;
pub mod bigint;
pub mod runtime;
pub mod meta;
pub mod append;

// Oracle calls are required to be wrapped in an unconstrained function
// Thus, the only argument to the `println` oracle is expected to always be an ident
Expand Down
2 changes: 1 addition & 1 deletion test_programs/execution_success/global_consts/src/foo.nr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod bar;
pub(crate) mod bar;

global N: u64 = 5;
global MAGIC_NUMBER: u64 = 3;
Expand Down
4 changes: 3 additions & 1 deletion test_programs/execution_success/import/src/import.nr
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub fn hello(x: Field) -> Field {
pub(crate) mod foo;

pub(crate) fn hello(x: Field) -> Field {
x
}
3 changes: 3 additions & 0 deletions test_programs/execution_success/import/src/import/foo.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub fn goodbye(x: Field) -> Field {
x
}
3 changes: 3 additions & 0 deletions test_programs/execution_success/import/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
mod import;
use crate::import::hello;
use import::foo::goodbye;

fn main(x: Field, y: Field) {
let _k = std::hash::pedersen_commitment([x]);
let _l = hello(x);
let _l = goodbye(x);

assert(x != import::hello(y));
assert(x != goodbye(y));
}
2 changes: 1 addition & 1 deletion test_programs/execution_success/modules_more/src/foo.nr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod bar;
pub(crate) mod bar;

fn hello(x: Field) -> Field {
x
Expand Down
2 changes: 1 addition & 1 deletion test_programs/execution_success/struct_inputs/src/foo.nr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod bar;
pub(crate) mod bar;

struct fooStruct {
bar_struct: bar::barStruct,
Expand Down