From a86bad1e9ca57f58c68d370073aa0667f12d285b Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 13 Jun 2014 17:44:09 -0700 Subject: [PATCH] RFC: Overloaded arithmetic and logical operators should take `self` and their arguments by value. --- active/0000-by-value-overloaded-operators.md | 79 ++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 active/0000-by-value-overloaded-operators.md diff --git a/active/0000-by-value-overloaded-operators.md b/active/0000-by-value-overloaded-operators.md new file mode 100644 index 00000000000..96d6a7a046d --- /dev/null +++ b/active/0000-by-value-overloaded-operators.md @@ -0,0 +1,79 @@ +- Start Date: 2014-06-13 +- RFC PR #: (leave this empty) +- Rust Issue #: (leave this empty) + +# Summary + +Overloaded arithmetic and logical operators should take `self` and their arguments by value. + +# Motivation + +Expensive objects that support arithmetic and logical operations—bignums, primarily—would benefit from not having to copy whenever arithmetic is used. This particular case was one of the motivations for rvalue references in C++, in fact. One can work around it with `RefCell`, but it's a pain and introduces dynamic failures. The easiest way to fix this is to make the traits that define arithmetic and operators take `self` and any arguments by value. + +# Detailed design + +The declarations of the traits `Add`, `Sub`, `Mul`, `Div`, `Rem`, `Neg`, `Not`, `BitAnd`, `BitOr`, `BitXor`, `Shl`, and `Shr` change to: + + pub trait Add { + fn add(self, rhs: RHS) -> Result; + } + + pub trait Sub { + fn sub(self, rhs: RHS) -> Result; + } + + pub trait Mul { + fn mul(self, rhs: RHS) -> Result; + } + + pub trait Div { + fn div(self, rhs: RHS) -> Result; + } + + pub trait Rem { + fn rem(self, rhs: RHS) -> Result; + } + + pub trait Neg { + fn neg(self) -> Result; + } + + pub trait Not { + fn not(self) -> Result; + } + + pub trait BitAnd { + fn bitand(self, rhs: RHS) -> Result; + } + + pub trait BitOr { + fn bitor(self, rhs: RHS) -> Result; + } + + pub trait BitXor { + fn bitxor(self, rhs: RHS) -> Result; + } + + pub trait Shl { + fn shl(self, rhs: RHS) -> Result; + } + + pub trait Shr { + fn shr(self, rhs: RHS) -> Result; + } + +The `AutorefArgs` stuff in `typeck` will be removed; all overloaded operators will typecheck as though they were `DontAutorefArgs`. + +# Drawbacks + +Some use cases of `+`, such as string and array concatentation, may become more verbose. It is likely that many of the use cases of `+` today will be compatible with these new semantics. + +# Alternatives + +As an alternative, each of these operators could have two methods, one for by-reference and one for by-value. This adds complexity, however. + +Not doing this will mean that the issues in "Motivation" will remain unsolved. + +# Unresolved questions + +None.