Skip to content

Commit f5b12ee

Browse files
committed
fix: Analyze assigned expr before bound variables
Let statements can redefine a variable. This variable can occur inside the assigned expression. The assigned expression must be analyzed with the old variable bindings (and types) before the variable bindings are updated. Assert correctness in a unit test.
1 parent 6f99023 commit f5b12ee

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

src/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,11 +634,11 @@ impl AbstractSyntaxTree for Assignment {
634634
// However, the expression evaluated in the assignment does have a type,
635635
// namely the type specified in the assignment.
636636
let ty_expr = scope.resolve(&from.ty).with_span(from)?;
637+
let expression = Expression::analyze(&from.expression, &ty_expr, scope)?;
637638
let typed_variables = from.pattern.is_of_type(&ty_expr).with_span(from)?;
638639
for (identifier, ty) in typed_variables {
639640
scope.insert_variable(identifier, ty);
640641
}
641-
let expression = Expression::analyze(&from.expression, &ty_expr, scope)?;
642642

643643
Ok(Self {
644644
pattern: from.pattern.clone(),

src/lib.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,12 @@ mod tests {
107107
panic!("{error}")
108108
}
109109
};
110-
let redeem_prog = match satisfy(&prog_text, &witness) {
110+
111+
assert_success(&prog_text, &witness);
112+
}
113+
114+
fn assert_success(prog_text: &str, witness: &WitnessValues) {
115+
let redeem_prog = match satisfy(prog_text, witness) {
111116
Ok(x) => x,
112117
Err(error) => {
113118
panic!("{error}");
@@ -120,10 +125,24 @@ mod tests {
120125
dbg!(&redeem_prog);
121126
println!("{}", Base64Display::new(&vec, &STANDARD));
122127

123-
let mut bit_mac = BitMachine::for_program(&redeem_prog);
128+
let mut mac = BitMachine::for_program(&redeem_prog);
124129
let env = dummy_env::dummy();
125-
bit_mac
126-
.exec(&redeem_prog, &env)
130+
mac.exec(&redeem_prog, &env)
127131
.expect("Machine execution failure");
128132
}
133+
134+
fn assert_success_empty_witness(prog_text: &str) {
135+
let witness = WitnessValues::empty();
136+
assert_success(prog_text, &witness)
137+
}
138+
139+
#[test]
140+
fn redefined_variable() {
141+
let prog_text = r#"fn main() {
142+
let beefbabe: (u16, u16) = (0xbeef, 0xbabe);
143+
let beefbabe: u32 = <(u16, u16)>::into(beefbabe);
144+
}
145+
"#;
146+
assert_success_empty_witness(prog_text);
147+
}
129148
}

0 commit comments

Comments
 (0)