mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix ternary operator type deduction
This commit is contained in:
parent
a0ee14f7c2
commit
780bf4ccac
@ -1467,24 +1467,25 @@ bool TypeChecker::visit(Conditional const& _conditional)
|
||||
_conditional.trueExpression().accept(*this);
|
||||
_conditional.falseExpression().accept(*this);
|
||||
|
||||
Type const* trueType = type(_conditional.trueExpression())->mobileType();
|
||||
Type const* falseType = type(_conditional.falseExpression())->mobileType();
|
||||
|
||||
Type const* trueType = type(_conditional.trueExpression());
|
||||
Type const* falseType = type(_conditional.falseExpression());
|
||||
Type const* trueMobileType = trueType->mobileType();
|
||||
Type const* falseMobileType = falseType->mobileType();
|
||||
Type const* commonType = nullptr;
|
||||
|
||||
if (!trueType)
|
||||
m_errorReporter.typeError(9717_error, _conditional.trueExpression().location(), "Invalid mobile type in true expression.");
|
||||
else
|
||||
if (trueMobileType)
|
||||
commonType = trueType;
|
||||
|
||||
if (!falseType)
|
||||
m_errorReporter.typeError(3703_error, _conditional.falseExpression().location(), "Invalid mobile type in false expression.");
|
||||
else
|
||||
commonType = falseType;
|
||||
m_errorReporter.typeError(9717_error, _conditional.trueExpression().location(), "Invalid mobile type in true expression.");
|
||||
|
||||
if (!trueType && !falseType)
|
||||
if (falseMobileType)
|
||||
commonType = falseType;
|
||||
else
|
||||
m_errorReporter.typeError(3703_error, _conditional.falseExpression().location(), "Invalid mobile type in false expression.");
|
||||
|
||||
if (!trueMobileType && !falseMobileType)
|
||||
BOOST_THROW_EXCEPTION(FatalError());
|
||||
else if (trueType && falseType)
|
||||
else if (trueMobileType && falseMobileType)
|
||||
{
|
||||
commonType = Type::commonType(trueType, falseType);
|
||||
|
||||
@ -1494,14 +1495,14 @@ bool TypeChecker::visit(Conditional const& _conditional)
|
||||
1080_error,
|
||||
_conditional.location(),
|
||||
"True expression's type " +
|
||||
trueType->humanReadableName() +
|
||||
trueMobileType->humanReadableName() +
|
||||
" does not match false expression's type " +
|
||||
falseType->humanReadableName() +
|
||||
falseMobileType->humanReadableName() +
|
||||
"."
|
||||
);
|
||||
// even we can't find a common type, we have to set a type here,
|
||||
// otherwise the upper statement will not be able to check the type.
|
||||
commonType = trueType;
|
||||
commonType = trueMobileType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
contract C {
|
||||
function f(int a, int b) public returns (int) {
|
||||
return a < b ? -1 : 1;
|
||||
}
|
||||
|
||||
function g(int a) public returns (int) {
|
||||
int8 b = -1;
|
||||
return a < 0 ? b : 1;
|
||||
}
|
||||
|
||||
function h(int a) public returns (int) {
|
||||
int8 b = -1;
|
||||
return a < 0 ? 1 : b;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// f(int256,int256): 0, 2 -> -1
|
||||
// f(int256,int256): 2, 0 -> 1
|
||||
// g(int256): -2 -> -1
|
||||
// g(int256): 2 -> 1
|
||||
// h(int256): -2 -> 1
|
||||
// h(int256): 2 -> -1
|
||||
@ -0,0 +1,14 @@
|
||||
contract C {
|
||||
function f(bool cond) public {
|
||||
// OK
|
||||
address a1 = cond ? 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF : payable(0x1234567890123456789012345678901234567890);
|
||||
address a2 = cond ? address(0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF) : 0x1234567890123456789012345678901234567890;
|
||||
|
||||
// Errors
|
||||
address payable a3 = cond ? 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF : payable(0x1234567890123456789012345678901234567890);
|
||||
cond ? 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF : 1;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 9574: (346-470): Type address is not implicitly convertible to expected type address payable.
|
||||
// TypeError 1080: (481-534): True expression's type address does not match false expression's type uint8.
|
||||
@ -0,0 +1,16 @@
|
||||
contract C {
|
||||
function f(bool cond) public {
|
||||
// OK
|
||||
string memory v1 = cond ? "foo" : string("bar");
|
||||
bytes1 v2 = cond ? bytes1("a") : "a";
|
||||
bytes2 v3 = cond ? bytes2("a") : "a";
|
||||
bytes2 v4 = cond ? bytes1("a") : bytes2("ab");
|
||||
|
||||
// Errors
|
||||
cond ? bytes1("a") : string("b");
|
||||
cond ? 1 : bytes1("a");
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 1080: (300-332): True expression's type bytes1 does not match false expression's type string memory.
|
||||
// TypeError 1080: (343-365): True expression's type uint8 does not match false expression's type bytes1.
|
||||
@ -0,0 +1,27 @@
|
||||
contract C {
|
||||
function f(bool cond, bytes calldata cbytes) public view {
|
||||
bytes1[2] memory marray;
|
||||
bytes1[2] storage sarray;
|
||||
uint8[2] memory uint8Array;
|
||||
int16[2] memory int16Array;
|
||||
bytes memory mbytes;
|
||||
|
||||
// OK
|
||||
bytes1[2] memory marray1 = cond ? sarray : marray;
|
||||
bytes1[2] memory marray2 = cond ? marray : sarray;
|
||||
bytes memory mbytes1 = cond ? cbytes[1:2] : mbytes;
|
||||
bytes memory mbytes2 = cond ? mbytes : cbytes[1:2];
|
||||
|
||||
// Errors
|
||||
bytes1[2] storage sarray1 = cond ? sarray : marray;
|
||||
bytes1[2] storage sarray2 = cond ? marray : sarray;
|
||||
|
||||
cond ? uint8Array : int16Array;
|
||||
cond ? [1, 2] : [-1, -3];
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 9574: (517-567): Type bytes1[2] memory is not implicitly convertible to expected type bytes1[2] storage pointer.
|
||||
// TypeError 9574: (577-627): Type bytes1[2] memory is not implicitly convertible to expected type bytes1[2] storage pointer.
|
||||
// TypeError 1080: (638-668): True expression's type uint8[2] memory does not match false expression's type int16[2] memory.
|
||||
// TypeError 1080: (678-702): True expression's type uint8[2] memory does not match false expression's type int8[2] memory.
|
||||
@ -0,0 +1,30 @@
|
||||
contract C {
|
||||
function f(bool cond) public {
|
||||
// OK
|
||||
int8 v1 = cond ? -1 : 1;
|
||||
int16 v2 = cond ? -32768 : 1;
|
||||
int16 v3 = cond ? -32768 : -1;
|
||||
int16 v4 = cond ? -32768 : int8(1);
|
||||
int16 v5 = cond ? int16(1) : 1;
|
||||
uint16 v6 = cond ? uint16(1) : 1;
|
||||
ufixed8x1 v7 = cond ? 1.0 : 1.1;
|
||||
ufixed8x1 v8 = cond ? 0 : 1.1;
|
||||
fixed8x1 v9 = cond ? -1.0 : -1.1;
|
||||
fixed8x1 v10 = cond ? -1.1 : 1;
|
||||
|
||||
// Errors
|
||||
cond ? 32768 : -1;
|
||||
cond ? int16(-1) : uint8(1);
|
||||
cond ? int8(-1) : uint8(1);
|
||||
cond ? -1 : 1.1;
|
||||
cond ? -1.0 : 1.1;
|
||||
cond ? true : 1;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 1080: (500-517): True expression's type uint16 does not match false expression's type int8.
|
||||
// TypeError 1080: (528-555): True expression's type int16 does not match false expression's type uint8.
|
||||
// TypeError 1080: (566-592): True expression's type int8 does not match false expression's type uint8.
|
||||
// TypeError 1080: (603-618): True expression's type int8 does not match false expression's type ufixed8x1.
|
||||
// TypeError 1080: (629-646): True expression's type int8 does not match false expression's type ufixed8x1.
|
||||
// TypeError 1080: (657-672): True expression's type bool does not match false expression's type uint8.
|
||||
@ -9,8 +9,8 @@ contract C {
|
||||
}
|
||||
// ----
|
||||
// TypeError 9717: (94-100): Invalid mobile type in true expression.
|
||||
// TypeError 9553: (87-105): Invalid type for argument in function call. Invalid implicit conversion from uint8 to bytes1 requested.
|
||||
// TypeError 9553: (87-105): Invalid type for argument in function call. Invalid implicit conversion from int_const 99 to bytes1 requested.
|
||||
// TypeError 3703: (130-136): Invalid mobile type in false expression.
|
||||
// TypeError 9553: (118-136): Invalid type for argument in function call. Invalid implicit conversion from uint8 to bytes1 requested.
|
||||
// TypeError 9553: (118-136): Invalid type for argument in function call. Invalid implicit conversion from int_const 99 to bytes1 requested.
|
||||
// TypeError 9717: (157-163): Invalid mobile type in true expression.
|
||||
// TypeError 3703: (166-172): Invalid mobile type in false expression.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user