Skip to content
This repository has been archived by the owner on May 4, 2024. It is now read-only.

[inlining] Revised inlining implementation #822

Merged
merged 1 commit into from
Jan 17, 2023
Merged
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
44 changes: 44 additions & 0 deletions language/documentation/book/src/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -509,3 +509,47 @@ Using `return` without an argument is shorthand for `return ()`. That is, the fo
fun foo() { return }
fun foo() { return () }
```

## Inline Functions

Inline functions are functions which are expanded at caller side instead
of compiled into Move bytecode. This allows to safe gas and may lead
to faster execution. For example, one can define an inline function

```move=
inline fun percent(x: u64, y: u64):u64 { x * 100 / y }
```

Now, when call `percent(2, 200)` the compiler will inline the function
definition as if the user has written `2 * 100 / 200`.

### Function Parameters

Inline functions support _function parameters_. This allows
to define higher-order functions in Move which can comprehend common
programming patterns. As inline functions are expanded at compilation time,
this feature of function parameters can be supported without direct
support for it in Move bytecode.

Consider the following function (from the `vector` module):

```move=
/// Fold the function over the elements. For example, `fold(vector[1,2,3], 0, f)` will execute
/// `f(f(f(0, 1), 2), 3)`
public inline fun fold<Accumulator, Element>(
v: vector<Element>,
init: Accumulator,
f: |Accumulator,Element|Accumulator
): Accumulator {
let accu = init;
foreach(v, |elem| accu = g(accu, elem));
accu
}
```

Here, `foreach` is itself an inline function.

In general, only lambda expressions can be passed to function parameters.
Similar as the inline function itself, those lambdas are expanded at caller
side. Notice that a lambda can access variables in the context, as in the
example the variable `accu`.
1 change: 0 additions & 1 deletion language/move-compiler/src/diagnostics/codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,6 @@ codes!(
// errors for inlining
Inlining: [
Recursion: { msg: "recursion during function inlining not allowed", severity: BlockingError },
InvalidBorrow: { msg: "inlined parameter cannot be borrowed", severity: BlockingError },
],
);

Expand Down
1 change: 1 addition & 0 deletions language/move-compiler/src/inlining/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
// SPDX-License-Identifier: Apache-2.0

pub mod translate;
mod visitor;
Loading