mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Simplify Type::userDefinedOperator function
This commit is contained in:
parent
e3f5c4c1b5
commit
b860561814
@ -1750,13 +1750,37 @@ bool TypeChecker::visit(UnaryOperation const& _operation)
|
||||
solAssert(!builtinResult || !userDefinedOperatorResult);
|
||||
if (userDefinedOperatorResult)
|
||||
{
|
||||
solAssert(userDefinedFunctionType->parameterTypes().size() == 1);
|
||||
solAssert(userDefinedFunctionType->returnParameterTypes().size() == 1);
|
||||
solAssert(
|
||||
*userDefinedFunctionType->parameterTypes().at(0) ==
|
||||
*userDefinedFunctionType->returnParameterTypes().at(0)
|
||||
);
|
||||
_operation.annotation().type = userDefinedFunctionType->returnParameterTypes().at(0);
|
||||
if (userDefinedFunctionType->returnParameterTypes().size() != 1)
|
||||
{
|
||||
m_errorReporter.typeError(
|
||||
3138_error,
|
||||
_operation.location(),
|
||||
"User defined operator " + string(TokenTraits::toString(_operation.getOperator())) +
|
||||
" needs to return exactly one value."
|
||||
);
|
||||
_operation.annotation().type = subExprType;
|
||||
}
|
||||
else if (*userDefinedFunctionType->returnParameterTypes().front() != *userDefinedFunctionType->parameterTypes().front())
|
||||
{
|
||||
m_errorReporter.typeError(
|
||||
7983_error,
|
||||
_operation.location(),
|
||||
"User defined operator " + string(TokenTraits::toString(_operation.getOperator())) +
|
||||
" needs to return value of type " +
|
||||
userDefinedFunctionType->parameterTypes().front()->humanReadableName() + "."
|
||||
);
|
||||
_operation.annotation().type = subExprType;
|
||||
}
|
||||
else
|
||||
{
|
||||
solAssert(userDefinedFunctionType->parameterTypes().size() == 1);
|
||||
solAssert(
|
||||
*userDefinedFunctionType->parameterTypes().at(0) ==
|
||||
*userDefinedFunctionType->returnParameterTypes().at(0)
|
||||
);
|
||||
_operation.annotation().type = userDefinedFunctionType->returnParameterTypes().at(0);
|
||||
}
|
||||
|
||||
}
|
||||
else if (builtinResult)
|
||||
_operation.annotation().type = builtinResult;
|
||||
@ -1840,7 +1864,8 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
|
||||
*userDefinedFunctionType->parameterTypes().at(0) ==
|
||||
*userDefinedFunctionType->parameterTypes().at(1)
|
||||
);
|
||||
commonType = userDefinedFunctionType->returnParameterTypes().at(0);
|
||||
if (userDefinedFunctionType->returnParameterTypes().size() == 1)
|
||||
commonType = userDefinedFunctionType->parameterTypes().at(0);
|
||||
}
|
||||
|
||||
_operation.annotation().commonType = commonType;
|
||||
@ -1850,11 +1875,24 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
|
||||
commonType;
|
||||
|
||||
if (userDefinedOperatorResult)
|
||||
solAssert(
|
||||
userDefinedFunctionType->returnParameterTypes().size() == 1 &&
|
||||
*userDefinedFunctionType->returnParameterTypes().front() == *_operation.annotation().type,
|
||||
"User defined operator has an invalid return parameter."
|
||||
);
|
||||
{
|
||||
if (userDefinedFunctionType->returnParameterTypes().size() != 1)
|
||||
m_errorReporter.typeError(
|
||||
1208_error,
|
||||
_operation.location(),
|
||||
"User defined operator " + string(TokenTraits::toString(_operation.getOperator())) +
|
||||
" needs to return exactly one value."
|
||||
);
|
||||
|
||||
else if (*userDefinedFunctionType->returnParameterTypes().front() != *_operation.annotation().type)
|
||||
m_errorReporter.typeError(
|
||||
3841_error,
|
||||
_operation.location(),
|
||||
"User defined operator " + string(TokenTraits::toString(_operation.getOperator())) +
|
||||
" needs to return value of type " +
|
||||
_operation.annotation().type->humanReadableName() + "."
|
||||
);
|
||||
}
|
||||
else if (_operation.getOperator() == Token::Exp || _operation.getOperator() == Token::SHL)
|
||||
{
|
||||
string operation = _operation.getOperator() == Token::Exp ? "exponentiation" : "shift";
|
||||
|
@ -404,14 +404,8 @@ Result<FunctionDefinition const*> Type::userDefinedOperator(Token _token, ASTNod
|
||||
);
|
||||
solAssert(functionType && !functionType->parameterTypes().empty());
|
||||
|
||||
Type const* expectedReturnType =
|
||||
TokenTraits::isCompareOp(_token) ?
|
||||
TypeProvider::boolean() : functionType->parameterTypes().front();
|
||||
|
||||
if (
|
||||
isImplicitlyConvertibleTo(*functionType->parameterTypes().front()) &&
|
||||
function.returnParameterList()->parameters().size() == 1 &&
|
||||
function.returnParameterList()->parameters().front()->type()->isImplicitlyConvertibleTo(*expectedReturnType) &&
|
||||
(
|
||||
(_unaryOperation && function.parameterList().parameters().size() == 1) ||
|
||||
(!_unaryOperation && function.parameterList().parameters().size() == 2)
|
||||
|
@ -4,6 +4,7 @@ using {
|
||||
add as +,
|
||||
div as /,
|
||||
unsub as -,
|
||||
bitnot as ~,
|
||||
gt as >,
|
||||
lt as <
|
||||
} for Int;
|
||||
@ -20,6 +21,10 @@ function unsub(Int) pure returns (Int, Int) {
|
||||
return (Int.wrap(0), Int.wrap(1));
|
||||
}
|
||||
|
||||
function bitnot(Int) pure returns (int256) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
function gt(Int, Int) pure returns (Int) {
|
||||
return Int.wrap(0);
|
||||
}
|
||||
@ -32,6 +37,7 @@ function f() pure {
|
||||
Int.wrap(0) + Int.wrap(1);
|
||||
Int.wrap(0) / Int.wrap(0);
|
||||
-Int.wrap(0);
|
||||
~Int.wrap(0);
|
||||
Int.wrap(0) < Int.wrap(0);
|
||||
Int.wrap(0) > Int.wrap(0);
|
||||
}
|
||||
@ -40,10 +46,12 @@ function f() pure {
|
||||
// TypeError 7743: (33-36): The function "add" needs to return exactly one value of type Int to be used for the operator +.
|
||||
// TypeError 7743: (47-50): The function "div" needs to return exactly one value of type Int to be used for the operator /.
|
||||
// TypeError 7743: (61-66): The function "unsub" needs to return exactly one value of type Int to be used for the operator -.
|
||||
// TypeError 7995: (77-79): The function "gt" needs to return exactly one value of type bool to be used for the operator >.
|
||||
// TypeError 7995: (90-92): The function "lt" needs to return exactly one value of type bool to be used for the operator <.
|
||||
// TypeError 2271: (492-517): Operator + not compatible with types Int and Int. No matching user-defined operator found.
|
||||
// TypeError 2271: (523-548): Operator / not compatible with types Int and Int. No matching user-defined operator found.
|
||||
// TypeError 4907: (554-566): Unary operator - cannot be applied to type Int. No matching user-defined operator found.
|
||||
// TypeError 2271: (572-597): Operator < not compatible with types Int and Int. No matching user-defined operator found.
|
||||
// TypeError 2271: (603-628): Operator > not compatible with types Int and Int. No matching user-defined operator found.
|
||||
// TypeError 7743: (77-83): The function "bitnot" needs to return exactly one value of type Int to be used for the operator ~.
|
||||
// TypeError 7995: (94-96): The function "gt" needs to return exactly one value of type bool to be used for the operator >.
|
||||
// TypeError 7995: (107-109): The function "lt" needs to return exactly one value of type bool to be used for the operator <.
|
||||
// TypeError 3841: (571-596): User defined operator + needs to return value of type Int.
|
||||
// TypeError 1208: (602-627): User defined operator / needs to return exactly one value.
|
||||
// TypeError 3138: (633-645): User defined operator - needs to return exactly one value.
|
||||
// TypeError 7983: (651-663): User defined operator ~ needs to return value of type Int.
|
||||
// TypeError 1208: (669-694): User defined operator < needs to return exactly one value.
|
||||
// TypeError 3841: (700-725): User defined operator > needs to return value of type bool.
|
||||
|
Loading…
Reference in New Issue
Block a user