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

fix: DefinitionIds should not be stored in id_to_type #4397

Merged
merged 2 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
7 changes: 3 additions & 4 deletions aztec_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -763,11 +763,11 @@ fn transform_event(
HirExpression::Literal(HirLiteral::Str(signature))
if signature == SIGNATURE_PLACEHOLDER =>
{
let selector_literal_id = first_arg_id;
let selector_literal_id = *first_arg_id;

let structure = interner.get_struct(struct_id);
let signature = event_signature(&structure.borrow());
interner.update_expression(*selector_literal_id, |expr| {
interner.update_expression(selector_literal_id, |expr| {
*expr = HirExpression::Literal(HirLiteral::Str(signature.clone()));
});

Expand Down Expand Up @@ -833,7 +833,7 @@ fn get_serialized_length(

let serialized_trait_impl_kind = traits
.iter()
.filter_map(|&trait_id| {
.find_map(|&trait_id| {
let r#trait = interner.get_trait(trait_id);
if r#trait.borrow().name.0.contents == "Serialize"
&& r#trait.borrow().generics.len() == 1
Expand All @@ -846,7 +846,6 @@ fn get_serialized_length(
None
}
})
.next()
.ok_or(AztecMacroError::CouldNotAssignStorageSlots {
secondary_message: Some("Stored data must implement Serialize trait".to_string()),
})?;
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/hir/def_map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub struct LocalModuleId(pub Index);

impl LocalModuleId {
pub fn dummy_id() -> LocalModuleId {
LocalModuleId(Index(std::usize::MAX))
LocalModuleId(Index::dummy())
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/hir/resolution/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1463,7 +1463,7 @@ impl<'a> Resolver<'a> {
// they're used in expressions. We must do this here since the type
// checker does not check definition kinds and otherwise expects
// parameters to already be typed.
if self.interner.id_type(hir_ident.id) == Type::Error {
if self.interner.definition_type(hir_ident.id) == Type::Error {
let typ = Type::polymorphic_integer(self.interner);
self.interner.push_definition_type(hir_ident.id, typ);
}
Expand Down
15 changes: 8 additions & 7 deletions compiler/noirc_frontend/src/hir/type_check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,9 @@ impl<'interner> TypeChecker<'interner> {
Type::Tuple(vecmap(&elements, |elem| self.check_expression(elem)))
}
HirExpression::Lambda(lambda) => {
let captured_vars =
vecmap(lambda.captures, |capture| self.interner.id_type(capture.ident.id));
let captured_vars = vecmap(lambda.captures, |capture| {
self.interner.definition_type(capture.ident.id)
});

let env_type: Type =
if captured_vars.is_empty() { Type::Unit } else { Type::Tuple(captured_vars) };
Expand All @@ -308,7 +309,7 @@ impl<'interner> TypeChecker<'interner> {
}
};

self.interner.push_expr_type(expr_id, typ.clone());
self.interner.push_expr_type(*expr_id, typ.clone());
typ
}

Expand Down Expand Up @@ -459,7 +460,7 @@ impl<'interner> TypeChecker<'interner> {
operator: UnaryOp::MutableReference,
rhs: method_call.object,
}));
self.interner.push_expr_type(&new_object, new_type);
self.interner.push_expr_type(new_object, new_type);
self.interner.push_expr_location(new_object, location.span, location.file);
new_object
});
Expand All @@ -485,7 +486,7 @@ impl<'interner> TypeChecker<'interner> {
operator: UnaryOp::Dereference { implicitly_added: true },
rhs: object,
}));
self.interner.push_expr_type(&object, element.as_ref().clone());
self.interner.push_expr_type(object, element.as_ref().clone());
self.interner.push_expr_location(object, location.span, location.file);

// Recursively dereference to allow for converting &mut &mut T to T
Expand Down Expand Up @@ -682,8 +683,8 @@ impl<'interner> TypeChecker<'interner> {
operator: crate::UnaryOp::Dereference { implicitly_added: true },
rhs: old_lhs,
}));
this.interner.push_expr_type(&old_lhs, lhs_type);
this.interner.push_expr_type(access_lhs, element);
this.interner.push_expr_type(old_lhs, lhs_type);
this.interner.push_expr_type(*access_lhs, element);

let old_location = this.interner.id_location(old_lhs);
this.interner.push_expr_location(*access_lhs, span, old_location.file);
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/hir/type_check/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ impl<'interner> TypeChecker<'interner> {
mutable = definition.mutable;
}

let typ = self.interner.id_type(ident.id).instantiate(self.interner).0;
let typ = self.interner.definition_type(ident.id).instantiate(self.interner).0;
typ.follow_bindings()
};

Expand Down
9 changes: 4 additions & 5 deletions compiler/noirc_frontend/src/hir_def/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1515,7 +1515,7 @@
Type::Tuple(fields)
}
Type::Forall(typevars, typ) => {
// Trying to substitute_helper a variable de, substitute_bound_typevarsfined within a nested Forall

Check warning on line 1518 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (typevarsfined)
// is usually impossible and indicative of an error in the type checker somewhere.
for var in typevars {
assert!(!type_bindings.contains_key(&var.id()));
Expand Down Expand Up @@ -1672,11 +1672,10 @@
interner.push_expr_location(call, location.span, location.file);
interner.push_expr_location(func, location.span, location.file);

interner.push_expr_type(&call, target_type.clone());
interner.push_expr_type(
&func,
Type::Function(vec![array_type], Box::new(target_type), Box::new(Type::Unit)),
);
interner.push_expr_type(call, target_type.clone());

let func_type = Type::Function(vec![array_type], Box::new(target_type), Box::new(Type::Unit));
interner.push_expr_type(func, func_type);
}

impl BinaryTypeOperator {
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/monomorphization/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
let index_id = self.interner.push_expr(HirExpression::Literal(
HirLiteral::Integer(field_index.into(), false),
));
self.interner.push_expr_type(&index_id, crate::Type::FieldElement);
self.interner.push_expr_type(index_id, crate::Type::FieldElement);
self.interner.push_expr_location(
index_id,
call.location.span,
Expand Down Expand Up @@ -171,14 +171,14 @@
fn intern_var_id(&mut self, var_id: DebugVarId, location: &Location) -> ExprId {
let var_id_literal = HirLiteral::Integer((var_id.0 as u128).into(), false);
let expr_id = self.interner.push_expr(HirExpression::Literal(var_id_literal));
self.interner.push_expr_type(&expr_id, crate::Type::FieldElement);
self.interner.push_expr_type(expr_id, crate::Type::FieldElement);
self.interner.push_expr_location(expr_id, location.span, location.file);
expr_id
}
}

fn element_type_at_index(ptype: &PrintableType, i: usize) -> &PrintableType {

Check warning on line 180 in compiler/noirc_frontend/src/monomorphization/debug.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (ptype)
match ptype {

Check warning on line 181 in compiler/noirc_frontend/src/monomorphization/debug.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (ptype)
PrintableType::Array { length: _length, typ } => typ.as_ref(),
PrintableType::Tuple { types } => &types[i],
PrintableType::Struct { name: _name, fields } => &fields[i].1,
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/monomorphization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@
let mutable = definition.mutable;

let definition = self.lookup_local(ident.id)?;
let typ = self.convert_type(&self.interner.id_type(ident.id));
let typ = self.convert_type(&self.interner.definition_type(ident.id));

Some(ast::Ident { location: Some(ident.location), mutable, definition, name, typ })
}
Expand Down Expand Up @@ -967,7 +967,7 @@
// The second argument is expected to always be an ident
self.append_printable_type_info(&hir_arguments[1], &mut arguments);
} else if name.as_str() == "assert_message" {
// The first argument to the `assert_message` oracle is the expression passed as a mesage to an `assert` or `assert_eq` statement

Check warning on line 970 in compiler/noirc_frontend/src/monomorphization/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (mesage)
self.append_printable_type_info(&hir_arguments[0], &mut arguments);
}
}
Expand Down Expand Up @@ -1038,7 +1038,7 @@
) {
match hir_argument {
HirExpression::Ident(ident) => {
let typ = self.interner.id_type(ident.id);
let typ = self.interner.definition_type(ident.id);
let typ: Type = typ.follow_bindings();
let is_fmt_str = match typ {
// A format string has many different possible types that need to be handled.
Expand Down
57 changes: 22 additions & 35 deletions compiler/noirc_frontend/src/node_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
use fm::FileId;
use iter_extended::vecmap;
use noirc_errors::{Location, Span, Spanned};
use petgraph::algo::tarjan_scc;

Check warning on line 9 in compiler/noirc_frontend/src/node_interner.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (petgraph)

Check warning on line 9 in compiler/noirc_frontend/src/node_interner.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (tarjan)
use petgraph::prelude::DiGraph;

Check warning on line 10 in compiler/noirc_frontend/src/node_interner.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (petgraph)
use petgraph::prelude::NodeIndex as PetGraphIndex;

Check warning on line 11 in compiler/noirc_frontend/src/node_interner.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (petgraph)

use crate::ast::Ident;
use crate::graph::CrateId;
Expand Down Expand Up @@ -60,7 +60,7 @@
function_modules: HashMap<FuncId, ModuleId>,

/// This graph tracks dependencies between different global definitions.
/// This is used to ensure the absense of dependency cycles for globals and types.

Check warning on line 63 in compiler/noirc_frontend/src/node_interner.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (absense)
dependency_graph: DiGraph<DependencyId, ()>,

/// To keep track of where each DependencyId is in `dependency_graph`, we need
Expand All @@ -75,13 +75,14 @@

// Type checking map
//
// Notice that we use `Index` as the Key and not an ExprId or IdentId
// Therefore, If a raw index is passed in, then it is not safe to assume that it will have
// a Type, as not all Ids have types associated to them.
// Further note, that an ExprId and an IdentId will never have the same underlying Index
// Because we use one Arena to store all Definitions/Nodes
// This should only be used with indices from the `nodes` arena.
// Otherwise the indices used may overwrite other existing indices.
// Each type for each index is filled in during type checking.
id_to_type: HashMap<Index, Type>,

// Similar to `id_to_type` but maps definitions to their type
definition_to_type: HashMap<DefinitionId, Type>,

// Struct map.
//
// Each struct definition is possibly shared across multiple type nodes.
Expand Down Expand Up @@ -277,12 +278,6 @@
}
}

impl From<DefinitionId> for Index {
fn from(id: DefinitionId) -> Self {
Index(id.0)
}
}

/// An ID for a global value
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
pub struct GlobalId(usize);
Expand All @@ -302,7 +297,7 @@
// This can be anything, as the program will ultimately fail
// after resolution
pub fn dummy_id() -> StmtId {
StmtId(Index(std::usize::MAX))
StmtId(Index::dummy())
}
}

Expand All @@ -311,7 +306,7 @@

impl ExprId {
pub fn empty_block_id() -> ExprId {
ExprId(Index(0))
ExprId(Index::unsafe_zeroed())
}
}
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)]
Expand All @@ -322,7 +317,7 @@
// This can be anything, as the program will ultimately fail
// after resolution
pub fn dummy_id() -> FuncId {
FuncId(Index(std::usize::MAX))
FuncId(Index::dummy())
}
}

Expand Down Expand Up @@ -396,23 +391,9 @@
};
}

macro_rules! partialeq {
($id_type:ty) => {
impl PartialEq<usize> for &$id_type {
fn eq(&self, other: &usize) -> bool {
let index = self.0 .0;
index == *other
}
}
};
}

into_index!(ExprId);
into_index!(StmtId);

partialeq!(ExprId);
partialeq!(StmtId);

/// A Definition enum specifies anything that we can intern in the NodeInterner
/// We use one Arena for all types that can be interned as that has better cache locality
/// This data structure is never accessed directly, so API wise there is no difference between using
Expand Down Expand Up @@ -491,11 +472,12 @@
function_modifiers: HashMap::new(),
function_modules: HashMap::new(),
func_id_to_trait: HashMap::new(),
dependency_graph: petgraph::graph::DiGraph::new(),

Check warning on line 475 in compiler/noirc_frontend/src/node_interner.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (petgraph)
dependency_graph_indices: HashMap::new(),
id_to_location: HashMap::new(),
definitions: vec![],
id_to_type: HashMap::new(),
definition_to_type: HashMap::new(),
structs: HashMap::new(),
struct_attributes: HashMap::new(),
type_aliases: Vec::new(),
Expand Down Expand Up @@ -545,10 +527,15 @@
}

/// Store the type for an interned expression
pub fn push_expr_type(&mut self, expr_id: &ExprId, typ: Type) {
pub fn push_expr_type(&mut self, expr_id: ExprId, typ: Type) {
self.id_to_type.insert(expr_id.into(), typ);
}

/// Store the type for an interned expression
pub fn push_definition_type(&mut self, definition_id: DefinitionId, typ: Type) {
self.definition_to_type.insert(definition_id, typ);
}

pub fn push_empty_trait(&mut self, type_id: TraitId, unresolved_trait: &UnresolvedTrait) {
let self_type_typevar_id = self.next_type_variable_id();

Expand Down Expand Up @@ -660,11 +647,6 @@
}
}

/// Store the type for an interned Identifier
pub fn push_definition_type(&mut self, definition_id: DefinitionId, typ: Type) {
self.id_to_type.insert(definition_id.into(), typ);
}

/// Store [Location] of [Type] reference
pub fn push_type_ref_location(&mut self, typ: Type, location: Location) {
self.type_ref_locations.push((typ, location));
Expand Down Expand Up @@ -980,8 +962,13 @@
self.id_to_type.get(&index.into()).cloned().unwrap_or(Type::Error)
}

/// Returns the type of the definition or `Type::Error` if it was not found.
pub fn definition_type(&self, id: DefinitionId) -> Type {
self.definition_to_type.get(&id).cloned().unwrap_or(Type::Error)
}

pub fn id_type_substitute_trait_as_type(&self, def_id: DefinitionId) -> Type {
let typ = self.id_type(def_id);
let typ = self.definition_type(def_id);
if let Type::Function(args, ret, env) = &typ {
let def = self.definition(def_id);
if let Type::TraitAsType(..) = ret.as_ref() {
Expand Down
21 changes: 20 additions & 1 deletion compiler/utils/arena/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,26 @@
#![warn(clippy::semicolon_if_nothing_returned)]

#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
pub struct Index(pub usize);
pub struct Index(usize);

impl Index {
#[cfg(test)]
pub fn test_new(index: usize) -> Index {
Self(index)
}

/// Return a dummy index (max value internally).
/// This should be avoided over `Option<Index>` if possible.
pub fn dummy() -> Self {
Self(usize::MAX)
}

/// Return the zeroed index. This is unsafe since we don't know
/// if this is a valid index for any particular map yet.
pub fn unsafe_zeroed() -> Self {
Self(0)
}
}

// #[derive(Debug, Eq, PartialEq, Hash, Clone)]
#[derive(Debug, Clone)]
Expand Down
Loading