Use overload_id for checked function overload resolution#2115
Open
xjasonli wants to merge 2 commits into
Open
Conversation
…nctions Align cel-cpp function resolution with cel-go and cel-java by introducing: 1. Plan-time overload filtering using overload_id from checked expressions 2. Runtime type-level argument matching for container elements and TypeParam, guarded by enable_type_level_overload 3. Parse-only and legacy fallback paths using arity/kind-based matching Key changes: - Add overload_id to FunctionDescriptor with Type-based constructors - Add FindStaticOverloadById/FindLazyOverloadById to FunctionRegistry - Add FindFunctionOverloadById(name, overload_id) to ActivationInterface - Add enable_type_level_overload flag to RuntimeOptions - Prefer checked overload_id candidates while still validating runtime arguments Compatibility: - Kind-level matching remains the default runtime behavior - Functions without overload_id fall back to arity-based matching
Annotate standard library, optional type, and extension function registrations with their corresponding overload_id constants. This enables plan-time overload resolution via overload_id lookup from the checker reference_map, replacing arity-only candidate selection for checked expressions where overload_id data is available. - runtime/standard/: standard functions pass StandardOverloadIds constants through RegisterHelper and FunctionAdapter interfaces. - runtime/optional_types.cc: optional functions use overload_id constants derived from checker/optional.cc declarations. - extensions/: extension registrations for strings, math, sets, lists, regex, encoders, formatting, and comprehensions_v2 are annotated with their checker-declared overload_id constants. - common/standard_definitions.h: add missing kBoolToInt constant. - checker/standard_library.cc: add missing bool-to-int overload decl. - checker/optional.cc: add unwrap/unwrapOpt declarations. Functions where the checker declaration count does not match the runtime registration count (e.g. container membership operators, list.sort) intentionally omit overload_id to preserve runtime dynamic matching.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1484.
This is a follow-up to #1530, rewritten around the approach suggested in that discussion.
The previous version tried to pass overload information through the runtime function invocation path. That made the overridable function interface harder to keep compatible. This version takes a different route:
FlatExprBuilderuses the checker’soverload_idinformation to narrow the candidate set ahead of time, and the runtime registry records which overload ID each implementation handles.This PR is a bit large because the registry, planner, runtime dispatch, standard function registrations, and tests need to move together to keep the tree green. If this is too large to review or sync comfortably, I am happy to discuss how to split it into smaller reviewable pieces.
What changed
This PR adds
overload_id-aware function overload resolution for checked expressions:FunctionDescriptorcan carry anoverload_idand fullcel::Typeinformation.FunctionRegistrycan look up static and lazy overloads by overload ID.ActivationInterfacecan look up activation-provided overloads by overload ID.FlatExprBuilderreads overload IDs from the checked expressionreference_mapand prefers the overloads selected by the checker.This PR also annotates standard library, optional types, and extension runtime function registrations with the overload IDs declared by the checker.
Why
Today, checked expressions can contain more precise overload information than the runtime normally uses during dispatch. For example, the checker may distinguish overloads such as
list<int>andlist<string>, while the default runtime matching path only sees both arguments ascel::Kind::kList.This change uses a two-part approach:
overload_iddata narrows the candidate set to the overloads selected by the checker.enable_type_level_overloadcan enable type-level verification for cases where precise container element/key/value types matter.The
overload_idpath also helps with empty containers, where runtime values may not carry enough element/key/value type information to disambiguate overloads on their own.Compatibility
The main compatibility note is
FunctionDescriptor:FunctionDescriptor::types()now returnsconst std::vector<cel::Type>&.FunctionDescriptor::kinds()returns the previous kind-level view:const std::vector<cel::Kind>&.Apart from that API adjustment, the runtime behavior is intended to stay compatible by default:
overload_id-based candidate filtering is used for checked expressions whenreference_mapoverload information is available.RuntimeOptions::enable_type_level_overloaddefaults tofalse.RuntimeOptions::enable_type_level_overloadis set totrue.