Type::userDefinedOperator takes return parameters into account

This commit is contained in:
wechman 2022-07-29 08:57:57 +02:00
parent e8243d49bc
commit fee6b5f96c
5 changed files with 96 additions and 43 deletions

View File

@ -1849,7 +1849,8 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
if (userDefinedOperatorResult)
solAssert(
userDefinedFunctionType->returnParameterTypes().size() == 1 &&
*userDefinedFunctionType->returnParameterTypes().front() == *_operation.annotation().type
*userDefinedFunctionType->returnParameterTypes().front() == *_operation.annotation().type,
"User defined operator has an invalid return parameter."
);
else if (_operation.getOperator() == Token::Exp || _operation.getOperator() == Token::SHL)
{

View File

@ -404,10 +404,19 @@ Result<FunctionDefinition const*> Type::userDefinedOperator(Token _token, ASTNod
function.libraryFunction() ? function.typeViaContractName() : function.type()
);
solAssert(functionType && !functionType->parameterTypes().empty());
solAssert(isImplicitlyConvertibleTo(*functionType->parameterTypes().front()));
Type const* expectedReturnType =
TokenTraits::isCompareOp(_token) ?
TypeProvider::boolean() : functionType->parameterTypes().front();
if (
(_unaryOperation && function.parameterList().parameters().size() == 1) ||
(!_unaryOperation && function.parameterList().parameters().size() == 2)
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)
)
)
seenFunctions.insert(&function);
}

View File

@ -0,0 +1,33 @@
type Int is int256;
using {
add as +, sub as -, div as /
} for Int;
function add(Int) pure returns (Int) {
return Int.wrap(0);
}
function sub(Int, Int, Int) pure returns (Int) {
return Int.wrap(1);
}
function div(int256, int256) pure returns (Int) {
return Int.wrap(2);
}
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);
}
// ----
// TypeError 1884: (33-36): The function "add" needs to have two parameters of equal type to be used for the operator +.
// TypeError 8112: (43-46): The function "sub" needs to have one or two parameters to be used for the operator -.
// TypeError 3100: (53-56): The function "div" cannot be bound to the type "Int" because the type cannot be implicitly converted to the first argument of the function ("int256").
// TypeError 2271: (317-342): Operator + not compatible with types Int and Int. No matching user-defined operator found.
// TypeError 2271: (348-373): Operator - not compatible with types Int and Int. No matching user-defined operator found.
// TypeError 2271: (379-404): Operator / not compatible with types Int and Int. No matching user-defined operator found.
// TypeError 2271: (410-435): Operator * not compatible with types Int and Int. No matching user-defined operator found.

View File

@ -0,0 +1,49 @@
type Int is int256;
using {
add as +,
div as /,
unsub as -,
gt as >,
lt as <
} for Int;
function add(Int x, Int y) pure returns (int256) {
return 0;
}
function div(Int x, Int y) pure {
x = y;
}
function unsub(Int) pure returns (Int, Int) {
return (Int.wrap(0), Int.wrap(1));
}
function gt(Int, Int) pure returns (Int) {
return Int.wrap(0);
}
function lt(Int, Int) pure returns (bool, Int) {
return (true, Int.wrap(1));
}
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);
}
// ----
// 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
// 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.

View File

@ -1,39 +0,0 @@
type Int is int256;
using {
add as +, sub as -,
mul as *, div as /,
gt as >, lt as <
} for Int;
function add(Int) pure returns (Int) {
return Int.wrap(0);
}
function sub(Int, Int, Int) pure returns (Int) {
return Int.wrap(1);
}
function mul(Int) pure returns (Int) {
return Int.wrap(2);
}
function div(Int x, Int y) pure {
x = y;
}
function gt(Int, Int) pure returns (Int) {
return Int.wrap(0);
}
function lt(Int, Int) pure returns (bool, Int) {
return (true, Int.wrap(1));
}
// ----
// TypeError 1884: (33-36): The function "add" needs to have two parameters of equal type to be used for the operator +.
// TypeError 8112: (43-46): The function "sub" needs to have one or two parameters to be used for the operator -.
// TypeError 1884: (57-60): The function "mul" needs to have two parameters of equal type to be used for the operator *.
// TypeError 7743: (67-70): The function "div" needs to return exactly one value of type Int to be used for the operator /.
// TypeError 7995: (81-83): 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 <.