Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rework def_interner storage of aliases
Browse files Browse the repository at this point in the history
jfecher committed Aug 1, 2023
1 parent dc05046 commit ac22a06
Showing 4 changed files with 64 additions and 61 deletions.
25 changes: 12 additions & 13 deletions crates/noirc_frontend/src/hir/def_collector/dc_mod.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}
67 changes: 33 additions & 34 deletions crates/noirc_frontend/src/hir/resolution/resolver.rs
Original file line number Diff line number Diff line change
@@ -399,47 +399,53 @@ 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)
}
None => Type::Error,
}
}

fn verify_generics_count(
&mut self,
expected_count: usize,
args: &mut Vec<Type>,
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<Type> {
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<RefCell<TypeAliasType>> {
self.interner.get_type_alias(type_alias_id)
}

fn lookup<T: TryFromModuleDefId>(&mut self, path: Path) -> Result<T, ResolverError> {
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<Rc<RefCell<TypeAliasType>>> {
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<ModuleDefId, ResolverError> {
9 changes: 8 additions & 1 deletion crates/noirc_frontend/src/hir_def/types.rs
Original file line number Diff line number Diff line change
@@ -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(())
}
}

24 changes: 11 additions & 13 deletions crates/noirc_frontend/src/node_interner.rs
Original file line number Diff line number Diff line change
@@ -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<Rc<RefCell<TypeAliasType>>>,
type_aliases: Vec<TypeAliasType>,

/// 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<RefCell<TypeAliasType>> {
self.type_aliases[id.0].clone()
}

pub fn get_all_type_aliases(&self) -> &Vec<Rc<RefCell<TypeAliasType>>> {
&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<GlobalInfo> {

0 comments on commit ac22a06

Please sign in to comment.