mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-23 18:21:38 +03:00
Merge branch 'testnet3' of github.com:AleoHQ/leo into feat/ped-commit
This commit is contained in:
commit
0c3342f151
@ -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");
|
||||
}
|
||||
|
@ -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_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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_ {
|
||||
|
@ -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}`.")),
|
||||
}
|
||||
);
|
||||
|
18
tests/compiler/circuits/circuit_contains_record_fail.leo
Normal file
18
tests/compiler/circuits/circuit_contains_record_fail.leo
Normal 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,
|
||||
}
|
35
tests/compiler/records/nested_record.leo
Normal file
35
tests/compiler/records/nested_record.leo
Normal 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;
|
||||
}
|
16
tests/compiler/records/nested_record_1_fail.leo
Normal file
16
tests/compiler/records/nested_record_1_fail.leo
Normal 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,
|
||||
}
|
17
tests/compiler/records/nested_record_2_fail.leo
Normal file
17
tests/compiler/records/nested_record_2_fail.leo
Normal 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,
|
||||
}
|
21
tests/compiler/records/nested_record_3_fail.leo
Normal file
21
tests/compiler/records/nested_record_3_fail.leo
Normal 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,
|
||||
}
|
25
tests/compiler/records/nested_record_4_fail.leo
Normal file
25
tests/compiler/records/nested_record_4_fail.leo
Normal 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,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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"
|
5
tests/expectations/compiler/records/nested_record.out
Normal file
5
tests/expectations/compiler/records/nested_record.out
Normal 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\""
|
@ -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"
|
@ -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"
|
@ -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"
|
@ -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"
|
Loading…
Reference in New Issue
Block a user