mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 18:52:58 +03:00
fix type checking bugs
This commit is contained in:
parent
21c6a2167a
commit
df8ee1a1f9
@ -60,7 +60,7 @@ impl Type {
|
|||||||
| (Type::Scalar, Type::Scalar)
|
| (Type::Scalar, Type::Scalar)
|
||||||
| (Type::String, Type::String) => true,
|
| (Type::String, Type::String) => true,
|
||||||
(Type::IntegerType(left), Type::IntegerType(right)) => left.eq(right),
|
(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,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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> {
|
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) {
|
if let VisitResult::VisitChildren = self.visitor.visit_identifier(var) {
|
||||||
return Some(self.visitor.assert_expected_option(
|
if let Some(circuit) = self.visitor.symbol_table.clone().lookup_circuit(&var.name) {
|
||||||
Type::Identifier(circuit.identifier.clone()),
|
return Some(self.visitor.assert_expected_option(
|
||||||
expected,
|
Type::Identifier(circuit.identifier.clone()),
|
||||||
circuit.span(),
|
expected,
|
||||||
));
|
circuit.span(),
|
||||||
} else if let Some(record) = self.visitor.symbol_table.clone().lookup_record(&var.name) {
|
));
|
||||||
return Some(self.visitor.assert_expected_option(
|
} else if let Some(record) = self.visitor.symbol_table.clone().lookup_record(&var.name) {
|
||||||
Type::Identifier(record.identifier.clone()),
|
return Some(self.visitor.assert_expected_option(
|
||||||
expected,
|
Type::Identifier(record.identifier.clone()),
|
||||||
record.span(),
|
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) {
|
} 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));
|
return Some(self.visitor.assert_expected_option(*var.type_, expected, var.span));
|
||||||
} else {
|
} else {
|
||||||
self.visitor
|
self.visitor
|
||||||
@ -651,26 +651,22 @@ impl<'a> ExpressionVisitorDirector<'a> for Director<'a> {
|
|||||||
|
|
||||||
// Check record variable types.
|
// Check record variable types.
|
||||||
input.members.iter().for_each(|actual| {
|
input.members.iter().for_each(|actual| {
|
||||||
// Check record owner.
|
|
||||||
if actual.identifier.matches(&expected.owner.ident) {
|
if actual.identifier.matches(&expected.owner.ident) {
|
||||||
|
// Check record owner.
|
||||||
if let Some(owner_expr) = &actual.expression {
|
if let Some(owner_expr) = &actual.expression {
|
||||||
self.visit_expression(owner_expr, &Some(Type::Address));
|
self.visit_expression(owner_expr, &Some(Type::Address));
|
||||||
}
|
}
|
||||||
}
|
} else if actual.identifier.matches(&expected.balance.ident) {
|
||||||
|
// Check record balance.
|
||||||
// Check record balance.
|
|
||||||
if actual.identifier.matches(&expected.balance.ident) {
|
|
||||||
if let Some(balance_expr) = &actual.expression {
|
if let Some(balance_expr) = &actual.expression {
|
||||||
self.visit_expression(balance_expr, &Some(Type::IntegerType(IntegerType::U64)));
|
self.visit_expression(balance_expr, &Some(Type::IntegerType(IntegerType::U64)));
|
||||||
}
|
}
|
||||||
}
|
} else if let Some(expected_var) = expected
|
||||||
|
|
||||||
// Check record data variable.
|
|
||||||
if let Some(expected_var) = expected
|
|
||||||
.data
|
.data
|
||||||
.iter()
|
.iter()
|
||||||
.find(|member| member.ident.matches(&actual.identifier))
|
.find(|member| member.ident.matches(&actual.identifier))
|
||||||
{
|
{
|
||||||
|
// Check record data variable.
|
||||||
if let Some(var_expr) = &actual.expression {
|
if let Some(var_expr) = &actual.expression {
|
||||||
self.visit_expression(var_expr, &Some(expected_var.type_));
|
self.visit_expression(var_expr, &Some(expected_var.type_));
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,6 @@ impl<'a> ProgramVisitorDirector<'a> for Director<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_record(&mut self, input: &'a Record) {
|
fn visit_record(&mut self, input: &'a Record) {
|
||||||
println!("visit record");
|
|
||||||
if let VisitResult::VisitChildren = self.visitor_ref().visit_record(input) {
|
if let VisitResult::VisitChildren = self.visitor_ref().visit_record(input) {
|
||||||
// Check for conflicting record member names.
|
// Check for conflicting record member names.
|
||||||
let mut used = HashSet::new();
|
let mut used = HashSet::new();
|
||||||
|
@ -159,7 +159,7 @@ impl<'a> TypeChecker<'a> {
|
|||||||
/// Returns the given `actual` type and emits an error if the `expected` type does not match.
|
/// 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 {
|
pub(crate) fn assert_expected_option(&mut self, actual: Type, expected: &Option<Type>, span: Span) -> Type {
|
||||||
if let Some(expected) = expected {
|
if let Some(expected) = expected {
|
||||||
if &actual != expected {
|
if !actual.eq_flat(expected) {
|
||||||
self.handler
|
self.handler
|
||||||
.emit_err(TypeCheckerError::type_should_be(actual, expected, span).into());
|
.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.
|
/// `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 {
|
pub(crate) fn assert_expected_type(&mut self, actual: &Option<Type>, expected: Type, span: Span) -> Type {
|
||||||
if let Some(actual) = actual {
|
if let Some(actual) = actual {
|
||||||
if actual != &expected {
|
if !actual.eq_flat(&expected) {
|
||||||
self.handler
|
self.handler
|
||||||
.emit_err(TypeCheckerError::type_should_be(actual, expected, span).into());
|
.emit_err(TypeCheckerError::type_should_be(actual, expected, span).into());
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
function main(a: u8) -> group {
|
||||||
|
|
||||||
return Pedersen64::hash(a);
|
return Pedersen64::hash(a);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user