fix type checking bugs

This commit is contained in:
collin 2022-06-26 15:13:58 -10:00
parent 21c6a2167a
commit df8ee1a1f9
5 changed files with 22 additions and 40 deletions

View File

@ -60,7 +60,7 @@ impl Type {
| (Type::Scalar, Type::Scalar)
| (Type::String, Type::String) => true,
(Type::IntegerType(left), Type::IntegerType(right)) => left.eq(right),
(Type::Identifier(left), Type::Identifier(right)) => left.eq(right),
(Type::Identifier(left), Type::Identifier(right)) => left.matches(right),
_ => false,
}
}

View File

@ -64,20 +64,20 @@ impl<'a> ExpressionVisitorDirector<'a> for Director<'a> {
}
fn visit_identifier(&mut self, var: &'a Identifier, expected: &Self::AdditionalInput) -> Option<Self::Output> {
if let Some(circuit) = self.visitor.symbol_table.clone().lookup_circuit(&var.name) {
return Some(self.visitor.assert_expected_option(
Type::Identifier(circuit.identifier.clone()),
expected,
circuit.span(),
));
} else if let Some(record) = self.visitor.symbol_table.clone().lookup_record(&var.name) {
return Some(self.visitor.assert_expected_option(
Type::Identifier(record.identifier.clone()),
expected,
record.span(),
));
} else if let VisitResult::VisitChildren = self.visitor.visit_identifier(var) {
if let Some(var) = self.visitor.symbol_table.clone().lookup_variable(&var.name) {
if let VisitResult::VisitChildren = self.visitor.visit_identifier(var) {
if let Some(circuit) = self.visitor.symbol_table.clone().lookup_circuit(&var.name) {
return Some(self.visitor.assert_expected_option(
Type::Identifier(circuit.identifier.clone()),
expected,
circuit.span(),
));
} else if let Some(record) = self.visitor.symbol_table.clone().lookup_record(&var.name) {
return Some(self.visitor.assert_expected_option(
Type::Identifier(record.identifier.clone()),
expected,
record.span(),
));
} else if let Some(var) = self.visitor.symbol_table.clone().lookup_variable(&var.name) {
return Some(self.visitor.assert_expected_option(*var.type_, expected, var.span));
} else {
self.visitor
@ -651,26 +651,22 @@ impl<'a> ExpressionVisitorDirector<'a> for Director<'a> {
// Check record variable types.
input.members.iter().for_each(|actual| {
// Check record owner.
if actual.identifier.matches(&expected.owner.ident) {
// Check record owner.
if let Some(owner_expr) = &actual.expression {
self.visit_expression(owner_expr, &Some(Type::Address));
}
}
// Check record balance.
if actual.identifier.matches(&expected.balance.ident) {
} else if actual.identifier.matches(&expected.balance.ident) {
// Check record balance.
if let Some(balance_expr) = &actual.expression {
self.visit_expression(balance_expr, &Some(Type::IntegerType(IntegerType::U64)));
}
}
// Check record data variable.
if let Some(expected_var) = expected
} else if let Some(expected_var) = expected
.data
.iter()
.find(|member| member.ident.matches(&actual.identifier))
{
// Check record data variable.
if let Some(var_expr) = &actual.expression {
self.visit_expression(var_expr, &Some(expected_var.type_));
}

View File

@ -68,7 +68,6 @@ impl<'a> ProgramVisitorDirector<'a> for Director<'a> {
}
fn visit_record(&mut self, input: &'a Record) {
println!("visit record");
if let VisitResult::VisitChildren = self.visitor_ref().visit_record(input) {
// Check for conflicting record member names.
let mut used = HashSet::new();

View File

@ -159,7 +159,7 @@ impl<'a> TypeChecker<'a> {
/// Returns the given `actual` type and emits an error if the `expected` type does not match.
pub(crate) fn assert_expected_option(&mut self, actual: Type, expected: &Option<Type>, span: Span) -> Type {
if let Some(expected) = expected {
if &actual != expected {
if !actual.eq_flat(expected) {
self.handler
.emit_err(TypeCheckerError::type_should_be(actual, expected, span).into());
}
@ -172,7 +172,7 @@ impl<'a> TypeChecker<'a> {
/// `span` should be the location of the expected type.
pub(crate) fn assert_expected_type(&mut self, actual: &Option<Type>, expected: Type, span: Span) -> Type {
if let Some(actual) = actual {
if actual != &expected {
if !actual.eq_flat(&expected) {
self.handler
.emit_err(TypeCheckerError::type_should_be(actual, expected, span).into());
}

View File

@ -1,16 +1,3 @@
circuit Token {
// The token owner.
balance: u64,
data: u64
}
function mint() -> Token {
let tok: Token = Token { balance: 1u64, data: 1u64};
return tok;
}
function main(a: u8) -> group {
return Pedersen64::hash(a);
}