Skip to content

Commit 13e9547

Browse files
committed
Clone all internal record inputs as outputs.
I messed this up in my previous commit, not handling the case of a single output. I also didn't correctly mark which record inputs were internal, potentially trying to tag some that were actually external. Fixes #28429
1 parent 2fdad2f commit 13e9547

File tree

7 files changed

+71
-10
lines changed

7 files changed

+71
-10
lines changed

compiler/ast/src/struct/mod.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use snarkvm::{
3838
/// Type identity is decided by the full path including `struct_name`,
3939
/// as the record is nominal, not structural.
4040
/// The fields are named so `struct Foo(u8, u16)` is not allowed.
41-
#[derive(Clone, Serialize, Deserialize)]
41+
#[derive(Clone, Debug, Serialize, Deserialize)]
4242
pub struct Composite {
4343
/// The name of the type in the type system in this module.
4444
pub identifier: Identifier,
@@ -126,12 +126,6 @@ impl Composite {
126126
}
127127
}
128128

129-
impl fmt::Debug for Composite {
130-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
131-
<Self as fmt::Display>::fmt(self, f)
132-
}
133-
}
134-
135129
impl fmt::Display for Composite {
136130
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
137131
f.write_str(if self.is_record { "record" } else { "struct" })?;

compiler/passes/src/code_generation/program.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ impl<'a> CodeGeneratingVisitor<'a> {
191191
if let Type::Composite(comp) = &input.type_ {
192192
let program = comp.program.unwrap_or(self.program_id.unwrap().name.name);
193193
if let Some(record) = self.state.symbol_table.lookup_record(Location::new(program, comp.id.name)) {
194-
if record.external.is_none() || record.external == Some(program) {
194+
if record.external.is_none() || record.external == self.program_id.map(|id| id.name.name) {
195195
self.internal_record_inputs.insert(register_string.clone());
196196
}
197197
}

compiler/passes/src/code_generation/statement.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,16 @@ impl CodeGeneratingVisitor<'_> {
112112
} else {
113113
// Not a tuple - only one output.
114114
let (operand, op_instructions) = self.visit_expression(&input.expression);
115-
instructions = op_instructions;
116-
operands.insert(operand);
115+
if self.internal_record_inputs.contains(&operand) {
116+
// We can't output an internal record we received as input.
117+
let (new_operand, new_instr) =
118+
self.clone_register(&operand, &self.current_function.unwrap().output_type);
119+
instructions.push_str(&new_instr);
120+
operands.insert(new_operand);
121+
} else {
122+
instructions = op_instructions;
123+
operands.insert(operand);
124+
}
117125
}
118126

119127
for (operand, output) in operands.iter().zip(&self.current_function.unwrap().output) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
program test0.aleo;
2+
3+
record R:
4+
owner as address.private;
5+
6+
function foo:
7+
cast self.signer into r0 as R.record;
8+
output r0 as R.record;
9+
// --- Next Program --- //
10+
import test0.aleo;
11+
program test1.aleo;
12+
13+
function bar:
14+
input r0 as test0.aleo/R.record;
15+
output r0 as test0.aleo/R.record;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
program test.aleo;
2+
3+
record R:
4+
owner as address.private;
5+
6+
function foo:
7+
input r0 as R.record;
8+
cast r0.owner into r1 as R.record;
9+
output r1 as R.record;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
program test0.aleo {
3+
record R {
4+
owner: address,
5+
}
6+
7+
transition foo() -> R {
8+
return R {
9+
owner: self.signer,
10+
};
11+
}
12+
}
13+
14+
// --- Next Program --- //
15+
16+
import test0.aleo;
17+
program test1.aleo {
18+
// This should compile fine without attempting to clone.
19+
transition bar(x: test0.aleo/R) -> test0.aleo/R {
20+
return x;
21+
}
22+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// As of commit 2fdad2fa89e6e47444676dbc2558c45d53550225,
2+
// programs with an internal record received as input
3+
// and output by themselves were not properly cloned.
4+
program test.aleo {
5+
record R {
6+
owner: address,
7+
}
8+
9+
transition foo(r: R) -> R {
10+
// This should be cloned.
11+
return r;
12+
}
13+
}

0 commit comments

Comments
 (0)