Skip to content

Commit

Permalink
chore: Add stdlib to every crate as it is added to graph
Browse files Browse the repository at this point in the history
  • Loading branch information
phated committed Aug 23, 2023
1 parent 182d017 commit 733acb8
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 39 deletions.
50 changes: 18 additions & 32 deletions crates/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ mod program;
pub use contract::{CompiledContract, ContractFunction, ContractFunctionType};
pub use program::CompiledProgram;

const STD_CRATE_NAME: &str = "std";

#[derive(Args, Clone, Debug, Default, Serialize, Deserialize)]
pub struct CompileOptions {
/// Emit debug information for the intermediate SSA IR
Expand Down Expand Up @@ -58,16 +60,30 @@ pub fn compile_file(

/// Adds the file from the file system at `Path` to the crate graph as a root file
pub fn prepare_crate(context: &mut Context, file_name: &Path) -> CrateId {
let path_to_std_lib_file = Path::new(STD_CRATE_NAME).join("lib.nr");
let std_file_id = context.file_manager.add_file(&path_to_std_lib_file).unwrap();
let std_crate_id = context.crate_graph.add_stdlib(std_file_id);

let root_file_id = context.file_manager.add_file(file_name).unwrap();

context.crate_graph.add_crate_root(root_file_id)
let root_crate_id = context.crate_graph.add_crate_root(root_file_id);

add_dep(context, root_crate_id, std_crate_id, STD_CRATE_NAME.parse().unwrap());

root_crate_id
}

// Adds the file from the file system at `Path` to the crate graph
pub fn prepare_dependency(context: &mut Context, file_name: &Path) -> CrateId {
let root_file_id = context.file_manager.add_file(file_name).unwrap();

context.crate_graph.add_crate(root_file_id)
let crate_id = context.crate_graph.add_crate(root_file_id);

// Every dependency has access to stdlib
let std_crate_id = context.stdlib_crate_id();
add_dep(context, crate_id, *std_crate_id, STD_CRATE_NAME.parse().unwrap());

crate_id
}

/// Adds a edge in the crate graph for two crates
Expand All @@ -83,23 +99,6 @@ pub fn add_dep(
.expect("cyclic dependency triggered");
}

/// Propagates a given dependency to every other crate.
pub fn propagate_dep(
context: &mut Context,
dep_to_propagate: CrateId,
dep_to_propagate_name: &CrateName,
) {
let crate_ids: Vec<_> =
context.crate_graph.iter_keys().filter(|crate_id| *crate_id != dep_to_propagate).collect();

for crate_id in crate_ids {
context
.crate_graph
.add_dep(crate_id, dep_to_propagate_name.clone(), dep_to_propagate)
.expect("ice: cyclic error triggered with std library");
}
}

/// Run the lexing, parsing, name resolution, and type checking passes.
///
/// This returns a (possibly empty) vector of any warnings found on success.
Expand All @@ -109,19 +108,6 @@ pub fn check_crate(
crate_id: CrateId,
deny_warnings: bool,
) -> Result<Warnings, ErrorsAndWarnings> {
// Add the stdlib before we check the crate
// TODO: This should actually be done when constructing the driver and then propagated to each dependency when added;
// however, the `create_non_local_crate` panics if you add the stdlib as the first crate in the graph and other
// parts of the code expect the `0` FileID to be the crate root. See also #1681
let std_crate_name = "std";
let path_to_std_lib_file = Path::new(std_crate_name).join("lib.nr");
let root_file_id = context.file_manager.add_file(&path_to_std_lib_file).unwrap();

// You can add any crate type to the crate graph
// but you cannot depend on Binaries
let std_crate = context.crate_graph.add_stdlib(root_file_id);
propagate_dep(context, std_crate, &std_crate_name.parse().unwrap());

let mut errors = vec![];
CrateDefMap::collect_defs(crate_id, context, &mut errors);

Expand Down
7 changes: 7 additions & 0 deletions crates/noirc_frontend/src/graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ impl CrateGraph {
.expect("ICE: A root crate should exist in the CrateGraph")
}

pub fn stdlib_crate_id(&self) -> &CrateId {
self.arena
.keys()
.find(|crate_id| crate_id.is_stdlib())
.expect("Something about no crates in graph")
}

pub fn add_crate_root(&mut self, file_id: FileId) -> CrateId {
for (crate_id, crate_data) in self.arena.iter() {
if crate_id.is_root() {
Expand Down
4 changes: 4 additions & 0 deletions crates/noirc_frontend/src/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ impl Context {
self.crate_graph.root_crate_id()
}

pub fn stdlib_crate_id(&self) -> &CrateId {
self.crate_graph.stdlib_crate_id()
}

// TODO: Decide if we actually need `function_name` and `fully_qualified_function_name`
pub fn function_name(&self, id: &FuncId) -> &str {
self.def_interner.function_name(id)
Expand Down
35 changes: 28 additions & 7 deletions crates/wasm/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use fm::FileManager;
use gloo_utils::format::JsValueSerdeExt;
use log::debug;
use noirc_driver::{
check_crate, compile_contracts, compile_no_check, prepare_crate, prepare_dependency,
propagate_dep, CompileOptions, CompiledContract,
add_dep, check_crate, compile_contracts, compile_no_check, prepare_crate, prepare_dependency,
CompileOptions, CompiledContract,
};
use noirc_frontend::{graph::CrateGraph, hir::Context};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -58,11 +58,32 @@ impl Default for WASMCompileOptions {
}
}

fn add_noir_lib(context: &mut Context, crate_name: &str) {
let path_to_lib = Path::new(&crate_name).join("lib.nr");
let library_crate = prepare_dependency(context, &path_to_lib);

propagate_dep(context, library_crate, &crate_name.parse().unwrap());
fn add_noir_lib(context: &mut Context, library_name: &str) {
let path_to_lib = Path::new(&library_name).join("lib.nr");
let library_crate_id = prepare_dependency(context, &path_to_lib);

add_dep(context, *context.root_crate_id(), library_crate_id, library_name.parse().unwrap());

// TODO: Remove this code that attaches every crate to every other crate as a dependency
let root_crate_id = context.root_crate_id();
let stdlib_crate_id = context.stdlib_crate_id();
let other_crate_ids: Vec<_> = context
.crate_graph
.iter_keys()
.filter(|crate_id| {
// We don't want to attach this crate to itself or stdlib, nor re-attach it to the root crate
crate_id != &library_crate_id
&& crate_id != root_crate_id
&& crate_id != stdlib_crate_id
})
.collect();

for crate_id in other_crate_ids {
context
.crate_graph
.add_dep(crate_id, library_name.parse().unwrap(), library_crate_id)
.expect(&format!("ICE: Cyclic error triggered by {} library", library_name));
}
}

#[wasm_bindgen]
Expand Down

0 comments on commit 733acb8

Please sign in to comment.