Skip to content

Commit

Permalink
Refactor and improve type checking.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikebenfield committed Dec 19, 2024
1 parent aa6a5f3 commit 9842b36
Show file tree
Hide file tree
Showing 126 changed files with 2,395 additions and 2,252 deletions.
2 changes: 1 addition & 1 deletion compiler/ast/src/functions/core_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use leo_span::{Symbol, sym};

/// A core instruction that maps directly to an AVM bytecode instruction.
#[derive(Clone, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum CoreFunction {
BHP256CommitToAddress,
BHP256CommitToField,
Expand Down
2 changes: 1 addition & 1 deletion compiler/ast/src/struct/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub struct Composite {

impl PartialEq for Composite {
fn eq(&self, other: &Self) -> bool {
self.identifier == other.identifier
self.identifier == other.identifier && self.external == other.external
}
}

Expand Down
10 changes: 9 additions & 1 deletion compiler/ast/src/types/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ impl TupleType {

impl fmt::Display for TupleType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({})", self.elements.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(","))
write!(f, "(")?;
let mut iter = self.elements.iter().peekable();
while let Some(element) = iter.next() {
write!(f, "{element}")?;
if iter.peek().is_some() {
write!(f, ", ")?;
}
}
write!(f, ")")
}
}
49 changes: 2 additions & 47 deletions compiler/ast/src/types/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use snarkvm::prelude::{
use std::fmt;

/// Explicit type used for defining a variable or expression type
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Type {
/// The `address` type.
Address,
Expand Down Expand Up @@ -61,56 +61,11 @@ pub enum Type {
Unit,
/// Placeholder for a type that could not be resolved or was not well-formed.
/// Will eventually lead to a compile error.
#[default]
Err,
}

impl Type {
///
/// Returns `true` if the self `Type` is equal to the other `Type`.
///
/// Flattens array syntax: `[[u8; 1]; 2] == [u8; (2, 1)] == true`
///
pub fn eq_flat(&self, other: &Self) -> bool {
match (self, other) {
(Type::Address, Type::Address)
| (Type::Boolean, Type::Boolean)
| (Type::Field, Type::Field)
| (Type::Group, Type::Group)
| (Type::Scalar, Type::Scalar)
| (Type::Signature, Type::Signature)
| (Type::String, Type::String)
| (Type::Unit, Type::Unit) => true,
(Type::Array(left), Type::Array(right)) => {
left.element_type().eq_flat(right.element_type()) && left.length() == right.length()
}
(Type::Identifier(left), Type::Identifier(right)) => left.name == right.name,
(Type::Integer(left), Type::Integer(right)) => left.eq(right),
(Type::Mapping(left), Type::Mapping(right)) => {
left.key.eq_flat(&right.key) && left.value.eq_flat(&right.value)
}
(Type::Tuple(left), Type::Tuple(right)) if left.length() == right.length() => left
.elements()
.iter()
.zip_eq(right.elements().iter())
.all(|(left_type, right_type)| left_type.eq_flat(right_type)),
(Type::Composite(left), Type::Composite(right)) => {
left.id.name == right.id.name && left.program == right.program
}
(Type::Future(left), Type::Future(right))
if left.inputs.len() == right.inputs.len() && left.location.is_some() && right.location.is_some() =>
{
left.location == right.location
&& left
.inputs()
.iter()
.zip_eq(right.inputs().iter())
.all(|(left_type, right_type)| left_type.eq_flat(right_type))
}
_ => false,
}
}

///
/// Returns `true` if the self `Type` is equal to the other `Type` in all aspects besides composite program of origin.
///
/// In the case of futures, it also makes sure that if both are not explicit, they are equal.
Expand Down
3 changes: 2 additions & 1 deletion compiler/passes/src/symbol_table_creation/creator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ impl<'a> ProgramVisitor<'a> for SymbolTableCreator<'a> {
if !input.is_record && !self.structs.insert(input.name()) {
return self.handler.emit_err::<LeoError>(AstError::shadowed_struct(input.name(), input.span).into());
}
if let Err(err) = self.symbol_table.insert_struct(Location::new(input.external, input.name()), input) {
let program_name = input.external.or(self.program_name);
if let Err(err) = self.symbol_table.insert_struct(Location::new(program_name, input.name()), input) {
self.handler.emit_err(err);
}
}
Expand Down
Loading

0 comments on commit 9842b36

Please sign in to comment.