View on GitHub

Ü Programming Language

Auto-move in return

Motivation

In the Compiler1 code it was usual to write code like this:

var SomeStruct mut s{ .x= InitX(), .y= InitY() };
return move(s);

return move was a common pattern in order to avoid taking copies in return. But it’s too verbose, so, i decided to change this.

Solution

Actually the compiler can automatically detect cases, where a local variable is returned and move it without explicit move operator. Recently i implemented exactly this behavior.

Now return some_var; behaves in certain circumstances like return move(some_var);. some_var should be the name of a local variable or value argument. This variable should not have alive references to it. Compared to regular move auto-move in return may also move immutable variables.

Automatic move in more complex cases is still not possible. For example return Foo(some_var); can’t be transformed into something like return Foo(move(some_var));. So, move should be still specified manually.

Automatic move works also in cases where implicit type conversion is performed:

struct S
{
	i32 x;
}
struct T
{
	fn conversion_constructor( S mut in_s ) ( s(move(in_s)) ) {}
	S s;
}
fn MakeT( S s ) : T
{
	return s; // Auto-move in "return" and than perform implicit type conversion.
}

Conclusion

Adding such easy feature allows to simplify code in many places. Writing return move isn’t needed anymore. Yet another benefit - in some cases it’s not longer needed to declare returned variable as mutable.

So, code like in the beginning of this post now looks like this:

var SomeStruct s{ .x= InitX(), .y= InitY() };
return s;

Future work

Automatic move in return is nice, but it’s still a partial solution. More general solution is to analyze variables lifetime and move them automatically at last usage. This may eliminate need for move at all or at least almost in all cases. But for now it’s too complicated. It requires substantial compiler architecture changing - introducing a whole new pass to analyze lifetimes, which isn’t so trivial.