Skip to content

Commit

Permalink
feat: visibility for traits (noir-lang/noir#6056)
Browse files Browse the repository at this point in the history
feat: allow visibility modifiers in struct definitions (noir-lang/noir#6054)
fix: let LSP suggest fields and methods in LValue chains (noir-lang/noir#6051)
feat(metaprogramming): Add `#[use_callers_scope]` (noir-lang/noir#6050)
feat: show test output when running via LSP (noir-lang/noir#6049)
feat: add `Expr::as_lambda` (noir-lang/noir#6048)
feat: faster LSP by caching file managers (noir-lang/noir#6047)
feat: implement `to_be_radix` in the comptime interpreter (noir-lang/noir#6043)
fix: prevent check_can_mutate crashing on undefined variable (noir-lang/noir#6044)
feat: add `Expr::as_for` and `Expr::as_for_range` (noir-lang/noir#6039)
fix: Fix canonicalization bug (noir-lang/noir#6033)
fix: Parse a statement as an expression (noir-lang/noir#6040)
chore: rename CustomAtrribute to CustomAttribute (noir-lang/noir#6038)
fix: error on `&mut x` when `x` is not mutable (noir-lang/noir#6037)
feat: add `Expr::as_constructor` (noir-lang/noir#5980)
chore: Fix docs (noir-lang/noir#6035)
chore: document array methods (noir-lang/noir#6034)
  • Loading branch information
AztecBot committed Sep 17, 2024
2 parents 5bdaa62 + 87df745 commit fa67794
Show file tree
Hide file tree
Showing 40 changed files with 246 additions and 111 deletions.
2 changes: 1 addition & 1 deletion .noir-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5bf6567320629835ef6fa7765ca87e9b38ae4c9a
5bbd9ba9a6d6494fd16813b44036b78c871f6613
3 changes: 2 additions & 1 deletion noir/noir-repo/compiler/noirc_frontend/src/ast/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ use crate::token::SecondaryAttribute;
use iter_extended::vecmap;
use noirc_errors::Span;

use super::Documented;
use super::{Documented, ItemVisibility};

/// Ast node for a struct
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct NoirStruct {
pub name: Ident,
pub attributes: Vec<SecondaryAttribute>,
pub visibility: ItemVisibility,
pub generics: UnresolvedGenerics,
pub fields: Vec<Documented<StructField>>,
pub span: Span,
Expand Down
1 change: 1 addition & 0 deletions noir/noir-repo/compiler/noirc_frontend/src/ast/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct NoirTrait {
pub span: Span,
pub items: Vec<Documented<TraitItem>>,
pub attributes: Vec<SecondaryAttribute>,
pub visibility: ItemVisibility,
}

/// Any declaration inside the body of a trait that a user is required to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,20 @@ impl<'a> ModCollector<'a> {
context.def_interner.set_doc_comments(ReferenceId::Trait(trait_id), doc_comments);

// Add the trait to scope so its path can be looked up later
let result = self.def_collector.def_map.modules[self.module_id.0]
.declare_trait(name.clone(), trait_id);
let visibility = trait_definition.visibility;
let result = self.def_collector.def_map.modules[self.module_id.0].declare_trait(
name.clone(),
visibility,
trait_id,
);

let parent_module_id = ModuleId { krate, local_id: self.module_id };
context.def_interner.usage_tracker.add_unused_item(
parent_module_id,
name.clone(),
UnusedItem::Trait(trait_id),
visibility,
);

if let Err((first_def, second_def)) = result {
let error = DefCollectorErrorKind::Duplicate {
Expand Down Expand Up @@ -976,7 +988,17 @@ pub fn collect_struct(
}

// Add the struct to scope so its path can be looked up later
let result = def_map.modules[module_id.0].declare_struct(name.clone(), id);
let visibility = unresolved.struct_def.visibility;
let result = def_map.modules[module_id.0].declare_struct(name.clone(), visibility, id);

let parent_module_id = ModuleId { krate, local_id: module_id };

interner.usage_tracker.add_unused_item(
parent_module_id,
name.clone(),
UnusedItem::Struct(id),
visibility,
);

if let Err((first_def, second_def)) = result {
let error = DefCollectorErrorKind::Duplicate {
Expand All @@ -988,8 +1010,7 @@ pub fn collect_struct(
}

if interner.is_in_lsp_mode() {
let parent_module_id = ModuleId { krate, local_id: module_id };
interner.register_struct(id, name.to_string(), parent_module_id);
interner.register_struct(id, name.to_string(), visibility, parent_module_id);
}

Some((id, unresolved))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,13 @@ impl ModuleData {
self.declare(name, ItemVisibility::Public, id.into(), None)
}

pub fn declare_struct(&mut self, name: Ident, id: StructId) -> Result<(), (Ident, Ident)> {
self.declare(name, ItemVisibility::Public, ModuleDefId::TypeId(id), None)
pub fn declare_struct(
&mut self,
name: Ident,
visibility: ItemVisibility,
id: StructId,
) -> Result<(), (Ident, Ident)> {
self.declare(name, visibility, ModuleDefId::TypeId(id), None)
}

pub fn declare_type_alias(
Expand All @@ -112,8 +117,13 @@ impl ModuleData {
self.declare(name, ItemVisibility::Public, id.into(), None)
}

pub fn declare_trait(&mut self, name: Ident, id: TraitId) -> Result<(), (Ident, Ident)> {
self.declare(name, ItemVisibility::Public, ModuleDefId::TraitId(id), None)
pub fn declare_trait(
&mut self,
name: Ident,
visibility: ItemVisibility,
id: TraitId,
) -> Result<(), (Ident, Ident)> {
self.declare(name, visibility, ModuleDefId::TraitId(id), None)
}

pub fn declare_child_module(
Expand Down
3 changes: 1 addition & 2 deletions noir/noir-repo/compiler/noirc_frontend/src/locations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,10 @@ impl NodeInterner {
&mut self,
id: StructId,
name: String,
visibility: ItemVisibility,
parent_module_id: ModuleId,
) {
self.add_definition_location(ReferenceId::Struct(id), Some(parent_module_id));

let visibility = ItemVisibility::Public;
self.register_name_for_auto_import(name, ModuleDefId::TypeId(id), visibility, None);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use chumsky::prelude::*;

use crate::ast::{Documented, NoirStruct, StructField};
use crate::parser::parser::visibility::item_visibility;
use crate::{
parser::{
parser::{
Expand Down Expand Up @@ -30,13 +31,21 @@ pub(super) fn struct_definition() -> impl NoirParser<TopLevelStatementKind> {
.or(just(Semicolon).to(Vec::new()));

attributes()
.then(item_visibility())
.then_ignore(keyword(Struct))
.then(ident())
.then(function::generics())
.then(fields)
.validate(|(((attributes, name), generics), fields), span, emit| {
.validate(|((((attributes, visibility), name), generics), fields), span, emit| {
let attributes = validate_secondary_attributes(attributes, span, emit);
TopLevelStatementKind::Struct(NoirStruct { name, attributes, generics, fields, span })
TopLevelStatementKind::Struct(NoirStruct {
name,
attributes,
visibility,
generics,
fields,
span,
})
})
}

Expand Down
27 changes: 16 additions & 11 deletions noir/noir-repo/compiler/noirc_frontend/src/parser/parser/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::attributes::{attributes, validate_secondary_attributes};
use super::doc_comments::outer_doc_comments;
use super::function::{function_modifiers, function_return_type};
use super::path::path_no_turbofish;
use super::visibility::item_visibility;
use super::{
block, expression, fresh_statement, function, function_declaration_parameters, let_statement,
};
Expand Down Expand Up @@ -42,22 +43,26 @@ pub(super) fn trait_definition() -> impl NoirParser<TopLevelStatementKind> {
});

attributes()
.then(item_visibility())
.then_ignore(keyword(Keyword::Trait))
.then(ident())
.then(function::generics())
.then(where_clause())
.then(trait_body_or_error)
.validate(|((((attributes, name), generics), where_clause), items), span, emit| {
let attributes = validate_secondary_attributes(attributes, span, emit);
TopLevelStatementKind::Trait(NoirTrait {
name,
generics,
where_clause,
span,
items,
attributes,
})
})
.validate(
|(((((attributes, visibility), name), generics), where_clause), items), span, emit| {
let attributes = validate_secondary_attributes(attributes, span, emit);
TopLevelStatementKind::Trait(NoirTrait {
name,
generics,
where_clause,
span,
items,
attributes,
visibility,
})
},
)
}

fn trait_body() -> impl NoirParser<Vec<Documented<TraitItem>>> {
Expand Down
88 changes: 70 additions & 18 deletions noir/noir-repo/compiler/noirc_frontend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ fn check_trait_wrong_parameter2() {
#[test]
fn check_trait_wrong_parameter_type() {
let src = "
trait Default {
pub trait Default {
fn default(x: Field, y: NotAType) -> Field;
}
Expand Down Expand Up @@ -1565,11 +1565,11 @@ fn struct_numeric_generic_in_function() {
#[test]
fn struct_numeric_generic_in_struct() {
let src = r#"
struct Foo {
pub struct Foo {
inner: u64
}
struct Bar<let N: Foo> { }
pub struct Bar<let N: Foo> { }
"#;
let errors = get_program_errors(src);
assert_eq!(errors.len(), 1);
Expand Down Expand Up @@ -1658,7 +1658,7 @@ fn numeric_generic_in_function_signature() {
#[test]
fn numeric_generic_as_struct_field_type() {
let src = r#"
struct Foo<let N: u32> {
pub struct Foo<let N: u32> {
a: Field,
b: N,
}
Expand All @@ -1674,7 +1674,7 @@ fn numeric_generic_as_struct_field_type() {
#[test]
fn normal_generic_as_array_length() {
let src = r#"
struct Foo<N> {
pub struct Foo<N> {
a: Field,
b: [Field; N],
}
Expand Down Expand Up @@ -1719,11 +1719,11 @@ fn numeric_generic_as_param_type() {
#[test]
fn numeric_generic_used_in_nested_type_fail() {
let src = r#"
struct Foo<let N: u32> {
pub struct Foo<let N: u32> {
a: Field,
b: Bar<N>,
}
struct Bar<N> {
pub struct Bar<N> {
inner: N
}
"#;
Expand All @@ -1738,11 +1738,11 @@ fn numeric_generic_used_in_nested_type_fail() {
#[test]
fn normal_generic_used_in_nested_array_length_fail() {
let src = r#"
struct Foo<N> {
pub struct Foo<N> {
a: Field,
b: Bar<N>,
}
struct Bar<let N: u32> {
pub struct Bar<let N: u32> {
inner: [Field; N]
}
"#;
Expand All @@ -1756,11 +1756,11 @@ fn numeric_generic_used_in_nested_type_pass() {
// The order of these structs should not be changed to make sure
// that we are accurately resolving all struct generics before struct fields
let src = r#"
struct NestedNumeric<let N: u32> {
pub struct NestedNumeric<let N: u32> {
a: Field,
b: InnerNumeric<N>
}
struct InnerNumeric<let N: u32> {
pub struct InnerNumeric<let N: u32> {
inner: [u64; N],
}
"#;
Expand Down Expand Up @@ -2721,7 +2721,7 @@ fn bit_not_on_untyped_integer() {
#[test]
fn duplicate_struct_field() {
let src = r#"
struct Foo {
pub struct Foo {
x: i32,
x: i32,
}
Expand All @@ -2742,8 +2742,8 @@ fn duplicate_struct_field() {
assert_eq!(first_def.to_string(), "x");
assert_eq!(second_def.to_string(), "x");

assert_eq!(first_def.span().start(), 26);
assert_eq!(second_def.span().start(), 42);
assert_eq!(first_def.span().start(), 30);
assert_eq!(second_def.span().start(), 46);
}

#[test]
Expand Down Expand Up @@ -2996,11 +2996,11 @@ fn uses_self_type_inside_trait() {
#[test]
fn uses_self_type_in_trait_where_clause() {
let src = r#"
trait Trait {
pub trait Trait {
fn trait_func() -> bool;
}
trait Foo where Self: Trait {
pub trait Foo where Self: Trait {
fn foo(self) -> bool {
self.trait_func()
}
Expand Down Expand Up @@ -3222,7 +3222,7 @@ fn errors_on_unused_private_import() {
pub fn bar() {}
pub fn baz() {}
trait Foo {
pub trait Foo {
}
}
Expand Down Expand Up @@ -3258,7 +3258,7 @@ fn errors_on_unused_pub_crate_import() {
pub fn bar() {}
pub fn baz() {}
trait Foo {
pub trait Foo {
}
}
Expand Down Expand Up @@ -3423,6 +3423,58 @@ fn errors_on_unused_function() {
assert_eq!(*item_type, "function");
}

#[test]
fn errors_on_unused_struct() {
let src = r#"
struct Foo {}
struct Bar {}
fn main() {
let _ = Bar {};
}
"#;

let errors = get_program_errors(src);
assert_eq!(errors.len(), 1);

let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item_type }) =
&errors[0].0
else {
panic!("Expected an unused item error");
};

assert_eq!(ident.to_string(), "Foo");
assert_eq!(*item_type, "struct");
}

#[test]
fn errors_on_unused_trait() {
let src = r#"
trait Foo {}
trait Bar {}
pub struct Baz {
}
impl Bar for Baz {}
fn main() {
}
"#;

let errors = get_program_errors(src);
assert_eq!(errors.len(), 1);

let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item_type }) =
&errors[0].0
else {
panic!("Expected an unused item error");
};

assert_eq!(ident.to_string(), "Foo");
assert_eq!(*item_type, "trait");
}

#[test]
fn constrained_reference_to_unconstrained() {
let src = r#"
Expand Down
Loading

0 comments on commit fa67794

Please sign in to comment.