-
Notifications
You must be signed in to change notification settings - Fork 61
feat: Add runtime function overload resolution based on Type information #1530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
f020409
to
3540ea5
Compare
a34ef8b
to
2b41197
Compare
2b41197
to
b761a2e
Compare
Hi maintainers, I wanted to follow up on my pull request #1530 regarding runtime function overload resolution enhancement. It's been about two months since submission, and I wanted to check on the current status. Current Status
What This PR DoesEnables runtime function overload resolution based on precise Type information rather than just Kind-level resolution, resolving the limitation where Potential ConcernThis PR modifies an abstract class's virtual function definition by adding an optional Questions
I'm committed to finding the right approach and ensuring this enhancement meets the project's compatibility standards. Thank you for your consideration. Best regards |
Hi there, sorry for the delay in responding. We won't be able to accept this change as is for a couple of reasons, but you are right that the way the C++ library handles function overload resolution is not ideal or consistent with the other runtime implementations. Issues here:
We'd be open to taking a contribution but we'd need to coordinate a bit up front to break the change down into syncable chunks. If you'd like to create an Issue we can coordinate there. We are pretty busy on internal work so I can't guarantee we'll be able to devote much time to this, but can at least keep the issue updated. Tagging @jcking if he has any additional input. |
Currently, CEL-C++ only supports Type-level function overload resolution during the type-checking phase, while runtime function dispatch is limited to Kind-level resolution. This limitation prevents runtime selection of the most appropriate function overload when dealing with complex type hierarchies or when type information is available but not fully determined during static analysis. As described in issue google#1484, the FunctionRegistry cannot distinguish overloads differing only by container parameter types (e.g., `list<int>` vs `list<string>`) because the current implementation only compares `cel::Kind` rather than precise `cel::Type` information during function registration and dispatch. Enable runtime function overload resolution based on precise Type information by propagating overload IDs from the type-checking phase to the runtime execution phase. This enhancement allows the runtime to make more informed decisions about which function overload to invoke, improving both correctness and performance in scenarios where multiple overloads are available. 1. **Enhanced Function Interface** - Extended `Function::Invoke()` method signature to accept an optional `overload_id` parameter (`absl::Span<const std::string>`) with default empty value - Updated all function adapter classes (Nullary, Unary, Binary, Ternary, Quaternary) to propagate overload ID information - Modified `CelFunction` implementation to support the new interface 2. **FlatExpr Builder Integration** - Added `reference_map_` field to `FlatExprVisitor` to access type-checking reference information during expression compilation - Implemented `FindReference()` helper method to retrieve overload IDs associated with specific expressions - Updated `CreateFunctionStep()` and `CreateDirectFunctionStep()` calls to pass overload ID information from the reference map - Added default parameter values to maintain backward compatibility 3. **Function Step Enhancement** - Extended `AbstractFunctionStep` constructor to accept overload IDs with move semantics - Updated both eager (`EagerFunctionStep`) and lazy (`LazyFunctionStep`) function step implementations to store overload ID information - Modified direct execution steps (`DirectFunctionStepImpl`) to store and utilize overload ID information - Enhanced the `Invoke()` helper function to pass overload IDs to the underlying function implementation - **Backward Compatibility**: All function creation methods provide default empty overload ID parameters, ensuring existing code continues to work without modification 1. **Enhanced Precision**: Runtime can select optimal function overloads based on complete type information rather than just value kinds 2. **Better Performance**: Reduced need for runtime type checks and fallback mechanisms when precise overload information is available 3. **Improved Extensibility**: Framework for future enhancements requiring type-aware runtime behavior 4. **Maintained Compatibility**: All existing functionality preserved while adding new capabilities 5. **Resolves Container Type Disambiguation**: Enables proper handling of function overloads that differ only in container element types, addressing the "empty container" problem described in the issue This change maintains full API and ABI compatibility through default parameter values. All existing tests should continue to pass without modification, and new tests can be added to verify type-aware overload resolution behavior. Closes google#1484
b761a2e
to
1f85b20
Compare
Motivation
Currently, CEL-C++ only supports Type-level function overload resolution during the type-checking phase, while runtime function dispatch is limited to Kind-level resolution. This limitation prevents runtime selection of the most appropriate function overload when dealing with complex type hierarchies or when type information is available but not fully determined during static analysis.
As described in issue #1484, the FunctionRegistry cannot distinguish overloads differing only by container parameter types (e.g.,
list<int>
vslist<string>
) because the current implementation only comparescel::Kind
rather than precisecel::Type
information during function registration and dispatch.Objective
Enable runtime function overload resolution based on precise Type information by propagating overload IDs from the type-checking phase to the runtime execution phase. This enhancement allows the runtime to make more informed decisions about which function overload to invoke, improving both correctness and performance in scenarios where multiple overloads are available.
Implementation
Core Changes
Enhanced Function Interface
Function::Invoke()
method signature to accept an optionaloverload_id
parameter (absl::Span<const std::string>
) with default empty valueCelFunction
implementation to support the new interfaceFlatExpr Builder Integration
reference_map_
field toFlatExprVisitor
to access type-checking reference information during expression compilationFindReference()
helper method to retrieve overload IDs associated with specific expressionsCreateFunctionStep()
andCreateDirectFunctionStep()
calls to pass overload ID information from the reference mapFunction Step Enhancement
AbstractFunctionStep
constructor to accept overload IDs with move semanticsEagerFunctionStep
) and lazy (LazyFunctionStep
) function step implementations to store overload ID informationDirectFunctionStepImpl
) to store and utilize overload ID informationInvoke()
helper function to pass overload IDs to the underlying function implementationTechnical Details
Benefits
Testing
This change maintains full API and ABI compatibility through default parameter values. All existing tests should continue to pass without modification, and new tests can be added to verify type-aware overload resolution behavior.
Closes #1484