Make constants data location more powerful#16560
Open
k06a wants to merge 1 commit intoargotorg:developfrom
Open
Make constants data location more powerful#16560k06a wants to merge 1 commit intoargotorg:developfrom
k06a wants to merge 1 commit intoargotorg:developfrom
Conversation
|
Thank you for your contribution to the Solidity compiler! A team member will follow up shortly. If you haven't read our contributing guidelines and our review checklist before, please do it now, this makes the reviewing process and accepting your contribution smoother. If you have any questions or need our help, feel free to post them in the PR or talk to us directly on the #solidity-dev channel on Matrix. |
0096dfb to
14d345f
Compare
14d345f to
eee65b7
Compare
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.
Feature: Constant Composite Types (
DataLocation::Constant)Summary
This PR extends the
constantkeyword to support composite types — structs, arrays (static and dynamic), arrays of strings, structs with string fields, arrays of structs, enum arrays, internal function pointer arrays, and dynamic arrays with slicing support. Previously, only value types andbytes/stringwere allowed asconstant.Additionally,
constantis introduced as a new data location specifier for parameters ofinternal/privatefunctions, enabling zero-copy passing of constant references (analogous tocalldata).Compilation is supported via the IR pipeline (
--via-ir). The legacy codegen emits a clear error directing users to use--via-ir.Motivation
Today, defining compile-time lookup tables, configs, or dispatch tables in Solidity requires either:
With this change, developers can write:
The constant data is evaluated once and accessed with standard Solidity syntax — no assembly, no storage, no per-call copies.
What's Supported
uint256[3] constantuint256[] constantDATA[s:e],DATA[s:e][i]struct { uint, address } constantstruct { Inner, uint } constantPoint[2] constantstruct { uint[3], address } constantstring[3] constantstruct { string, uint } constantuint256[2][3] constantColor[3] constantfunction()[3] constantconstantas function param locationfunction f(Config constant cfg) internalmapping(...) constantDesign Decisions
New
DataLocation::ConstantA new enum value
DataLocation::Constantis added to the type system. Constant composites behave likecalldataarrays:codeOffset) — a memory pointer to the evaluated constant datauint256[]): 2 stack slots (codeOffset,length) — matching calldata dynamic array layout. ThecodeOffsetpoints directly to elements in memory (no length prefix), andlengthis on the stackbytes/stringconstants: 1 stack slot (memory pointer with length prefix) — unchanged from existing behaviorBytecode-Embedded Constants (Data Section)
For "flat" constant composites (value-type-only arrays and structs without nested reference types), the initializer data is serialized at compile time and stored as a
data "cdo_<id>" hex"..."block in the Yul object. At runtime, a singledatacopyloads the blob into memory:Types with pointer-based memory layouts (string arrays, nested structs, structs with array fields) fall back to runtime evaluation via the existing
constantValueFunction()mechanism.Constant-Index Folding
When accessing
arr[0]orcfg.feewhere the base is a constant variable and the index/member resolves to a compile-time known value, the IR generator folds the access to a literal constant directly, eliminating all memory operations:Dynamic Array Slicing
Dynamic constant arrays support index range access (slicing), matching calldata semantics:
The slice produces a 2-slot
ArraySliceTypevalue(offset, length)with bounds checking, and supports nested slicingDATA[s:e][ss:ee][i].constantas Function Parameter LocationThe parser recognizes
constantas a data location specifier for function parameters (only ininternal/privatefunctions, analogous tostorage). This enables passing constant references without copying:Internal Function Pointer Support
Internal function definitions are accepted as compile-time constant expressions in constant initializers via the
isCompileTimeConstantExpression()helper inTypeChecker.cpp. This is narrowly scoped — only identifiers referencingFunctionDefinitionnodes withFunctionType::Kind::Internalare accepted, not function pointer variables or function calls.Changes
Source (20 files, +448 -42 lines)
Types.h— AddedDataLocation::Constantto enumTypes.cpp— PropagatedConstantthrough allDataLocationswitch statements; 2-slotmakeStackItemsfor dynamic constant arrays (excluding bytes/string);isImplicitlyConvertibleTofor constant arrays (static-to-dynamic allowed);ArraySliceTypeconversion for ConstantAST.h— AddedLocation::ConstanttoVariableDeclaration::LocationenumAST.cpp— AddedLocation::ConstanttoallowedDataLocations()for internal callable parametersASTJsonExporter.cpp/ASTJsonImporter.cpp— JSON serialization/deserialization forConstantlocationParser.cpp— Recognizesconstantas a location specifier whenallowLocationSpecifieris true (function parameters)DeclarationTypeChecker.cpp— Lifted restriction on constant composites (arrays, structs allowed; mappings rejected); mapsLocation::ConstanttoDataLocation::ConstantTypeChecker.cpp—isCompileTimeConstantExpression()for internal function pointer references; slicing allowed for constant dynamic arrays; index access on constant slicesIRGeneratorForStatements.cpp—constantValueFunctionwith multi-return assignment, data section optimization, constant-index folding; index access for static/dynamic/slice constant arrays; struct member access with folding;IndexRangeAccessfor constant slicingIRGenerationContext.h— Constant data objects registry for bytecode-embedded dataIRGenerator.cpp— Emitsdata "cdo_<id>" hex"..."blocks in Yul object templateCommon.h/cpp—IRNames::constantDataObjectName()helperYulUtilFunctions.h/cpp—arrayLengthFunctionuses stack length for constant dynamic;arrayConversionFunction2-slot support;memoryArrayIndexRangeAccesshelper; slice conversion assertion for ConstantABIFunctions.cpp— Minor adjustments for constant location handlingArrayUtils.cpp/CompilerUtils.cpp/ExpressionCompiler.cpp— Legacy codegen stubs with clear error: "Constant composite types require compilation via the IR pipeline (use --via-ir)."Tests (53 files, +292 -75 lines)
12 new semantic tests (all
compileViaYul: true):constant_static_array.sol—uint256[3], index access + copy to memoryconstant_struct.sol— struct with value fields (uint, address, bytes32)constant_nested_struct.sol— nested structs, deep member accessconstant_string_array.sol—string[3], string element accessconstant_struct_with_string.sol— struct with string fieldconstant_nested_array.sol—uint256[2][3], nested index accessconstant_struct_with_array.sol— struct withuint256[3]fieldconstant_array_of_structs.sol—Point[3], struct field access through arrayconstant_enum_array.sol—Color[3]constant_function_pointers.sol— internal function pointer dispatch tableconstant_parameter_passing.sol—constantas function parameter locationconstant_array_slicing.sol—uint256[]dynamic constant:.length, index access, slicing, nested slicing, bounds checking41 updated syntax tests — Updated expected error messages to reflect the new
"constant"location in error output for internal/private function parameters and slicing.Test Results
clz.sol)Backward Compatibility
constantvalue types andbytes/stringconstants continue to work unchangedconstant)