Merge branch 'testnet3' of github.com:AleoHQ/leo into feat/ped-commit

This commit is contained in:
collin 2022-08-15 22:11:21 -07:00
commit 0c3342f151
16 changed files with 201 additions and 2 deletions

View File

@ -149,7 +149,8 @@ impl<'a> CodeGenerator<'a> {
writeln!(
output_string,
" {} as {}.private;", // todo: CAUTION private record variables only.
name, type_,
name,
type_.to_string().to_lowercase(),
)
.expect("failed to write to string");
}

View File

@ -24,6 +24,8 @@ use leo_span::sym;
use std::cell::RefCell;
use std::collections::HashSet;
// TODO: Generally, cleanup tyc logic.
impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
fn visit_function(&mut self, input: &'a Function) {
// Check that the function's annotations are valid.
@ -138,9 +140,11 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
check_has_field(sym::gates, Type::Integer(IntegerType::U64));
}
// Ensure there are no tuple typed members.
for CircuitMember::CircuitVariable(v, type_) in input.members.iter() {
// Ensure there are no tuple typed members.
self.assert_not_tuple(v.span, type_);
// Ensure that there are no record members.
self.assert_member_is_not_record(v.span, input.identifier.name, type_);
}
}
}

View File

@ -332,6 +332,31 @@ impl<'a> TypeChecker<'a> {
}
}
/// Emits an error if the circuit member is a record type.
pub(crate) fn assert_member_is_not_record(&self, span: Span, parent: Symbol, type_: &Type) {
match type_ {
Type::Identifier(identifier)
if self
.symbol_table
.borrow()
.lookup_circuit(identifier.name)
.map_or(false, |circuit| circuit.is_record) =>
{
self.emit_err(TypeCheckerError::circuit_or_record_cannot_contain_record(
parent,
identifier.name,
span,
))
}
Type::Tuple(tuple_type) => {
for type_ in tuple_type.iter() {
self.assert_member_is_not_record(span, parent, type_)
}
}
_ => {} // Do nothing.
}
}
/// Emits an error if the type is not valid.
pub(crate) fn assert_type_is_valid(&self, span: Span, type_: &Type) {
match type_ {

View File

@ -288,4 +288,11 @@ create_messages!(
msg: format!("Helper functions cannot have modes associated with their inputs."),
help: Some("Consider removing the mode or adding a `@program` annotation to the function.".to_string()),
}
@formatted
circuit_or_record_cannot_contain_record {
args: (parent: impl Display, child: impl Display),
msg: format!("A circuit or record cannot contain another record."),
help: Some(format!("Remove the record `{child}` from `{parent}`.")),
}
);

View File

@ -0,0 +1,18 @@
/*
namespace: Compile
expectation: Fail
*/
circuit Foo {
// The token amount.
token: Token,
}
record Token {
// The token owner.
owner: address,
// The Aleo balance (in gates).
gates: u64,
// The token amount.
foo: Foo,
}

View File

@ -0,0 +1,35 @@
/*
namespace: Compile
expectation: Fail
*/
circuit Amount {
amount: u64,
amt: u64,
}
record Token {
// The token owner.
owner: address,
// The Aleo balance (in gates).
gates: u64,
// The token amount.
amount: Amount,
}
@program
function mint(r0: address, r1: u64) -> Token {
return Token {
owner: r0,
gates: 0u64,
amount: Amount { amount: r1, amt: r1 },
};
}
@program
function main(x: address) -> u64 {
const c: u64 = 1u64;
let t: Token = Token { owner: x, gates: 0u64, amount: Amount { amount: c, amt: c } };
return t.gates;
}

View File

@ -0,0 +1,16 @@
/*
namespace: Compile
expectation: Fail
*/
record Foo {
owner: address,
gates: u64,
amount: u64,
}
record Token {
owner: address,
gates: u64,
foo: Foo,
}

View File

@ -0,0 +1,17 @@
/*
namespace: Compile
expectation: Fail
*/
record Token2 {
owner: address,
gates: u64,
foo: (Foo, Foo),
}
record Foo {
owner: address,
gates: u64,
amount: u64,
}

View File

@ -0,0 +1,21 @@
/*
namespace: Compile
expectation: Fail
*/
record Token {
owner: address,
gates: u64,
bar: Bar,
}
circuit Bar {
bar: Foo,
}
record Foo {
owner: address,
gates: u64,
amount: u64,
}

View File

@ -0,0 +1,25 @@
/*
namespace: Compile
expectation: Fail
*/
record Token3 {
owner: address,
gates: u64,
bar: (Bar, Bar),
}
circuit Bar {
bar: (Token, Token),
}
record Token {
owner: address,
gates: u64,
amount: u64,
}

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372030]: A circuit or record cannot contain another record.\n --> compiler-test:5:5\n |\n 5 | token: Token,\n | ^^^^^\n |\n = Remove the record `Token` from `Foo`.\n"

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Failed to parse string. Remaining invalid string is: \"amount as circuit amount.private;\n\n\nfunction mint:\n input r0 as address.private;\n input r1 as u64.private;\n cast r1 r1 into r2 as amount;\n cast r0 0u64 r2 into r3 as token.record;\n output r3 as token.record;\n\nfunction main:\n input r0 as address.private;\n cast 1u64 1u64 into r1 as amount;\n cast r0 0u64 r1 into r2 as token.record;\n output r2.gates as u64.private;\n\n\""

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372030]: A circuit or record cannot contain another record.\n --> compiler-test:12:5\n |\n 12 | foo: Foo,\n | ^^^\n |\n = Remove the record `Foo` from `Token`.\n"

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372025]: Tuples are only allowed as function return types.\n --> compiler-test:7:5\n |\n 7 | foo: (Foo, Foo),\n | ^^^\nError [ETYC0372030]: A circuit or record cannot contain another record.\n --> compiler-test:7:5\n |\n 7 | foo: (Foo, Foo),\n | ^^^\n |\n = Remove the record `Foo` from `Token2`.\nError [ETYC0372030]: A circuit or record cannot contain another record.\n --> compiler-test:7:5\n |\n 7 | foo: (Foo, Foo),\n | ^^^\n |\n = Remove the record `Foo` from `Token2`.\n"

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372030]: A circuit or record cannot contain another record.\n --> compiler-test:11:5\n |\n 11 | bar: Foo,\n | ^^^\n |\n = Remove the record `Foo` from `Bar`.\n"

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372025]: Tuples are only allowed as function return types.\n --> compiler-test:6:5\n |\n 6 | bar: (Bar, Bar),\n | ^^^\nError [ETYC0372025]: Tuples are only allowed as function return types.\n --> compiler-test:10:5\n |\n 10 | bar: (Token, Token),\n | ^^^\nError [ETYC0372030]: A circuit or record cannot contain another record.\n --> compiler-test:10:5\n |\n 10 | bar: (Token, Token),\n | ^^^\n |\n = Remove the record `Token` from `Bar`.\nError [ETYC0372030]: A circuit or record cannot contain another record.\n --> compiler-test:10:5\n |\n 10 | bar: (Token, Token),\n | ^^^\n |\n = Remove the record `Token` from `Bar`.\n"