Skip to content

Commit

Permalink
[move][move-2024] Adjust HLIR to allow reuse of labels in different s…
Browse files Browse the repository at this point in the history
…copes (#19289)

## Description 

While name resolution and typing ensure uniquely-named labels, they can
appear on the right-hand side of an `or`-pattern match, meaning they
will be duplicated during match compilation. This currently causes a
panic (cc @damirka ), but the revised code allows for block name reuse
in different scopes in HLIR by adding them to the map for processing the
body and removing them afterwards.

This also cleans up a redundant error being generated in typing, which
was also being reported in naming.

## Test plan 

Several new tests, plus a bunch of other tests for match features.

---

## Release notes

Check each box that your changes affect. If none of the boxes relate to
your changes, release notes aren't required.

For each box you select, include information after the relevant heading
that describes the impact of your changes that a user might notice and
any actions they must take to implement updates.

- [ ] Protocol: 
- [ ] Nodes (Validators and Full nodes): 
- [ ] Indexer: 
- [ ] JSON-RPC: 
- [ ] GraphQL: 
- [ ] CLI: 
- [ ] Rust SDK:
- [ ] REST API:
  • Loading branch information
cgswords authored Sep 12, 2024
1 parent 7fd291a commit 8a96ddb
Show file tree
Hide file tree
Showing 51 changed files with 907 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
processed 3 tasks
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//# init --edition 2024.beta

//# publish
module 0x42::m {

public enum E {
One { a: u64, b: u64, c: u64 },
Two { d: u64, e: u64, f: u64 },
}

fun test() {
let e_0 = E::One { a: 0, b: 1, c: 2 };
let x = match (e_0) {
E::One { c: a, b: b, a: c } => a + c * b,
E::Two { .. } => abort 0,
};
assert!(x == 2);
let e_1 = E::Two { d: 0, e: 1, f: 2 };
let x = match (e_1) {
E::Two { e: d, f: e, d: f } => d * e + f,
E::One { .. } => abort 0,
};
assert!(x == 2);
}
}

//# run 0x42::m::test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
processed 3 tasks
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//# init --edition 2024.beta

//# publish
module 0x42::m {

public enum E {
One { a: u64, b: u64, c: u64 },
Two(u64, u64, u64)
}

fun do(e: E): u64 {
match (e) {
E::One { c: a, b: c, a: b } | E::Two(c, b, a) => a * (b + c)
}
}


fun test() {
let e_0 = E::One { a: 0, b: 1, c: 2 };
assert!(do(e_0) == 2);
let e_1 = E::Two(0, 1, 2);
assert!(do(e_1) == 2);
}
}

//# run 0x42::m::test
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
processed 3 tasks
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//# init --edition 2024.beta

//# publish
module 0x42::m {

public enum E has drop {
A { a: vector<u64> },
B { b: vector<u64> }
}

#[syntax(index)]
fun e_index(e: &E, ndx: u64): &u64 {
match (e) {
E::A { a } => &a[ndx],
E::B { b } => &b[ndx],
}
}

fun test() {
let e = E::A { a: vector[0,1,2,3,4] };
assert!(e[0] == 0);
assert!(e[1] == 1);
assert!(e[2] == 2);
assert!(e[3] == 3);
assert!(e[4] == 4);
let e = E::B { b: vector[0,1,2,3,4] };
assert!(e[0] == 0);
assert!(e[1] == 1);
assert!(e[2] == 2);
assert!(e[3] == 3);
assert!(e[4] == 4);
}
}

//# run 0x42::m::test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
processed 3 tasks
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//# init --edition 2024.beta

//# publish
module 0x42::m {

public enum E has drop {
A { a: vector<u64> },
B { b: vector<u64> }
}

#[syntax(index)]
fun e_index(e: &E, ndx: u64): &u64 {
match (e) {
E::A { a } | E::B { b: a } => &a[ndx],
}
}

fun test() {
let e = E::A { a: vector[0,1,2,3,4] };
assert!(e[0] == 0);
assert!(e[1] == 1);
assert!(e[2] == 2);
assert!(e[3] == 3);
assert!(e[4] == 4);
let e = E::B { b: vector[0,1,2,3,4] };
assert!(e[0] == 0);
assert!(e[1] == 1);
assert!(e[2] == 2);
assert!(e[3] == 3);
assert!(e[4] == 4);
}
}

//# run 0x42::m::test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
processed 3 tasks
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//# init --edition 2024.beta

//# publish
module 0x42::m {

public enum E has drop {
A { a: vector<u64> },
B { b: vector<u64> }
}

fun get_vec(e: &E): &vector<u64> {
match (e) {
E::A { a } => a,
E::B { b } => b,
}
}

#[syntax(index)]
fun e_index(e: &E, ndx: u64): &u64 {
&e.get_vec()[ndx]
}

fun test() {
let e = E::A { a: vector[0,1,2,3,4] };
assert!(e[0] == 0);
assert!(e[1] == 1);
assert!(e[2] == 2);
assert!(e[3] == 3);
assert!(e[4] == 4);
let e = E::B { b: vector[0,1,2,3,4] };
assert!(e[0] == 0);
assert!(e[1] == 1);
assert!(e[2] == 2);
assert!(e[3] == 3);
assert!(e[4] == 4);
}
}

//# run 0x42::m::test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
processed 3 tasks
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//# init --edition 2024.beta

//# publish
module 0x42::m {
public fun test() {
let x = 10;
let y = match (x) {
0 => 10,
mut x => {
x = x + 10;
x
}
};
assert!(y == 20);
let y = match (x) {
0 => 10,
mut y => {
y = y + 10;
y
}
};
assert!(y == 20);
}
}

//# run 0x42::m::test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
processed 3 tasks
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//# init --edition 2024.beta

//# publish
module 0x42::m {
public enum E {
X { x: u64 },
Y { y: u64 }
}

public fun test() {
let e = E::Y { y: 1 };
let value = match (e) {
E::X { mut x } | E::Y { y: mut x } => {
x = x + 1;
x
}
};
assert!(value == 2);
}
}

//# run 0x42::m::test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
processed 3 tasks
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//# init --edition 2024.beta

//# publish
module 0x42::m {

public enum Action has drop {
Stop,
MoveTo { x: u64, y: u64 },
ChangeSpeed(u64),
}

public fun test() {
// Define a list of actions
let actions: vector<Action> = vector[
Action::MoveTo { x: 10, y: 20 },
Action::ChangeSpeed(40),
Action::MoveTo { x: 10, y: 20 },
Action::Stop,
Action::ChangeSpeed(40),
];

let mut total_moves = 0;

'loop_label: loop {
let mut i = 0;
while (i < actions.length()) {
let action = &actions[i];

match (action) {
Action::MoveTo { x, y } => {
'loop_label: loop {
total_moves = total_moves + *x + *y;
break 'loop_label
};
},
Action::ChangeSpeed(speed) => {
'loop_label: loop {
total_moves = total_moves + *speed;
break 'loop_label
};
},
Action::Stop => {
break 'loop_label
},
};
i = i + 1;
};
};

actions.destroy!(|_| {});

assert!(total_moves == 100);
}
}

//# run 0x42::m::test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
processed 3 tasks
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//# init --edition 2024.beta

//# publish
module 0x42::m {

public enum Action has drop {
Stop,
MoveTo { x: u64, y: u64 },
ChangeSpeed(u64),
}

public fun test() {
// Define a list of actions
let actions: vector<Action> = vector[
Action::MoveTo { x: 10, y: 20 },
Action::ChangeSpeed(20),
Action::MoveTo { x: 10, y: 20 },
Action::Stop,
Action::ChangeSpeed(40),
];

let mut total_moves = 0;

'loop_label: loop {
let mut i = 0;
while (i < actions.length()) {
let action = &actions[i];

match (action) {
Action::MoveTo { x: speed, y: _ } | Action::ChangeSpeed(speed) => {
'loop_label: loop {
total_moves = total_moves + *speed;
break 'loop_label
};
},
Action::Stop => {
break 'loop_label
},
};
i = i + 1;
};
};

actions.destroy!(|_| {});

assert!(total_moves == 40);
}
}

//# run 0x42::m::test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
processed 3 tasks
Loading

0 comments on commit 8a96ddb

Please sign in to comment.