Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[framework] vector zip destroy_empty + allow return values in lambdas #20745

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions crates/sui-framework/packages/move-stdlib/sources/macros.move
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public macro fun num_to_string($x: _): String {
buffer.to_string()
}

public macro fun range_do($start: _, $stop: _, $f: |_|) {
public macro fun range_do($start: _, $stop: _, $f: |_| -> _) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes feel fine to me, I just wonder if it is worth annotating, e.g.

Suggested change
public macro fun range_do($start: _, $stop: _, $f: |_| -> _) {
public macro fun range_do<R: drop>($start: _, $stop: _, $f: |_| -> R) {

Perhaps @tzakian or @cgswords will have opinions

let mut i = $start;
let stop = $stop;
while (i < stop) {
Expand All @@ -93,7 +93,7 @@ public macro fun range_do($start: _, $stop: _, $f: |_|) {
}
}

public macro fun range_do_eq($start: _, $stop: _, $f: |_|) {
public macro fun range_do_eq($start: _, $stop: _, $f: |_| -> _) {
let mut i = $start;
let stop = $stop;
// we check `i >= stop` inside the loop instead of `i <= stop` as `while` condition to avoid
Expand All @@ -108,11 +108,11 @@ public macro fun range_do_eq($start: _, $stop: _, $f: |_|) {
}
}

public macro fun do($stop: _, $f: |_|) {
public macro fun do($stop: _, $f: |_| -> _) {
range_do!(0, $stop, $f)
}

public macro fun do_eq($stop: _, $f: |_|) {
public macro fun do_eq($stop: _, $f: |_| -> _) {
range_do_eq!(0, $stop, $f)
}

Expand Down
8 changes: 4 additions & 4 deletions crates/sui-framework/packages/move-stdlib/sources/option.move
Original file line number Diff line number Diff line change
Expand Up @@ -144,26 +144,26 @@ public fun to_vec<Element>(t: Option<Element>): vector<Element> {
// === Macro Functions ===

/// Destroy `Option<T>` and call the closure `f` on the value inside if it holds one.
public macro fun destroy<$T>($o: Option<$T>, $f: |$T|) {
public macro fun destroy<$T>($o: Option<$T>, $f: |$T| -> _) {
let o = $o;
o.do!($f);
}

/// Destroy `Option<T>` and call the closure `f` on the value inside if it holds one.
public macro fun do<$T>($o: Option<$T>, $f: |$T|) {
public macro fun do<$T>($o: Option<$T>, $f: |$T| -> _) {
let o = $o;
if (o.is_some()) $f(o.destroy_some())
else o.destroy_none()
}

/// Execute a closure on the value inside `t` if it holds one.
public macro fun do_ref<$T>($o: &Option<$T>, $f: |&$T|) {
public macro fun do_ref<$T>($o: &Option<$T>, $f: |&$T| -> _) {
let o = $o;
if (o.is_some()) $f(o.borrow());
}

/// Execute a closure on the mutable reference to the value inside `t` if it holds one.
public macro fun do_mut<$T>($o: &mut Option<$T>, $f: |&mut $T|) {
public macro fun do_mut<$T>($o: &mut Option<$T>, $f: |&mut $T| -> _) {
let o = $o;
if (o.is_some()) $f(o.borrow_mut());
}
Expand Down
17 changes: 9 additions & 8 deletions crates/sui-framework/packages/move-stdlib/sources/vector.move
Original file line number Diff line number Diff line change
Expand Up @@ -172,30 +172,30 @@ public macro fun tabulate<$T>($n: u64, $f: |u64| -> $T): vector<$T> {

/// Destroy the vector `v` by calling `f` on each element and then destroying the vector.
/// Does not preserve the order of elements in the vector (starts from the end of the vector).
public macro fun destroy<$T>($v: vector<$T>, $f: |$T|) {
public macro fun destroy<$T>($v: vector<$T>, $f: |$T| -> _) {
let mut v = $v;
while (v.length() != 0) $f(v.pop_back());
v.destroy_empty();
}

/// Destroy the vector `v` by calling `f` on each element and then destroying the vector.
/// Preserves the order of elements in the vector.
public macro fun do<$T>($v: vector<$T>, $f: |$T|) {
public macro fun do<$T>($v: vector<$T>, $f: |$T| -> _) {
let mut v = $v;
v.reverse();
v.length().do!(|_| $f(v.pop_back()));
v.destroy_empty();
}

/// Perform an action `f` on each element of the vector `v`. The vector is not modified.
public macro fun do_ref<$T>($v: &vector<$T>, $f: |&$T|) {
public macro fun do_ref<$T>($v: &vector<$T>, $f: |&$T| -> _) {
let v = $v;
v.length().do!(|i| $f(&v[i]))
}

/// Perform an action `f` on each element of the vector `v`.
/// The function `f` takes a mutable reference to the element.
public macro fun do_mut<$T>($v: &mut vector<$T>, $f: |&mut $T|) {
public macro fun do_mut<$T>($v: &mut vector<$T>, $f: |&mut $T| -> _) {
let v = $v;
v.length().do!(|i| $f(&mut v[i]))
}
Expand Down Expand Up @@ -295,19 +295,20 @@ public macro fun all<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool {
/// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements.
/// Aborts if the vectors are not of the same length.
/// The order of elements in the vectors is preserved.
public macro fun zip_do<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) {
public macro fun zip_do<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2| -> _) {
let v1 = $v1;
let mut v2 = $v2;
v2.reverse();
let len = v1.length();
assert!(len == v2.length());
v1.do!(|el1| $f(el1, v2.pop_back()));
v2.destroy_empty();
}

/// Destroys two vectors `v1` and `v2` by calling `f` to each pair of elements.
/// Aborts if the vectors are not of the same length.
/// Starts from the end of the vectors.
public macro fun zip_do_reverse<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2|) {
public macro fun zip_do_reverse<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f: |$T1, $T2| -> _) {
let v1 = $v1;
let mut v2 = $v2;
let len = v1.length();
Expand All @@ -319,7 +320,7 @@ public macro fun zip_do_reverse<$T1, $T2>($v1: vector<$T1>, $v2: vector<$T2>, $f
/// elements. The vectors are not modified.
/// Aborts if the vectors are not of the same length.
/// The order of elements in the vectors is preserved.
public macro fun zip_do_ref<$T1, $T2>($v1: &vector<$T1>, $v2: &vector<$T2>, $f: |&$T1, &$T2|) {
public macro fun zip_do_ref<$T1, $T2>($v1: &vector<$T1>, $v2: &vector<$T2>, $f: |&$T1, &$T2| -> _) {
let v1 = $v1;
let v2 = $v2;
let len = v1.length();
Expand All @@ -334,7 +335,7 @@ public macro fun zip_do_ref<$T1, $T2>($v1: &vector<$T1>, $v2: &vector<$T2>, $f:
public macro fun zip_do_mut<$T1, $T2>(
$v1: &mut vector<$T1>,
$v2: &mut vector<$T2>,
$f: |&mut $T1, &mut $T2|,
$f: |&mut $T1, &mut $T2| -> _,
) {
let v1 = $v1;
let v2 = $v2;
Expand Down
16 changes: 16 additions & 0 deletions crates/sui-framework/packages/move-stdlib/tests/vector_tests.move
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,11 @@ fun test_do_macro() {
assert!(vec == vector[11, 21, 31, 41]);
}

#[test]
fun test_do_macro_with_return_value() {
vector[10, 20, 30].do!(|e| e);
}

#[test]
fun test_map_macro() {
let e = vector<u8>[];
Expand Down Expand Up @@ -741,6 +746,17 @@ fun zip_do_macro() {
assert!(res == vector[5, 7, 9]);
}

#[test]
fun zip_do_undroppable_macro() {
let v1 = vector[NotDroppable {}, NotDroppable {}];
let v2 = vector[NotDroppable {}, NotDroppable {}];

v1.zip_do!(v2, |a, b| {
let NotDroppable {} = a;
let NotDroppable {} = b;
});
}

#[test, expected_failure]
fun zip_do_reverse_macro_fail() {
let v1 = vector[1u64];
Expand Down
Loading