fix(runtime): Temporal PlainDate/YearMonth/MonthDay/Time/Instant/Now tail -> ~98%#4923
Merged
Conversation
…tail -> 98.3% ToTemporalX rewrite (calendar-first, alphabetical fields, overflow-last, positive month/day, real ToNumber on constructors), require-new, with() RejectObjectWithCalendarOrTimeZone, Instant epoch coercion + SyntaxError, Now timezone wrong-type, valueOf TypeError, MonthDay equals reference-year.
proggeramlug
added a commit
that referenced
this pull request
Jun 10, 2026
date.rs grew to 2008 lines (pushed over by the Temporal tail in #4923), tripping scripts/check_file_size.sh and failing the required lint gate on every open PR (the check runs against each PR's merge with current main). Extract the date-string parsing cluster - parse_date_string + its per-grammar helpers (parse_iso8601, parse_rfc_or_named, parse_tz_offset, normalize_millis, month_from_name, FULL_MONTHS) - into a new crates/perry-runtime/src/date/parse.rs submodule (Rust 2018 keeps date.rs alongside date/parse.rs, no rename). date.rs declares `mod parse;` and re-exports the single entry point via `use parse::parse_date_string;`; the per-grammar helpers stay private to the submodule. Shared time math (make_utc_ms, time_clip, timestamp_to_local_components) stays in the parent and is reached via super:: (a child module can see its ancestor's private items, so no visibility was widened beyond parse_date_string). Pure code movement, no behavior change. date.rs 2008 -> 1675 lines, date/parse.rs 347. fmt clean; all date tests pass except the pre-existing test_full_year_setters_revive_invalid_date_only, which is timezone-dependent (asserts local hours == 0 after a local setFullYear) and fails identically on clean main on a non-UTC host - CI runs UTC and passes it. Co-authored-by: Ralph Kuepper <ralph@skelpo.com>
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
Pushes the remaining
Temporal.Plain*/Instant/Nowtest262 tails to ~98%, grouped by root cause, zero regressions.Measured on the 48-core box vs
node v26(self-validating Temporal cases),built-ins/Temporal/{PlainDate,PlainYearMonth,PlainMonthDay,PlainTime,Instant,Now},PERRY_NO_AUTO_OPTIMIZE=1 --jobs 12(the contended default run mislabels ~66 cache/auto-opt races ascompile-fail; the clean run shows the real picture):+102 tests, 0 regressions.
Broad regression check —
built-ins languageshard0/12(2645 cases) diffed vs the branch base:Root causes fixed (grouped)
1.
from()/ ToTemporalX bag reading (~40 tests). Rewrote the property-bag path forPlainDate/PlainYearMonth/PlainMonthDay/PlainTime:calendarslot read first, then the calendar's date fields alphabetically (day,[era,eraYear],month,monthCode,year; era/eraYear only for non-ISO calendars), thenoverflowlast — matching the observable order-of-operations.monthCodenowToPrimitiveAndRequireString(wasstr_field, which dropped atoString-wrapped value);month/daynowToPositiveIntegerWithTruncation(a value < 1 is aRangeErroreven underconstrain, was silently saturated to 255).RangeError) beforeoptionsis validated; a wrong-typedoptionsis aTypeErroronly after the fields are read.PlainMonthDay.frompreviously ignoredoptions/overflowentirely.PlainDatepassed toPlainYearMonth.from) are read as property bags, not rejected.2. Constructors (~10).
PlainDate/PlainYearMonth/PlainMonthDay/PlainTimenow coerce each numeric field via realToNumber(ToIntegerWithTruncation— observesvalueOf, rejectsInfinity/NaNwith aRangeErrorat the field's read position) and resolvecalendarvia the strictToTemporalCalendarIdentifier. All five are now[[Construct]]-only — calling withoutnewis aTypeError.3.
with()(~16).PlainDate/PlainYearMonth/PlainMonthDay/PlainTimewithnow runRejectObjectWithCalendarOrTimeZone(readscalendar+timeZonefirst,TypeErrorif present), read fields alphabetically with positive validation, and readoverflowlast.withCalendar()with a missing argument is aTypeError.4.
valueOf/ relational (5). A statically-loweredtemporal.valueOf()(lowered toDateValueOffor ananyreceiver) andtemporal < temporal(relationalToPrimitive(number)) now route to the Temporal brand dispatch, which throwsTypeErrorper spec.5. Instant / Now / misc.
Now.plainDate*ISO(tz)/PlainDate.toZonedDateTime(tz): a wrong-typed time-zone is nowTypeError(was silently dropped /RangeError).new Temporal.Instant("abc123")->SyntaxError;Instant.fromEpochMilliseconds-> realToNumber(BigInt/SymbolTypeError) +NumberToBigIntintegral check (RangeError).Instant.prototypeno longer advertises the removedepochSeconds/epochMicrosecondsaccessors.PlainMonthDay.prototype.equalscompares the reference (ISO) year.toPlainDatereads onlyday(YearMonth) /year(MonthDay) from its argument.Deferred (out of scope / other workers)
[[Prototype]]link; full subclass support is an architectural change (also deferred by the big-3 worker).PlainDate.add/subtractduration-bag order-of-operations (2): lives induration.rs(big-3 worker's domain).exact-multiple-of-larger-unit/float64-representable-integer(6):temporal_rs0.2.3 rounding-precision internals.Instant/large-bigint(1): pre-existing BigInt unary-negation bug, outside Temporal.Files
crates/perry-runtime/src/temporal/{options,plain_date,plain_year_month,plain_month_day,plain_time,instant,now,dispatch}.rs,object/global_this.rs,date.rs,builtins/arithmetic.rs.