From 2c5acdc624ed498936b8a8021925bedab321a403 Mon Sep 17 00:00:00 2001 From: genisis0x Date: Fri, 15 May 2026 15:32:21 +0530 Subject: [PATCH] Type Checker: skip zero-param free functions in attachedFunctions resolution When a using-for directive binds a zero-parameter free function and the call site (`x.zero()`) appears earlier in the contract body than the directive itself, member resolution runs before TypeChecker visits the directive. attachedFunctions reaches addFunction(), which calls FunctionType::withBoundFirstArgument() and asserts on `!m_parameterTypes.empty()`, triggering an internal compiler error before the user-visible 4731 ("function does not have any parameters") is emitted. Library-bound resolution already filters out zero-parameter functions in the loop above; mirror the same filter for the non-library branch. The TypeChecker's endVisit(UsingForDirective) still reports 4731 for the directive itself, and the call-site separately reports 9582 ("member not found"). The user-visible diagnostics are unchanged for well-typed code. Fixes #16610 --- libsolidity/ast/Types.cpp | 14 ++++++++++---- ...ee_no_parameters_call_site_before_directive.sol | 11 +++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 test/libsolidity/syntaxTests/using/using_free_no_parameters_call_site_before_directive.sol diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 3fa068491d9f..cfc62b469fb3 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -457,10 +457,16 @@ MemberList::MemberMap Type::attachedFunctions(Type const& _type, ASTNode const& } } else - addFunction( - dynamic_cast(*declaration), - identifierPath->path().back() - ); + { + auto const& functionDefinition = dynamic_cast(*declaration); + // Zero-parameter functions are rejected by TypeChecker::endVisit(UsingForDirective) + // with error 4731, but member resolution can run before the directive is visited + // when the call site precedes the directive in the contract body. Skip these here + // so addFunction() does not assert in withBoundFirstArgument() (#16610). + if (functionDefinition.parameters().empty()) + continue; + addFunction(functionDefinition, identifierPath->path().back()); + } } return members; diff --git a/test/libsolidity/syntaxTests/using/using_free_no_parameters_call_site_before_directive.sol b/test/libsolidity/syntaxTests/using/using_free_no_parameters_call_site_before_directive.sol new file mode 100644 index 000000000000..eb853b75481b --- /dev/null +++ b/test/libsolidity/syntaxTests/using/using_free_no_parameters_call_site_before_directive.sol @@ -0,0 +1,11 @@ +function zero() pure returns (uint) { return 0; } + +contract C { + function f(uint z) pure external returns (uint) { + return z.zero(); + } + using {zero} for uint; +} +// ---- +// TypeError 9582: (133-139): Member "zero" not found or not visible after argument-dependent lookup in uint256. +// TypeError 4731: (160-164): The function "zero" does not have any parameters, and therefore cannot be attached to the type "uint256".