Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement type aliases #2112

Merged
merged 38 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
6f7ea52
.
Ethan-000 Jul 21, 2023
07d946f
.
Ethan-000 Jul 21, 2023
96b9c94
.
Ethan-000 Jul 21, 2023
5dc1ff9
.
Ethan-000 Jul 21, 2023
86ac531
Merge branch 'noir-lang:master' into type_aliases_2
Ethan-000 Jul 21, 2023
0168106
stash
Ethan-000 Jul 22, 2023
ef80b01
.
Ethan-000 Jul 22, 2023
54c9c59
.
Ethan-000 Jul 22, 2023
3b61ee8
.
Ethan-000 Jul 22, 2023
5d10c18
remove tyalias as an hir type
Ethan-000 Jul 22, 2023
7d82d82
Merge remote-tracking branch 'origin/master' into type_aliases_2
Ethan-000 Jul 25, 2023
9d8bc59
namings
Ethan-000 Jul 25, 2023
4eac204
.
Ethan-000 Jul 25, 2023
2d3bfb6
clippy
Ethan-000 Jul 25, 2023
35c2639
move to collector
Ethan-000 Jul 25, 2023
649ed8a
working?
Ethan-000 Jul 26, 2023
2cd5dc3
working?
Ethan-000 Jul 26, 2023
50bc485
move test to new_ssa
Ethan-000 Jul 26, 2023
83ec6cd
resolve type alias name in module
Ethan-000 Jul 26, 2023
8b26665
.
Ethan-000 Jul 26, 2023
ff712e5
comments
Ethan-000 Jul 26, 2023
5c60dd6
review
Ethan-000 Jul 26, 2023
f917c08
Merge branch 'master' into type_aliases_2
Ethan-000 Jul 28, 2023
e1a6c48
Merge branch 'master' into type_aliases_2
Ethan-000 Jul 29, 2023
fe47dec
move test to test_data folder
Ethan-000 Jul 31, 2023
8c5df0d
type aliases cannot be used in type namespace
Ethan-000 Jul 31, 2023
fc6a41b
more efficient?
Ethan-000 Jul 31, 2023
15cba2a
remove comment
Ethan-000 Jul 31, 2023
13f481b
use interner for id
Ethan-000 Jul 31, 2023
dc05046
.
Ethan-000 Jul 31, 2023
ac22a06
Rework def_interner storage of aliases
jfecher Aug 1, 2023
163d9c3
Merge branch 'master' into pr/2003
jfecher Aug 1, 2023
672c7c3
Update crates/noirc_frontend/src/ast/type_alias.rs
jfecher Aug 1, 2023
ce34c80
Update crates/noirc_frontend/src/ast/type_alias.rs
jfecher Aug 1, 2023
901c973
Update crates/noirc_frontend/src/ast/type_alias.rs
jfecher Aug 1, 2023
1e8c63b
Update crates/noirc_frontend/src/hir/def_collector/dc_mod.rs
jfecher Aug 1, 2023
2a9de51
Update crates/noirc_frontend/src/hir/resolution/resolver.rs
jfecher Aug 1, 2023
c346c83
typ -> type
jfecher Aug 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions crates/nargo_cli/tests/test_data/type_aliases/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "type_aliases"
authors = [""]
compiler_version = "0.1"

[dependencies]
1 change: 1 addition & 0 deletions crates/nargo_cli/tests/test_data/type_aliases/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = [2, 3]
31 changes: 31 additions & 0 deletions crates/nargo_cli/tests/test_data/type_aliases/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use dep::std;

type Foo<T> = [T; 2];

type Bar = Field;

type Three = Two<u8>;
type Two<A> = One<A, u32>;
type One<A, B> = (A, B);

struct MyStruct {
foo: Bar,
}

fn main(x : [Field; 2]) {
let a: Foo<Field> = [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 s = MyStruct {
foo: 10
};
assert(s.foo == 10);
}
2 changes: 1 addition & 1 deletion crates/noirc_evaluator/src/ssa_refactor/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,7 @@ impl Context {
}
Intrinsic::ArrayLen => {
let len = match self.convert_value(arguments[0], dfg) {
AcirValue::Var(_, _) => unreachable!("Non-array passed to array.len() method"),
AcirValue::Var(_, _) => unreachable!("Non-array passed to array.len() method"),
AcirValue::Array(values) => (values.len() as u128).into(),
AcirValue::DynamicArray(array) => (array.len as u128).into(),
};
Expand Down
2 changes: 2 additions & 0 deletions crates/noirc_frontend/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod function;
mod statement;
mod structure;
mod traits;
mod type_alias;

pub use expression::*;
pub use function::*;
Expand All @@ -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},
Expand Down
31 changes: 31 additions & 0 deletions crates/noirc_frontend/src/ast/type_alias.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::{Ident, UnresolvedGenerics, UnresolvedType};
use iter_extended::vecmap;
use noirc_errors::Span;
use std::fmt::Display;

/// Ast node for type aliases
#[derive(Clone, Debug)]
pub struct NoirTypeAlias {
pub name: Ident,
pub generics: UnresolvedGenerics,
pub typ: UnresolvedType,
pub span: Span,
}

impl NoirTypeAlias {
pub fn new(
name: Ident,
generics: UnresolvedGenerics,
typ: UnresolvedType,
span: Span,
) -> NoirTypeAlias {
NoirTypeAlias { name, generics, typ, span }
}
}

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.typ)
}
}
38 changes: 35 additions & 3 deletions crates/noirc_frontend/src/hir/def_collector/dc_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, TypeAliasId};
use crate::{
ExpressionKind, Generics, Ident, LetStatement, NoirFunction, NoirStruct, ParsedModule, Shared,
Type, TypeBinding, UnresolvedGenerics, UnresolvedType,
ExpressionKind, Generics, Ident, LetStatement, NoirFunction, NoirStruct, NoirTypeAlias,
ParsedModule, Shared, Type, TypeBinding, UnresolvedGenerics, UnresolvedType,
};
use fm::FileId;
use iter_extended::vecmap;
Expand All @@ -40,6 +40,13 @@ pub struct UnresolvedStruct {
pub struct_def: NoirStruct,
}

#[derive(Clone)]
pub struct UnresolvedTypeAlias {
pub file_id: FileId,
pub module_id: LocalModuleId,
pub type_alias_def: NoirTypeAlias,
}

#[derive(Clone)]
pub struct UnresolvedGlobal {
pub file_id: FileId,
Expand All @@ -54,6 +61,7 @@ pub struct DefCollector {
pub(crate) collected_imports: Vec<ImportDirective>,
pub(crate) collected_functions: Vec<UnresolvedFunctions>,
pub(crate) collected_types: HashMap<StructId, UnresolvedStruct>,
pub(crate) collected_type_aliases: HashMap<TypeAliasId, UnresolvedTypeAlias>,
pub(crate) collected_globals: Vec<UnresolvedGlobal>,
pub(crate) collected_impls: ImplMap,
}
Expand All @@ -71,6 +79,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![],
}
Expand Down Expand Up @@ -157,6 +166,8 @@ 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);

Expand Down Expand Up @@ -358,6 +369,27 @@ fn resolve_struct_fields(
(generics, fields)
}

fn resolve_type_aliases(
context: &mut Context,
type_aliases: HashMap<TypeAliasId, UnresolvedTypeAlias>,
crate_id: CrateId,
all_errors: &mut Vec<FileDiagnostic>,
) {
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 (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.set_type_alias(type_id, typ, generics);
}
}

fn resolve_impls(
interner: &mut NodeInterner,
crate_id: CrateId,
Expand Down
40 changes: 38 additions & 2 deletions crates/noirc_frontend/src/hir/def_collector/dc_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ 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,
parser::SubModule, Ident, LetStatement, NoirFunction, NoirStruct, NoirTypeAlias, 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};
Expand Down Expand Up @@ -55,6 +56,8 @@ pub fn collect_defs(

collector.collect_structs(ast.types, crate_id, errors);

collector.collect_type_aliases(context, ast.type_aliases, errors);

collector.collect_functions(context, ast.functions, errors);

collector.collect_impls(context, ast.impls);
Expand Down Expand Up @@ -183,6 +186,39 @@ 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,
context: &mut Context,
type_aliases: Vec<NoirTypeAlias>,
errors: &mut Vec<FileDiagnostic>,
) {
for type_alias in type_aliases {
let name = type_alias.name.clone();

// 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 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, 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(type_alias_id, unresolved);
}
}

fn collect_submodules(
&mut self,
context: &mut Context,
Expand Down
1 change: 1 addition & 0 deletions crates/noirc_frontend/src/hir/def_map/item_scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}
Expand Down
10 changes: 9 additions & 1 deletion crates/noirc_frontend/src/hir/def_map/module_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::collections::HashMap;
use fm::FileId;

use crate::{
node_interner::{FuncId, StmtId, StructId},
node_interner::{FuncId, StmtId, StructId, TypeAliasId},
Ident,
};

Expand Down Expand Up @@ -65,6 +65,14 @@ impl ModuleData {
self.declare(name, ModuleDefId::TypeId(id))
}

pub fn declare_type_alias(
&mut self,
name: Ident,
id: TypeAliasId,
) -> Result<(), (Ident, Ident)> {
self.declare(name, id.into())
}

pub fn declare_child_module(
&mut self,
name: Ident,
Expand Down
31 changes: 30 additions & 1 deletion crates/noirc_frontend/src/hir/def_map/module_def.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::node_interner::{FuncId, StmtId, StructId};
use crate::node_interner::{FuncId, StmtId, StructId, TypeAliasId};

use super::ModuleId;

Expand All @@ -8,6 +8,7 @@ pub enum ModuleDefId {
ModuleId(ModuleId),
FunctionId(FuncId),
TypeId(StructId),
TypeAliasId(TypeAliasId),
GlobalId(StmtId),
}

Expand All @@ -26,6 +27,13 @@ impl ModuleDefId {
}
}

pub fn as_type_alias(&self) -> Option<TypeAliasId> {
match self {
ModuleDefId::TypeAliasId(type_alias_id) => Some(*type_alias_id),
_ => None,
}
}

pub fn as_global(&self) -> Option<StmtId> {
match self {
ModuleDefId::GlobalId(stmt_id) => Some(*stmt_id),
Expand All @@ -39,6 +47,7 @@ impl ModuleDefId {
match self {
ModuleDefId::FunctionId(_) => "function",
ModuleDefId::TypeId(_) => "type",
ModuleDefId::TypeAliasId(_) => "type alias",
ModuleDefId::ModuleId(_) => "module",
ModuleDefId::GlobalId(_) => "global",
}
Expand All @@ -57,6 +66,12 @@ impl From<FuncId> for ModuleDefId {
}
}

impl From<TypeAliasId> for ModuleDefId {
fn from(fid: TypeAliasId) -> Self {
ModuleDefId::TypeAliasId(fid)
}
}

impl From<StmtId> for ModuleDefId {
fn from(stmt_id: StmtId) -> Self {
ModuleDefId::GlobalId(stmt_id)
Expand Down Expand Up @@ -97,6 +112,20 @@ impl TryFromModuleDefId for StructId {
}
}

impl TryFromModuleDefId for TypeAliasId {
fn try_from(id: ModuleDefId) -> Option<Self> {
id.as_type_alias()
}

fn dummy_id() -> Self {
TypeAliasId::dummy_id()
}

fn description() -> String {
"type alias".to_string()
}
}

impl TryFromModuleDefId for StmtId {
fn try_from(id: ModuleDefId) -> Option<Self> {
id.as_global()
Expand Down
1 change: 1 addition & 0 deletions crates/noirc_frontend/src/hir/resolution/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 used in type namespace"),
ModuleDefId::GlobalId(_) => panic!("globals cannot be in the type namespace"),
};

Expand Down
Loading