mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Disallow defining operators with non-pure functions
This commit is contained in:
parent
56ebb5f901
commit
e0722732f6
@ -45,7 +45,7 @@ Note that private library functions can only be specified when ``using for`` is
|
||||
|
||||
If you define an operator (e.g. ``using {f as +} for T``), then the type (``T``) must be a
|
||||
:ref:`user-defined value type <user-defined-value-types>`.
|
||||
The definition of an operator must be a function with the types of all parameters and
|
||||
The definition of an operator must be a ``pure`` function with the types of all parameters and
|
||||
the return value matching ``T``, except for comparison operators, where the return value must
|
||||
be of type ``bool``.
|
||||
|
||||
|
@ -4001,6 +4001,13 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
||||
}
|
||||
solAssert(usingForType->typeDefinition());
|
||||
|
||||
if (functionType->stateMutability() != StateMutability::Pure)
|
||||
m_errorReporter.typeError(
|
||||
7775_error,
|
||||
path->location(),
|
||||
"Only pure functions can be used to define operators."
|
||||
);
|
||||
|
||||
bool identicalFirstTwoParameters = (parameterCount < 2 || *parameterTypes.at(0) == *parameterTypes.at(1));
|
||||
bool isUnaryOnlyOperator = (!TokenTraits::isBinaryOp(*operator_) && TokenTraits::isUnaryOp(*operator_));
|
||||
bool isBinaryOnlyOperator =
|
||||
|
@ -653,7 +653,7 @@ private:
|
||||
* all functions, and this is checked at the point of the using statement. For versions 1 and
|
||||
* 2, this check is only done when a function is called.
|
||||
*
|
||||
* For version 4, T has to be user-defined value type.
|
||||
* For version 4, T has to be user-defined value type and the function must be pure.
|
||||
* All parameters and return value of all the functions have to be of type T.
|
||||
* This version can be combined with version 3 - a single directive may attach functions to the
|
||||
* type and define operators on it at the same time.
|
||||
|
@ -21,5 +21,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// test() -> 3
|
||||
// gas legacy: 119695
|
||||
// TypeError 7775: (27-30): Only pure functions can be used to define operators.
|
@ -0,0 +1,12 @@
|
||||
using {add as +, sub as -, mul as *} for A;
|
||||
|
||||
function add(A, A) view returns (A) {}
|
||||
function sub(A, A) returns (A) {}
|
||||
function mul(A, A) payable returns (A) {}
|
||||
|
||||
type A is address payable;
|
||||
// ----
|
||||
// TypeError 7775: (7-10): Only pure functions can be used to define operators.
|
||||
// TypeError 7775: (17-20): Only pure functions can be used to define operators.
|
||||
// TypeError 7775: (27-30): Only pure functions can be used to define operators.
|
||||
// TypeError 9559: (118-159): Free functions cannot be payable.
|
@ -1,17 +0,0 @@
|
||||
type Int is uint8;
|
||||
|
||||
using {
|
||||
add as +
|
||||
} for Int;
|
||||
|
||||
|
||||
function f_view() view {}
|
||||
|
||||
function add(Int, Int) view returns (Int) {
|
||||
f_view();
|
||||
return Int.wrap(0);
|
||||
}
|
||||
|
||||
function f() view {
|
||||
Int.wrap(0) + Int.wrap(0);
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
type Int is uint8;
|
||||
|
||||
using {
|
||||
add as +
|
||||
} for Int;
|
||||
|
||||
|
||||
function f_view() view {}
|
||||
|
||||
function add(Int, Int) view returns (Int) {
|
||||
f_view();
|
||||
return Int.wrap(0);
|
||||
}
|
||||
|
||||
function f() view {
|
||||
Int.wrap(0) + Int.wrap(0);
|
||||
}
|
||||
|
||||
function g() {
|
||||
Int.wrap(0) + Int.wrap(0);
|
||||
}
|
||||
|
||||
function h() pure {
|
||||
Int.wrap(0) + Int.wrap(0);
|
||||
}
|
||||
// ----
|
||||
// Warning 2018: (220-267): Function state mutability can be restricted to view
|
||||
// TypeError 2527: (293-318): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view".
|
Loading…
Reference in New Issue
Block a user