Skip to content

refactor: extract type-check boilerplate into a single require_internal_slot! macro#5233

Open
Nakshatra480 wants to merge 3 commits intoboa-dev:mainfrom
Nakshatra480:refactor/temporal-this-type-check
Open

refactor: extract type-check boilerplate into a single require_internal_slot! macro#5233
Nakshatra480 wants to merge 3 commits intoboa-dev:mainfrom
Nakshatra480:refactor/temporal-this-type-check

Conversation

@Nakshatra480
Copy link
Contributor

@Nakshatra480 Nakshatra480 commented Mar 23, 2026

Summary

This PR introduces a new require_internal_slot! macro to replace the repetitive 5-line this-type-checking boilerplate found across the engine's built-in prototype methods.

Previously, almost every prototype method (across Temporal, Date, TypedArrays, etc.) manually downcasted this and returned a TypeError if the internal slot was missing:

let object = this.as_object();
let date = object
    .as_ref()
    .and_then(JsObject::downcast_ref::<Self>)
    .ok_or_else(|| JsNativeError::typ().with_message("'this' is not a Date"))?;

This PR refactors those occurrences into a single, much cleaner macro call that correctly handles the necessary borrowing and lifetime scoping:

require_internal_slot!(date = this, Date, "Date");

Scope of changes

While originally intended for just the Temporal built-ins, I realized this boilerplate is heavily duplicated across the entire engine. Therefore, I've broadened the scope and applied the macro to all affected built-ins, including:

  • Temporal (all modules)
  • Date
  • ArrayBuffer & SharedArrayBuffer
  • DataView
  • TypedArray
  • WeakRef, WeakMap, WeakSet
  • Intl (Collator, Segmenter, Segments)

Error Messages & Testing

As part of standardizing this pattern, all error messages across the engine for missing internal slots have been unified to use the generic format: TypeError: "the this object must be a {Type} object.".

All existing tests (specifically in Builtin::Date) that previously relied on custom error strings like "'this' is not a Date" have been updated to expect the new standardized message. CI tests now pass cleanly with these updates.

@github-actions github-actions bot added Waiting On Review Waiting on reviews from the maintainers C-Builtins PRs and Issues related to builtins/intrinsics and removed Waiting On Review Waiting on reviews from the maintainers labels Mar 23, 2026
@github-actions github-actions bot added this to the v1.0.0 milestone Mar 23, 2026
@Nakshatra480 Nakshatra480 force-pushed the refactor/temporal-this-type-check branch from 4053092 to 4c42492 Compare March 23, 2026 05:48
@github-actions github-actions bot added the Waiting On Review Waiting on reviews from the maintainers label Mar 23, 2026
@github-actions
Copy link

github-actions bot commented Mar 23, 2026

Test262 conformance changes

Test result main count PR count difference
Total 52,963 52,963 0
Passed 50,732 50,732 0
Ignored 1,426 1,426 0
Failed 805 805 0
Panics 0 0 0
Conformance 95.79% 95.79% 0.00%

Tested main commit: 2437b6704c4315f6ec8f0766bf229fba23e0e61e
Tested PR commit: f0b154ada75b5fbb1804b3bba535e99ebaed4bb4
Compare commits: 2437b67...f0b154a

@codecov
Copy link

codecov bot commented Mar 23, 2026

Codecov Report

❌ Patch coverage is 22.13855% with 517 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.25%. Comparing base (6ddc2b4) to head (f0b154a).
⚠️ Report is 919 commits behind head on main.

Files with missing lines Patch % Lines
.../engine/src/builtins/temporal/zoneddatetime/mod.rs 0.00% 116 Missing ⚠️
...ngine/src/builtins/temporal/plain_date_time/mod.rs 2.00% 98 Missing ⚠️
...gine/src/builtins/temporal/plain_year_month/mod.rs 0.00% 57 Missing ⚠️
core/engine/src/builtins/temporal/duration/mod.rs 14.54% 47 Missing ⚠️
...ore/engine/src/builtins/temporal/plain_date/mod.rs 0.00% 46 Missing ⚠️
core/engine/src/builtins/temporal/instant/mod.rs 0.00% 45 Missing ⚠️
...ore/engine/src/builtins/temporal/plain_time/mod.rs 10.00% 36 Missing ⚠️
...ngine/src/builtins/temporal/plain_month_day/mod.rs 0.00% 29 Missing ⚠️
core/engine/src/builtins/intl/collator/mod.rs 0.00% 12 Missing ⚠️
...ore/engine/src/builtins/intl/segmenter/segments.rs 0.00% 10 Missing ⚠️
... and 5 more
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #5233       +/-   ##
===========================================
+ Coverage   47.24%   60.25%   +13.01%     
===========================================
  Files         476      589      +113     
  Lines       46892    62702    +15810     
===========================================
+ Hits        22154    37783    +15629     
- Misses      24738    24919      +181     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Member

@nekevss nekevss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do sort of like the change for how succinct it is, and it's potential for making the code more readable.

One question: why change just the temporal objects and not the built-ins in general? Had you looked at other built-ins?

@Nakshatra480 Nakshatra480 force-pushed the refactor/temporal-this-type-check branch from 4c42492 to 56ac6f3 Compare March 25, 2026 09:38
@Nakshatra480 Nakshatra480 requested a review from nekevss March 25, 2026 10:50
@Nakshatra480 Nakshatra480 marked this pull request as draft March 25, 2026 14:57
@Nakshatra480 Nakshatra480 force-pushed the refactor/temporal-this-type-check branch from 56ac6f3 to 4fee1fe Compare March 25, 2026 15:02
@github-actions github-actions bot added the C-Intl Changes related to the `Intl` implementation label Mar 25, 2026
@Nakshatra480 Nakshatra480 marked this pull request as ready for review March 25, 2026 15:05
@Nakshatra480 Nakshatra480 requested a review from a team as a code owner March 25, 2026 15:05
@Nakshatra480 Nakshatra480 marked this pull request as draft March 25, 2026 15:16
@Nakshatra480 Nakshatra480 force-pushed the refactor/temporal-this-type-check branch from 4fee1fe to 2fdc570 Compare March 25, 2026 16:37
@github-actions github-actions bot added the C-Tests Issues and PRs related to the tests. label Mar 25, 2026
@Nakshatra480 Nakshatra480 force-pushed the refactor/temporal-this-type-check branch from 2fdc570 to 4c4edd1 Compare March 25, 2026 17:20
…lot! macro

Replace the repeated as_object/downcast_ref/ok_or_else boilerplate with
a single require_internal_slot! macro defined in builtins/mod.rs.

The macro produces two let-bindings in the caller's scope: one for the
owned JsObject (to keep it alive) and one for the downcast Ref<T>.
Uses the js_error! macro internally for error construction.

Temporal modules (163 replacements):
- zoneddatetime, plain_date_time, plain_time, plain_year_month,
  plain_date, duration, instant, plain_month_day

Other builtins (32 replacements):
- date (9), dataview (5), typed_array (4), array_buffer (4),
  shared_array_buffer (3), weak_map (2), intl/segmenter (2),
  intl/collator (1), weak_set (1), weak_ref (1)
@Nakshatra480 Nakshatra480 force-pushed the refactor/temporal-this-type-check branch from 4c4edd1 to fb5096a Compare March 25, 2026 17:23
@Nakshatra480 Nakshatra480 changed the title refactor(temporal): extract this-type-check boilerplate into a macro refactor: extract [this](cci:1://file:///Users/nakshatrasharma/Desktop/boa/core/engine/src/builtins/date/tests.rs:100:0-107:1) type-check boilerplate into a single require_internal_slot! macro Mar 25, 2026
@Nakshatra480 Nakshatra480 changed the title refactor: extract [this](cci:1://file:///Users/nakshatrasharma/Desktop/boa/core/engine/src/builtins/date/tests.rs:100:0-107:1) type-check boilerplate into a single require_internal_slot! macro refactor: extract type-check boilerplate into a single require_internal_slot! macro Mar 25, 2026
@Nakshatra480 Nakshatra480 marked this pull request as ready for review March 25, 2026 18:02
@Nakshatra480
Copy link
Contributor Author

Hey @nekevss Thanks for the review!

To answer your question: Yes, while originally working on Temporal, I realized that the 5-line this-type-check boilerplate is heavily duplicated across almost all built-ins. I have now expanded the scope of this PR to apply the macro across the entire engine, not just Temporal.

Here is a summary of the updates in the latest push:

  1. Scope Expanded: Applied the macro to all affected built-ins, including Date, ArrayBuffer, SharedArrayBuffer, DataView, TypedArray, WeakRef, WeakMap, WeakSet, and Intl (Collator, Segmenter, Segments), replacing hundreds of lines of repetitive downcasting boilerplate.
  2. Macro Renamed: Renamed the macro to require_internal_slot! as suggested.
  3. js_error! Used: Updated the macro to use js_error! internally as requested.
  4. Error Messages: The macro standardizes the error message to TypeError: "the this object must be a {Type} object.". A few tests (specifically in Builtin::Date) that explicitly asserted the old "'this' is not a Date" error string have been updated to expect the new standardized message.

All CI tests, including cargo fmt and cargo clippy, now pass cleanly. Let me know if there's anything else you'd like me to adjust!

Switch the require_internal_slot! macro to use JsObject::downcast instead
of downcast_ref, returning JsObject<T> (owned handle) rather than Ref<T>.
This prevents GcRefCell borrow panics by ensuring borrows are only held
for the duration of specific read/write operations.

Updated all call sites across 20 built-in modules to use
.borrow().data() / .borrow_mut().data_mut() for inner field access:
- Date (renamed macro binding to date_obj in setters to avoid shadowing)
- Temporal (Duration, Instant, PlainDate, PlainDateTime, PlainTime,
  PlainMonthDay, PlainYearMonth, ZonedDateTime)
- ArrayBuffer, SharedArrayBuffer, DataView, TypedArray
- WeakRef, WeakMap, WeakSet
- Intl (Collator, Segmenter, Segments)
@Nakshatra480 Nakshatra480 marked this pull request as draft March 25, 2026 19:52
@Nakshatra480 Nakshatra480 marked this pull request as ready for review March 25, 2026 20:09
@Nakshatra480 Nakshatra480 requested a review from jedel1043 March 25, 2026 20:09
@Nakshatra480
Copy link
Contributor Author

Hey @jedel1043 I've pushed the requested changes using JsObject::downcast, and all builds and tests are now passing cleanly. The PR is ready for another look whenever you have time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-Builtins PRs and Issues related to builtins/intrinsics C-Intl Changes related to the `Intl` implementation C-Tests Issues and PRs related to the tests. Waiting On Review Waiting on reviews from the maintainers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants