feat(frontend): make the front half of the compiler field-generic - #11
Merged
Conversation
|
Thank you for your contribution to the Noir language. Please do not force push to this branch after the Noir team have started review of this PR. Doing so will only delay us merging your PR as we will need to start the review process from scratch. Thanks for your understanding. |
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.
Summary
The front half of the compiler, from source text to the monomorphized AST, is now correct for more than one prime field: an integer is never carried through the field where it might not fit, a value outside the field is an error rather than a reduction, and stdlib items that only work on bn254 are gated to it. bn254 stays the default and fully green. The
goldilocksfeature ofnoirc_driverselects Goldilocks (p = 2^64 − 2^32 + 1) in every crate below it, and the Goldilocks CI lane now runs the ABI, frontend and stdlib checks under that build.The rules, in one place:
x as Fieldis the identity on the value and is defined only for source types whose every value lies below p. An unsigned type that can hold a value at or above p (u64andu128under Goldilocks) is refused at type check; the escape hatch is an explicit narrowing cast. Signed sources stay a type error.Fieldliteral or a comptimeFieldresult must lie in[0, p); nothing reduces a value into the field.u128stay exact in the monomorphized AST under every field.Changes
acir_field:to_i128reads the shorter of an element's two spellings on the field's own byte width (8 bytes under Goldilocks, 32 under bn254), with a round-trip test generic over the field;assert_unique_feature!coversgoldilocks.implblocks and trait impls keep their attributes. The formatter prints them and the LSP remaps their locations; function-only attributes on animplare now a parse error instead of being dropped silently.#[field(..)]gates impl blocks, impl methods, trait impls (whole blocks), inline modules,mod x;declarations and comptime-generated impls. A gated-out item is dropped at definition collection before anything about it is interned, so two same-named items gated to different fields coexist and a gated-outmod x;needs no file.BigInt: an integer target takes the two's complement pattern at the target width and reads it by the target's signedness; aFieldtarget takes the source's own-width pattern exactly and is an error if it is not below p.scalar_to_fieldapplies the one-element rule for both formats and for quoted and native spellings, andnoirc_abiforwards thegoldilocksfeature.IntegerTypeExceedsFieldrefusesas Fieldfrom an unsigned type whose width reaches the field's. The monomorphizer re-checks a cast whose source type was still a type variable at type check.From<u64>andFrom<u128>forField,Hashforu64/u128/i64, and the wrapping arithmetic on those types (implemented through the field) are gated to bn254. TheAsPrimitive<Field>impls are generated only for widths below the modulus. The driver teststdlib_field_castspins that the stdlib never casts a wide integer toFieldunder either build.acir_field,noirc_abi, the frontend suite minus six bn254-pinned tests, and the driver's stdlib checks.Each place where the feature flag stands in for a runtime field selection carries a
TODOnaming the follow-up: a runtimeFieldConfig, struct and trait gating with a negated form and a width predicate, and native wrapping arithmetic on wide types.