From 6f7ea52a0cb4d131640d1c0db34806bac72fdfd1 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Fri, 21 Jul 2023 15:34:02 +0100 Subject: [PATCH 01/33] . --- .../tests/test_data/type_aliases/Nargo.toml | 5 +++ .../tests/test_data/type_aliases/Prover.toml | 1 + .../tests/test_data/type_aliases/main.nr | 8 ++++ crates/noirc_frontend/src/ast/mod.rs | 2 + crates/noirc_frontend/src/ast/type_alias.rs | 26 ++++++++++++ .../src/hir/def_collector/dc_crate.rs | 32 ++++++++++++-- .../src/hir/def_collector/dc_mod.rs | 42 +++++++++++++++++-- .../src/hir/def_map/item_scope.rs | 1 + .../src/hir/def_map/module_data.rs | 6 ++- .../src/hir/def_map/module_def.rs | 31 +++++++++++++- .../src/hir/resolution/import.rs | 1 + .../src/hir/resolution/resolver.rs | 17 +++++++- crates/noirc_frontend/src/node_interner.rs | 27 ++++++++++++ crates/noirc_frontend/src/parser/mod.rs | 15 ++++++- crates/noirc_frontend/src/parser/parser.rs | 25 ++++++++++- 15 files changed, 226 insertions(+), 13 deletions(-) create mode 100644 crates/nargo_cli/tests/test_data/type_aliases/Nargo.toml create mode 100644 crates/nargo_cli/tests/test_data/type_aliases/Prover.toml create mode 100644 crates/nargo_cli/tests/test_data/type_aliases/main.nr create mode 100644 crates/noirc_frontend/src/ast/type_alias.rs diff --git a/crates/nargo_cli/tests/test_data/type_aliases/Nargo.toml b/crates/nargo_cli/tests/test_data/type_aliases/Nargo.toml new file mode 100644 index 00000000000..5082c6e12ec --- /dev/null +++ b/crates/nargo_cli/tests/test_data/type_aliases/Nargo.toml @@ -0,0 +1,5 @@ +[package] +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/crates/nargo_cli/tests/test_data/type_aliases/Prover.toml b/crates/nargo_cli/tests/test_data/type_aliases/Prover.toml new file mode 100644 index 00000000000..07890234a19 --- /dev/null +++ b/crates/nargo_cli/tests/test_data/type_aliases/Prover.toml @@ -0,0 +1 @@ +x = "3" diff --git a/crates/nargo_cli/tests/test_data/type_aliases/main.nr b/crates/nargo_cli/tests/test_data/type_aliases/main.nr new file mode 100644 index 00000000000..6c5ee8ea595 --- /dev/null +++ b/crates/nargo_cli/tests/test_data/type_aliases/main.nr @@ -0,0 +1,8 @@ +use dep::std; + +type foo = u8; + +fn main(x : u8) { + let a: foo = 1; + constrain a != x; +} \ No newline at end of file diff --git a/crates/noirc_frontend/src/ast/mod.rs b/crates/noirc_frontend/src/ast/mod.rs index ed73cce486a..4920c8d9b64 100644 --- a/crates/noirc_frontend/src/ast/mod.rs +++ b/crates/noirc_frontend/src/ast/mod.rs @@ -9,6 +9,7 @@ mod function; mod statement; mod structure; mod traits; +mod type_alias; pub use expression::*; pub use function::*; @@ -17,6 +18,7 @@ use noirc_errors::Span; pub use statement::*; pub use structure::*; pub use traits::*; +pub use type_alias::*; use crate::{ parser::{ParserError, ParserErrorReason}, diff --git a/crates/noirc_frontend/src/ast/type_alias.rs b/crates/noirc_frontend/src/ast/type_alias.rs new file mode 100644 index 00000000000..72dc88efc25 --- /dev/null +++ b/crates/noirc_frontend/src/ast/type_alias.rs @@ -0,0 +1,26 @@ +use crate::{Ident, UnresolvedType}; +use noirc_errors::Span; +use std::fmt::Display; + +/// Ast node for type aliases +#[derive(Clone, Debug)] +pub struct NoirTyAlias { + pub name: Ident, + pub ty: UnresolvedType, + pub span: Span, + // TODO: should probabaly allow generics + // eg. type foo = Vec; + // pub generics: UnresolvedGenerics, +} + +impl NoirTyAlias { + pub fn new(name: Ident, ty: UnresolvedType, span: Span) -> NoirTyAlias { + NoirTyAlias { name, ty, span } + } +} + +impl Display for NoirTyAlias { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "type {} = {}", self.name, self.ty) + } +} diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs index d5fc0251d6e..2bfe3a416b5 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -10,10 +10,10 @@ use crate::hir::resolution::{ }; use crate::hir::type_check::{type_check_func, TypeChecker}; use crate::hir::Context; -use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId}; +use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId, TyAliasId}; use crate::{ - ExpressionKind, Generics, Ident, LetStatement, NoirFunction, NoirStruct, ParsedModule, Shared, - Type, TypeBinding, UnresolvedGenerics, UnresolvedType, + ExpressionKind, Generics, Ident, LetStatement, NoirFunction, NoirStruct, NoirTyAlias, + ParsedModule, Shared, Type, TypeBinding, UnresolvedGenerics, UnresolvedType, }; use fm::FileId; use iter_extended::vecmap; @@ -40,6 +40,12 @@ pub struct UnresolvedStruct { pub struct_def: NoirStruct, } +pub struct UnresolvedTypeAlias { + pub file_id: FileId, + pub module_id: LocalModuleId, + pub type_alias_def: NoirTyAlias, +} + #[derive(Clone)] pub struct UnresolvedGlobal { pub file_id: FileId, @@ -54,6 +60,7 @@ pub struct DefCollector { pub(crate) collected_imports: Vec, pub(crate) collected_functions: Vec, pub(crate) collected_types: HashMap, + pub(crate) collected_type_aliases: HashMap, pub(crate) collected_globals: Vec, pub(crate) collected_impls: ImplMap, } @@ -71,6 +78,7 @@ impl DefCollector { collected_imports: vec![], collected_functions: vec![], collected_types: HashMap::new(), + collected_type_aliases: HashMap::new(), collected_impls: HashMap::new(), collected_globals: vec![], } @@ -159,6 +167,7 @@ impl DefCollector { // Must resolve structs before we resolve globals. resolve_structs(context, def_collector.collected_types, crate_id, errors); + resolve_type_aliases(context, def_collector.collected_type_aliases, crate_id); // We must wait to resolve non-integer globals until after we resolve structs since structs // globals will need to reference the struct type they're initialized to to ensure they are valid. @@ -358,6 +367,23 @@ fn resolve_struct_fields( (generics, fields) } +fn resolve_type_aliases( + context: &mut Context, + type_aliases: HashMap, + crate_id: CrateId, +) { + for (type_id, unresolved_typ) in &type_aliases { + let path_resolver = StandardPathResolver::new(ModuleId { + local_id: unresolved_typ.module_id, + krate: crate_id, + }); + let file = unresolved_typ.file_id; + let ty = Resolver::new(&mut context.def_interner, &path_resolver, &context.def_maps, file) + .resolve_type(unresolved_typ.type_alias_def.ty.clone()); + context.def_interner.push_type_alias(*type_id, ty); + } +} + fn resolve_impls( interner: &mut NodeInterner, crate_id: CrateId, diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs index 2e478b6c040..78a041b5dca 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -2,12 +2,15 @@ use fm::FileId; use noirc_errors::FileDiagnostic; use crate::{ - graph::CrateId, hir::def_collector::dc_crate::UnresolvedStruct, node_interner::StructId, - parser::SubModule, Ident, LetStatement, NoirFunction, NoirStruct, ParsedModule, TypeImpl, + graph::CrateId, + hir::def_collector::dc_crate::UnresolvedStruct, + node_interner::{StructId, TyAliasId}, + parser::SubModule, + Ident, LetStatement, NoirFunction, NoirStruct, NoirTyAlias, ParsedModule, TypeImpl, }; use super::{ - dc_crate::{DefCollector, UnresolvedFunctions, UnresolvedGlobal}, + dc_crate::{DefCollector, UnresolvedFunctions, UnresolvedGlobal, UnresolvedTypeAlias}, errors::DefCollectorErrorKind, }; use crate::hir::def_map::{parse_file, LocalModuleId, ModuleData, ModuleId, ModuleOrigin}; @@ -55,6 +58,8 @@ pub fn collect_defs( collector.collect_structs(ast.types, crate_id, errors); + collector.collect_type_aliases(ast.type_aliases, crate_id, errors); + collector.collect_functions(context, ast.functions, errors); collector.collect_impls(context, ast.impls); @@ -183,6 +188,37 @@ impl<'a> ModCollector<'a> { } } + /// Collect any type aliases definitions declared within the ast. + /// Returns a vector of errors if any type aliases were already defined. + fn collect_type_aliases( + &mut self, + type_aliases: Vec, + krate: CrateId, + errors: &mut Vec, + ) { + for type_alias in type_aliases { + let name = type_alias.name.clone(); + + let ty_alias_id = TyAliasId(ModuleId { krate, local_id: self.module_id }); + // Add the type alias to scope so its path can be looked up later + let result = self.def_collector.def_map.modules[self.module_id.0] + .declare_type_alias(name, ty_alias_id); + + if let Err((first_def, second_def)) = result { + let err = DefCollectorErrorKind::DuplicateFunction { first_def, second_def }; + errors.push(err.into_file_diagnostic(self.file_id)); + } + + // And store the TypeId -> TypeAlias mapping somewhere it is reachable + let unresolved = UnresolvedTypeAlias { + file_id: self.file_id, + module_id: self.module_id, + type_alias_def: type_alias, + }; + self.def_collector.collected_type_aliases.insert(ty_alias_id, unresolved); + } + } + fn collect_submodules( &mut self, context: &mut Context, diff --git a/crates/noirc_frontend/src/hir/def_map/item_scope.rs b/crates/noirc_frontend/src/hir/def_map/item_scope.rs index 52201f7ade3..760088a3b7e 100644 --- a/crates/noirc_frontend/src/hir/def_map/item_scope.rs +++ b/crates/noirc_frontend/src/hir/def_map/item_scope.rs @@ -48,6 +48,7 @@ impl ItemScope { ModuleDefId::ModuleId(_) => add_item(&mut self.types), ModuleDefId::FunctionId(_) => add_item(&mut self.values), ModuleDefId::TypeId(_) => add_item(&mut self.types), + ModuleDefId::TypeAliasId(_) => add_item(&mut self.types), ModuleDefId::GlobalId(_) => add_item(&mut self.values), } } diff --git a/crates/noirc_frontend/src/hir/def_map/module_data.rs b/crates/noirc_frontend/src/hir/def_map/module_data.rs index 20906885ad9..e2960a7c4c3 100644 --- a/crates/noirc_frontend/src/hir/def_map/module_data.rs +++ b/crates/noirc_frontend/src/hir/def_map/module_data.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use fm::FileId; use crate::{ - node_interner::{FuncId, StmtId, StructId}, + node_interner::{FuncId, StmtId, StructId, TyAliasId}, Ident, }; @@ -65,6 +65,10 @@ impl ModuleData { self.declare(name, ModuleDefId::TypeId(id)) } + pub fn declare_type_alias(&mut self, name: Ident, id: TyAliasId) -> Result<(), (Ident, Ident)> { + self.declare(name, id.into()) + } + pub fn declare_child_module( &mut self, name: Ident, diff --git a/crates/noirc_frontend/src/hir/def_map/module_def.rs b/crates/noirc_frontend/src/hir/def_map/module_def.rs index 399ee15700c..ce67cda72a5 100644 --- a/crates/noirc_frontend/src/hir/def_map/module_def.rs +++ b/crates/noirc_frontend/src/hir/def_map/module_def.rs @@ -1,4 +1,4 @@ -use crate::node_interner::{FuncId, StmtId, StructId}; +use crate::node_interner::{FuncId, StmtId, StructId, TyAliasId}; use super::ModuleId; @@ -8,6 +8,7 @@ pub enum ModuleDefId { ModuleId(ModuleId), FunctionId(FuncId), TypeId(StructId), + TypeAliasId(TyAliasId), GlobalId(StmtId), } @@ -26,6 +27,13 @@ impl ModuleDefId { } } + pub fn as_type_alias(&self) -> Option { + match self { + ModuleDefId::TypeAliasId(type_alias_id) => Some(*type_alias_id), + _ => None, + } + } + pub fn as_global(&self) -> Option { match self { ModuleDefId::GlobalId(stmt_id) => Some(*stmt_id), @@ -39,6 +47,7 @@ impl ModuleDefId { match self { ModuleDefId::FunctionId(_) => "function", ModuleDefId::TypeId(_) => "type", + ModuleDefId::TypeAliasId(_) => "type alias", ModuleDefId::ModuleId(_) => "module", ModuleDefId::GlobalId(_) => "global", } @@ -57,6 +66,12 @@ impl From for ModuleDefId { } } +impl From for ModuleDefId { + fn from(fid: TyAliasId) -> Self { + ModuleDefId::TypeAliasId(fid) + } +} + impl From for ModuleDefId { fn from(stmt_id: StmtId) -> Self { ModuleDefId::GlobalId(stmt_id) @@ -97,6 +112,20 @@ impl TryFromModuleDefId for StructId { } } +impl TryFromModuleDefId for TyAliasId { + fn try_from(id: ModuleDefId) -> Option { + id.as_type_alias() + } + + fn dummy_id() -> Self { + TyAliasId::dummy_id() + } + + fn description() -> String { + "type alias".to_string() + } +} + impl TryFromModuleDefId for StmtId { fn try_from(id: ModuleDefId) -> Option { id.as_global() diff --git a/crates/noirc_frontend/src/hir/resolution/import.rs b/crates/noirc_frontend/src/hir/resolution/import.rs index 0bc7e065adb..50e8be75904 100644 --- a/crates/noirc_frontend/src/hir/resolution/import.rs +++ b/crates/noirc_frontend/src/hir/resolution/import.rs @@ -152,6 +152,7 @@ fn resolve_name_in_module( ModuleDefId::FunctionId(_) => panic!("functions cannot be in the type namespace"), // TODO: If impls are ever implemented, types can be used in a path ModuleDefId::TypeId(id) => id.0, + ModuleDefId::TypeAliasId(_) => panic!("type aliases cannot be in the type namespace"), ModuleDefId::GlobalId(_) => panic!("globals cannot be in the type namespace"), }; diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index f314cd63e44..e201270f605 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -25,7 +25,7 @@ use crate::graph::CrateId; use crate::hir::def_map::{ModuleDefId, TryFromModuleDefId, MAIN_FUNCTION}; use crate::hir_def::stmt::{HirAssignStatement, HirLValue, HirPattern}; use crate::node_interner::{ - DefinitionId, DefinitionKind, ExprId, FuncId, NodeInterner, StmtId, StructId, + DefinitionId, DefinitionKind, ExprId, FuncId, NodeInterner, StmtId, StructId, TyAliasId, }; use crate::{ hir::{def_map::CrateDefMap, resolution::path_resolver::PathResolver}, @@ -391,6 +391,10 @@ impl<'a> Resolver<'a> { } } + if let Some(type_alias_type) = self.lookup_type_alias(path.clone()) { + return type_alias_type; + } + let span = path.span(); match self.lookup_struct_or_error(path) { Some(struct_type) => { @@ -1154,6 +1158,10 @@ impl<'a> Resolver<'a> { self.interner.get_struct(type_id) } + pub fn get_type_alias(&self, type_alias_id: TyAliasId) -> Type { + self.interner.get_type_alias(type_alias_id) + } + fn lookup(&mut self, path: Path) -> Result { let span = path.span(); let id = self.resolve_path(path)?; @@ -1216,6 +1224,13 @@ impl<'a> Resolver<'a> { } } + fn lookup_type_alias(&mut self, path: Path) -> Option { + match self.lookup(path) { + Ok(type_alias_id) => Some(self.get_type_alias(type_alias_id)), + Err(_) => None, + } + } + fn resolve_path(&mut self, path: Path) -> Result { self.path_resolver.resolve(self.def_maps, path).map_err(ResolverError::PathResolutionError) } diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index 69b313fd538..fdd70bf4a7f 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -52,6 +52,12 @@ pub struct NodeInterner { // methods from impls to the type. structs: HashMap>, + // Type Aliases map. + // + // Map type aliases to the actual type. + // When resolving types, check against this map to see if a type alias is defined. + type_aliases: HashMap, + /// Map from ExprId (referring to a Function/Method call) to its corresponding TypeBindings, /// filled out during type checking from instantiated variables. Used during monomorphization /// to map call site types back onto function parameter types, and undo this binding as needed. @@ -137,6 +143,18 @@ impl StructId { } } +#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] +pub struct TyAliasId(pub ModuleId); + +impl TyAliasId { + //dummy id for error reporting + // This can be anything, as the program will ultimately fail + // after resolution + pub fn dummy_id() -> TyAliasId { + TyAliasId(ModuleId { krate: CrateId::dummy_id(), local_id: LocalModuleId::dummy_id() }) + } +} + macro_rules! into_index { ($id_type:ty) => { impl From<$id_type> for Index { @@ -248,6 +266,7 @@ impl Default for NodeInterner { definitions: vec![], id_to_type: HashMap::new(), structs: HashMap::new(), + type_aliases: HashMap::new(), instantiation_bindings: HashMap::new(), field_indices: HashMap::new(), next_type_variable_id: 0, @@ -316,6 +335,10 @@ impl NodeInterner { f(&mut value); } + pub fn push_type_alias(&mut self, type_id: TyAliasId, typ: Type) { + self.type_aliases.insert(type_id, typ); + } + /// Returns the interned statement corresponding to `stmt_id` pub fn update_statement(&mut self, stmt_id: &StmtId, f: impl FnOnce(&mut HirStatement)) { let def = @@ -512,6 +535,10 @@ impl NodeInterner { self.structs[&id].clone() } + pub fn get_type_alias(&self, id: TyAliasId) -> Type { + self.type_aliases[&id].clone() + } + pub fn get_global(&self, stmt_id: &StmtId) -> Option { self.globals.get(stmt_id).cloned() } diff --git a/crates/noirc_frontend/src/parser/mod.rs b/crates/noirc_frontend/src/parser/mod.rs index 9cf9f1e9869..42ef77cb808 100644 --- a/crates/noirc_frontend/src/parser/mod.rs +++ b/crates/noirc_frontend/src/parser/mod.rs @@ -17,8 +17,8 @@ use crate::token::{Keyword, Token}; use crate::{ast::ImportStatement, Expression, NoirStruct}; use crate::{ BlockExpression, ExpressionKind, ForExpression, Ident, IndexExpression, LetStatement, - MethodCallExpression, NoirFunction, NoirTrait, Path, PathKind, Pattern, Recoverable, Statement, - TraitImpl, TypeImpl, UnresolvedType, UseTree, + MethodCallExpression, NoirFunction, NoirTrait, NoirTyAlias, Path, PathKind, Pattern, + Recoverable, Statement, TraitImpl, TypeImpl, UnresolvedType, UseTree, }; use acvm::FieldElement; @@ -43,6 +43,7 @@ pub(crate) enum TopLevelStatement { Trait(NoirTrait), TraitImpl(TraitImpl), Impl(TypeImpl), + TyAlias(NoirTyAlias), SubModule(SubModule), Global(LetStatement), Error, @@ -225,6 +226,7 @@ pub struct ParsedModule { pub traits: Vec, pub trait_impls: Vec, pub impls: Vec, + pub type_aliases: Vec, pub globals: Vec, /// Module declarations like `mod foo;` @@ -264,6 +266,10 @@ impl ParsedModule { self.impls.push(r#impl); } + fn push_type_alias(&mut self, type_alias: NoirTyAlias) { + self.type_aliases.push(type_alias); + } + fn push_import(&mut self, import_stmt: UseTree) { self.imports.extend(import_stmt.desugar(None)); } @@ -463,6 +469,7 @@ impl std::fmt::Display for TopLevelStatement { TopLevelStatement::TraitImpl(i) => i.fmt(f), TopLevelStatement::Struct(s) => s.fmt(f), TopLevelStatement::Impl(i) => i.fmt(f), + TopLevelStatement::TyAlias(t) => t.fmt(f), TopLevelStatement::SubModule(s) => s.fmt(f), TopLevelStatement::Global(c) => c.fmt(f), TopLevelStatement::Error => write!(f, "error"), @@ -496,6 +503,10 @@ impl std::fmt::Display for ParsedModule { write!(f, "{impl_}")?; } + for type_alias in &self.type_aliases { + write!(f, "{type_alias}")?; + } + for submodule in &self.submodules { write!(f, "{submodule}")?; } diff --git a/crates/noirc_frontend/src/parser/parser.rs b/crates/noirc_frontend/src/parser/parser.rs index b44e4536844..47071a35d5a 100644 --- a/crates/noirc_frontend/src/parser/parser.rs +++ b/crates/noirc_frontend/src/parser/parser.rs @@ -36,8 +36,8 @@ use crate::token::{Attribute, Keyword, Token, TokenKind}; use crate::{ BinaryOp, BinaryOpKind, BlockExpression, CompTime, ConstrainStatement, FunctionDefinition, Ident, IfExpression, InfixExpression, LValue, Lambda, Literal, NoirFunction, NoirStruct, - NoirTrait, Path, PathKind, Pattern, Recoverable, TraitConstraint, TraitImpl, TraitImplItem, - TraitItem, TypeImpl, UnaryOp, UnresolvedTypeExpression, UseTree, UseTreeKind, + NoirTrait, NoirTyAlias, Path, PathKind, Pattern, Recoverable, TraitConstraint, TraitImpl, + TraitImplItem, TraitItem, TypeImpl, UnaryOp, UnresolvedTypeExpression, UseTree, UseTreeKind, }; use chumsky::prelude::*; @@ -82,6 +82,7 @@ fn module() -> impl NoirParser { TopLevelStatement::Trait(t) => program.push_trait(t), TopLevelStatement::TraitImpl(t) => program.push_trait_impl(t), TopLevelStatement::Impl(i) => program.push_impl(i), + TopLevelStatement::TyAlias(t) => program.push_type_alias(t), TopLevelStatement::SubModule(s) => program.push_submodule(s), TopLevelStatement::Global(c) => program.push_global(c), TopLevelStatement::Error => (), @@ -108,6 +109,7 @@ fn top_level_statement( trait_definition(), trait_implementation(), implementation(), + type_alias_definition().then_ignore(force(just(Token::Semicolon))), submodule(module_parser.clone()), contract(module_parser), module_declaration().then_ignore(force(just(Token::Semicolon))), @@ -236,6 +238,16 @@ fn struct_definition() -> impl NoirParser { ) } +fn type_alias_definition() -> impl NoirParser { + use self::Keyword::Type; + + let p = ignore_then_commit(keyword(Type), ident()); + let p = then_commit_ignore(p, just(Token::Assign)); + let p = then_commit(p, parse_type()); + + p.map_with_span(|(name, ty), span| TopLevelStatement::TyAlias(NoirTyAlias { name, ty, span })) +} + fn lambda_return_type() -> impl NoirParser { just(Token::Arrow) .ignore_then(parse_type()) @@ -1893,6 +1905,15 @@ mod test { parse_all_failing(struct_definition(), failing); } + #[test] + fn parse_type_aliases() { + let cases = vec!["type foo = u8", "type bar = String", "type baz = Vec"]; + parse_all(type_alias_definition(), cases); + + let failing = vec!["type = u8", "type foo", "type foo = 1"]; + parse_all_failing(struct_definition(), failing); + } + #[test] fn parse_member_access() { let cases = vec!["a.b", "a + b.c", "foo.bar as i32"]; From 07d946fe17bcc120b01674d18eaf3135d40b72da Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Fri, 21 Jul 2023 16:52:37 +0100 Subject: [PATCH 02/33] . --- crates/nargo_cli/tests/test_data/type_aliases/{ => src}/main.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename crates/nargo_cli/tests/test_data/type_aliases/{ => src}/main.nr (76%) diff --git a/crates/nargo_cli/tests/test_data/type_aliases/main.nr b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr similarity index 76% rename from crates/nargo_cli/tests/test_data/type_aliases/main.nr rename to crates/nargo_cli/tests/test_data/type_aliases/src/main.nr index 6c5ee8ea595..9573e85ad30 100644 --- a/crates/nargo_cli/tests/test_data/type_aliases/main.nr +++ b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr @@ -4,5 +4,5 @@ type foo = u8; fn main(x : u8) { let a: foo = 1; - constrain a != x; + assert(a != x); } \ No newline at end of file From 96b9c9436ea1b59d745361836fed8b83ba176b2f Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Fri, 21 Jul 2023 20:33:41 +0100 Subject: [PATCH 03/33] . --- .../tests/test_data/type_aliases/Prover.toml | 2 +- .../tests/test_data/type_aliases/src/main.nr | 12 +++++------ crates/noirc_frontend/src/ast/type_alias.rs | 21 ++++++++++++------- .../src/hir/def_collector/dc_crate.rs | 3 ++- .../src/hir/resolution/resolver.rs | 12 ++++++++--- .../noirc_frontend/src/hir/type_check/expr.rs | 2 ++ .../noirc_frontend/src/hir/type_check/mod.rs | 1 + .../src/monomorphization/mod.rs | 3 ++- crates/noirc_frontend/src/parser/parser.rs | 9 +++++--- 9 files changed, 42 insertions(+), 23 deletions(-) diff --git a/crates/nargo_cli/tests/test_data/type_aliases/Prover.toml b/crates/nargo_cli/tests/test_data/type_aliases/Prover.toml index 07890234a19..771df41899d 100644 --- a/crates/nargo_cli/tests/test_data/type_aliases/Prover.toml +++ b/crates/nargo_cli/tests/test_data/type_aliases/Prover.toml @@ -1 +1 @@ -x = "3" +x = [2, 3] diff --git a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr index 9573e85ad30..0ebacc83eee 100644 --- a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr +++ b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr @@ -1,8 +1,6 @@ -use dep::std; +type foo = [T;2]; -type foo = u8; - -fn main(x : u8) { - let a: foo = 1; - assert(a != x); -} \ No newline at end of file +fn main(x : [Field; 2]) { + let a: foo = [1, 2]; + // assert(a[0] != x[0]); +} diff --git a/crates/noirc_frontend/src/ast/type_alias.rs b/crates/noirc_frontend/src/ast/type_alias.rs index 72dc88efc25..22ddf701bd6 100644 --- a/crates/noirc_frontend/src/ast/type_alias.rs +++ b/crates/noirc_frontend/src/ast/type_alias.rs @@ -1,4 +1,5 @@ -use crate::{Ident, UnresolvedType}; +use crate::{Ident, UnresolvedGenerics, UnresolvedType}; +use iter_extended::vecmap; use noirc_errors::Span; use std::fmt::Display; @@ -6,21 +7,27 @@ use std::fmt::Display; #[derive(Clone, Debug)] pub struct NoirTyAlias { pub name: Ident, + pub generics: UnresolvedGenerics, pub ty: UnresolvedType, pub span: Span, - // TODO: should probabaly allow generics - // eg. type foo = Vec; - // pub generics: UnresolvedGenerics, } impl NoirTyAlias { - pub fn new(name: Ident, ty: UnresolvedType, span: Span) -> NoirTyAlias { - NoirTyAlias { name, ty, span } + pub fn new( + name: Ident, + generics: UnresolvedGenerics, + ty: UnresolvedType, + span: Span, + ) -> NoirTyAlias { + NoirTyAlias { name, generics, ty, span } } } impl Display for NoirTyAlias { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "type {} = {}", self.name, self.ty) + let generics = vecmap(&self.generics, |generic| generic.to_string()); + let generics = if generics.is_empty() { "".into() } else { generics.join(", ") }; + + write!(f, "type {}<{}> = {}", self.name, generics, self.ty) } } diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs index 2bfe3a416b5..73aaff866ca 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -379,7 +379,8 @@ fn resolve_type_aliases( }); let file = unresolved_typ.file_id; let ty = Resolver::new(&mut context.def_interner, &path_resolver, &context.def_maps, file) - .resolve_type(unresolved_typ.type_alias_def.ty.clone()); + .resolve_type_aliases(unresolved_typ.type_alias_def.clone()); + context.def_interner.push_type_alias(*type_id, ty); } } diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index e201270f605..d4e778c2e35 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -33,9 +33,9 @@ use crate::{ Statement, }; use crate::{ - ArrayLiteral, ContractFunctionType, Generics, LValue, NoirStruct, Path, Pattern, Shared, - StructType, Type, TypeBinding, TypeVariable, UnaryOp, UnresolvedGenerics, UnresolvedType, - UnresolvedTypeExpression, ERROR_IDENT, + ArrayLiteral, ContractFunctionType, Generics, LValue, NoirStruct, NoirTyAlias, Path, Pattern, + Shared, StructType, Type, TypeBinding, TypeVariable, UnaryOp, UnresolvedGenerics, + UnresolvedType, UnresolvedTypeExpression, ERROR_IDENT, }; use fm::FileId; use iter_extended::vecmap; @@ -510,6 +510,12 @@ impl<'a> Resolver<'a> { self.resolve_type_inner(typ, &mut vec![]) } + pub fn resolve_type_aliases(&mut self, unresolved: NoirTyAlias) -> Type { + let mut generics = self.add_generics(&unresolved.generics); + + self.resolve_type_inner(unresolved.ty, &mut generics) + } + pub fn take_errors(self) -> Vec { self.errors } diff --git a/crates/noirc_frontend/src/hir/type_check/expr.rs b/crates/noirc_frontend/src/hir/type_check/expr.rs index 1625c8a320f..78a82d3985c 100644 --- a/crates/noirc_frontend/src/hir/type_check/expr.rs +++ b/crates/noirc_frontend/src/hir/type_check/expr.rs @@ -26,6 +26,7 @@ impl<'interner> TypeChecker<'interner> { /// be done earlier since we need to know the type of the object `a` to resolve which /// function `foo` to refer to. pub(crate) fn check_expression(&mut self, expr_id: &ExprId) -> Type { + println!("{:?}", self.interner.expression(expr_id)); let typ = match self.interner.expression(expr_id) { HirExpression::Ident(ident) => { // An identifiers type may be forall-quantified in the case of generic functions. @@ -74,6 +75,7 @@ impl<'interner> TypeChecker<'interner> { ); } + println!("{:?}", arr_type); arr_type } HirLiteral::Array(HirArrayLiteral::Repeated { repeated_element, length }) => { diff --git a/crates/noirc_frontend/src/hir/type_check/mod.rs b/crates/noirc_frontend/src/hir/type_check/mod.rs index b8bb6c788e9..9af4e0c6c81 100644 --- a/crates/noirc_frontend/src/hir/type_check/mod.rs +++ b/crates/noirc_frontend/src/hir/type_check/mod.rs @@ -53,6 +53,7 @@ pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Vec Monomorphizer<'interner> { /// Convert a non-tuple/struct type to a monomorphized type fn convert_type(&self, typ: &HirType) -> ast::Type { + println!("{:?}", typ); match typ { HirType::FieldElement(_) => ast::Type::Field, HirType::Integer(_, sign, bits) => ast::Type::Integer(*sign, *bits), @@ -778,7 +779,7 @@ impl<'interner> Monomorphizer<'interner> { if let Definition::Oracle(name) = &ident.definition { if name.as_str() == "println" { // 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 + // Thus, the only argument to the `println` oracle is expected to always be an ident self.append_abi_arg(&hir_arguments[0], &mut arguments); } } diff --git a/crates/noirc_frontend/src/parser/parser.rs b/crates/noirc_frontend/src/parser/parser.rs index 47071a35d5a..6da3907e748 100644 --- a/crates/noirc_frontend/src/parser/parser.rs +++ b/crates/noirc_frontend/src/parser/parser.rs @@ -242,10 +242,13 @@ fn type_alias_definition() -> impl NoirParser { use self::Keyword::Type; let p = ignore_then_commit(keyword(Type), ident()); + let p = then_commit(p, generics()); let p = then_commit_ignore(p, just(Token::Assign)); let p = then_commit(p, parse_type()); - p.map_with_span(|(name, ty), span| TopLevelStatement::TyAlias(NoirTyAlias { name, ty, span })) + p.map_with_span(|((name, generics), ty), span| { + TopLevelStatement::TyAlias(NoirTyAlias { name, generics, ty, span }) + }) } fn lambda_return_type() -> impl NoirParser { @@ -1907,11 +1910,11 @@ mod test { #[test] fn parse_type_aliases() { - let cases = vec!["type foo = u8", "type bar = String", "type baz = Vec"]; + let cases = vec!["type foo = u8", "type bar = String", "type baz = Vec"]; parse_all(type_alias_definition(), cases); let failing = vec!["type = u8", "type foo", "type foo = 1"]; - parse_all_failing(struct_definition(), failing); + parse_all_failing(type_alias_definition(), failing); } #[test] From 5dc1ff956aef82f7cfd7e92455e1951219adf6fa Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Fri, 21 Jul 2023 22:19:44 +0100 Subject: [PATCH 04/33] . --- .../tests/test_data/type_aliases/src/main.nr | 10 ++++++++-- .../test_data/type_aliases/target/test.json | 1 + .../src/hir/def_collector/dc_crate.rs | 17 ++++++----------- .../noirc_frontend/src/hir/resolution/import.rs | 2 +- .../src/hir/resolution/resolver.rs | 8 +++++--- .../noirc_frontend/src/hir/type_check/expr.rs | 2 -- crates/noirc_frontend/src/hir/type_check/mod.rs | 1 - .../noirc_frontend/src/monomorphization/mod.rs | 1 - crates/noirc_frontend/src/node_interner.rs | 8 ++++---- 9 files changed, 25 insertions(+), 25 deletions(-) create mode 100644 crates/nargo_cli/tests/test_data/type_aliases/target/test.json diff --git a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr index 0ebacc83eee..13095b9b47d 100644 --- a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr +++ b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr @@ -1,6 +1,12 @@ -type foo = [T;2]; +use dep::std; + +type foo = [T; 2]; +type bar = Field; fn main(x : [Field; 2]) { - let a: foo = [1, 2]; + // let a: foo = [1, 2]; // assert(a[0] != x[0]); + + let b: bar = 2; + assert(x[0] == b); } diff --git a/crates/nargo_cli/tests/test_data/type_aliases/target/test.json b/crates/nargo_cli/tests/test_data/type_aliases/target/test.json new file mode 100644 index 00000000000..27fc4f281e5 --- /dev/null +++ b/crates/nargo_cli/tests/test_data/type_aliases/target/test.json @@ -0,0 +1 @@ +{"backend":"acvm-backend-barretenberg","abi":{"parameters":[{"name":"x","type":{"kind":"array","length":2,"type":{"kind":"field"}},"visibility":"private"}],"param_witnesses":{"x":[1,2]},"return_type":null,"return_witnesses":[]},"bytecode":"H4sIAAAAAAAA/7WRQQ7DMAgEnabue8BADLd+pVbx/59QVXWkqDkG7wVOI4Z9pJRyOuc25nNMuBZcDiyCjdlrcSR8QbGmAixtU1QUlXdRIlfWas0qGDI5djHqA7YGsLz/snt+mfexL8HuO/ufe/UPOe5GmOWdJ3ivwd5pUu/R/RzzAX2gnCq4AwAA","proving_key":null,"verification_key":null} \ No newline at end of file diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs index 73aaff866ca..abf53922238 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -40,6 +40,7 @@ pub struct UnresolvedStruct { pub struct_def: NoirStruct, } +#[derive(Clone)] pub struct UnresolvedTypeAlias { pub file_id: FileId, pub module_id: LocalModuleId, @@ -367,21 +368,15 @@ fn resolve_struct_fields( (generics, fields) } +// Don't resolve type aliases here +// because they may have generics fn resolve_type_aliases( context: &mut Context, type_aliases: HashMap, - crate_id: CrateId, + _crate_id: CrateId, ) { - for (type_id, unresolved_typ) in &type_aliases { - let path_resolver = StandardPathResolver::new(ModuleId { - local_id: unresolved_typ.module_id, - krate: crate_id, - }); - let file = unresolved_typ.file_id; - let ty = Resolver::new(&mut context.def_interner, &path_resolver, &context.def_maps, file) - .resolve_type_aliases(unresolved_typ.type_alias_def.clone()); - - context.def_interner.push_type_alias(*type_id, ty); + for (type_id, unresolved_typ) in type_aliases { + context.def_interner.push_type_alias(type_id, unresolved_typ); } } diff --git a/crates/noirc_frontend/src/hir/resolution/import.rs b/crates/noirc_frontend/src/hir/resolution/import.rs index 50e8be75904..b66ffc207c5 100644 --- a/crates/noirc_frontend/src/hir/resolution/import.rs +++ b/crates/noirc_frontend/src/hir/resolution/import.rs @@ -152,7 +152,7 @@ fn resolve_name_in_module( ModuleDefId::FunctionId(_) => panic!("functions cannot be in the type namespace"), // TODO: If impls are ever implemented, types can be used in a path ModuleDefId::TypeId(id) => id.0, - ModuleDefId::TypeAliasId(_) => panic!("type aliases cannot be in the type namespace"), + ModuleDefId::TypeAliasId(id) => id.0, ModuleDefId::GlobalId(_) => panic!("globals cannot be in the type namespace"), }; diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index d4e778c2e35..1fde9ad3bf0 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -22,6 +22,7 @@ use std::collections::{HashMap, HashSet}; use std::rc::Rc; use crate::graph::CrateId; +use crate::hir::def_collector::dc_crate::UnresolvedTypeAlias; use crate::hir::def_map::{ModuleDefId, TryFromModuleDefId, MAIN_FUNCTION}; use crate::hir_def::stmt::{HirAssignStatement, HirLValue, HirPattern}; use crate::node_interner::{ @@ -391,8 +392,9 @@ impl<'a> Resolver<'a> { } } + // resolve type alias here if let Some(type_alias_type) = self.lookup_type_alias(path.clone()) { - return type_alias_type; + return self.resolve_type_inner(type_alias_type.type_alias_def.ty, new_variables); } let span = path.span(); @@ -1164,7 +1166,7 @@ impl<'a> Resolver<'a> { self.interner.get_struct(type_id) } - pub fn get_type_alias(&self, type_alias_id: TyAliasId) -> Type { + pub fn get_type_alias(&self, type_alias_id: TyAliasId) -> UnresolvedTypeAlias { self.interner.get_type_alias(type_alias_id) } @@ -1230,7 +1232,7 @@ impl<'a> Resolver<'a> { } } - fn lookup_type_alias(&mut self, path: Path) -> Option { + fn lookup_type_alias(&mut self, path: Path) -> Option { match self.lookup(path) { Ok(type_alias_id) => Some(self.get_type_alias(type_alias_id)), Err(_) => None, diff --git a/crates/noirc_frontend/src/hir/type_check/expr.rs b/crates/noirc_frontend/src/hir/type_check/expr.rs index 78a82d3985c..1625c8a320f 100644 --- a/crates/noirc_frontend/src/hir/type_check/expr.rs +++ b/crates/noirc_frontend/src/hir/type_check/expr.rs @@ -26,7 +26,6 @@ impl<'interner> TypeChecker<'interner> { /// be done earlier since we need to know the type of the object `a` to resolve which /// function `foo` to refer to. pub(crate) fn check_expression(&mut self, expr_id: &ExprId) -> Type { - println!("{:?}", self.interner.expression(expr_id)); let typ = match self.interner.expression(expr_id) { HirExpression::Ident(ident) => { // An identifiers type may be forall-quantified in the case of generic functions. @@ -75,7 +74,6 @@ impl<'interner> TypeChecker<'interner> { ); } - println!("{:?}", arr_type); arr_type } HirLiteral::Array(HirArrayLiteral::Repeated { repeated_element, length }) => { diff --git a/crates/noirc_frontend/src/hir/type_check/mod.rs b/crates/noirc_frontend/src/hir/type_check/mod.rs index 9af4e0c6c81..b8bb6c788e9 100644 --- a/crates/noirc_frontend/src/hir/type_check/mod.rs +++ b/crates/noirc_frontend/src/hir/type_check/mod.rs @@ -53,7 +53,6 @@ pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Vec Monomorphizer<'interner> { /// Convert a non-tuple/struct type to a monomorphized type fn convert_type(&self, typ: &HirType) -> ast::Type { - println!("{:?}", typ); match typ { HirType::FieldElement(_) => ast::Type::Field, HirType::Integer(_, sign, bits) => ast::Type::Integer(*sign, *bits), diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index fdd70bf4a7f..e3281d1f66f 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -7,7 +7,7 @@ use noirc_errors::{Location, Span, Spanned}; use crate::ast::Ident; use crate::graph::CrateId; -use crate::hir::def_collector::dc_crate::UnresolvedStruct; +use crate::hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTypeAlias}; use crate::hir::def_map::{LocalModuleId, ModuleId}; use crate::hir::StorageSlot; use crate::hir_def::stmt::HirLetStatement; @@ -56,7 +56,7 @@ pub struct NodeInterner { // // Map type aliases to the actual type. // When resolving types, check against this map to see if a type alias is defined. - type_aliases: HashMap, + type_aliases: HashMap, /// Map from ExprId (referring to a Function/Method call) to its corresponding TypeBindings, /// filled out during type checking from instantiated variables. Used during monomorphization @@ -335,7 +335,7 @@ impl NodeInterner { f(&mut value); } - pub fn push_type_alias(&mut self, type_id: TyAliasId, typ: Type) { + pub fn push_type_alias(&mut self, type_id: TyAliasId, typ: UnresolvedTypeAlias) { self.type_aliases.insert(type_id, typ); } @@ -535,7 +535,7 @@ impl NodeInterner { self.structs[&id].clone() } - pub fn get_type_alias(&self, id: TyAliasId) -> Type { + pub fn get_type_alias(&self, id: TyAliasId) -> UnresolvedTypeAlias { self.type_aliases[&id].clone() } From 01681062724b286e78ea88c79044cd8d144f9c57 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Sat, 22 Jul 2023 10:51:20 +0100 Subject: [PATCH 05/33] stash --- .../tests/test_data/type_aliases/src/main.nr | 10 +- .../src/hir/def_collector/dc_crate.rs | 22 +++- .../src/hir/resolution/resolver.rs | 48 ++++++-- .../noirc_frontend/src/hir/type_check/stmt.rs | 3 + crates/noirc_frontend/src/hir_def/types.rs | 103 +++++++++++++++++- .../src/monomorphization/mod.rs | 5 + crates/noirc_frontend/src/node_interner.rs | 30 ++++- 7 files changed, 195 insertions(+), 26 deletions(-) diff --git a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr index 13095b9b47d..1b6e85d6836 100644 --- a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr +++ b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr @@ -1,12 +1,12 @@ use dep::std; type foo = [T; 2]; -type bar = Field; +//type bar = Field; fn main(x : [Field; 2]) { - // let a: foo = [1, 2]; - // assert(a[0] != x[0]); + let a: foo = [1, 2]; + assert(a[0] != x[0]); - let b: bar = 2; - assert(x[0] == b); + //let b: bar = 2; + //assert(x[0] == b); } diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs index abf53922238..156727fb03a 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -368,15 +368,29 @@ fn resolve_struct_fields( (generics, fields) } -// Don't resolve type aliases here -// because they may have generics fn resolve_type_aliases( context: &mut Context, type_aliases: HashMap, - _crate_id: CrateId, + crate_id: CrateId, ) { + for (type_id, typ) in &type_aliases { + context.def_interner.push_empty_type_alias(*type_id, typ); + } + for (type_id, unresolved_typ) in type_aliases { - context.def_interner.push_type_alias(type_id, unresolved_typ); + let path_resolver = StandardPathResolver::new(ModuleId { + local_id: unresolved_typ.module_id, + krate: crate_id, + }); + let file = unresolved_typ.file_id; + let (typ, generics) = + Resolver::new(&mut context.def_interner, &path_resolver, &context.def_maps, file) + .resolve_type_aliases(unresolved_typ.type_alias_def); + + context.def_interner.update_type_alias(type_id, |type_alias_def| { + type_alias_def.set_type(typ); + type_alias_def.generics = generics; + }); } } diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index 1fde9ad3bf0..ad2a07fbd45 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -22,7 +22,6 @@ use std::collections::{HashMap, HashSet}; use std::rc::Rc; use crate::graph::CrateId; -use crate::hir::def_collector::dc_crate::UnresolvedTypeAlias; use crate::hir::def_map::{ModuleDefId, TryFromModuleDefId, MAIN_FUNCTION}; use crate::hir_def::stmt::{HirAssignStatement, HirLValue, HirPattern}; use crate::node_interner::{ @@ -35,7 +34,7 @@ use crate::{ }; use crate::{ ArrayLiteral, ContractFunctionType, Generics, LValue, NoirStruct, NoirTyAlias, Path, Pattern, - Shared, StructType, Type, TypeBinding, TypeVariable, UnaryOp, UnresolvedGenerics, + Shared, StructType, Type, TypeAliasTy, TypeBinding, TypeVariable, UnaryOp, UnresolvedGenerics, UnresolvedType, UnresolvedTypeExpression, ERROR_IDENT, }; use fm::FileId; @@ -392,12 +391,26 @@ impl<'a> Resolver<'a> { } } - // resolve type alias here + let span = path.span(); if let Some(type_alias_type) = self.lookup_type_alias(path.clone()) { - return self.resolve_type_inner(type_alias_type.type_alias_def.ty, new_variables); + let mut args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); + let expected_generic_count = type_alias_type.borrow().generics.len(); + + if args.len() != expected_generic_count { + self.push_err(ResolverError::IncorrectGenericCount { + span, + struct_type: type_alias_type.borrow().to_string(), + actual: args.len(), + expected: expected_generic_count, + }); + + // Fix the generic count so we can continue typechecking + args.resize_with(expected_generic_count, || Type::Error); + } + + return Type::TypeAlias(type_alias_type, args); } - let span = path.span(); match self.lookup_struct_or_error(path) { Some(struct_type) => { let mut args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); @@ -512,10 +525,14 @@ impl<'a> Resolver<'a> { self.resolve_type_inner(typ, &mut vec![]) } - pub fn resolve_type_aliases(&mut self, unresolved: NoirTyAlias) -> Type { - let mut generics = self.add_generics(&unresolved.generics); + pub fn resolve_type_aliases(&mut self, unresolved: NoirTyAlias) -> (Type, Generics) { + let generics = self.add_generics(&unresolved.generics); + + self.resolve_local_globals(); + + let typ = self.resolve_type(unresolved.ty); - self.resolve_type_inner(unresolved.ty, &mut generics) + (typ, generics) } pub fn take_errors(self) -> Vec { @@ -806,6 +823,17 @@ impl<'a> Resolver<'a> { } } } + Type::TypeAlias(struct_type, generics) => { + for (i, generic) in generics.iter().enumerate() { + if let Type::NamedGeneric(type_variable, name) = generic { + if struct_type.borrow().generic_is_numeric(i) { + found.insert(name.to_string(), type_variable.clone()); + } + } else { + Self::find_numeric_generics_in_type(generic, found); + } + } + } Type::MutableReference(element) => Self::find_numeric_generics_in_type(element, found), } } @@ -1166,7 +1194,7 @@ impl<'a> Resolver<'a> { self.interner.get_struct(type_id) } - pub fn get_type_alias(&self, type_alias_id: TyAliasId) -> UnresolvedTypeAlias { + pub fn get_type_alias(&self, type_alias_id: TyAliasId) -> Shared { self.interner.get_type_alias(type_alias_id) } @@ -1232,7 +1260,7 @@ impl<'a> Resolver<'a> { } } - fn lookup_type_alias(&mut self, path: Path) -> Option { + fn lookup_type_alias(&mut self, path: Path) -> Option> { match self.lookup(path) { Ok(type_alias_id) => Some(self.get_type_alias(type_alias_id)), Err(_) => None, diff --git a/crates/noirc_frontend/src/hir/type_check/stmt.rs b/crates/noirc_frontend/src/hir/type_check/stmt.rs index 4354d4cc77b..44159b573bf 100644 --- a/crates/noirc_frontend/src/hir/type_check/stmt.rs +++ b/crates/noirc_frontend/src/hir/type_check/stmt.rs @@ -256,6 +256,9 @@ impl<'interner> TypeChecker<'interner> { // Type check the expression on the RHS let expr_type = self.check_expression(&rhs_expr); + println!("annotated_type {:?}", annotated_type); + println!("expr_type {:?}", expr_type); + // First check if the LHS is unspecified // If so, then we give it the same type as the expression if annotated_type != Type::Error { diff --git a/crates/noirc_frontend/src/hir_def/types.rs b/crates/noirc_frontend/src/hir_def/types.rs index 9441307bf28..3a1dcfe3d46 100644 --- a/crates/noirc_frontend/src/hir_def/types.rs +++ b/crates/noirc_frontend/src/hir_def/types.rs @@ -5,7 +5,10 @@ use std::{ rc::Rc, }; -use crate::{hir::type_check::TypeCheckError, node_interner::NodeInterner}; +use crate::{ + hir::type_check::TypeCheckError, + node_interner::{NodeInterner, TyAliasId}, +}; use iter_extended::vecmap; use noirc_abi::AbiType; use noirc_errors::Span; @@ -45,6 +48,11 @@ pub enum Type { /// represents the generic arguments (if any) to this struct type. Struct(Shared, Vec), + /// A user-defined struct type. The `Shared` field here refers to + /// the shared definition for each instance of this struct type. The `Vec` + /// represents the generic arguments (if any) to this struct type. + TypeAlias(Shared, Vec), + /// A tuple type with the given list of fields in the order they appear in source code. Tuple(Vec), @@ -222,6 +230,70 @@ impl std::fmt::Display for StructType { } } +/// Wrap around an unsolved type +#[derive(Debug, Clone, Eq)] +pub struct TypeAliasTy { + pub name: Ident, + pub id: TyAliasId, + pub typ: Type, + pub generics: Generics, + pub span: Span, +} + +impl std::hash::Hash for TypeAliasTy { + fn hash(&self, state: &mut H) { + self.id.hash(state); + } +} + +impl PartialEq for TypeAliasTy { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } +} + +impl std::fmt::Display for TypeAliasTy { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.typ) + } +} + +impl TypeAliasTy { + pub fn new( + id: TyAliasId, + name: Ident, + span: Span, + typ: Type, + generics: Generics, + ) -> TypeAliasTy { + TypeAliasTy { id, typ, name, span, generics } + } + + pub fn set_type(&mut self, typ: Type) { + assert_eq!(self.typ, Type::Unit); + self.typ = typ; + } + + // Returns all the fields of this type, after being applied to the given generic arguments. + pub fn get_type(&self, generic_args: &[Type]) -> Type { + assert_eq!(self.generics.len(), generic_args.len()); + + let substitutions = self + .generics + .iter() + .zip(generic_args) + .map(|((old_id, old_var), new)| (*old_id, (old_var.clone(), new.clone()))) + .collect(); + + self.typ.substitute(&substitutions) + } + + pub fn generic_is_numeric(&self, index_of_generic: usize) -> bool { + let target_id = self.generics[index_of_generic].0; + self.typ.contains_numeric_typevar(target_id) + } +} + /// A shared, mutable reference to some T. /// Wrapper is required for Hash impl of RefCell. #[derive(Debug, Eq, PartialOrd, Ord)] @@ -600,6 +672,15 @@ impl Type { } }) } + Type::TypeAlias(struct_type, generics) => { + generics.iter().enumerate().any(|(i, generic)| { + if named_generic_id_matches_target(generic) { + struct_type.borrow().generic_is_numeric(i) + } else { + generic.contains_numeric_typevar(target_id) + } + }) + } Type::MutableReference(element) => element.contains_numeric_typevar(target_id), } } @@ -645,6 +726,14 @@ impl std::fmt::Display for Type { write!(f, "{}<{}>", s.borrow(), args.join(", ")) } } + Type::TypeAlias(s, args) => { + let args = vecmap(args, |arg| arg.to_string()); + if args.is_empty() { + write!(f, "{}", s.borrow()) + } else { + write!(f, "{}<{}>", s.borrow(), args.join(", ")) + } + } Type::Tuple(elements) => { let elements = vecmap(elements, ToString::to_string); write!(f, "({})", elements.join(", ")) @@ -1221,6 +1310,7 @@ impl Type { let fields = vecmap(fields, |(name, typ)| (name, typ.as_abi_type())); AbiType::Struct { fields } } + Type::TypeAlias(_, _) => todo!("as_abi_type not yet implemented for type alias types"), Type::Tuple(_) => todo!("as_abi_type not yet implemented for tuple types"), Type::TypeVariable(_) => unreachable!(), Type::NamedGeneric(..) => unreachable!(), @@ -1327,6 +1417,10 @@ impl Type { let args = vecmap(args, |arg| arg.substitute(type_bindings)); Type::Struct(fields.clone(), args) } + Type::TypeAlias(typ, args) => { + let args = vecmap(args, |arg| arg.substitute(type_bindings)); + Type::TypeAlias(typ.clone(), args) + } Type::Tuple(fields) => { let fields = vecmap(fields, |field| field.substitute(type_bindings)); Type::Tuple(fields) @@ -1365,6 +1459,9 @@ impl Type { Type::Slice(element) => element.occurs(target_id), Type::String(len) => len.occurs(target_id), Type::Struct(_, generic_args) => generic_args.iter().any(|arg| arg.occurs(target_id)), + Type::TypeAlias(_, generic_args) => { + generic_args.iter().any(|arg| arg.occurs(target_id)) + } Type::Tuple(fields) => fields.iter().any(|field| field.occurs(target_id)), Type::PolymorphicInteger(_, binding) | Type::NamedGeneric(binding, _) @@ -1407,6 +1504,10 @@ impl Type { let args = vecmap(args, |arg| arg.follow_bindings()); Struct(def.clone(), args) } + TypeAlias(def, args) => { + let args = vecmap(args, |arg| arg.follow_bindings()); + TypeAlias(def.clone(), args) + } Tuple(args) => Tuple(vecmap(args, |arg| arg.follow_bindings())), TypeVariable(var) | PolymorphicInteger(_, var) | NamedGeneric(var, _) => { diff --git a/crates/noirc_frontend/src/monomorphization/mod.rs b/crates/noirc_frontend/src/monomorphization/mod.rs index ed14f79f95b..cfd470e5464 100644 --- a/crates/noirc_frontend/src/monomorphization/mod.rs +++ b/crates/noirc_frontend/src/monomorphization/mod.rs @@ -716,6 +716,11 @@ impl<'interner> Monomorphizer<'interner> { ast::Type::Tuple(fields) } + HirType::TypeAlias(def, args) => { + let typ = def.borrow().get_type(args); + self.convert_type(&typ) + } + HirType::Tuple(fields) => { let fields = vecmap(fields, |typ| self.convert_type(typ)); ast::Type::Tuple(fields) diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index e3281d1f66f..0ea99199887 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -17,7 +17,7 @@ use crate::hir_def::{ function::{FuncMeta, HirFunction}, stmt::HirStatement, }; -use crate::{Shared, TypeBinding, TypeBindings, TypeVariable, TypeVariableId}; +use crate::{Shared, TypeAliasTy, TypeBinding, TypeBindings, TypeVariable, TypeVariableId}; /// The node interner is the central storage location of all nodes in Noir's Hir (the /// various node types can be found in hir_def). The interner is also used to collect @@ -56,7 +56,7 @@ pub struct NodeInterner { // // Map type aliases to the actual type. // When resolving types, check against this map to see if a type alias is defined. - type_aliases: HashMap, + type_aliases: HashMap>, /// Map from ExprId (referring to a Function/Method call) to its corresponding TypeBindings, /// filled out during type checking from instantiated variables. Used during monomorphization @@ -330,13 +330,30 @@ impl NodeInterner { ); } + pub fn push_empty_type_alias(&mut self, type_id: TyAliasId, typ: &UnresolvedTypeAlias) { + self.type_aliases.insert( + type_id, + Shared::new(TypeAliasTy::new( + type_id, + typ.type_alias_def.name.clone(), + typ.type_alias_def.span, + Type::Unit, + vecmap(&typ.type_alias_def.generics, |_| { + let id = TypeVariableId(0); + (id, Shared::new(TypeBinding::Unbound(id))) + }), + )), + ); + } + pub fn update_struct(&mut self, type_id: StructId, f: impl FnOnce(&mut StructType)) { let mut value = self.structs.get_mut(&type_id).unwrap().borrow_mut(); f(&mut value); } - pub fn push_type_alias(&mut self, type_id: TyAliasId, typ: UnresolvedTypeAlias) { - self.type_aliases.insert(type_id, typ); + pub fn update_type_alias(&mut self, type_id: TyAliasId, f: impl FnOnce(&mut TypeAliasTy)) { + let mut value = self.type_aliases.get_mut(&type_id).unwrap().borrow_mut(); + f(&mut value); } /// Returns the interned statement corresponding to `stmt_id` @@ -535,7 +552,7 @@ impl NodeInterner { self.structs[&id].clone() } - pub fn get_type_alias(&self, id: TyAliasId) -> UnresolvedTypeAlias { + pub fn get_type_alias(&self, id: TyAliasId) -> Shared { self.type_aliases[&id].clone() } @@ -671,6 +688,7 @@ fn get_type_method_key(typ: &Type) -> Option { | Type::Forall(_, _) | Type::Constant(_) | Type::Error - | Type::Struct(_, _) => None, + | Type::Struct(_, _) + | Type::TypeAlias(_, _) => None, } } From ef80b01af4b074d470506664b646d6d92647337b Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Sat, 22 Jul 2023 11:03:47 +0100 Subject: [PATCH 06/33] . --- .../nargo_cli/tests/test_data/type_aliases/src/main.nr | 9 +++++---- crates/noirc_frontend/src/hir/resolution/resolver.rs | 4 +++- crates/noirc_frontend/src/hir/type_check/stmt.rs | 3 --- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr index 1b6e85d6836..b5948670c42 100644 --- a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr +++ b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr @@ -1,12 +1,13 @@ use dep::std; type foo = [T; 2]; -//type bar = Field; + +// type bar = Field; fn main(x : [Field; 2]) { - let a: foo = [1, 2]; + let a: foo = [1, 2]; assert(a[0] != x[0]); - //let b: bar = 2; - //assert(x[0] == b); + let b: Field = 2; + assert(x[0] == b); } diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index ad2a07fbd45..5dd14cb0852 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -408,7 +408,9 @@ impl<'a> Resolver<'a> { args.resize_with(expected_generic_count, || Type::Error); } - return Type::TypeAlias(type_alias_type, args); + let typ = type_alias_type.borrow().get_type(&args); + + return typ; } match self.lookup_struct_or_error(path) { diff --git a/crates/noirc_frontend/src/hir/type_check/stmt.rs b/crates/noirc_frontend/src/hir/type_check/stmt.rs index 44159b573bf..4354d4cc77b 100644 --- a/crates/noirc_frontend/src/hir/type_check/stmt.rs +++ b/crates/noirc_frontend/src/hir/type_check/stmt.rs @@ -256,9 +256,6 @@ impl<'interner> TypeChecker<'interner> { // Type check the expression on the RHS let expr_type = self.check_expression(&rhs_expr); - println!("annotated_type {:?}", annotated_type); - println!("expr_type {:?}", expr_type); - // First check if the LHS is unspecified // If so, then we give it the same type as the expression if annotated_type != Type::Error { From 54c9c594610e4a64184b737ed58bbbb731261a8d Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Sat, 22 Jul 2023 11:04:29 +0100 Subject: [PATCH 07/33] . --- crates/nargo_cli/tests/test_data/type_aliases/target/test.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 crates/nargo_cli/tests/test_data/type_aliases/target/test.json diff --git a/crates/nargo_cli/tests/test_data/type_aliases/target/test.json b/crates/nargo_cli/tests/test_data/type_aliases/target/test.json deleted file mode 100644 index 27fc4f281e5..00000000000 --- a/crates/nargo_cli/tests/test_data/type_aliases/target/test.json +++ /dev/null @@ -1 +0,0 @@ -{"backend":"acvm-backend-barretenberg","abi":{"parameters":[{"name":"x","type":{"kind":"array","length":2,"type":{"kind":"field"}},"visibility":"private"}],"param_witnesses":{"x":[1,2]},"return_type":null,"return_witnesses":[]},"bytecode":"H4sIAAAAAAAA/7WRQQ7DMAgEnabue8BADLd+pVbx/59QVXWkqDkG7wVOI4Z9pJRyOuc25nNMuBZcDiyCjdlrcSR8QbGmAixtU1QUlXdRIlfWas0qGDI5djHqA7YGsLz/snt+mfexL8HuO/ufe/UPOe5GmOWdJ3ivwd5pUu/R/RzzAX2gnCq4AwAA","proving_key":null,"verification_key":null} \ No newline at end of file From 3b61ee889ab3f94fe6cfc86f465bdcbf698eae2d Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Sat, 22 Jul 2023 11:47:05 +0100 Subject: [PATCH 08/33] . --- .../tests/test_data/type_aliases/src/main.nr | 4 ++-- .../noirc_frontend/src/hir/def_collector/dc_mod.rs | 14 ++++++-------- crates/noirc_frontend/src/hir/resolution/import.rs | 2 +- crates/noirc_frontend/src/node_interner.rs | 8 ++++++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr index b5948670c42..4d1fe1a0ebc 100644 --- a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr +++ b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr @@ -2,12 +2,12 @@ use dep::std; type foo = [T; 2]; -// type bar = Field; +type bar = Field; fn main(x : [Field; 2]) { let a: foo = [1, 2]; assert(a[0] != x[0]); - let b: Field = 2; + let b: bar = 2; assert(x[0] == b); } diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs index 78a041b5dca..1b26a1f4400 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -2,11 +2,9 @@ use fm::FileId; use noirc_errors::FileDiagnostic; use crate::{ - graph::CrateId, - hir::def_collector::dc_crate::UnresolvedStruct, - node_interner::{StructId, TyAliasId}, - parser::SubModule, - Ident, LetStatement, NoirFunction, NoirStruct, NoirTyAlias, ParsedModule, TypeImpl, + graph::CrateId, hir::def_collector::dc_crate::UnresolvedStruct, node_interner::StructId, + parser::SubModule, Ident, LetStatement, NoirFunction, NoirStruct, NoirTyAlias, ParsedModule, + TypeImpl, }; use super::{ @@ -58,7 +56,7 @@ pub fn collect_defs( collector.collect_structs(ast.types, crate_id, errors); - collector.collect_type_aliases(ast.type_aliases, crate_id, errors); + collector.collect_type_aliases(context, ast.type_aliases, errors); collector.collect_functions(context, ast.functions, errors); @@ -192,14 +190,14 @@ impl<'a> ModCollector<'a> { /// Returns a vector of errors if any type aliases were already defined. fn collect_type_aliases( &mut self, + context: &mut Context, type_aliases: Vec, - krate: CrateId, errors: &mut Vec, ) { for type_alias in type_aliases { let name = type_alias.name.clone(); - let ty_alias_id = TyAliasId(ModuleId { krate, local_id: self.module_id }); + let ty_alias_id = context.def_interner.push_type_alias(); // Add the type alias to scope so its path can be looked up later let result = self.def_collector.def_map.modules[self.module_id.0] .declare_type_alias(name, ty_alias_id); diff --git a/crates/noirc_frontend/src/hir/resolution/import.rs b/crates/noirc_frontend/src/hir/resolution/import.rs index b66ffc207c5..50e8be75904 100644 --- a/crates/noirc_frontend/src/hir/resolution/import.rs +++ b/crates/noirc_frontend/src/hir/resolution/import.rs @@ -152,7 +152,7 @@ fn resolve_name_in_module( ModuleDefId::FunctionId(_) => panic!("functions cannot be in the type namespace"), // TODO: If impls are ever implemented, types can be used in a path ModuleDefId::TypeId(id) => id.0, - ModuleDefId::TypeAliasId(id) => id.0, + ModuleDefId::TypeAliasId(_) => panic!("type aliases cannot be in the type namespace"), ModuleDefId::GlobalId(_) => panic!("globals cannot be in the type namespace"), }; diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index 0ea99199887..a1845771c7d 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -144,14 +144,14 @@ impl StructId { } #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] -pub struct TyAliasId(pub ModuleId); +pub struct TyAliasId(Index); impl TyAliasId { //dummy id for error reporting // This can be anything, as the program will ultimately fail // after resolution pub fn dummy_id() -> TyAliasId { - TyAliasId(ModuleId { krate: CrateId::dummy_id(), local_id: LocalModuleId::dummy_id() }) + TyAliasId(Index::from_raw_parts(std::usize::MAX, 0)) } } @@ -197,6 +197,7 @@ enum Node { Function(HirFunction), Statement(HirStatement), Expression(HirExpression), + TypeAlias, } #[derive(Debug, Clone)] @@ -294,6 +295,9 @@ impl NodeInterner { pub fn push_expr(&mut self, expr: HirExpression) -> ExprId { ExprId(self.nodes.insert(Node::Expression(expr))) } + pub fn push_type_alias(&mut self) -> TyAliasId { + TyAliasId(self.nodes.insert(Node::TypeAlias)) + } /// Stores the span for an interned expression. pub fn push_expr_location(&mut self, expr_id: ExprId, span: Span, file: FileId) { From 5d10c18430974070b1b730e91f771d47540c2c5a Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Sat, 22 Jul 2023 11:59:19 +0100 Subject: [PATCH 09/33] remove tyalias as an hir type --- .../src/hir/resolution/resolver.rs | 14 ++------ crates/noirc_frontend/src/hir_def/types.rs | 34 ------------------- .../src/monomorphization/mod.rs | 5 --- crates/noirc_frontend/src/node_interner.rs | 3 +- 4 files changed, 4 insertions(+), 52 deletions(-) diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index 5dd14cb0852..8f327edcb3e 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -408,6 +408,9 @@ impl<'a> Resolver<'a> { args.resize_with(expected_generic_count, || Type::Error); } + // Type Alias is monomorphized here because we do type checking before monomorphization + // If this is done in normal monomorphization phase type checking will return errors + // TODO(ethan): not sure if this is the best practice though let typ = type_alias_type.borrow().get_type(&args); return typ; @@ -825,17 +828,6 @@ impl<'a> Resolver<'a> { } } } - Type::TypeAlias(struct_type, generics) => { - for (i, generic) in generics.iter().enumerate() { - if let Type::NamedGeneric(type_variable, name) = generic { - if struct_type.borrow().generic_is_numeric(i) { - found.insert(name.to_string(), type_variable.clone()); - } - } else { - Self::find_numeric_generics_in_type(generic, found); - } - } - } Type::MutableReference(element) => Self::find_numeric_generics_in_type(element, found), } } diff --git a/crates/noirc_frontend/src/hir_def/types.rs b/crates/noirc_frontend/src/hir_def/types.rs index 3a1dcfe3d46..4fd4012fea1 100644 --- a/crates/noirc_frontend/src/hir_def/types.rs +++ b/crates/noirc_frontend/src/hir_def/types.rs @@ -48,11 +48,6 @@ pub enum Type { /// represents the generic arguments (if any) to this struct type. Struct(Shared, Vec), - /// A user-defined struct type. The `Shared` field here refers to - /// the shared definition for each instance of this struct type. The `Vec` - /// represents the generic arguments (if any) to this struct type. - TypeAlias(Shared, Vec), - /// A tuple type with the given list of fields in the order they appear in source code. Tuple(Vec), @@ -672,15 +667,6 @@ impl Type { } }) } - Type::TypeAlias(struct_type, generics) => { - generics.iter().enumerate().any(|(i, generic)| { - if named_generic_id_matches_target(generic) { - struct_type.borrow().generic_is_numeric(i) - } else { - generic.contains_numeric_typevar(target_id) - } - }) - } Type::MutableReference(element) => element.contains_numeric_typevar(target_id), } } @@ -726,14 +712,6 @@ impl std::fmt::Display for Type { write!(f, "{}<{}>", s.borrow(), args.join(", ")) } } - Type::TypeAlias(s, args) => { - let args = vecmap(args, |arg| arg.to_string()); - if args.is_empty() { - write!(f, "{}", s.borrow()) - } else { - write!(f, "{}<{}>", s.borrow(), args.join(", ")) - } - } Type::Tuple(elements) => { let elements = vecmap(elements, ToString::to_string); write!(f, "({})", elements.join(", ")) @@ -1310,7 +1288,6 @@ impl Type { let fields = vecmap(fields, |(name, typ)| (name, typ.as_abi_type())); AbiType::Struct { fields } } - Type::TypeAlias(_, _) => todo!("as_abi_type not yet implemented for type alias types"), Type::Tuple(_) => todo!("as_abi_type not yet implemented for tuple types"), Type::TypeVariable(_) => unreachable!(), Type::NamedGeneric(..) => unreachable!(), @@ -1417,10 +1394,6 @@ impl Type { let args = vecmap(args, |arg| arg.substitute(type_bindings)); Type::Struct(fields.clone(), args) } - Type::TypeAlias(typ, args) => { - let args = vecmap(args, |arg| arg.substitute(type_bindings)); - Type::TypeAlias(typ.clone(), args) - } Type::Tuple(fields) => { let fields = vecmap(fields, |field| field.substitute(type_bindings)); Type::Tuple(fields) @@ -1459,9 +1432,6 @@ impl Type { Type::Slice(element) => element.occurs(target_id), Type::String(len) => len.occurs(target_id), Type::Struct(_, generic_args) => generic_args.iter().any(|arg| arg.occurs(target_id)), - Type::TypeAlias(_, generic_args) => { - generic_args.iter().any(|arg| arg.occurs(target_id)) - } Type::Tuple(fields) => fields.iter().any(|field| field.occurs(target_id)), Type::PolymorphicInteger(_, binding) | Type::NamedGeneric(binding, _) @@ -1504,10 +1474,6 @@ impl Type { let args = vecmap(args, |arg| arg.follow_bindings()); Struct(def.clone(), args) } - TypeAlias(def, args) => { - let args = vecmap(args, |arg| arg.follow_bindings()); - TypeAlias(def.clone(), args) - } Tuple(args) => Tuple(vecmap(args, |arg| arg.follow_bindings())), TypeVariable(var) | PolymorphicInteger(_, var) | NamedGeneric(var, _) => { diff --git a/crates/noirc_frontend/src/monomorphization/mod.rs b/crates/noirc_frontend/src/monomorphization/mod.rs index cfd470e5464..ed14f79f95b 100644 --- a/crates/noirc_frontend/src/monomorphization/mod.rs +++ b/crates/noirc_frontend/src/monomorphization/mod.rs @@ -716,11 +716,6 @@ impl<'interner> Monomorphizer<'interner> { ast::Type::Tuple(fields) } - HirType::TypeAlias(def, args) => { - let typ = def.borrow().get_type(args); - self.convert_type(&typ) - } - HirType::Tuple(fields) => { let fields = vecmap(fields, |typ| self.convert_type(typ)); ast::Type::Tuple(fields) diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index a1845771c7d..cd0b13e769d 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -692,7 +692,6 @@ fn get_type_method_key(typ: &Type) -> Option { | Type::Forall(_, _) | Type::Constant(_) | Type::Error - | Type::Struct(_, _) - | Type::TypeAlias(_, _) => None, + | Type::Struct(_, _) => None, } } From 9d8bc59cb3b8fd80ffbb6994d03562a4badb6d50 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Tue, 25 Jul 2023 16:51:47 +0100 Subject: [PATCH 10/33] namings --- .../tests/test_data/type_aliases/src/main.nr | 30 ++++++++++++++---- crates/noirc_frontend/src/ast/type_alias.rs | 14 ++++----- .../src/hir/def_collector/dc_crate.rs | 20 +++++++----- .../src/hir/def_collector/dc_mod.rs | 4 +-- .../src/hir/def_map/module_data.rs | 8 +++-- .../src/hir/def_map/module_def.rs | 14 ++++----- .../src/hir/resolution/resolver.rs | 31 ++++++++++--------- crates/noirc_frontend/src/hir_def/types.rs | 29 +++++++---------- crates/noirc_frontend/src/node_interner.rs | 31 +++++++++---------- crates/noirc_frontend/src/parser/mod.rs | 10 +++--- crates/noirc_frontend/src/parser/parser.rs | 6 ++-- 11 files changed, 109 insertions(+), 88 deletions(-) diff --git a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr index 4d1fe1a0ebc..04385937b85 100644 --- a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr +++ b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr @@ -1,13 +1,31 @@ use dep::std; -type foo = [T; 2]; +//type Foo = [T; 2]; -type bar = Field; +//type Bar = Field; + +type Three = Two; +type Two = One; +type One = (A, B); + +//struct MyStruct { +// foo: Bar, +//} fn main(x : [Field; 2]) { - let a: foo = [1, 2]; - assert(a[0] != x[0]); + //let a: Foo = [1, 2]; + //assert(a[0] != x[0]); + + //let b: Bar = 2; + //assert(x[0] == b); + + let c: u8 = 1; + let d: u32 = 2; + let e: Three = (c, d); + assert(e.0 == 1); - let b: bar = 2; - assert(x[0] == b); + //let s = MyStruct { + // foo: 10 + //}; + //assert(s.foo == 10); } diff --git a/crates/noirc_frontend/src/ast/type_alias.rs b/crates/noirc_frontend/src/ast/type_alias.rs index 22ddf701bd6..49d8941f3b3 100644 --- a/crates/noirc_frontend/src/ast/type_alias.rs +++ b/crates/noirc_frontend/src/ast/type_alias.rs @@ -5,29 +5,27 @@ use std::fmt::Display; /// Ast node for type aliases #[derive(Clone, Debug)] -pub struct NoirTyAlias { +pub struct NoirTypeAlias { pub name: Ident, pub generics: UnresolvedGenerics, pub ty: UnresolvedType, pub span: Span, } -impl NoirTyAlias { +impl NoirTypeAlias { pub fn new( name: Ident, generics: UnresolvedGenerics, ty: UnresolvedType, span: Span, - ) -> NoirTyAlias { - NoirTyAlias { name, generics, ty, span } + ) -> NoirTypeAlias { + NoirTypeAlias { name, generics, ty, span } } } -impl Display for NoirTyAlias { +impl Display for NoirTypeAlias { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let generics = vecmap(&self.generics, |generic| generic.to_string()); - let generics = if generics.is_empty() { "".into() } else { generics.join(", ") }; - - write!(f, "type {}<{}> = {}", self.name, generics, self.ty) + write!(f, "type {}<{}> = {}", self.name, generics.join(", "), self.ty) } } diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs index fd9badcd113..9e2b9feec8f 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -10,9 +10,9 @@ use crate::hir::resolution::{ }; use crate::hir::type_check::{type_check_func, TypeChecker}; use crate::hir::Context; -use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId, TyAliasId}; +use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId, TypeAliasId}; use crate::{ - ExpressionKind, Generics, Ident, LetStatement, NoirFunction, NoirStruct, NoirTyAlias, + ExpressionKind, Generics, Ident, LetStatement, NoirFunction, NoirStruct, NoirTypeAlias, ParsedModule, Shared, Type, TypeBinding, UnresolvedGenerics, UnresolvedType, }; use fm::FileId; @@ -44,7 +44,7 @@ pub struct UnresolvedStruct { pub struct UnresolvedTypeAlias { pub file_id: FileId, pub module_id: LocalModuleId, - pub type_alias_def: NoirTyAlias, + pub type_alias_def: NoirTypeAlias, } #[derive(Clone)] @@ -61,7 +61,7 @@ pub struct DefCollector { pub(crate) collected_imports: Vec, pub(crate) collected_functions: Vec, pub(crate) collected_types: HashMap, - pub(crate) collected_type_aliases: HashMap, + pub(crate) collected_type_aliases: HashMap, pub(crate) collected_globals: Vec, pub(crate) collected_impls: ImplMap, } @@ -166,9 +166,10 @@ impl DefCollector { let mut file_global_ids = resolve_globals(context, integer_globals, crate_id, errors); + resolve_type_aliases(context, def_collector.collected_type_aliases, crate_id, errors); + // Must resolve structs before we resolve globals. resolve_structs(context, def_collector.collected_types, crate_id, errors); - resolve_type_aliases(context, def_collector.collected_type_aliases, crate_id); // We must wait to resolve non-integer globals until after we resolve structs since structs // globals will need to reference the struct type they're initialized to to ensure they are valid. @@ -370,8 +371,9 @@ fn resolve_struct_fields( fn resolve_type_aliases( context: &mut Context, - type_aliases: HashMap, + type_aliases: HashMap, crate_id: CrateId, + all_errors: &mut Vec, ) { for (type_id, typ) in &type_aliases { context.def_interner.push_empty_type_alias(*type_id, typ); @@ -383,13 +385,17 @@ fn resolve_type_aliases( krate: crate_id, }); let file = unresolved_typ.file_id; - let (typ, generics) = + let (typ, generics, errors) = Resolver::new(&mut context.def_interner, &path_resolver, &context.def_maps, file) .resolve_type_aliases(unresolved_typ.type_alias_def); + extend_errors(all_errors, file, errors); context.def_interner.update_type_alias(type_id, |type_alias_def| { + // println!("typ: {:?}", typ); type_alias_def.set_type(typ); + // println!("generics: {:?}", generics); type_alias_def.generics = generics; + // println!("type_alias_def: {:?}", type_alias_def); }); } } diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs index 1b26a1f4400..98733a9723e 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -3,7 +3,7 @@ use noirc_errors::FileDiagnostic; use crate::{ graph::CrateId, hir::def_collector::dc_crate::UnresolvedStruct, node_interner::StructId, - parser::SubModule, Ident, LetStatement, NoirFunction, NoirStruct, NoirTyAlias, ParsedModule, + parser::SubModule, Ident, LetStatement, NoirFunction, NoirStruct, NoirTypeAlias, ParsedModule, TypeImpl, }; @@ -191,7 +191,7 @@ impl<'a> ModCollector<'a> { fn collect_type_aliases( &mut self, context: &mut Context, - type_aliases: Vec, + type_aliases: Vec, errors: &mut Vec, ) { for type_alias in type_aliases { diff --git a/crates/noirc_frontend/src/hir/def_map/module_data.rs b/crates/noirc_frontend/src/hir/def_map/module_data.rs index e2960a7c4c3..5b93d04fea7 100644 --- a/crates/noirc_frontend/src/hir/def_map/module_data.rs +++ b/crates/noirc_frontend/src/hir/def_map/module_data.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use fm::FileId; use crate::{ - node_interner::{FuncId, StmtId, StructId, TyAliasId}, + node_interner::{FuncId, StmtId, StructId, TypeAliasId}, Ident, }; @@ -65,7 +65,11 @@ impl ModuleData { self.declare(name, ModuleDefId::TypeId(id)) } - pub fn declare_type_alias(&mut self, name: Ident, id: TyAliasId) -> Result<(), (Ident, Ident)> { + pub fn declare_type_alias( + &mut self, + name: Ident, + id: TypeAliasId, + ) -> Result<(), (Ident, Ident)> { self.declare(name, id.into()) } diff --git a/crates/noirc_frontend/src/hir/def_map/module_def.rs b/crates/noirc_frontend/src/hir/def_map/module_def.rs index ce67cda72a5..b64ced78772 100644 --- a/crates/noirc_frontend/src/hir/def_map/module_def.rs +++ b/crates/noirc_frontend/src/hir/def_map/module_def.rs @@ -1,4 +1,4 @@ -use crate::node_interner::{FuncId, StmtId, StructId, TyAliasId}; +use crate::node_interner::{FuncId, StmtId, StructId, TypeAliasId}; use super::ModuleId; @@ -8,7 +8,7 @@ pub enum ModuleDefId { ModuleId(ModuleId), FunctionId(FuncId), TypeId(StructId), - TypeAliasId(TyAliasId), + TypeAliasId(TypeAliasId), GlobalId(StmtId), } @@ -27,7 +27,7 @@ impl ModuleDefId { } } - pub fn as_type_alias(&self) -> Option { + pub fn as_type_alias(&self) -> Option { match self { ModuleDefId::TypeAliasId(type_alias_id) => Some(*type_alias_id), _ => None, @@ -66,8 +66,8 @@ impl From for ModuleDefId { } } -impl From for ModuleDefId { - fn from(fid: TyAliasId) -> Self { +impl From for ModuleDefId { + fn from(fid: TypeAliasId) -> Self { ModuleDefId::TypeAliasId(fid) } } @@ -112,13 +112,13 @@ impl TryFromModuleDefId for StructId { } } -impl TryFromModuleDefId for TyAliasId { +impl TryFromModuleDefId for TypeAliasId { fn try_from(id: ModuleDefId) -> Option { id.as_type_alias() } fn dummy_id() -> Self { - TyAliasId::dummy_id() + TypeAliasId::dummy_id() } fn description() -> String { diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index 29409734673..e2a9b3f330a 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -25,7 +25,7 @@ use crate::graph::CrateId; use crate::hir::def_map::{ModuleDefId, ModuleId, TryFromModuleDefId, MAIN_FUNCTION}; use crate::hir_def::stmt::{HirAssignStatement, HirLValue, HirPattern}; use crate::node_interner::{ - DefinitionId, DefinitionKind, ExprId, FuncId, NodeInterner, StmtId, StructId, TyAliasId, + DefinitionId, DefinitionKind, ExprId, FuncId, NodeInterner, StmtId, StructId, TypeAliasId, }; use crate::{ hir::{def_map::CrateDefMap, resolution::path_resolver::PathResolver}, @@ -33,9 +33,9 @@ use crate::{ Statement, }; use crate::{ - ArrayLiteral, ContractFunctionType, Generics, LValue, NoirStruct, NoirTyAlias, Path, Pattern, - Shared, StructType, Type, TypeAliasTy, TypeBinding, TypeVariable, UnaryOp, UnresolvedGenerics, - UnresolvedType, UnresolvedTypeExpression, ERROR_IDENT, + ArrayLiteral, ContractFunctionType, Generics, LValue, NoirStruct, NoirTypeAlias, Path, Pattern, + Shared, StructType, Type, TypeAliasType, TypeBinding, TypeVariable, UnaryOp, + UnresolvedGenerics, UnresolvedType, UnresolvedTypeExpression, ERROR_IDENT, }; use fm::FileId; use iter_extended::vecmap; @@ -398,12 +398,12 @@ impl<'a> Resolver<'a> { let span = path.span(); if let Some(type_alias_type) = self.lookup_type_alias(path.clone()) { let mut args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); - let expected_generic_count = type_alias_type.borrow().generics.len(); + let expected_generic_count = type_alias_type.generics.len(); if args.len() != expected_generic_count { self.push_err(ResolverError::IncorrectGenericCount { span, - struct_type: type_alias_type.borrow().to_string(), + struct_type: type_alias_type.to_string(), actual: args.len(), expected: expected_generic_count, }); @@ -412,10 +412,8 @@ impl<'a> Resolver<'a> { args.resize_with(expected_generic_count, || Type::Error); } - // Type Alias is monomorphized here because we do type checking before monomorphization - // If this is done in normal monomorphization phase type checking will return errors - // TODO(ethan): not sure if this is the best practice though - let typ = type_alias_type.borrow().get_type(&args); + // resolve type generics + let typ = type_alias_type.get_type(&args); return typ; } @@ -534,14 +532,19 @@ impl<'a> Resolver<'a> { self.resolve_type_inner(typ, &mut vec![]) } - pub fn resolve_type_aliases(&mut self, unresolved: NoirTyAlias) -> (Type, Generics) { + pub fn resolve_type_aliases( + mut self, + unresolved: NoirTypeAlias, + ) -> (Type, Generics, Vec) { + // println!("unresolved: {:?}", unresolved); + let generics = self.add_generics(&unresolved.generics); self.resolve_local_globals(); let typ = self.resolve_type(unresolved.ty); - (typ, generics) + (typ, generics, self.errors) } pub fn take_errors(self) -> Vec { @@ -1198,7 +1201,7 @@ impl<'a> Resolver<'a> { self.interner.get_struct(type_id) } - pub fn get_type_alias(&self, type_alias_id: TyAliasId) -> Shared { + pub fn get_type_alias(&self, type_alias_id: TypeAliasId) -> TypeAliasType { self.interner.get_type_alias(type_alias_id) } @@ -1264,7 +1267,7 @@ impl<'a> Resolver<'a> { } } - fn lookup_type_alias(&mut self, path: Path) -> Option> { + fn lookup_type_alias(&mut self, path: Path) -> Option { match self.lookup(path) { Ok(type_alias_id) => Some(self.get_type_alias(type_alias_id)), Err(_) => None, diff --git a/crates/noirc_frontend/src/hir_def/types.rs b/crates/noirc_frontend/src/hir_def/types.rs index 4fd4012fea1..8179abf9d67 100644 --- a/crates/noirc_frontend/src/hir_def/types.rs +++ b/crates/noirc_frontend/src/hir_def/types.rs @@ -7,7 +7,7 @@ use std::{ use crate::{ hir::type_check::TypeCheckError, - node_interner::{NodeInterner, TyAliasId}, + node_interner::{NodeInterner, TypeAliasId}, }; use iter_extended::vecmap; use noirc_abi::AbiType; @@ -227,46 +227,46 @@ impl std::fmt::Display for StructType { /// Wrap around an unsolved type #[derive(Debug, Clone, Eq)] -pub struct TypeAliasTy { +pub struct TypeAliasType { pub name: Ident, - pub id: TyAliasId, + pub id: TypeAliasId, pub typ: Type, pub generics: Generics, pub span: Span, } -impl std::hash::Hash for TypeAliasTy { +impl std::hash::Hash for TypeAliasType { fn hash(&self, state: &mut H) { self.id.hash(state); } } -impl PartialEq for TypeAliasTy { +impl PartialEq for TypeAliasType { fn eq(&self, other: &Self) -> bool { self.id == other.id } } -impl std::fmt::Display for TypeAliasTy { +impl std::fmt::Display for TypeAliasType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.typ) } } -impl TypeAliasTy { +impl TypeAliasType { pub fn new( - id: TyAliasId, + id: TypeAliasId, name: Ident, span: Span, typ: Type, generics: Generics, - ) -> TypeAliasTy { - TypeAliasTy { id, typ, name, span, generics } + ) -> TypeAliasType { + TypeAliasType { id, typ, name, span, generics } } - pub fn set_type(&mut self, typ: Type) { + pub fn set_type(&mut self, new_typ: Type) { assert_eq!(self.typ, Type::Unit); - self.typ = typ; + self.typ = new_typ; } // Returns all the fields of this type, after being applied to the given generic arguments. @@ -282,11 +282,6 @@ impl TypeAliasTy { self.typ.substitute(&substitutions) } - - pub fn generic_is_numeric(&self, index_of_generic: usize) -> bool { - let target_id = self.generics[index_of_generic].0; - self.typ.contains_numeric_typevar(target_id) - } } /// A shared, mutable reference to some T. diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index cd0b13e769d..2c12d8434aa 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -17,7 +17,7 @@ use crate::hir_def::{ function::{FuncMeta, HirFunction}, stmt::HirStatement, }; -use crate::{Shared, TypeAliasTy, TypeBinding, TypeBindings, TypeVariable, TypeVariableId}; +use crate::{Shared, TypeAliasType, TypeBinding, TypeBindings, TypeVariable, TypeVariableId}; /// The node interner is the central storage location of all nodes in Noir's Hir (the /// various node types can be found in hir_def). The interner is also used to collect @@ -56,7 +56,7 @@ pub struct NodeInterner { // // Map type aliases to the actual type. // When resolving types, check against this map to see if a type alias is defined. - type_aliases: HashMap>, + type_aliases: HashMap, /// Map from ExprId (referring to a Function/Method call) to its corresponding TypeBindings, /// filled out during type checking from instantiated variables. Used during monomorphization @@ -144,14 +144,11 @@ impl StructId { } #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] -pub struct TyAliasId(Index); +pub struct TypeAliasId(Index); -impl TyAliasId { - //dummy id for error reporting - // This can be anything, as the program will ultimately fail - // after resolution - pub fn dummy_id() -> TyAliasId { - TyAliasId(Index::from_raw_parts(std::usize::MAX, 0)) +impl TypeAliasId { + pub fn dummy_id() -> TypeAliasId { + TypeAliasId(Index::from_raw_parts(std::usize::MAX, 0)) } } @@ -295,8 +292,8 @@ impl NodeInterner { pub fn push_expr(&mut self, expr: HirExpression) -> ExprId { ExprId(self.nodes.insert(Node::Expression(expr))) } - pub fn push_type_alias(&mut self) -> TyAliasId { - TyAliasId(self.nodes.insert(Node::TypeAlias)) + pub fn push_type_alias(&mut self) -> TypeAliasId { + TypeAliasId(self.nodes.insert(Node::TypeAlias)) } /// Stores the span for an interned expression. @@ -334,10 +331,10 @@ impl NodeInterner { ); } - pub fn push_empty_type_alias(&mut self, type_id: TyAliasId, typ: &UnresolvedTypeAlias) { + pub fn push_empty_type_alias(&mut self, type_id: TypeAliasId, typ: &UnresolvedTypeAlias) { self.type_aliases.insert( type_id, - Shared::new(TypeAliasTy::new( + TypeAliasType::new( type_id, typ.type_alias_def.name.clone(), typ.type_alias_def.span, @@ -346,7 +343,7 @@ impl NodeInterner { let id = TypeVariableId(0); (id, Shared::new(TypeBinding::Unbound(id))) }), - )), + ), ); } @@ -355,8 +352,8 @@ impl NodeInterner { f(&mut value); } - pub fn update_type_alias(&mut self, type_id: TyAliasId, f: impl FnOnce(&mut TypeAliasTy)) { - let mut value = self.type_aliases.get_mut(&type_id).unwrap().borrow_mut(); + pub fn update_type_alias(&mut self, type_id: TypeAliasId, f: impl FnOnce(&mut TypeAliasType)) { + let mut value = self.type_aliases.get_mut(&type_id).unwrap(); f(&mut value); } @@ -556,7 +553,7 @@ impl NodeInterner { self.structs[&id].clone() } - pub fn get_type_alias(&self, id: TyAliasId) -> Shared { + pub fn get_type_alias(&self, id: TypeAliasId) -> TypeAliasType { self.type_aliases[&id].clone() } diff --git a/crates/noirc_frontend/src/parser/mod.rs b/crates/noirc_frontend/src/parser/mod.rs index 42ef77cb808..ad519836b39 100644 --- a/crates/noirc_frontend/src/parser/mod.rs +++ b/crates/noirc_frontend/src/parser/mod.rs @@ -17,7 +17,7 @@ use crate::token::{Keyword, Token}; use crate::{ast::ImportStatement, Expression, NoirStruct}; use crate::{ BlockExpression, ExpressionKind, ForExpression, Ident, IndexExpression, LetStatement, - MethodCallExpression, NoirFunction, NoirTrait, NoirTyAlias, Path, PathKind, Pattern, + MethodCallExpression, NoirFunction, NoirTrait, NoirTypeAlias, Path, PathKind, Pattern, Recoverable, Statement, TraitImpl, TypeImpl, UnresolvedType, UseTree, }; @@ -43,7 +43,7 @@ pub(crate) enum TopLevelStatement { Trait(NoirTrait), TraitImpl(TraitImpl), Impl(TypeImpl), - TyAlias(NoirTyAlias), + TypeAlias(NoirTypeAlias), SubModule(SubModule), Global(LetStatement), Error, @@ -226,7 +226,7 @@ pub struct ParsedModule { pub traits: Vec, pub trait_impls: Vec, pub impls: Vec, - pub type_aliases: Vec, + pub type_aliases: Vec, pub globals: Vec, /// Module declarations like `mod foo;` @@ -266,7 +266,7 @@ impl ParsedModule { self.impls.push(r#impl); } - fn push_type_alias(&mut self, type_alias: NoirTyAlias) { + fn push_type_alias(&mut self, type_alias: NoirTypeAlias) { self.type_aliases.push(type_alias); } @@ -469,7 +469,7 @@ impl std::fmt::Display for TopLevelStatement { TopLevelStatement::TraitImpl(i) => i.fmt(f), TopLevelStatement::Struct(s) => s.fmt(f), TopLevelStatement::Impl(i) => i.fmt(f), - TopLevelStatement::TyAlias(t) => t.fmt(f), + TopLevelStatement::TypeAlias(t) => t.fmt(f), TopLevelStatement::SubModule(s) => s.fmt(f), TopLevelStatement::Global(c) => c.fmt(f), TopLevelStatement::Error => write!(f, "error"), diff --git a/crates/noirc_frontend/src/parser/parser.rs b/crates/noirc_frontend/src/parser/parser.rs index 6da3907e748..c3fbcf60c02 100644 --- a/crates/noirc_frontend/src/parser/parser.rs +++ b/crates/noirc_frontend/src/parser/parser.rs @@ -36,7 +36,7 @@ use crate::token::{Attribute, Keyword, Token, TokenKind}; use crate::{ BinaryOp, BinaryOpKind, BlockExpression, CompTime, ConstrainStatement, FunctionDefinition, Ident, IfExpression, InfixExpression, LValue, Lambda, Literal, NoirFunction, NoirStruct, - NoirTrait, NoirTyAlias, Path, PathKind, Pattern, Recoverable, TraitConstraint, TraitImpl, + NoirTrait, NoirTypeAlias, Path, PathKind, Pattern, Recoverable, TraitConstraint, TraitImpl, TraitImplItem, TraitItem, TypeImpl, UnaryOp, UnresolvedTypeExpression, UseTree, UseTreeKind, }; @@ -82,7 +82,7 @@ fn module() -> impl NoirParser { TopLevelStatement::Trait(t) => program.push_trait(t), TopLevelStatement::TraitImpl(t) => program.push_trait_impl(t), TopLevelStatement::Impl(i) => program.push_impl(i), - TopLevelStatement::TyAlias(t) => program.push_type_alias(t), + TopLevelStatement::TypeAlias(t) => program.push_type_alias(t), TopLevelStatement::SubModule(s) => program.push_submodule(s), TopLevelStatement::Global(c) => program.push_global(c), TopLevelStatement::Error => (), @@ -247,7 +247,7 @@ fn type_alias_definition() -> impl NoirParser { let p = then_commit(p, parse_type()); p.map_with_span(|((name, generics), ty), span| { - TopLevelStatement::TyAlias(NoirTyAlias { name, generics, ty, span }) + TopLevelStatement::TypeAlias(NoirTypeAlias { name, generics, ty, span }) }) } From 4eac204b04bf03b8020e307f1f64c22f62bc9c6f Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Tue, 25 Jul 2023 17:21:08 +0100 Subject: [PATCH 11/33] . --- .../tests/test_data/type_aliases/src/main.nr | 40 +++++++++---------- .../src/hir/def_collector/dc_crate.rs | 3 -- .../src/hir/resolution/resolver.rs | 2 - crates/noirc_frontend/src/node_interner.rs | 1 + 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr index 04385937b85..b0993551e47 100644 --- a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr +++ b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr @@ -1,31 +1,31 @@ use dep::std; -//type Foo = [T; 2]; +type Foo = [T; 2]; -//type Bar = Field; +type Bar = Field; -type Three = Two; -type Two = One; -type One = (A, B); +//type Three = Two; +//type Two = One; +//type One = (A, B); -//struct MyStruct { -// foo: Bar, -//} +struct MyStruct { + foo: Bar, +} fn main(x : [Field; 2]) { - //let a: Foo = [1, 2]; - //assert(a[0] != x[0]); + let a: Foo = [1, 2]; + assert(a[0] != x[0]); - //let b: Bar = 2; - //assert(x[0] == b); + let b: Bar = 2; + assert(x[0] == b); - let c: u8 = 1; - let d: u32 = 2; - let e: Three = (c, d); - assert(e.0 == 1); + //let c: u8 = 1; + //let d: u32 = 2; + //let e: Three = (c, d); + //assert(e.0 == 1); - //let s = MyStruct { - // foo: 10 - //}; - //assert(s.foo == 10); + let s = MyStruct { + foo: 10 + }; + assert(s.foo == 10); } diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs index 9e2b9feec8f..27912ae9234 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -391,11 +391,8 @@ fn resolve_type_aliases( extend_errors(all_errors, file, errors); context.def_interner.update_type_alias(type_id, |type_alias_def| { - // println!("typ: {:?}", typ); type_alias_def.set_type(typ); - // println!("generics: {:?}", generics); type_alias_def.generics = generics; - // println!("type_alias_def: {:?}", type_alias_def); }); } } diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index e2a9b3f330a..f2ba01ffbc4 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -536,8 +536,6 @@ impl<'a> Resolver<'a> { mut self, unresolved: NoirTypeAlias, ) -> (Type, Generics, Vec) { - // println!("unresolved: {:?}", unresolved); - let generics = self.add_generics(&unresolved.generics); self.resolve_local_globals(); diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index 2c12d8434aa..6f9de7932eb 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::rc::Rc; use arena::{Arena, Index}; use fm::FileId; From 2d3bfb698ea7f0fda54742966eeaf7280ef259a1 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Tue, 25 Jul 2023 17:22:28 +0100 Subject: [PATCH 12/33] clippy --- crates/noirc_frontend/src/node_interner.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index 6f9de7932eb..e9074459ec5 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -1,5 +1,4 @@ use std::collections::HashMap; -use std::rc::Rc; use arena::{Arena, Index}; use fm::FileId; @@ -354,8 +353,8 @@ impl NodeInterner { } pub fn update_type_alias(&mut self, type_id: TypeAliasId, f: impl FnOnce(&mut TypeAliasType)) { - let mut value = self.type_aliases.get_mut(&type_id).unwrap(); - f(&mut value); + let value = self.type_aliases.get_mut(&type_id).unwrap(); + f(value); } /// Returns the interned statement corresponding to `stmt_id` From 35c2639edec2b73731a03ef9f6a496aa3aa927ca Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Tue, 25 Jul 2023 18:09:33 +0100 Subject: [PATCH 13/33] move to collector --- crates/noirc_frontend/src/hir/def_collector/dc_crate.rs | 4 ---- crates/noirc_frontend/src/hir/def_collector/dc_mod.rs | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs index 27912ae9234..9794b4ae032 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -375,10 +375,6 @@ fn resolve_type_aliases( crate_id: CrateId, all_errors: &mut Vec, ) { - for (type_id, typ) in &type_aliases { - context.def_interner.push_empty_type_alias(*type_id, typ); - } - for (type_id, unresolved_typ) in type_aliases { let path_resolver = StandardPathResolver::new(ModuleId { local_id: unresolved_typ.module_id, diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs index 98733a9723e..ada449ad81b 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -215,6 +215,10 @@ impl<'a> ModCollector<'a> { }; self.def_collector.collected_type_aliases.insert(ty_alias_id, unresolved); } + + for (type_id, typ) in &self.def_collector.collected_type_aliases { + context.def_interner.push_empty_type_alias(*type_id, typ); + } } fn collect_submodules( From 649ed8a3b691bdc323f4b8ee6ed10f0bd6a357ee Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Wed, 26 Jul 2023 14:38:08 +0100 Subject: [PATCH 14/33] working? --- .../tests/test_data/type_aliases/src/main.nr | 14 +++++++------- crates/noirc_frontend/src/hir_def/types.rs | 2 +- crates/noirc_frontend/src/node_interner.rs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr index b0993551e47..6cfafc91b7d 100644 --- a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr +++ b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr @@ -4,9 +4,9 @@ type Foo = [T; 2]; type Bar = Field; -//type Three = Two; -//type Two = One; -//type One = (A, B); +type Three = Two; +type Two = One; +type One = (A, B); struct MyStruct { foo: Bar, @@ -19,10 +19,10 @@ fn main(x : [Field; 2]) { let b: Bar = 2; assert(x[0] == b); - //let c: u8 = 1; - //let d: u32 = 2; - //let e: Three = (c, d); - //assert(e.0 == 1); + let c: u8 = 1; + let d: u32 = 2; + let e: Three = (c, d); + assert(e.0 == 1); let s = MyStruct { foo: 10 diff --git a/crates/noirc_frontend/src/hir_def/types.rs b/crates/noirc_frontend/src/hir_def/types.rs index 8179abf9d67..abb62599710 100644 --- a/crates/noirc_frontend/src/hir_def/types.rs +++ b/crates/noirc_frontend/src/hir_def/types.rs @@ -265,7 +265,7 @@ impl TypeAliasType { } pub fn set_type(&mut self, new_typ: Type) { - assert_eq!(self.typ, Type::Unit); + assert_eq!(self.typ, Type::Error); self.typ = new_typ; } diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index e9074459ec5..356e78612f9 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -338,7 +338,7 @@ impl NodeInterner { type_id, typ.type_alias_def.name.clone(), typ.type_alias_def.span, - Type::Unit, + Type::Error, vecmap(&typ.type_alias_def.generics, |_| { let id = TypeVariableId(0); (id, Shared::new(TypeBinding::Unbound(id))) From 2cd5dc3935fca160c952815c0dc17c516a74561c Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Wed, 26 Jul 2023 14:49:40 +0100 Subject: [PATCH 15/33] working? --- .../src/hir/def_collector/dc_mod.rs | 18 +++++++++++++----- crates/noirc_frontend/src/node_interner.rs | 8 ++------ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs index ada449ad81b..d11326ee589 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -2,9 +2,11 @@ use fm::FileId; use noirc_errors::FileDiagnostic; use crate::{ - graph::CrateId, hir::def_collector::dc_crate::UnresolvedStruct, node_interner::StructId, - parser::SubModule, Ident, LetStatement, NoirFunction, NoirStruct, NoirTypeAlias, ParsedModule, - TypeImpl, + graph::CrateId, + hir::def_collector::dc_crate::UnresolvedStruct, + node_interner::{StructId, TypeAliasId}, + parser::SubModule, + Ident, LetStatement, NoirFunction, NoirStruct, NoirTypeAlias, ParsedModule, TypeImpl, }; use super::{ @@ -56,7 +58,7 @@ pub fn collect_defs( collector.collect_structs(ast.types, crate_id, errors); - collector.collect_type_aliases(context, ast.type_aliases, errors); + collector.collect_type_aliases(context, ast.type_aliases, crate_id, errors); collector.collect_functions(context, ast.functions, errors); @@ -192,12 +194,18 @@ impl<'a> ModCollector<'a> { &mut self, context: &mut Context, type_aliases: Vec, + krate: CrateId, errors: &mut Vec, ) { for type_alias in type_aliases { let name = type_alias.name.clone(); - let ty_alias_id = context.def_interner.push_type_alias(); + // let ty_alias_id = context.def_interner.push_type_alias(); + let ty_alias_id = + match self.push_child_module(&name, self.file_id, false, false, errors) { + Some(local_id) => TypeAliasId(ModuleId { krate, local_id }), + None => continue, + }; // Add the type alias to scope so its path can be looked up later let result = self.def_collector.def_map.modules[self.module_id.0] .declare_type_alias(name, ty_alias_id); diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index 356e78612f9..355da769ced 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -144,11 +144,11 @@ impl StructId { } #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] -pub struct TypeAliasId(Index); +pub struct TypeAliasId(pub ModuleId); impl TypeAliasId { pub fn dummy_id() -> TypeAliasId { - TypeAliasId(Index::from_raw_parts(std::usize::MAX, 0)) + TypeAliasId(ModuleId { krate: CrateId::dummy_id(), local_id: LocalModuleId::dummy_id() }) } } @@ -194,7 +194,6 @@ enum Node { Function(HirFunction), Statement(HirStatement), Expression(HirExpression), - TypeAlias, } #[derive(Debug, Clone)] @@ -292,9 +291,6 @@ impl NodeInterner { pub fn push_expr(&mut self, expr: HirExpression) -> ExprId { ExprId(self.nodes.insert(Node::Expression(expr))) } - pub fn push_type_alias(&mut self) -> TypeAliasId { - TypeAliasId(self.nodes.insert(Node::TypeAlias)) - } /// Stores the span for an interned expression. pub fn push_expr_location(&mut self, expr_id: ExprId, span: Span, file: FileId) { From 50bc485597c327b582c8eb5b494ac0536bbb8adf Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Wed, 26 Jul 2023 14:52:55 +0100 Subject: [PATCH 16/33] move test to new_ssa --- .../{test_data => test_data_ssa_refactor}/type_aliases/Nargo.toml | 0 .../type_aliases/Prover.toml | 0 .../type_aliases/src/main.nr | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename crates/nargo_cli/tests/{test_data => test_data_ssa_refactor}/type_aliases/Nargo.toml (100%) rename crates/nargo_cli/tests/{test_data => test_data_ssa_refactor}/type_aliases/Prover.toml (100%) rename crates/nargo_cli/tests/{test_data => test_data_ssa_refactor}/type_aliases/src/main.nr (100%) diff --git a/crates/nargo_cli/tests/test_data/type_aliases/Nargo.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/type_aliases/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/test_data/type_aliases/Nargo.toml rename to crates/nargo_cli/tests/test_data_ssa_refactor/type_aliases/Nargo.toml diff --git a/crates/nargo_cli/tests/test_data/type_aliases/Prover.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/type_aliases/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/test_data/type_aliases/Prover.toml rename to crates/nargo_cli/tests/test_data_ssa_refactor/type_aliases/Prover.toml diff --git a/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr b/crates/nargo_cli/tests/test_data_ssa_refactor/type_aliases/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/test_data/type_aliases/src/main.nr rename to crates/nargo_cli/tests/test_data_ssa_refactor/type_aliases/src/main.nr From 83ec6cd7e19ab3bbec2a9d26e82f501596e7ae4d Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Wed, 26 Jul 2023 15:15:18 +0100 Subject: [PATCH 17/33] resolve type alias name in module --- crates/noirc_frontend/src/hir/resolution/import.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/noirc_frontend/src/hir/resolution/import.rs b/crates/noirc_frontend/src/hir/resolution/import.rs index 50e8be75904..b66ffc207c5 100644 --- a/crates/noirc_frontend/src/hir/resolution/import.rs +++ b/crates/noirc_frontend/src/hir/resolution/import.rs @@ -152,7 +152,7 @@ fn resolve_name_in_module( ModuleDefId::FunctionId(_) => panic!("functions cannot be in the type namespace"), // TODO: If impls are ever implemented, types can be used in a path ModuleDefId::TypeId(id) => id.0, - ModuleDefId::TypeAliasId(_) => panic!("type aliases cannot be in the type namespace"), + ModuleDefId::TypeAliasId(id) => id.0, ModuleDefId::GlobalId(_) => panic!("globals cannot be in the type namespace"), }; From 8b26665123b508f8976e2bdc2efa9d576dbe0e79 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Wed, 26 Jul 2023 16:08:31 +0100 Subject: [PATCH 18/33] . --- crates/noirc_frontend/src/hir/def_collector/dc_mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs index d11326ee589..6c7bcb19fd9 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -200,7 +200,6 @@ impl<'a> ModCollector<'a> { for type_alias in type_aliases { let name = type_alias.name.clone(); - // let ty_alias_id = context.def_interner.push_type_alias(); let ty_alias_id = match self.push_child_module(&name, self.file_id, false, false, errors) { Some(local_id) => TypeAliasId(ModuleId { krate, local_id }), From ff712e5a9adb0c3470359ea63eb45a6948d0e7e9 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Wed, 26 Jul 2023 16:11:35 +0100 Subject: [PATCH 19/33] comments --- crates/noirc_frontend/src/hir/resolution/resolver.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index f2ba01ffbc4..6b740ebef96 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -412,7 +412,7 @@ impl<'a> Resolver<'a> { args.resize_with(expected_generic_count, || Type::Error); } - // resolve type generics + // resolve generics in type aliases let typ = type_alias_type.get_type(&args); return typ; @@ -537,9 +537,7 @@ impl<'a> Resolver<'a> { unresolved: NoirTypeAlias, ) -> (Type, Generics, Vec) { let generics = self.add_generics(&unresolved.generics); - self.resolve_local_globals(); - let typ = self.resolve_type(unresolved.ty); (typ, generics, self.errors) From 5c60dd6c4ee6666c3b5da21c66a8a9de832cb025 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Wed, 26 Jul 2023 18:53:58 +0100 Subject: [PATCH 20/33] review --- .../src/hir/def_collector/dc_crate.rs | 5 +-- .../src/hir/def_collector/dc_mod.rs | 14 ++----- .../src/hir/resolution/import.rs | 2 +- .../src/hir/resolution/resolver.rs | 4 +- crates/noirc_frontend/src/hir_def/types.rs | 3 +- crates/noirc_frontend/src/node_interner.rs | 41 +++++++++---------- 6 files changed, 28 insertions(+), 41 deletions(-) diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs index 9794b4ae032..e974961a405 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -386,10 +386,7 @@ fn resolve_type_aliases( .resolve_type_aliases(unresolved_typ.type_alias_def); extend_errors(all_errors, file, errors); - context.def_interner.update_type_alias(type_id, |type_alias_def| { - type_alias_def.set_type(typ); - type_alias_def.generics = generics; - }); + context.def_interner.set_type_alias(type_id, typ, generics); } } diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs index 6c7bcb19fd9..b74ff1f5d2d 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -58,7 +58,7 @@ pub fn collect_defs( collector.collect_structs(ast.types, crate_id, errors); - collector.collect_type_aliases(context, ast.type_aliases, crate_id, errors); + collector.collect_type_aliases(context, ast.type_aliases, errors); collector.collect_functions(context, ast.functions, errors); @@ -194,17 +194,12 @@ impl<'a> ModCollector<'a> { &mut self, context: &mut Context, type_aliases: Vec, - krate: CrateId, errors: &mut Vec, ) { for type_alias in type_aliases { let name = type_alias.name.clone(); - let ty_alias_id = - match self.push_child_module(&name, self.file_id, false, false, errors) { - Some(local_id) => TypeAliasId(ModuleId { krate, local_id }), - None => continue, - }; + let ty_alias_id = TypeAliasId(self.def_collector.collected_type_aliases.len()); // Add the type alias to scope so its path can be looked up later let result = self.def_collector.def_map.modules[self.module_id.0] .declare_type_alias(name, ty_alias_id); @@ -220,12 +215,9 @@ impl<'a> ModCollector<'a> { module_id: self.module_id, type_alias_def: type_alias, }; + context.def_interner.push_empty_type_alias(ty_alias_id, &unresolved); self.def_collector.collected_type_aliases.insert(ty_alias_id, unresolved); } - - for (type_id, typ) in &self.def_collector.collected_type_aliases { - context.def_interner.push_empty_type_alias(*type_id, typ); - } } fn collect_submodules( diff --git a/crates/noirc_frontend/src/hir/resolution/import.rs b/crates/noirc_frontend/src/hir/resolution/import.rs index b66ffc207c5..eeccda97ffb 100644 --- a/crates/noirc_frontend/src/hir/resolution/import.rs +++ b/crates/noirc_frontend/src/hir/resolution/import.rs @@ -152,7 +152,7 @@ fn resolve_name_in_module( ModuleDefId::FunctionId(_) => panic!("functions cannot be in the type namespace"), // TODO: If impls are ever implemented, types can be used in a path ModuleDefId::TypeId(id) => id.0, - ModuleDefId::TypeAliasId(id) => id.0, + ModuleDefId::TypeAliasId(_) => unimplemented!(), ModuleDefId::GlobalId(_) => panic!("globals cannot be in the type namespace"), }; diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index 6b740ebef96..7f6adbaac72 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -413,9 +413,7 @@ impl<'a> Resolver<'a> { } // resolve generics in type aliases - let typ = type_alias_type.get_type(&args); - - return typ; + return type_alias_type.get_type(&args); } match self.lookup_struct_or_error(path) { diff --git a/crates/noirc_frontend/src/hir_def/types.rs b/crates/noirc_frontend/src/hir_def/types.rs index abb62599710..6a33829f407 100644 --- a/crates/noirc_frontend/src/hir_def/types.rs +++ b/crates/noirc_frontend/src/hir_def/types.rs @@ -264,9 +264,10 @@ impl TypeAliasType { TypeAliasType { id, typ, name, span, generics } } - pub fn set_type(&mut self, new_typ: Type) { + pub fn set_type_and_generics(&mut self, new_typ: Type, new_generics: Generics) { assert_eq!(self.typ, Type::Error); self.typ = new_typ; + self.generics = new_generics; } // Returns all the fields of this type, after being applied to the given generic arguments. diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index 355da769ced..f054fbb4ed1 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -17,7 +17,9 @@ use crate::hir_def::{ function::{FuncMeta, HirFunction}, stmt::HirStatement, }; -use crate::{Shared, TypeAliasType, TypeBinding, TypeBindings, TypeVariable, TypeVariableId}; +use crate::{ + Generics, Shared, TypeAliasType, TypeBinding, TypeBindings, TypeVariable, TypeVariableId, +}; /// The node interner is the central storage location of all nodes in Noir's Hir (the /// various node types can be found in hir_def). The interner is also used to collect @@ -56,7 +58,7 @@ pub struct NodeInterner { // // Map type aliases to the actual type. // When resolving types, check against this map to see if a type alias is defined. - type_aliases: HashMap, + type_aliases: Vec, /// Map from ExprId (referring to a Function/Method call) to its corresponding TypeBindings, /// filled out during type checking from instantiated variables. Used during monomorphization @@ -144,11 +146,11 @@ impl StructId { } #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] -pub struct TypeAliasId(pub ModuleId); +pub struct TypeAliasId(pub usize); impl TypeAliasId { pub fn dummy_id() -> TypeAliasId { - TypeAliasId(ModuleId { krate: CrateId::dummy_id(), local_id: LocalModuleId::dummy_id() }) + TypeAliasId(std::usize::MAX) } } @@ -263,7 +265,7 @@ impl Default for NodeInterner { definitions: vec![], id_to_type: HashMap::new(), structs: HashMap::new(), - type_aliases: HashMap::new(), + type_aliases: Vec::new(), instantiation_bindings: HashMap::new(), field_indices: HashMap::new(), next_type_variable_id: 0, @@ -328,19 +330,16 @@ impl NodeInterner { } pub fn push_empty_type_alias(&mut self, type_id: TypeAliasId, typ: &UnresolvedTypeAlias) { - self.type_aliases.insert( + self.type_aliases.push(TypeAliasType::new( type_id, - TypeAliasType::new( - type_id, - typ.type_alias_def.name.clone(), - typ.type_alias_def.span, - Type::Error, - vecmap(&typ.type_alias_def.generics, |_| { - let id = TypeVariableId(0); - (id, Shared::new(TypeBinding::Unbound(id))) - }), - ), - ); + typ.type_alias_def.name.clone(), + typ.type_alias_def.span, + Type::Error, + vecmap(&typ.type_alias_def.generics, |_| { + let id = TypeVariableId(0); + (id, Shared::new(TypeBinding::Unbound(id))) + }), + )); } pub fn update_struct(&mut self, type_id: StructId, f: impl FnOnce(&mut StructType)) { @@ -348,9 +347,9 @@ impl NodeInterner { f(&mut value); } - pub fn update_type_alias(&mut self, type_id: TypeAliasId, f: impl FnOnce(&mut TypeAliasType)) { - let value = self.type_aliases.get_mut(&type_id).unwrap(); - f(value); + pub fn set_type_alias(&mut self, type_id: TypeAliasId, typ: Type, generics: Generics) { + let type_alias_type = &mut self.type_aliases[type_id.0]; + type_alias_type.set_type_and_generics(typ, generics); } /// Returns the interned statement corresponding to `stmt_id` @@ -550,7 +549,7 @@ impl NodeInterner { } pub fn get_type_alias(&self, id: TypeAliasId) -> TypeAliasType { - self.type_aliases[&id].clone() + self.type_aliases[id.0].clone() } pub fn get_global(&self, stmt_id: &StmtId) -> Option { From fe47dec9cb67e2898cc6c09d00fdd4c5e32cd660 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Mon, 31 Jul 2023 14:44:02 +0100 Subject: [PATCH 21/33] move test to test_data folder --- .../{test_data_ssa_refactor => test_data}/type_aliases/Nargo.toml | 0 .../type_aliases/Prover.toml | 0 .../type_aliases/src/main.nr | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename crates/nargo_cli/tests/{test_data_ssa_refactor => test_data}/type_aliases/Nargo.toml (100%) rename crates/nargo_cli/tests/{test_data_ssa_refactor => test_data}/type_aliases/Prover.toml (100%) rename crates/nargo_cli/tests/{test_data_ssa_refactor => test_data}/type_aliases/src/main.nr (100%) diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/type_aliases/Nargo.toml b/crates/nargo_cli/tests/test_data/type_aliases/Nargo.toml similarity index 100% rename from crates/nargo_cli/tests/test_data_ssa_refactor/type_aliases/Nargo.toml rename to crates/nargo_cli/tests/test_data/type_aliases/Nargo.toml diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/type_aliases/Prover.toml b/crates/nargo_cli/tests/test_data/type_aliases/Prover.toml similarity index 100% rename from crates/nargo_cli/tests/test_data_ssa_refactor/type_aliases/Prover.toml rename to crates/nargo_cli/tests/test_data/type_aliases/Prover.toml diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/type_aliases/src/main.nr b/crates/nargo_cli/tests/test_data/type_aliases/src/main.nr similarity index 100% rename from crates/nargo_cli/tests/test_data_ssa_refactor/type_aliases/src/main.nr rename to crates/nargo_cli/tests/test_data/type_aliases/src/main.nr From 8c5df0d7c8be2bf53f9a41e54bc4a6ed8f936310 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Mon, 31 Jul 2023 14:50:45 +0100 Subject: [PATCH 22/33] type aliases cannot be used in type namespace --- crates/noirc_frontend/src/hir/resolution/import.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/noirc_frontend/src/hir/resolution/import.rs b/crates/noirc_frontend/src/hir/resolution/import.rs index eeccda97ffb..9a6ef9b1b8b 100644 --- a/crates/noirc_frontend/src/hir/resolution/import.rs +++ b/crates/noirc_frontend/src/hir/resolution/import.rs @@ -152,7 +152,7 @@ fn resolve_name_in_module( ModuleDefId::FunctionId(_) => panic!("functions cannot be in the type namespace"), // TODO: If impls are ever implemented, types can be used in a path ModuleDefId::TypeId(id) => id.0, - ModuleDefId::TypeAliasId(_) => unimplemented!(), + ModuleDefId::TypeAliasId(_) => panic!("type aliases cannot be used in type namespace"), ModuleDefId::GlobalId(_) => panic!("globals cannot be in the type namespace"), }; From fc6a41babb7121503cdd45c4a38cee68802e92a7 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Mon, 31 Jul 2023 15:04:26 +0100 Subject: [PATCH 23/33] more efficient? --- .../tests/test_data/type_aliases/Nargo.toml | 1 + .../src/hir/resolution/resolver.rs | 11 ++++++----- crates/noirc_frontend/src/node_interner.rs | 16 +++++++++------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/crates/nargo_cli/tests/test_data/type_aliases/Nargo.toml b/crates/nargo_cli/tests/test_data/type_aliases/Nargo.toml index 5082c6e12ec..a797cb0bbe2 100644 --- a/crates/nargo_cli/tests/test_data/type_aliases/Nargo.toml +++ b/crates/nargo_cli/tests/test_data/type_aliases/Nargo.toml @@ -1,4 +1,5 @@ [package] +name = "type_aliases" authors = [""] compiler_version = "0.1" diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index 8a28f7c1905..3c64c98cbe3 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -18,6 +18,7 @@ use crate::hir_def::expr::{ HirMethodCallExpression, HirPrefixExpression, }; use crate::token::Attribute; +use std::cell::RefCell; use std::collections::{HashMap, HashSet}; use std::rc::Rc; @@ -399,12 +400,12 @@ impl<'a> Resolver<'a> { let span = path.span(); if let Some(type_alias_type) = self.lookup_type_alias(path.clone()) { let mut args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); - let expected_generic_count = type_alias_type.generics.len(); + let expected_generic_count = type_alias_type.borrow().generics.len(); if args.len() != expected_generic_count { self.push_err(ResolverError::IncorrectGenericCount { span, - struct_type: type_alias_type.to_string(), + struct_type: type_alias_type.borrow().to_string(), actual: args.len(), expected: expected_generic_count, }); @@ -414,7 +415,7 @@ impl<'a> Resolver<'a> { } // resolve generics in type aliases - return type_alias_type.get_type(&args); + return type_alias_type.borrow().get_type(&args); } match self.lookup_struct_or_error(path) { @@ -1203,7 +1204,7 @@ impl<'a> Resolver<'a> { self.interner.get_struct(type_id) } - pub fn get_type_alias(&self, type_alias_id: TypeAliasId) -> TypeAliasType { + pub fn get_type_alias(&self, type_alias_id: TypeAliasId) -> Rc> { self.interner.get_type_alias(type_alias_id) } @@ -1269,7 +1270,7 @@ impl<'a> Resolver<'a> { } } - fn lookup_type_alias(&mut self, path: Path) -> Option { + fn lookup_type_alias(&mut self, path: Path) -> Option>> { match self.lookup(path) { Ok(type_alias_id) => Some(self.get_type_alias(type_alias_id)), Err(_) => None, diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index c8e17fb1ea2..0bf185cb8aa 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -1,4 +1,6 @@ +use std::cell::RefCell; use std::collections::HashMap; +use std::rc::Rc; use arena::{Arena, Index}; use fm::FileId; @@ -18,10 +20,10 @@ use crate::hir_def::{ stmt::HirStatement, }; use crate::{ - Generics, Shared, TypeAliasType, TypeBinding, TypeBindings, TypeVariable, TypeVariableId, TypeVariableKind + Generics, Shared, TypeAliasType, TypeBinding, TypeBindings, TypeVariable, TypeVariableId, + TypeVariableKind, }; - /// The node interner is the central storage location of all nodes in Noir's Hir (the /// various node types can be found in hir_def). The interner is also used to collect /// extra information about the Hir, such as the type of each node, information about @@ -59,7 +61,7 @@ pub struct NodeInterner { // // Map type aliases to the actual type. // When resolving types, check against this map to see if a type alias is defined. - type_aliases: Vec, + type_aliases: Vec>>, /// Map from ExprId (referring to a Function/Method call) to its corresponding TypeBindings, /// filled out during type checking from instantiated variables. Used during monomorphization @@ -325,7 +327,7 @@ impl NodeInterner { } pub fn push_empty_type_alias(&mut self, type_id: TypeAliasId, typ: &UnresolvedTypeAlias) { - self.type_aliases.push(TypeAliasType::new( + self.type_aliases.push(Rc::new(RefCell::new(TypeAliasType::new( type_id, typ.type_alias_def.name.clone(), typ.type_alias_def.span, @@ -334,7 +336,7 @@ impl NodeInterner { let id = TypeVariableId(0); (id, Shared::new(TypeBinding::Unbound(id))) }), - )); + )))); } pub fn update_struct(&mut self, type_id: StructId, f: impl FnOnce(&mut StructType)) { @@ -343,7 +345,7 @@ impl NodeInterner { } pub fn set_type_alias(&mut self, type_id: TypeAliasId, typ: Type, generics: Generics) { - let type_alias_type = &mut self.type_aliases[type_id.0]; + let type_alias_type = &mut self.type_aliases[type_id.0].borrow_mut(); type_alias_type.set_type_and_generics(typ, generics); } @@ -543,7 +545,7 @@ impl NodeInterner { self.structs[&id].clone() } - pub fn get_type_alias(&self, id: TypeAliasId) -> TypeAliasType { + pub fn get_type_alias(&self, id: TypeAliasId) -> Rc> { self.type_aliases[id.0].clone() } From 15cba2a439e79101032978cc5a3844313e537410 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Mon, 31 Jul 2023 19:30:22 +0100 Subject: [PATCH 24/33] remove comment --- crates/noirc_frontend/src/hir_def/types.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/noirc_frontend/src/hir_def/types.rs b/crates/noirc_frontend/src/hir_def/types.rs index c2f36e68083..cd039800227 100644 --- a/crates/noirc_frontend/src/hir_def/types.rs +++ b/crates/noirc_frontend/src/hir_def/types.rs @@ -267,7 +267,6 @@ impl TypeAliasType { self.generics = new_generics; } - // Returns all the fields of this type, after being applied to the given generic arguments. pub fn get_type(&self, generic_args: &[Type]) -> Type { assert_eq!(self.generics.len(), generic_args.len()); From 13f481b2d527a45714e759d729052d1a511a65b0 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Mon, 31 Jul 2023 20:08:42 +0100 Subject: [PATCH 25/33] use interner for id --- crates/noirc_frontend/src/hir/def_collector/dc_mod.rs | 2 +- crates/noirc_frontend/src/node_interner.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs index b74ff1f5d2d..0a4b00cbc30 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -199,7 +199,7 @@ impl<'a> ModCollector<'a> { for type_alias in type_aliases { let name = type_alias.name.clone(); - let ty_alias_id = TypeAliasId(self.def_collector.collected_type_aliases.len()); + let ty_alias_id = TypeAliasId(context.def_interner.get_all_type_aliases().len()); // Add the type alias to scope so its path can be looked up later let result = self.def_collector.def_map.modules[self.module_id.0] .declare_type_alias(name, ty_alias_id); diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index 0bf185cb8aa..bd6a0a1033c 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -549,6 +549,10 @@ impl NodeInterner { self.type_aliases[id.0].clone() } + pub fn get_all_type_aliases(&self) -> &Vec>> { + &self.type_aliases + } + pub fn get_global(&self, stmt_id: &StmtId) -> Option { self.globals.get(stmt_id).cloned() } From dc050464ff8ddffa9b9e00567aa42c9b188df741 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Mon, 31 Jul 2023 21:35:06 +0100 Subject: [PATCH 26/33] . --- crates/noirc_frontend/src/hir/resolution/resolver.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index 3c64c98cbe3..b769404f948 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -398,8 +398,8 @@ impl<'a> Resolver<'a> { } let span = path.span(); + let mut args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); if let Some(type_alias_type) = self.lookup_type_alias(path.clone()) { - let mut args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); let expected_generic_count = type_alias_type.borrow().generics.len(); if args.len() != expected_generic_count { @@ -420,7 +420,6 @@ impl<'a> Resolver<'a> { match self.lookup_struct_or_error(path) { Some(struct_type) => { - let mut args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); let expected_generic_count = struct_type.borrow().generics.len(); if args.len() != expected_generic_count { From ac22a06c4d1677d1c732e83d0b6857383bda7e92 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Tue, 1 Aug 2023 14:27:26 -0500 Subject: [PATCH 27/33] Rework def_interner storage of aliases --- .../src/hir/def_collector/dc_mod.rs | 25 ++++--- .../src/hir/resolution/resolver.rs | 67 +++++++++---------- crates/noirc_frontend/src/hir_def/types.rs | 9 ++- crates/noirc_frontend/src/node_interner.rs | 24 +++---- 4 files changed, 64 insertions(+), 61 deletions(-) diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs index 0a4b00cbc30..cac2abf8523 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -2,11 +2,9 @@ use fm::FileId; use noirc_errors::FileDiagnostic; use crate::{ - graph::CrateId, - hir::def_collector::dc_crate::UnresolvedStruct, - node_interner::{StructId, TypeAliasId}, - parser::SubModule, - Ident, LetStatement, NoirFunction, NoirStruct, NoirTypeAlias, ParsedModule, TypeImpl, + graph::CrateId, hir::def_collector::dc_crate::UnresolvedStruct, node_interner::StructId, + parser::SubModule, Ident, LetStatement, NoirFunction, NoirStruct, NoirTypeAlias, ParsedModule, + TypeImpl, }; use super::{ @@ -199,7 +197,15 @@ impl<'a> ModCollector<'a> { for type_alias in type_aliases { let name = type_alias.name.clone(); - let ty_alias_id = TypeAliasId(context.def_interner.get_all_type_aliases().len()); + // And store the TypeId -> TypeAlias mapping somewhere it is reachable + let unresolved = UnresolvedTypeAlias { + file_id: self.file_id, + module_id: self.module_id, + type_alias_def: type_alias, + }; + + let ty_alias_id = context.def_interner.push_type_alias(&unresolved); + // Add the type alias to scope so its path can be looked up later let result = self.def_collector.def_map.modules[self.module_id.0] .declare_type_alias(name, ty_alias_id); @@ -209,13 +215,6 @@ impl<'a> ModCollector<'a> { errors.push(err.into_file_diagnostic(self.file_id)); } - // And store the TypeId -> TypeAlias mapping somewhere it is reachable - let unresolved = UnresolvedTypeAlias { - file_id: self.file_id, - module_id: self.module_id, - type_alias_def: type_alias, - }; - context.def_interner.push_empty_type_alias(ty_alias_id, &unresolved); self.def_collector.collected_type_aliases.insert(ty_alias_id, unresolved); } } diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index b769404f948..96473809855 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -399,40 +399,26 @@ impl<'a> Resolver<'a> { let span = path.span(); let mut args = vecmap(args, |arg| self.resolve_type_inner(arg, new_variables)); + if let Some(type_alias_type) = self.lookup_type_alias(path.clone()) { - let expected_generic_count = type_alias_type.borrow().generics.len(); - - if args.len() != expected_generic_count { - self.push_err(ResolverError::IncorrectGenericCount { - span, - struct_type: type_alias_type.borrow().to_string(), - actual: args.len(), - expected: expected_generic_count, - }); + let expected_generic_count = type_alias_type.generics.len(); + let type_alias_string = type_alias_type.to_string(); + let id = type_alias_type.id; - // Fix the generic count so we can continue typechecking - args.resize_with(expected_generic_count, || Type::Error); - } + self.verify_generics_count(expected_generic_count, &mut args, span, || { + type_alias_string + }); - // resolve generics in type aliases - return type_alias_type.borrow().get_type(&args); + return self.interner.get_type_alias(id).get_type(&args); } match self.lookup_struct_or_error(path) { Some(struct_type) => { let expected_generic_count = struct_type.borrow().generics.len(); - if args.len() != expected_generic_count { - self.push_err(ResolverError::IncorrectGenericCount { - span, - struct_type: struct_type.borrow().to_string(), - actual: args.len(), - expected: expected_generic_count, - }); - - // Fix the generic count so we can continue typechecking - args.resize_with(expected_generic_count, || Type::Error); - } + self.verify_generics_count(expected_generic_count, &mut args, span, || { + struct_type.borrow().to_string() + }); Type::Struct(struct_type, args) } @@ -440,6 +426,26 @@ impl<'a> Resolver<'a> { } } + fn verify_generics_count( + &mut self, + expected_count: usize, + args: &mut Vec, + span: Span, + type_name: impl FnOnce() -> String, + ) { + if args.len() != expected_count { + self.errors.push(ResolverError::IncorrectGenericCount { + span, + struct_type: type_name(), + actual: args.len(), + expected: expected_count, + }); + + // Fix the generic count so we can continue typechecking + args.resize_with(expected_count, || Type::Error); + } + } + fn lookup_generic_or_global_type(&mut self, path: &Path) -> Option { if path.segments.len() == 1 { let name = &path.last_segment().0.contents; @@ -1203,10 +1209,6 @@ impl<'a> Resolver<'a> { self.interner.get_struct(type_id) } - pub fn get_type_alias(&self, type_alias_id: TypeAliasId) -> Rc> { - self.interner.get_type_alias(type_alias_id) - } - fn lookup(&mut self, path: Path) -> Result { let span = path.span(); let id = self.resolve_path(path)?; @@ -1269,11 +1271,8 @@ impl<'a> Resolver<'a> { } } - fn lookup_type_alias(&mut self, path: Path) -> Option>> { - match self.lookup(path) { - Ok(type_alias_id) => Some(self.get_type_alias(type_alias_id)), - Err(_) => None, - } + fn lookup_type_alias(&mut self, path: Path) -> Option<&TypeAliasType> { + self.lookup(path).ok().map(|id| self.interner.get_type_alias(id)) } fn resolve_path(&mut self, path: Path) -> Result { diff --git a/crates/noirc_frontend/src/hir_def/types.rs b/crates/noirc_frontend/src/hir_def/types.rs index cd039800227..06884ad700d 100644 --- a/crates/noirc_frontend/src/hir_def/types.rs +++ b/crates/noirc_frontend/src/hir_def/types.rs @@ -246,7 +246,14 @@ impl PartialEq for TypeAliasType { impl std::fmt::Display for TypeAliasType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.typ) + write!(f, "{}", self.name)?; + + if !self.generics.is_empty() { + let generics = vecmap(&self.generics, |(_, binding)| binding.borrow().to_string()); + write!(f, "{}", generics.join(", "))?; + } + + Ok(()) } } diff --git a/crates/noirc_frontend/src/node_interner.rs b/crates/noirc_frontend/src/node_interner.rs index bd6a0a1033c..6a698ee0004 100644 --- a/crates/noirc_frontend/src/node_interner.rs +++ b/crates/noirc_frontend/src/node_interner.rs @@ -1,6 +1,4 @@ -use std::cell::RefCell; use std::collections::HashMap; -use std::rc::Rc; use arena::{Arena, Index}; use fm::FileId; @@ -61,7 +59,7 @@ pub struct NodeInterner { // // Map type aliases to the actual type. // When resolving types, check against this map to see if a type alias is defined. - type_aliases: Vec>>, + type_aliases: Vec, /// Map from ExprId (referring to a Function/Method call) to its corresponding TypeBindings, /// filled out during type checking from instantiated variables. Used during monomorphization @@ -326,8 +324,10 @@ impl NodeInterner { ); } - pub fn push_empty_type_alias(&mut self, type_id: TypeAliasId, typ: &UnresolvedTypeAlias) { - self.type_aliases.push(Rc::new(RefCell::new(TypeAliasType::new( + pub fn push_type_alias(&mut self, typ: &UnresolvedTypeAlias) -> TypeAliasId { + let type_id = TypeAliasId(self.type_aliases.len()); + + self.type_aliases.push(TypeAliasType::new( type_id, typ.type_alias_def.name.clone(), typ.type_alias_def.span, @@ -336,7 +336,9 @@ impl NodeInterner { let id = TypeVariableId(0); (id, Shared::new(TypeBinding::Unbound(id))) }), - )))); + )); + + type_id } pub fn update_struct(&mut self, type_id: StructId, f: impl FnOnce(&mut StructType)) { @@ -345,7 +347,7 @@ impl NodeInterner { } pub fn set_type_alias(&mut self, type_id: TypeAliasId, typ: Type, generics: Generics) { - let type_alias_type = &mut self.type_aliases[type_id.0].borrow_mut(); + let type_alias_type = &mut self.type_aliases[type_id.0]; type_alias_type.set_type_and_generics(typ, generics); } @@ -545,12 +547,8 @@ impl NodeInterner { self.structs[&id].clone() } - pub fn get_type_alias(&self, id: TypeAliasId) -> Rc> { - self.type_aliases[id.0].clone() - } - - pub fn get_all_type_aliases(&self) -> &Vec>> { - &self.type_aliases + pub fn get_type_alias(&self, id: TypeAliasId) -> &TypeAliasType { + &self.type_aliases[id.0] } pub fn get_global(&self, stmt_id: &StmtId) -> Option { From 672c7c3e2be15f598c2b28c70208a4c76994ec36 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 1 Aug 2023 14:52:58 -0500 Subject: [PATCH 28/33] Update crates/noirc_frontend/src/ast/type_alias.rs Co-authored-by: Maxim Vezenov --- crates/noirc_frontend/src/ast/type_alias.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/noirc_frontend/src/ast/type_alias.rs b/crates/noirc_frontend/src/ast/type_alias.rs index 49d8941f3b3..d8884b74d41 100644 --- a/crates/noirc_frontend/src/ast/type_alias.rs +++ b/crates/noirc_frontend/src/ast/type_alias.rs @@ -8,7 +8,7 @@ use std::fmt::Display; pub struct NoirTypeAlias { pub name: Ident, pub generics: UnresolvedGenerics, - pub ty: UnresolvedType, + pub typ: UnresolvedType, pub span: Span, } From ce34c80e5b0a587c28337cc1dad2a98dea0769b1 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 1 Aug 2023 14:53:05 -0500 Subject: [PATCH 29/33] Update crates/noirc_frontend/src/ast/type_alias.rs Co-authored-by: Maxim Vezenov --- crates/noirc_frontend/src/ast/type_alias.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/noirc_frontend/src/ast/type_alias.rs b/crates/noirc_frontend/src/ast/type_alias.rs index d8884b74d41..11e85b928ea 100644 --- a/crates/noirc_frontend/src/ast/type_alias.rs +++ b/crates/noirc_frontend/src/ast/type_alias.rs @@ -16,7 +16,7 @@ impl NoirTypeAlias { pub fn new( name: Ident, generics: UnresolvedGenerics, - ty: UnresolvedType, + typ: UnresolvedType, span: Span, ) -> NoirTypeAlias { NoirTypeAlias { name, generics, ty, span } From 901c973a6f9f55bc3518b573f69fccf9ed5aba23 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 1 Aug 2023 14:53:15 -0500 Subject: [PATCH 30/33] Update crates/noirc_frontend/src/ast/type_alias.rs Co-authored-by: Maxim Vezenov --- crates/noirc_frontend/src/ast/type_alias.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/noirc_frontend/src/ast/type_alias.rs b/crates/noirc_frontend/src/ast/type_alias.rs index 11e85b928ea..d01c25fb666 100644 --- a/crates/noirc_frontend/src/ast/type_alias.rs +++ b/crates/noirc_frontend/src/ast/type_alias.rs @@ -19,7 +19,7 @@ impl NoirTypeAlias { typ: UnresolvedType, span: Span, ) -> NoirTypeAlias { - NoirTypeAlias { name, generics, ty, span } + NoirTypeAlias { name, generics, typ, span } } } From 1e8c63beddee71dec043a233ee59b5b682bac1b5 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 1 Aug 2023 14:53:33 -0500 Subject: [PATCH 31/33] Update crates/noirc_frontend/src/hir/def_collector/dc_mod.rs Co-authored-by: Maxim Vezenov --- crates/noirc_frontend/src/hir/def_collector/dc_mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs index cac2abf8523..a65a94eaa9e 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -204,18 +204,18 @@ impl<'a> ModCollector<'a> { type_alias_def: type_alias, }; - let ty_alias_id = context.def_interner.push_type_alias(&unresolved); + let typ_alias_id = context.def_interner.push_type_alias(&unresolved); // Add the type alias to scope so its path can be looked up later let result = self.def_collector.def_map.modules[self.module_id.0] - .declare_type_alias(name, ty_alias_id); + .declare_type_alias(name, typ_alias_id); if let Err((first_def, second_def)) = result { let err = DefCollectorErrorKind::DuplicateFunction { first_def, second_def }; errors.push(err.into_file_diagnostic(self.file_id)); } - self.def_collector.collected_type_aliases.insert(ty_alias_id, unresolved); + self.def_collector.collected_type_aliases.insert(typ_alias_id, unresolved); } } From 2a9de519ba7c71b36662ad8fb43faa4ebb83a139 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 1 Aug 2023 14:53:39 -0500 Subject: [PATCH 32/33] Update crates/noirc_frontend/src/hir/resolution/resolver.rs Co-authored-by: Maxim Vezenov --- crates/noirc_frontend/src/hir/resolution/resolver.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index 0c70f3aa250..8b4f97dbd8e 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -548,7 +548,7 @@ impl<'a> Resolver<'a> { ) -> (Type, Generics, Vec) { let generics = self.add_generics(&unresolved.generics); self.resolve_local_globals(); - let typ = self.resolve_type(unresolved.ty); + let typ = self.resolve_type(unresolved.typ); (typ, generics, self.errors) } From c346c83ebde86cbdd852927aeab75de4d664df06 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Tue, 1 Aug 2023 14:55:37 -0500 Subject: [PATCH 33/33] typ -> type --- crates/noirc_frontend/src/ast/type_alias.rs | 2 +- crates/noirc_frontend/src/hir/def_collector/dc_mod.rs | 6 +++--- crates/noirc_frontend/src/parser/parser.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/noirc_frontend/src/ast/type_alias.rs b/crates/noirc_frontend/src/ast/type_alias.rs index d01c25fb666..76a1e5a7e30 100644 --- a/crates/noirc_frontend/src/ast/type_alias.rs +++ b/crates/noirc_frontend/src/ast/type_alias.rs @@ -26,6 +26,6 @@ impl NoirTypeAlias { impl Display for NoirTypeAlias { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let generics = vecmap(&self.generics, |generic| generic.to_string()); - write!(f, "type {}<{}> = {}", self.name, generics.join(", "), self.ty) + write!(f, "type {}<{}> = {}", self.name, generics.join(", "), self.typ) } } diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs index a65a94eaa9e..37c017ecb96 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -204,18 +204,18 @@ impl<'a> ModCollector<'a> { type_alias_def: type_alias, }; - let typ_alias_id = context.def_interner.push_type_alias(&unresolved); + let type_alias_id = context.def_interner.push_type_alias(&unresolved); // Add the type alias to scope so its path can be looked up later let result = self.def_collector.def_map.modules[self.module_id.0] - .declare_type_alias(name, typ_alias_id); + .declare_type_alias(name, type_alias_id); if let Err((first_def, second_def)) = result { let err = DefCollectorErrorKind::DuplicateFunction { first_def, second_def }; errors.push(err.into_file_diagnostic(self.file_id)); } - self.def_collector.collected_type_aliases.insert(typ_alias_id, unresolved); + self.def_collector.collected_type_aliases.insert(type_alias_id, unresolved); } } diff --git a/crates/noirc_frontend/src/parser/parser.rs b/crates/noirc_frontend/src/parser/parser.rs index e19e1bfaace..6445205eae6 100644 --- a/crates/noirc_frontend/src/parser/parser.rs +++ b/crates/noirc_frontend/src/parser/parser.rs @@ -246,8 +246,8 @@ fn type_alias_definition() -> impl NoirParser { let p = then_commit_ignore(p, just(Token::Assign)); let p = then_commit(p, parse_type()); - p.map_with_span(|((name, generics), ty), span| { - TopLevelStatement::TypeAlias(NoirTypeAlias { name, generics, ty, span }) + p.map_with_span(|((name, generics), typ), span| { + TopLevelStatement::TypeAlias(NoirTypeAlias { name, generics, typ, span }) }) }