Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 0 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions compiler/noirc_frontend/src/hir/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod comptime;
pub mod def_collector;
pub mod def_map;
pub mod printer;
pub mod resolution;
pub mod scope;
pub mod type_check;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
//! This final code has all macros expanded and is mainly gathered from data
//! inside `NodeInterner`, modules in `DefMaps` and function bodies from `HirExpression`s.

use noirc_errors::Location;
use noirc_frontend::{
mod hir_def;
mod types;

use crate::{
Kind, NamedGeneric, Type,
ast::ItemVisibility,
hir::def_map::ModuleId,
Expand All @@ -13,10 +15,11 @@ use noirc_frontend::{
FuncId, GlobalId, ImplMethod, Methods, TraitId, TraitImplId, TypeAliasId, TypeId,
},
};
use noirc_errors::Location;
use std::collections::{BTreeMap, BTreeSet, HashSet};

use noirc_driver::CrateId;
use noirc_frontend::{
use crate::graph::CrateId;
use crate::{
ast::Ident,
hir::def_map::{DefMaps, ModuleDefId},
node_interner::NodeInterner,
Expand Down Expand Up @@ -256,10 +259,7 @@ impl<'context> ItemBuilder<'context> {
Impl { generics, typ, methods }
}

fn build_data_type_trait_impls(
&mut self,
data_type: &noirc_frontend::DataType,
) -> Vec<TraitImpl> {
fn build_data_type_trait_impls(&mut self, data_type: &crate::DataType) -> Vec<TraitImpl> {
let mut trait_impls = self
.trait_impls
.iter()
Expand Down Expand Up @@ -485,7 +485,7 @@ fn gather_named_type_vars(typ: &Type, type_vars: &mut BTreeSet<(String, Kind)>)
}
}

fn type_mentions_data_type(typ: &Type, data_type: &noirc_frontend::DataType) -> bool {
fn type_mentions_data_type(typ: &Type, data_type: &crate::DataType) -> bool {
match typ {
Type::Array(length, typ) => {
type_mentions_data_type(length, data_type) || type_mentions_data_type(typ, data_type)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use noirc_frontend::{
use crate::{
NamedGeneric, Type, TypeBindings,
ast::{ItemVisibility, UnaryOp},
hir::def_map::ModuleDefId,
Expand All @@ -13,7 +13,7 @@ use noirc_frontend::{
token::FmtStrFragment,
};

use super::ItemPrinter;
use crate::hir::printer::ItemPrinter;

impl ItemPrinter<'_, '_> {
fn show_hir_expression_id(&mut self, expr_id: ExprId) {
Expand Down Expand Up @@ -61,7 +61,7 @@ impl ItemPrinter<'_, '_> {
}
}

pub(super) fn show_hir_expression(&mut self, hir_expr: HirExpression, expr_id: ExprId) {
pub(crate) fn show_hir_expression(&mut self, hir_expr: HirExpression, expr_id: ExprId) {
match hir_expr {
HirExpression::Ident(hir_ident, generics) => {
self.show_hir_ident(hir_ident, Some(expr_id));
Expand Down Expand Up @@ -258,7 +258,7 @@ impl ItemPrinter<'_, '_> {
}
}

pub(super) fn show_hir_lambda(&mut self, hir_lambda: HirLambda) {
pub(crate) fn show_hir_lambda(&mut self, hir_lambda: HirLambda) {
self.push('|');
self.show_separated_by_comma(&hir_lambda.parameters, |this, (parameter, typ)| {
this.show_hir_pattern(parameter.clone());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use noirc_frontend::{NamedGeneric, Type, TypeBinding, hir::def_map::ModuleDefId};
use crate::{NamedGeneric, Type, TypeBinding, hir::def_map::ModuleDefId};

use super::ItemPrinter;
use crate::hir::printer::ItemPrinter;

impl ItemPrinter<'_, '_> {
pub(super) fn show_types_separated_by_comma(&mut self, types: &[Type]) {
pub(crate) fn show_types_separated_by_comma(&mut self, types: &[Type]) {
self.show_separated_by_comma(types, |this, typ| {
this.show_type(typ);
});
}

pub(super) fn show_type(&mut self, typ: &Type) {
pub(crate) fn show_type(&mut self, typ: &Type) {
self.show_type_impl(typ, false /* as expression */);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::collections::{BTreeSet, HashMap};

use noirc_driver::CrateId;
use noirc_frontend::{
use crate::graph::{CrateGraph, CrateId};
use crate::hir::printer::items::ItemBuilder;
use crate::{
DataType, Generics, Kind, NamedGeneric, Type,
ast::{Ident, ItemVisibility},
graph::Dependency,
Expand All @@ -21,12 +22,34 @@ use noirc_frontend::{
token::{FunctionAttributeKind, LocatedToken, SecondaryAttribute, SecondaryAttributeKind},
};

use super::items::{Impl, Import, Item, Module, TraitImpl};
mod items;

mod hir;
mod types;
use items::{Impl, Import, Item, Module, Trait, TraitImpl};

pub(super) struct ItemPrinter<'context, 'string> {
/// Returns the HIR as human-readable code for the given crate.
/// At this point it is expected that all macros and comptime blocks have been expanded.
pub fn display_crate(
crate_id: CrateId,
crate_graph: &CrateGraph,
def_maps: &DefMaps,
interner: &NodeInterner,
) -> String {
let root_module_id = def_maps[&crate_id].root();
let module_id = ModuleId { krate: crate_id, local_id: root_module_id };

let mut builder = ItemBuilder::new(crate_id, interner, def_maps);
let item = builder.build_module(module_id);

let dependencies = &crate_graph[crate_id].dependencies;

let mut string = String::new();
let mut printer = ItemPrinter::new(crate_id, interner, def_maps, dependencies, &mut string);
printer.show_item(item);

string
}

struct ItemPrinter<'context, 'string> {
crate_id: CrateId,
interner: &'context NodeInterner,
def_maps: &'context DefMaps,
Expand Down Expand Up @@ -213,7 +236,7 @@ impl<'context, 'string> ItemPrinter<'context, 'string> {
}
}

fn show_data_type(&mut self, item_data_type: super::items::DataType) {
fn show_data_type(&mut self, item_data_type: items::DataType) {
let type_id = item_data_type.id;
let shared_data_type = self.interner.get_type(type_id);
let data_type = shared_data_type.borrow();
Expand Down Expand Up @@ -335,7 +358,7 @@ impl<'context, 'string> ItemPrinter<'context, 'string> {
self.push(';');
}

fn show_trait(&mut self, item_trait: super::items::Trait) {
fn show_trait(&mut self, item_trait: Trait) {
let trait_id = item_trait.id;
let trait_ = self.interner.get_trait(trait_id);

Expand Down
14 changes: 13 additions & 1 deletion compiler/noirc_frontend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ mod visibility;
use std::collections::HashMap;

use crate::elaborator::{FrontendOptions, UnstableFeature};
use crate::hir::printer::display_crate;
use crate::test_utils::{get_program, get_program_with_options};

use noirc_errors::reporter::report_all;
Expand All @@ -54,13 +55,24 @@ pub(crate) fn get_program_errors(src: &str) -> Vec<CompilationError> {
get_program(src).2
}

fn assert_no_errors(src: &str) {
fn assert_no_errors(src: &str) -> Context<'_, '_> {
let (_, context, errors) = get_program(src);
if !errors.is_empty() {
let errors = errors.iter().map(CustomDiagnostic::from).collect::<Vec<_>>();
report_all(context.file_manager.as_file_map(), &errors, false, false);
panic!("Expected no errors");
}
context
}

fn assert_no_errors_and_to_string(src: &str) -> String {
let context = assert_no_errors(src);
display_crate(
*context.crate_graph.root_crate_id(),
&context.crate_graph,
&context.def_maps,
&context.def_interner,
)
}

/// Given a source file with annotated errors, like this
Expand Down
111 changes: 108 additions & 3 deletions compiler/noirc_frontend/src/tests/metaprogramming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use crate::hir::{
},
};

use crate::tests::{assert_no_errors, check_errors, get_program_errors};
use crate::tests::{
assert_no_errors, assert_no_errors_and_to_string, check_errors, get_program_errors,
};

// Regression for #5388
#[test]
Expand Down Expand Up @@ -82,7 +84,32 @@ fn unquoted_integer_as_integer_token() {
}
"#;

assert_no_errors(src);
let expanded = assert_no_errors_and_to_string(src);
insta::assert_snapshot!(expanded, @r"
trait Serialize<let N: u32> {
fn serialize() {
}
}

impl Serialize<1> for Field {
fn serialize() {
}
}

pub fn foobar() {
}

comptime fn attr(_f: FunctionDefinition) -> Quoted {
let serialized_len: Field = 1_Field;
quote {
impl Serialize < $serialized_len > for Field {
fn serialize() {

}
}
}
}
");
}

#[test]
Expand All @@ -101,7 +128,59 @@ fn allows_references_to_structs_generated_by_macros() {
}
"#;

assert_no_errors(src);
let expanded = assert_no_errors_and_to_string(src);
insta::assert_snapshot!(expanded, @r"
comptime fn make_new_struct(_s: TypeDefinition) -> Quoted {
quote {
struct Bar {

}
}
}

struct Bar {
}

struct Foo {
}

fn main() {
let _: Foo = Foo { };
let _: Bar = Bar { };
}
");
}

#[test]
fn generate_function_with_macros() {
let src = "
#[foo]
comptime fn foo(_f: FunctionDefinition) -> Quoted {
quote {
pub fn bar(x: i32) -> i32 {
let y = x + 1;
y + 2
}
}
}
";

let expanded = assert_no_errors_and_to_string(src);
insta::assert_snapshot!(expanded, @r"
comptime fn foo(_f: FunctionDefinition) -> Quoted {
quote {
pub fn bar(x: i32) -> i32 {
let y = x + 1;
y + 2
}
}
}

pub fn bar(x: i32) -> i32 {
let y: i32 = x + 1_i32;
y + 2_i32
}
");
}

#[test]
Expand Down Expand Up @@ -213,6 +292,32 @@ fn quote_code_fragments() {
check_errors(src);
}

#[test]
fn quote_code_fragments_no_failure() {
let src = r#"
fn main() {
comptime {
concat!(quote { assert( }, quote { true); });
}
}

comptime fn concat(a: Quoted, b: Quoted) -> Quoted {
quote { $a $b }
}
"#;

let expanded = assert_no_errors_and_to_string(src);
insta::assert_snapshot!(expanded, @r"
fn main() {
()
}

comptime fn concat(a: Quoted, b: Quoted) -> Quoted {
quote { $a $b }
}
");
}

#[test]
fn attempt_to_add_with_overflow_at_comptime() {
let src = r#"
Expand Down
3 changes: 0 additions & 3 deletions tooling/nargo_expand/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ license.workspace = true
workspace = true

[dependencies]
fm.workspace = true
nargo.workspace = true
nargo_fmt.workspace = true
noirc_driver.workspace = true
noirc_errors.workspace = true
noirc_frontend.workspace = true

[dev-dependencies]
Loading
Loading