From bf7a36df9e0dd432d484825444ebb304c6694071 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Tue, 5 Dec 2023 14:57:50 +0000 Subject: [PATCH 01/12] feat: add `prelude.nr` --- .../src/hir/def_collector/dc_crate.rs | 9 ++- .../src/hir/def_collector/dc_mod.rs | 25 +++++++- .../src/hir/def_map/item_scope.rs | 60 ++++++++++++------- .../src/hir/def_map/module_data.rs | 13 ++-- .../src/hir/def_map/namespace.rs | 8 +-- .../src/hir/resolution/import.rs | 17 +++++- .../src/hir/resolution/path_resolver.rs | 7 ++- noir_stdlib/src/lib.nr | 2 + noir_stdlib/src/prelude.nr | 2 + .../execution_success/prelude/Nargo.toml | 7 +++ .../execution_success/prelude/src/main.nr | 14 +++++ 11 files changed, 123 insertions(+), 41 deletions(-) create mode 100644 noir_stdlib/src/prelude.nr create mode 100644 tooling/nargo_cli/tests/execution_success/prelude/Nargo.toml create mode 100644 tooling/nargo_cli/tests/execution_success/prelude/src/main.nr diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 86122530cde..fd679f2168a 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -264,10 +264,15 @@ impl DefCollector { for resolved_import in resolved { let name = resolved_import.name; for ns in resolved_import.resolved_namespace.iter_defs() { - let result = current_def_map.modules[resolved_import.module_scope.0] - .import(name.clone(), ns); + let result = current_def_map.modules[resolved_import.module_scope.0].import( + name.clone(), + ns, + resolved_import.is_prelude, + ); if let Err((first_def, second_def)) = result { + dbg!((&first_def, &second_def)); + let err = DefCollectorErrorKind::Duplicate { typ: DuplicateType::Import, first_def, diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 2f79333620e..77ce003f4b2 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -2,7 +2,7 @@ use std::vec; use acvm::acir::acir_field::FieldOptions; use fm::FileId; -use noirc_errors::Location; +use noirc_errors::{Location, Span}; use crate::{ graph::CrateId, @@ -10,7 +10,7 @@ use crate::{ node_interner::{FunctionModifiers, TraitId, TypeAliasId}, parser::{SortedModule, SortedSubModule}, FunctionDefinition, Ident, LetStatement, NoirFunction, NoirStruct, NoirTrait, NoirTraitImpl, - NoirTypeAlias, TraitImplItem, TraitItem, TypeImpl, + NoirTypeAlias, Path, PathKind, TraitImplItem, TraitItem, TypeImpl, }; use super::{ @@ -44,6 +44,26 @@ pub fn collect_defs( ) -> Vec<(CompilationError, FileId)> { let mut collector = ModCollector { def_collector, file_id, module_id }; let mut errors: Vec<(CompilationError, FileId)> = vec![]; + + if !crate_id.is_stdlib() { + let head: Vec<_> = "std::prelude" + .split("::") + .map(|segment| Ident::new(segment.into(), Span::default())) + .collect(); + + for tail in ["Vec", "Option"] { + let mut segments = head.clone(); + segments.push(Ident::new(tail.into(), Span::default())); + + collector.def_collector.collected_imports.push(ImportDirective { + module_id: collector.module_id, + path: Path { segments, kind: PathKind::Dep, span: Span::default() }, + alias: None, + is_prelude: true, + }); + } + } + // First resolve the module declarations for decl in ast.module_decls { errors.extend(collector.parse_module_declaration(context, &decl, crate_id)); @@ -57,6 +77,7 @@ pub fn collect_defs( module_id: collector.module_id, path: import.path, alias: import.alias, + is_prelude: false, }); } diff --git a/compiler/noirc_frontend/src/hir/def_map/item_scope.rs b/compiler/noirc_frontend/src/hir/def_map/item_scope.rs index 42cca550651..0589bfa2520 100644 --- a/compiler/noirc_frontend/src/hir/def_map/item_scope.rs +++ b/compiler/noirc_frontend/src/hir/def_map/item_scope.rs @@ -12,8 +12,9 @@ pub enum Visibility { #[derive(Default, Debug, PartialEq, Eq)] pub struct ItemScope { - types: HashMap, (ModuleDefId, Visibility)>>, - values: HashMap, (ModuleDefId, Visibility)>>, + types: HashMap, (ModuleDefId, Visibility, bool /*is_prelude*/)>>, + values: + HashMap, (ModuleDefId, Visibility, bool /*is_prelude*/)>>, defs: Vec, } @@ -25,7 +26,7 @@ impl ItemScope { mod_def: ModuleDefId, trait_id: Option, ) -> Result<(), (Ident, Ident)> { - self.add_item_to_namespace(name, mod_def, trait_id)?; + self.add_item_to_namespace(name, mod_def, trait_id, false)?; self.defs.push(mod_def); Ok(()) } @@ -38,25 +39,34 @@ impl ItemScope { name: Ident, mod_def: ModuleDefId, trait_id: Option, + is_prelude: bool, ) -> Result<(), (Ident, Ident)> { - let add_item = - |map: &mut HashMap, (ModuleDefId, Visibility)>>| { - if let Entry::Occupied(mut o) = map.entry(name.clone()) { - let trait_hashmap = o.get_mut(); - if let Entry::Occupied(_) = trait_hashmap.entry(trait_id) { - let old_ident = o.key(); - Err((old_ident.clone(), name)) - } else { - trait_hashmap.insert(trait_id, (mod_def, Visibility::Public)); + let add_item = |map: &mut HashMap< + Ident, + HashMap, (ModuleDefId, Visibility, bool)>, + >| { + if let Entry::Occupied(mut o) = map.entry(name.clone()) { + let trait_hashmap = o.get_mut(); + if let Entry::Occupied(n) = trait_hashmap.entry(trait_id) { + let is_prelude = n.get().2; + let old_ident = o.key(); + + if is_prelude { Ok(()) + } else { + Err((old_ident.clone(), name)) } } else { - let mut trait_hashmap = HashMap::new(); - trait_hashmap.insert(trait_id, (mod_def, Visibility::Public)); - map.insert(name, trait_hashmap); + trait_hashmap.insert(trait_id, (mod_def, Visibility::Public, is_prelude)); Ok(()) } - }; + } else { + let mut trait_hashmap = HashMap::new(); + trait_hashmap.insert(trait_id, (mod_def, Visibility::Public, is_prelude)); + map.insert(name, trait_hashmap); + Ok(()) + } + }; match mod_def { ModuleDefId::ModuleId(_) => add_item(&mut self.types), @@ -69,7 +79,7 @@ impl ItemScope { } pub fn find_module_with_name(&self, mod_name: &Ident) -> Option<&ModuleId> { - let (module_def, _) = self.types.get(mod_name)?.get(&None)?; + let (module_def, _, _) = self.types.get(mod_name)?.get(&None)?; match module_def { ModuleDefId::ModuleId(id) => Some(id), _ => None, @@ -81,13 +91,13 @@ impl ItemScope { // methods introduced without trait take priority and hide methods with the same name that come from a trait let a = trait_hashmap.get(&None); match a { - Some((module_def, _)) => match module_def { + Some((module_def, _, _)) => match module_def { ModuleDefId::FunctionId(id) => Some(*id), _ => None, }, None => { if trait_hashmap.len() == 1 { - let (module_def, _) = trait_hashmap.get(trait_hashmap.keys().last()?)?; + let (module_def, _, _) = trait_hashmap.get(trait_hashmap.keys().last()?)?; match module_def { ModuleDefId::FunctionId(id) => Some(*id), _ => None, @@ -105,7 +115,7 @@ impl ItemScope { func_name: &Ident, trait_id: &Option, ) -> Option { - let (module_def, _) = self.values.get(func_name)?.get(trait_id)?; + let (module_def, _, _) = self.values.get(func_name)?.get(trait_id)?; match module_def { ModuleDefId::FunctionId(id) => Some(*id), _ => None, @@ -116,7 +126,7 @@ impl ItemScope { // Names, not associated with traits are searched first. If not found, we search for name, coming from a trait. // If we find only one name from trait, we return it. If there are multiple traits, providing the same name, we return None. let find_name_in = - |a: &HashMap, (ModuleDefId, Visibility)>>| { + |a: &HashMap, (ModuleDefId, Visibility, bool)>>| { if let Some(t) = a.get(name) { if let Some(tt) = t.get(&None) { Some(*tt) @@ -148,11 +158,15 @@ impl ItemScope { self.defs.clone() } - pub fn types(&self) -> &HashMap, (ModuleDefId, Visibility)>> { + pub fn types( + &self, + ) -> &HashMap, (ModuleDefId, Visibility, bool)>> { &self.types } - pub fn values(&self) -> &HashMap, (ModuleDefId, Visibility)>> { + pub fn values( + &self, + ) -> &HashMap, (ModuleDefId, Visibility, bool)>> { &self.values } diff --git a/compiler/noirc_frontend/src/hir/def_map/module_data.rs b/compiler/noirc_frontend/src/hir/def_map/module_data.rs index 29b11e92c01..0f7da804513 100644 --- a/compiler/noirc_frontend/src/hir/def_map/module_data.rs +++ b/compiler/noirc_frontend/src/hir/def_map/module_data.rs @@ -104,8 +104,13 @@ impl ModuleData { self.scope.find_func_with_name(name) } - pub fn import(&mut self, name: Ident, id: ModuleDefId) -> Result<(), (Ident, Ident)> { - self.scope.add_item_to_namespace(name, id, None) + pub fn import( + &mut self, + name: Ident, + id: ModuleDefId, + is_prelude: bool, + ) -> Result<(), (Ident, Ident)> { + self.scope.add_item_to_namespace(name, id, None, is_prelude) } pub fn find_name(&self, name: &Ident) -> PerNs { @@ -113,12 +118,12 @@ impl ModuleData { } pub fn type_definitions(&self) -> impl Iterator + '_ { - self.definitions.types().values().flat_map(|a| a.values().map(|(id, _)| *id)) + self.definitions.types().values().flat_map(|a| a.values().map(|(id, _, _)| *id)) } /// Return an iterator over all definitions defined within this module, /// excluding any type definitions. pub fn value_definitions(&self) -> impl Iterator + '_ { - self.definitions.values().values().flat_map(|a| a.values().map(|(id, _)| *id)) + self.definitions.values().values().flat_map(|a| a.values().map(|(id, _, _)| *id)) } } diff --git a/compiler/noirc_frontend/src/hir/def_map/namespace.rs b/compiler/noirc_frontend/src/hir/def_map/namespace.rs index 9221b389d84..ca14d9f8617 100644 --- a/compiler/noirc_frontend/src/hir/def_map/namespace.rs +++ b/compiler/noirc_frontend/src/hir/def_map/namespace.rs @@ -3,13 +3,13 @@ use super::{item_scope::Visibility, ModuleDefId}; // This works exactly the same as in r-a, just simplified #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub struct PerNs { - pub types: Option<(ModuleDefId, Visibility)>, - pub values: Option<(ModuleDefId, Visibility)>, + pub types: Option<(ModuleDefId, Visibility, bool)>, + pub values: Option<(ModuleDefId, Visibility, bool)>, } impl PerNs { pub fn types(t: ModuleDefId) -> PerNs { - PerNs { types: Some((t, Visibility::Public)), values: None } + PerNs { types: Some((t, Visibility::Public, false)), values: None } } pub fn take_types(self) -> Option { @@ -24,7 +24,7 @@ impl PerNs { self.types.map(|it| it.0).into_iter().chain(self.values.map(|it| it.0)) } - pub fn iter_items(self) -> impl Iterator { + pub fn iter_items(self) -> impl Iterator { self.types.into_iter().chain(self.values) } diff --git a/compiler/noirc_frontend/src/hir/resolution/import.rs b/compiler/noirc_frontend/src/hir/resolution/import.rs index 5b59dcd2241..41fdac746bd 100644 --- a/compiler/noirc_frontend/src/hir/resolution/import.rs +++ b/compiler/noirc_frontend/src/hir/resolution/import.rs @@ -12,6 +12,7 @@ pub struct ImportDirective { pub module_id: LocalModuleId, pub path: Path, pub alias: Option, + pub is_prelude: bool, } pub type PathResolution = Result; @@ -30,6 +31,7 @@ pub struct ResolvedImport { pub resolved_namespace: PerNs, // The module which we must add the resolved namespace to pub module_scope: LocalModuleId, + pub is_prelude: bool, } impl From for CustomDiagnostic { @@ -66,7 +68,12 @@ pub fn resolve_imports( .map_err(|error| (error, module_scope))?; let name = resolve_path_name(&import_directive); - Ok(ResolvedImport { name, resolved_namespace, module_scope }) + Ok(ResolvedImport { + name, + resolved_namespace, + module_scope, + is_prelude: import_directive.is_prelude, + }) }) } @@ -207,8 +214,12 @@ fn resolve_external_dep( kind: PathKind::Plain, span: Span::default(), }; - let dep_directive = - ImportDirective { module_id: dep_module.local_id, path, alias: directive.alias.clone() }; + let dep_directive = ImportDirective { + module_id: dep_module.local_id, + path, + alias: directive.alias.clone(), + is_prelude: false, + }; let dep_def_map = def_maps.get(&dep_module.krate).unwrap(); diff --git a/compiler/noirc_frontend/src/hir/resolution/path_resolver.rs b/compiler/noirc_frontend/src/hir/resolution/path_resolver.rs index 4c16edd56f1..4c5fa3bceef 100644 --- a/compiler/noirc_frontend/src/hir/resolution/path_resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/path_resolver.rs @@ -57,14 +57,15 @@ pub fn resolve_path( path: Path, ) -> Result { // lets package up the path into an ImportDirective and resolve it using that - let import = ImportDirective { module_id: module_id.local_id, path, alias: None }; + let import = + ImportDirective { module_id: module_id.local_id, path, alias: None, is_prelude: false }; let allow_referencing_contracts = allow_referencing_contracts(def_maps, module_id.krate, module_id.local_id); let def_map = &def_maps[&module_id.krate]; let ns = resolve_path_to_ns(&import, def_map, def_maps, allow_referencing_contracts)?; - let function = ns.values.map(|(id, _)| id); - let id = function.or_else(|| ns.types.map(|(id, _)| id)); + let function = ns.values.map(|(id, _, _)| id); + let id = function.or_else(|| ns.types.map(|(id, _, _)| id)); Ok(id.expect("Found empty namespace")) } diff --git a/noir_stdlib/src/lib.nr b/noir_stdlib/src/lib.nr index 8d878eecbb3..94225b9f1e8 100644 --- a/noir_stdlib/src/lib.nr +++ b/noir_stdlib/src/lib.nr @@ -19,6 +19,8 @@ mod compat; mod option; mod string; mod test; +mod prelude; + // 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 #[oracle(println)] diff --git a/noir_stdlib/src/prelude.nr b/noir_stdlib/src/prelude.nr new file mode 100644 index 00000000000..973592c99a4 --- /dev/null +++ b/noir_stdlib/src/prelude.nr @@ -0,0 +1,2 @@ +use crate::collections::vec::Vec; +use crate::option::Option; diff --git a/tooling/nargo_cli/tests/execution_success/prelude/Nargo.toml b/tooling/nargo_cli/tests/execution_success/prelude/Nargo.toml new file mode 100644 index 00000000000..35f223bce02 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/prelude/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "prelude" +type = "bin" +authors = [""] +compiler_version = ">=0.20.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr b/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr new file mode 100644 index 00000000000..a2a8f995af5 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr @@ -0,0 +1,14 @@ +fn main(x: Field, y: pub Field) { + let xs = Vec::new(); + let option = Option::none(); +} + +mod a { + use dep::std::collections::vec::Vec; + use dep::std::option::Option; + + fn main(x: Field, y: pub Field) { + let xs = Vec::new(); + let option = Option::none(); + } +} From db0f2018443dc12a2fbb213525e91808f4eca150 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Wed, 6 Dec 2023 13:19:25 +0000 Subject: [PATCH 02/12] remove dbg! --- .../src/hir/def_collector/dc_crate.rs | 2 - .../src/hir/def_map/item_scope.rs | 45 ++++++++----------- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index fd679f2168a..e8d8f8e16ea 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -271,8 +271,6 @@ impl DefCollector { ); if let Err((first_def, second_def)) = result { - dbg!((&first_def, &second_def)); - let err = DefCollectorErrorKind::Duplicate { typ: DuplicateType::Import, first_def, diff --git a/compiler/noirc_frontend/src/hir/def_map/item_scope.rs b/compiler/noirc_frontend/src/hir/def_map/item_scope.rs index 0589bfa2520..250c6cbf02b 100644 --- a/compiler/noirc_frontend/src/hir/def_map/item_scope.rs +++ b/compiler/noirc_frontend/src/hir/def_map/item_scope.rs @@ -5,6 +5,8 @@ use crate::{ }; use std::collections::{hash_map::Entry, HashMap}; +type Scope = HashMap, (ModuleDefId, Visibility, bool /*is_prelude*/)>; + #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum Visibility { Public, @@ -12,9 +14,8 @@ pub enum Visibility { #[derive(Default, Debug, PartialEq, Eq)] pub struct ItemScope { - types: HashMap, (ModuleDefId, Visibility, bool /*is_prelude*/)>>, - values: - HashMap, (ModuleDefId, Visibility, bool /*is_prelude*/)>>, + types: HashMap, + values: HashMap, defs: Vec, } @@ -41,14 +42,11 @@ impl ItemScope { trait_id: Option, is_prelude: bool, ) -> Result<(), (Ident, Ident)> { - let add_item = |map: &mut HashMap< - Ident, - HashMap, (ModuleDefId, Visibility, bool)>, - >| { + let add_item = |map: &mut HashMap| { if let Entry::Occupied(mut o) = map.entry(name.clone()) { let trait_hashmap = o.get_mut(); - if let Entry::Occupied(n) = trait_hashmap.entry(trait_id) { - let is_prelude = n.get().2; + if let Entry::Occupied(mut n) = trait_hashmap.entry(trait_id) { + let is_prelude = std::mem::take(&mut n.get_mut().2); let old_ident = o.key(); if is_prelude { @@ -125,20 +123,19 @@ impl ItemScope { pub fn find_name(&self, name: &Ident) -> PerNs { // Names, not associated with traits are searched first. If not found, we search for name, coming from a trait. // If we find only one name from trait, we return it. If there are multiple traits, providing the same name, we return None. - let find_name_in = - |a: &HashMap, (ModuleDefId, Visibility, bool)>>| { - if let Some(t) = a.get(name) { - if let Some(tt) = t.get(&None) { - Some(*tt) - } else if t.len() == 1 { - t.values().last().cloned() - } else { - None - } + let find_name_in = |a: &HashMap| { + if let Some(t) = a.get(name) { + if let Some(tt) = t.get(&None) { + Some(*tt) + } else if t.len() == 1 { + t.values().last().cloned() } else { None } - }; + } else { + None + } + }; PerNs { types: find_name_in(&self.types), values: find_name_in(&self.values) } } @@ -158,15 +155,11 @@ impl ItemScope { self.defs.clone() } - pub fn types( - &self, - ) -> &HashMap, (ModuleDefId, Visibility, bool)>> { + pub fn types(&self) -> &HashMap { &self.types } - pub fn values( - &self, - ) -> &HashMap, (ModuleDefId, Visibility, bool)>> { + pub fn values(&self) -> &HashMap { &self.values } From fedd62bfdb450c3c94b458bb3a1a8ae5b1aa49b4 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Thu, 7 Dec 2023 11:59:28 +0000 Subject: [PATCH 03/12] chore: fix prelude import --- .../src/hir/def_collector/dc_crate.rs | 51 +++++++++++++++++-- .../src/hir/def_collector/dc_mod.rs | 23 +-------- .../src/hir/def_map/module_data.rs | 4 ++ .../src/hir/def_map/module_def.rs | 7 +++ 4 files changed, 60 insertions(+), 25 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index e8d8f8e16ea..034cf60a54a 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -7,8 +7,8 @@ use crate::hir::resolution::errors::ResolverError; use crate::hir::resolution::import::{resolve_imports, ImportDirective}; use crate::hir::resolution::resolver::Resolver; use crate::hir::resolution::{ - collect_impls, collect_trait_impls, resolve_free_functions, resolve_globals, resolve_impls, - resolve_structs, resolve_trait_by_path, resolve_trait_impls, resolve_traits, + collect_impls, collect_trait_impls, path_resolver, resolve_free_functions, resolve_globals, + resolve_impls, resolve_structs, resolve_trait_by_path, resolve_trait_impls, resolve_traits, resolve_type_aliases, }; use crate::hir::type_check::{type_check_func, TypeCheckError, TypeChecker}; @@ -19,8 +19,9 @@ use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId, TraitId, Type use crate::parser::{ParserError, SortedModule}; use crate::{ - ExpressionKind, LetStatement, Literal, NoirFunction, NoirStruct, NoirTrait, NoirTypeAlias, - Path, Type, UnresolvedGenerics, UnresolvedTraitConstraint, UnresolvedType, + ExpressionKind, Ident, LetStatement, Literal, NoirFunction, NoirStruct, NoirTrait, + NoirTypeAlias, Path, PathKind, Type, UnresolvedGenerics, UnresolvedTraitConstraint, + UnresolvedType, }; use fm::FileId; use iter_extended::vecmap; @@ -246,6 +247,8 @@ impl DefCollector { // Add the current crate to the collection of DefMaps context.def_maps.insert(crate_id, def_collector.def_map); + inject_prelude(crate_id, context, crate_root, &mut def_collector.collected_imports); + // Resolve unresolved imports collected from the crate let (resolved, unresolved_imports) = resolve_imports(crate_id, def_collector.collected_imports, &context.def_maps); @@ -361,6 +364,46 @@ impl DefCollector { } } +fn inject_prelude( + crate_id: CrateId, + context: &mut Context, + crate_root: LocalModuleId, + collected_imports: &mut Vec, +) { + let segments: Vec<_> = "std::prelude" + .split("::") + .map(|segment| crate::Ident::new(segment.into(), Span::default())) + .collect(); + + let path = + Path { segments: segments.clone(), kind: crate::PathKind::Dep, span: Span::default() }; + + if !crate_id.is_stdlib() { + if let Ok(module_def) = path_resolver::resolve_path( + &context.def_maps, + ModuleId { krate: crate_id, local_id: crate_root }, + path, + ) { + // let imports = Vec::new(); + + let module_id = module_def.as_module().expect("std::prelude is module"); + let prelude = context.module(module_id).scope().types().keys(); + + for path in prelude { + let mut segments = segments.clone(); + segments.push(Ident::new(path.to_string(), Span::default())); + + collected_imports.push(ImportDirective { + module_id: crate_root, + path: Path { segments, kind: PathKind::Dep, span: Span::default() }, + alias: None, + is_prelude: true, + }); + } + } + } +} + /// Separate the globals Vec into two. The first element in the tuple will be the /// literal globals, except for arrays, and the second will be all other globals. /// We exclude array literals as they can contain complex types diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 77ce003f4b2..ee81531ad74 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -2,7 +2,7 @@ use std::vec; use acvm::acir::acir_field::FieldOptions; use fm::FileId; -use noirc_errors::{Location, Span}; +use noirc_errors::Location; use crate::{ graph::CrateId, @@ -10,7 +10,7 @@ use crate::{ node_interner::{FunctionModifiers, TraitId, TypeAliasId}, parser::{SortedModule, SortedSubModule}, FunctionDefinition, Ident, LetStatement, NoirFunction, NoirStruct, NoirTrait, NoirTraitImpl, - NoirTypeAlias, Path, PathKind, TraitImplItem, TraitItem, TypeImpl, + NoirTypeAlias, TraitImplItem, TraitItem, TypeImpl, }; use super::{ @@ -45,25 +45,6 @@ pub fn collect_defs( let mut collector = ModCollector { def_collector, file_id, module_id }; let mut errors: Vec<(CompilationError, FileId)> = vec![]; - if !crate_id.is_stdlib() { - let head: Vec<_> = "std::prelude" - .split("::") - .map(|segment| Ident::new(segment.into(), Span::default())) - .collect(); - - for tail in ["Vec", "Option"] { - let mut segments = head.clone(); - segments.push(Ident::new(tail.into(), Span::default())); - - collector.def_collector.collected_imports.push(ImportDirective { - module_id: collector.module_id, - path: Path { segments, kind: PathKind::Dep, span: Span::default() }, - alias: None, - is_prelude: true, - }); - } - } - // First resolve the module declarations for decl in ast.module_decls { errors.extend(collector.parse_module_declaration(context, &decl, crate_id)); diff --git a/compiler/noirc_frontend/src/hir/def_map/module_data.rs b/compiler/noirc_frontend/src/hir/def_map/module_data.rs index 0f7da804513..fbb5e5cf741 100644 --- a/compiler/noirc_frontend/src/hir/def_map/module_data.rs +++ b/compiler/noirc_frontend/src/hir/def_map/module_data.rs @@ -41,6 +41,10 @@ impl ModuleData { } } + pub(crate) fn scope(&self) -> &ItemScope { + &self.scope + } + fn declare( &mut self, name: Ident, diff --git a/compiler/noirc_frontend/src/hir/def_map/module_def.rs b/compiler/noirc_frontend/src/hir/def_map/module_def.rs index 659d7712ab4..3e5629639fa 100644 --- a/compiler/noirc_frontend/src/hir/def_map/module_def.rs +++ b/compiler/noirc_frontend/src/hir/def_map/module_def.rs @@ -61,6 +61,13 @@ impl ModuleDefId { ModuleDefId::GlobalId(_) => "global", } } + + pub fn as_module(&self) -> Option { + match self { + Self::ModuleId(v) => Some(*v), + _ => None, + } + } } impl From for ModuleDefId { From f5b58cf7cef1bff78e3db56cdc34971e63726d16 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Thu, 7 Dec 2023 12:15:57 +0000 Subject: [PATCH 04/12] chore: fix? --- .../src/hir/def_collector/dc_crate.rs | 17 +++++++++-------- .../src/hir/def_map/item_scope.rs | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 034cf60a54a..3a56ec1485f 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -384,8 +384,6 @@ fn inject_prelude( ModuleId { krate: crate_id, local_id: crate_root }, path, ) { - // let imports = Vec::new(); - let module_id = module_def.as_module().expect("std::prelude is module"); let prelude = context.module(module_id).scope().types().keys(); @@ -393,12 +391,15 @@ fn inject_prelude( let mut segments = segments.clone(); segments.push(Ident::new(path.to_string(), Span::default())); - collected_imports.push(ImportDirective { - module_id: crate_root, - path: Path { segments, kind: PathKind::Dep, span: Span::default() }, - alias: None, - is_prelude: true, - }); + collected_imports.insert( + 0, + ImportDirective { + module_id: crate_root, + path: Path { segments, kind: PathKind::Dep, span: Span::default() }, + alias: None, + is_prelude: true, + }, + ); } } } diff --git a/compiler/noirc_frontend/src/hir/def_map/item_scope.rs b/compiler/noirc_frontend/src/hir/def_map/item_scope.rs index 250c6cbf02b..d5724f3be9f 100644 --- a/compiler/noirc_frontend/src/hir/def_map/item_scope.rs +++ b/compiler/noirc_frontend/src/hir/def_map/item_scope.rs @@ -46,7 +46,7 @@ impl ItemScope { if let Entry::Occupied(mut o) = map.entry(name.clone()) { let trait_hashmap = o.get_mut(); if let Entry::Occupied(mut n) = trait_hashmap.entry(trait_id) { - let is_prelude = std::mem::take(&mut n.get_mut().2); + let is_prelude = std::mem::replace(&mut n.get_mut().2, is_prelude); let old_ident = o.key(); if is_prelude { From c52ec9ec7ff98c3d6e87ff8651be4595c0e52de9 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Fri, 8 Dec 2023 01:58:20 +0000 Subject: [PATCH 05/12] chore: submodules work? --- .../noirc_frontend/src/hir/def_collector/dc_crate.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 3a56ec1485f..92f049d1d47 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -244,10 +244,19 @@ impl DefCollector { context, )); + let submodules = vecmap(def_collector.def_map.modules().iter(), |(index, _)| index); // Add the current crate to the collection of DefMaps context.def_maps.insert(crate_id, def_collector.def_map); inject_prelude(crate_id, context, crate_root, &mut def_collector.collected_imports); + for submodule in submodules { + inject_prelude( + crate_id, + context, + LocalModuleId(submodule), + &mut def_collector.collected_imports, + ); + } // Resolve unresolved imports collected from the crate let (resolved, unresolved_imports) = From 9d204bae67d0e660febc0a7f948ff0a992d83e2f Mon Sep 17 00:00:00 2001 From: kek kek kek Date: Mon, 11 Dec 2023 02:20:22 -0800 Subject: [PATCH 06/12] chore: `&mut Context` -> `&Context` Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> --- compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index f1765468429..2c61d2f9b02 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -375,7 +375,7 @@ impl DefCollector { fn inject_prelude( crate_id: CrateId, - context: &mut Context, + context: &Context, crate_root: LocalModuleId, collected_imports: &mut Vec, ) { From e101772bf9b564be80f65e858f8df3918e3e5fde Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Mon, 11 Dec 2023 10:46:36 +0000 Subject: [PATCH 07/12] chore: 'print', 'println', and 'assert_constant' functions to the prelude --- noir_stdlib/src/prelude.nr | 1 + 1 file changed, 1 insertion(+) diff --git a/noir_stdlib/src/prelude.nr b/noir_stdlib/src/prelude.nr index 973592c99a4..f33a1f7e7f1 100644 --- a/noir_stdlib/src/prelude.nr +++ b/noir_stdlib/src/prelude.nr @@ -1,2 +1,3 @@ use crate::collections::vec::Vec; use crate::option::Option; +use crate::{print, println, assert_constant}; From 7ef95007829661ee5fd9eac8ac139ca5e33dc253 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Mon, 11 Dec 2023 12:16:30 +0000 Subject: [PATCH 08/12] chore: fix import functions --- compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs | 2 +- compiler/noirc_frontend/src/hir/def_map/item_scope.rs | 4 ++++ tooling/nargo_cli/tests/execution_success/prelude/src/main.nr | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 2c61d2f9b02..3582b5de9a2 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -394,7 +394,7 @@ fn inject_prelude( path, ) { let module_id = module_def.as_module().expect("std::prelude is module"); - let prelude = context.module(module_id).scope().types().keys(); + let prelude = context.module(module_id).scope().names(); for path in prelude { let mut segments = segments.clone(); diff --git a/compiler/noirc_frontend/src/hir/def_map/item_scope.rs b/compiler/noirc_frontend/src/hir/def_map/item_scope.rs index d5724f3be9f..523def89518 100644 --- a/compiler/noirc_frontend/src/hir/def_map/item_scope.rs +++ b/compiler/noirc_frontend/src/hir/def_map/item_scope.rs @@ -151,6 +151,10 @@ impl ItemScope { } } + pub fn names(&self) -> impl Iterator { + self.types.keys().chain(self.values.keys()) + } + pub fn definitions(&self) -> Vec { self.defs.clone() } diff --git a/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr b/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr index a2a8f995af5..308f3905558 100644 --- a/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr +++ b/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr @@ -1,6 +1,9 @@ fn main(x: Field, y: pub Field) { let xs = Vec::new(); let option = Option::none(); + + print("42\n"); + println("42"); } mod a { From b2aaae0c11d8b4fcbd8923998e86d9d685a4e430 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Mon, 11 Dec 2023 13:58:29 +0000 Subject: [PATCH 09/12] chore: add commet --- tooling/nargo_cli/tests/execution_success/prelude/src/main.nr | 1 + 1 file changed, 1 insertion(+) diff --git a/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr b/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr index 308f3905558..99e4442bcbf 100644 --- a/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr +++ b/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr @@ -7,6 +7,7 @@ fn main(x: Field, y: pub Field) { } mod a { + // We don't want to give an error due to re-importing elements that are already in the prelude. use dep::std::collections::vec::Vec; use dep::std::option::Option; From a18973455b290540359cfbdd4101b70e4f91865a Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Tue, 12 Dec 2023 12:18:42 +0000 Subject: [PATCH 10/12] chore: update test --- .../tests/execution_success/prelude/src/main.nr | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr b/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr index 99e4442bcbf..7ca1b322a59 100644 --- a/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr +++ b/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr @@ -11,7 +11,14 @@ mod a { use dep::std::collections::vec::Vec; use dep::std::option::Option; - fn main(x: Field, y: pub Field) { + fn main() { + let xs = Vec::new(); + let option = Option::none(); + } +} + +mod b { + fn main() { let xs = Vec::new(); let option = Option::none(); } From 5d4fee7768a74b1477fa1ff8188e682d661d92e4 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Tue, 12 Dec 2023 12:58:39 +0000 Subject: [PATCH 11/12] chore: update test --- .../nargo_cli/tests/execution_success/prelude/src/main.nr | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr b/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr index 7ca1b322a59..9bf2ec18f3a 100644 --- a/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr +++ b/tooling/nargo_cli/tests/execution_success/prelude/src/main.nr @@ -10,10 +10,14 @@ mod a { // We don't want to give an error due to re-importing elements that are already in the prelude. use dep::std::collections::vec::Vec; use dep::std::option::Option; + use dep::{print, println}; fn main() { let xs = Vec::new(); let option = Option::none(); + + print("42\n"); + println("42"); } } @@ -21,5 +25,8 @@ mod b { fn main() { let xs = Vec::new(); let option = Option::none(); + + print("42\n"); + println("42"); } } From 6b2442542f947705a48d97452ecfaf70168a35b0 Mon Sep 17 00:00:00 2001 From: kek kek kek Date: Tue, 12 Dec 2023 07:02:20 -0800 Subject: [PATCH 12/12] chore: fix panic message Co-authored-by: kevaundray --- compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index cbc383cd26a..a008874dc80 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -393,7 +393,7 @@ fn inject_prelude( ModuleId { krate: crate_id, local_id: crate_root }, path, ) { - let module_id = module_def.as_module().expect("std::prelude is module"); + let module_id = module_def.as_module().expect("std::prelude should be a module"); let prelude = context.module(module_id).scope().names(); for path in prelude {