Modules are pure.

This commit is contained in:
chriseth 2020-06-16 16:49:31 +02:00
parent b1d22ab2c8
commit cd2cc76f20
4 changed files with 47 additions and 1 deletions

View File

@ -2704,6 +2704,8 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
annotation.isPure = _memberAccess.expression().annotation().isPure;
}
}
else if (exprType->category() == Type::Category::Module)
annotation.isPure = _memberAccess.expression().annotation().isPure;
// TODO some members might be pure, but for example `address(0x123).balance` is not pure
// although every subexpression is, so leaving this limited for now.
@ -3053,7 +3055,8 @@ bool TypeChecker::visit(Identifier const& _identifier)
}
else if (dynamic_cast<TypeType const*>(annotation.type))
annotation.isPure = true;
else if (dynamic_cast<ModuleType const*>(annotation.type))
annotation.isPure = true;
// Check for deprecated function names.
// The check is done here for the case without an actual function call.

View File

@ -1718,6 +1718,16 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
solAssert(false, "Illegal fixed bytes member.");
break;
}
case Type::Category::Module:
{
Type::Category category = _memberAccess.annotation().type->category();
solAssert(
category == Type::Category::TypeType ||
category == Type::Category::Module,
""
);
break;
}
default:
solAssert(false, "Member access to unknown type.");
}
@ -1933,6 +1943,10 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
{
// no-op
}
else if (dynamic_cast<ImportDirective const*>(declaration))
{
// no-op
}
else
{
solAssert(false, "Identifier type not expected in expression context.");

View File

@ -0,0 +1,14 @@
==== Source: a ====
struct S { uint x; }
==== Source: b ====
import "a" as A;
struct T { uint x; }
contract C {
function f() public pure {
T;
A.S;
}
}
// ----
// Warning: (b:90-91): Statement has no effect.
// Warning: (b:101-104): Statement has no effect.

View File

@ -0,0 +1,15 @@
==== Source: a ====
struct S { uint[2] mS; }
==== Source: b ====
import "a" as A;
struct T { A.S[2] mT; }
==== Source: c ====
pragma experimental ABIEncoderV2;
import "b" as B;
contract C {
function f(B.T memory y, B.A.S memory z) public pure returns (uint, uint) {
z = B.A.S([uint(2), 3]);
y = B.T([z, z]);
return (y.mT[0].mS[0], z.mS[0]);
}
}