@@ -3171,6 +3171,59 @@ void TypeChecker::handleUnresolvedMemberAccessErrors(
31713171 );
31723172}
31733173
3174+ void TypeChecker::validateAccessMemberFunctionType (
3175+ FunctionType const * _accessedMemberFunctionType,
3176+ Type const * _expressionObjectType,
3177+ ASTString const & _memberName,
3178+ SourceLocation const & _location,
3179+ bool _emptyArguments,
3180+ bool _isDefined
3181+ ) const
3182+ {
3183+ solAssert (
3184+ !_accessedMemberFunctionType->hasBoundFirstArgument () ||
3185+ _expressionObjectType->isImplicitlyConvertibleTo (*_accessedMemberFunctionType->selfType ()),
3186+ " Function \" " + _memberName + " \" cannot be called on an object of type " +
3187+ _expressionObjectType->humanReadableName () +
3188+ " (expected " + _accessedMemberFunctionType->selfType ()->humanReadableName () + " )."
3189+ );
3190+
3191+ if (
3192+ dynamic_cast <FunctionType const *>(_expressionObjectType) &&
3193+ !_isDefined &&
3194+ (_memberName == " value" || _memberName == " gas" )
3195+ )
3196+ m_errorReporter.typeError (
3197+ 1621_error,
3198+ _location,
3199+ " Using \" ." + _memberName + " (...)\" is deprecated. Use \" {" + _memberName + " : ...}\" instead."
3200+ );
3201+
3202+ if (
3203+ _accessedMemberFunctionType->kind () == FunctionType::Kind::ArrayPush &&
3204+ !_emptyArguments &&
3205+ _expressionObjectType->containsNestedMapping ()
3206+ )
3207+ m_errorReporter.typeError (
3208+ 8871_error,
3209+ _location,
3210+ " Storage arrays with nested mappings do not support .push(<arg>)."
3211+ );
3212+
3213+ if (
3214+ _accessedMemberFunctionType->kind () == FunctionType::Kind::Send ||
3215+ _accessedMemberFunctionType->kind () == FunctionType::Kind::Transfer
3216+ )
3217+ m_errorReporter.warning (
3218+ 9207_error,
3219+ _location,
3220+ fmt::format (
3221+ " '{}' is deprecated and scheduled for removal. Use 'call{{value: <amount>}}(\"\" )' instead." ,
3222+ _accessedMemberFunctionType->kind () == FunctionType::Kind::Send ? " send" : " transfer"
3223+ )
3224+ );
3225+ }
3226+
31743227bool TypeChecker::visit (MemberAccess const & _memberAccess)
31753228{
31763229 _memberAccess.expression ().accept (*this );
@@ -3210,56 +3263,26 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
32103263 // TODO: Explain
32113264 VirtualLookup requiredLookup = VirtualLookup::Static;
32123265
3213- if (auto funType = dynamic_cast <FunctionType const *>(accessedMemberAnnotation.type ))
3266+ if (auto accessedMemberFunctionTypeType = dynamic_cast <FunctionType const *>(accessedMemberAnnotation.type ))
32143267 {
3215- solAssert (
3216- !funType->hasBoundFirstArgument () || expressionObjectType->isImplicitlyConvertibleTo (*funType->selfType ()),
3217- " Function \" " + memberName + " \" cannot be called on an object of type " +
3218- expressionObjectType->humanReadableName () + " (expected " + funType->selfType ()->humanReadableName () + " )."
3219- );
3220-
3221- if (
3222- dynamic_cast <FunctionType const *>(expressionObjectType) &&
3223- !accessedMemberAnnotation.referencedDeclaration &&
3224- (memberName == " value" || memberName == " gas" )
3225- )
3226- m_errorReporter.typeError (
3227- 1621_error,
3228- _memberAccess.location (),
3229- " Using \" ." + memberName + " (...)\" is deprecated. Use \" {" + memberName + " : ...}\" instead."
3230- );
3231-
3232- if (
3233- funType->kind () == FunctionType::Kind::ArrayPush &&
3234- arguments.value ().numArguments () != 0 &&
3235- expressionObjectType->containsNestedMapping ()
3236- )
3237- m_errorReporter.typeError (
3238- 8871_error,
3239- _memberAccess.location (),
3240- " Storage arrays with nested mappings do not support .push(<arg>)."
3241- );
3242-
3243- if (!funType->hasBoundFirstArgument ())
3268+ // Update required lookup
3269+ if (!accessedMemberFunctionTypeType->hasBoundFirstArgument ())
32443270 if (auto typeType = dynamic_cast <TypeType const *>(expressionObjectType))
32453271 {
32463272 auto contractType = dynamic_cast <ContractType const *>(typeType->actualType ());
32473273 if (contractType && contractType->isSuper ())
32483274 requiredLookup = VirtualLookup::Super;
32493275 }
32503276
3251- if (
3252- funType->kind () == FunctionType::Kind::Send ||
3253- funType->kind () == FunctionType::Kind::Transfer
3254- )
3255- m_errorReporter.warning (
3256- 9207_error,
3257- _memberAccess.location (),
3258- fmt::format (
3259- " '{}' is deprecated and scheduled for removal. Use 'call{{value: <amount>}}(\"\" )' instead." ,
3260- funType->kind () == FunctionType::Kind::Send ? " send" : " transfer"
3261- )
3262- );
3277+ // Validate an accessed member function type.
3278+ validateAccessMemberFunctionType (
3279+ accessedMemberFunctionTypeType,
3280+ expressionObjectType,
3281+ memberName,
3282+ _memberAccess.location (),
3283+ (*arguments).numArguments () == 0 ,
3284+ accessedMemberAnnotation.referencedDeclaration != nullptr
3285+ );
32633286 }
32643287
32653288 accessedMemberAnnotation.requiredLookup = requiredLookup;
0 commit comments