mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 10:41:57 +03:00
Add check for nested records; fix codegen for circuit nested in record
This commit is contained in:
parent
a26c452de2
commit
da7ff48b11
@ -111,7 +111,7 @@ impl fmt::Display for Type {
|
|||||||
Type::I32 => write!(f, "i32"),
|
Type::I32 => write!(f, "i32"),
|
||||||
Type::I64 => write!(f, "i64"),
|
Type::I64 => write!(f, "i64"),
|
||||||
Type::I128 => write!(f, "i128"),
|
Type::I128 => write!(f, "i128"),
|
||||||
Type::Identifier(ref variable) => write!(f, "circuit {}", variable),
|
Type::Identifier(ref variable) => write!(f, "{}", variable),
|
||||||
Type::Scalar => write!(f, "scalar"),
|
Type::Scalar => write!(f, "scalar"),
|
||||||
Type::String => write!(f, "string"),
|
Type::String => write!(f, "string"),
|
||||||
Type::U8 => write!(f, "u8"),
|
Type::U8 => write!(f, "u8"),
|
||||||
|
@ -149,7 +149,7 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
writeln!(
|
writeln!(
|
||||||
output_string,
|
output_string,
|
||||||
" {} as {}.private;", // todo: CAUTION private record variables only.
|
" {} as {}.private;", // todo: CAUTION private record variables only.
|
||||||
name, type_,
|
name, type_.to_string().to_lowercase(),
|
||||||
)
|
)
|
||||||
.expect("failed to write to string");
|
.expect("failed to write to string");
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,21 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
|||||||
};
|
};
|
||||||
check_has_field(sym::owner, Type::Address);
|
check_has_field(sym::owner, Type::Address);
|
||||||
check_has_field(sym::gates, Type::U64);
|
check_has_field(sym::gates, Type::U64);
|
||||||
|
|
||||||
|
// Check that the record does not contain another record.
|
||||||
|
for member in input.members.iter() {
|
||||||
|
if let CircuitMember::CircuitVariable(_, Type::Identifier(identifier)) = member {
|
||||||
|
if let Some(circuit) = self.symbol_table.borrow().lookup_circuit(identifier.name) {
|
||||||
|
if circuit.is_record {
|
||||||
|
self.emit_err(TypeCheckerError::record_cannot_contain_record(
|
||||||
|
input.identifier.name,
|
||||||
|
identifier.name,
|
||||||
|
input.span(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure there are no tuple typed members.
|
// Ensure there are no tuple typed members.
|
||||||
|
@ -288,4 +288,11 @@ create_messages!(
|
|||||||
msg: format!("Helper functions cannot have modes associated with their inputs."),
|
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()),
|
help: Some("Consider removing the mode or adding a `@program` annotation to the function.".to_string()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@formatted
|
||||||
|
record_cannot_contain_record {
|
||||||
|
args: (parent_record: impl Display, child_record: impl Display),
|
||||||
|
msg: format!("A record cannot contain another record."),
|
||||||
|
help: Some(format!("Remove the record `{child_record} from `{parent_record}`.")),
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
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: Pass
|
||||||
|
*/
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
22
tests/compiler/records/nested_record_fail.leo
Normal file
22
tests/compiler/records/nested_record_fail.leo
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Fail
|
||||||
|
*/
|
||||||
|
|
||||||
|
record Foo {
|
||||||
|
// The token owner.
|
||||||
|
owner: address,
|
||||||
|
// The Aleo balance (in gates).
|
||||||
|
gates: u64,
|
||||||
|
// The token amount.
|
||||||
|
amount: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
record Token {
|
||||||
|
// The token owner.
|
||||||
|
owner: address,
|
||||||
|
// The Aleo balance (in gates).
|
||||||
|
gates: u64,
|
||||||
|
// The token amount.
|
||||||
|
foo: Foo,
|
||||||
|
}
|
9
tests/expectations/compiler/records/nested_record.out
Normal file
9
tests/expectations/compiler/records/nested_record.out
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
outputs:
|
||||||
|
- output:
|
||||||
|
- initial_input_ast: no input
|
||||||
|
initial_ast: e781700aae47b3e3e6fabae4bc8620588ce4a91c8ed500cd1bfb0005ba92f9a0
|
||||||
|
unrolled_ast: e781700aae47b3e3e6fabae4bc8620588ce4a91c8ed500cd1bfb0005ba92f9a0
|
||||||
|
ssa_ast: fdd24be71c71d34367fdd00465fa80391d89776c49e62ad13bea07385dfeb8f8
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Fail
|
||||||
|
outputs:
|
||||||
|
- "Error [ETYC0372030]: A record cannot contain another record.\n --> compiler-test:12:1\n |\n 12 | record Token {\n 13 | // The token owner.\n 14 | owner: address,\n 15 | // The Aleo balance (in gates).\n 16 | gates: u64,\n 17 | // The token amount.\n 18 | foo: Foo,\n 19 | }\n | ^\n |\n = Remove the record `Foo from `Token`.\n"
|
Loading…
Reference in New Issue
Block a user