From 00be632b36e620316f97076579cff233b3f59b6e Mon Sep 17 00:00:00 2001 From: jedel1043 Date: Mon, 31 Aug 2026 02:05:20 -0600 Subject: [PATCH 1/4] fix: resolve failing tests from iterator zip --- .../builtins/iterable/iterator_constructor.rs | 36 ++++-- .../builtins/iterable/iterator_helper/mod.rs | 122 ++++++++++++------ 2 files changed, 106 insertions(+), 52 deletions(-) diff --git a/core/engine/src/builtins/iterable/iterator_constructor.rs b/core/engine/src/builtins/iterable/iterator_constructor.rs index 0b41b185801..6237c4de1e5 100644 --- a/core/engine/src/builtins/iterable/iterator_constructor.rs +++ b/core/engine/src/builtins/iterable/iterator_constructor.rs @@ -40,7 +40,7 @@ use super::{ }; #[cfg(feature = "experimental")] -use crate::{JsVariant, PanicError, builtins::options::get_options_object, property::PropertyKey}; +use crate::{JsVariant, builtins::options::get_options_object, property::PropertyKey}; /// [`IfAbruptCloseIterators ( value, iteratorRecords )`][spec] /// @@ -56,11 +56,13 @@ macro_rules! if_abrupt_close_iterators { // 2. If value is an abrupt completion, return ? IteratorCloseAll(iteratorRecords, value). Err(err) => { let mut completion = Err(err); - for iterator in $iterators { + // 1. For each element iterator of iterators, in reverse List order, do + for iterator in $iterators.rev() { + // 1.a. Set completion to Completion(IteratorClose(iterator, completion)). completion = iterator.close(completion, $context); } return match completion { - Ok(_) => Err(PanicError::new( + Ok(_) => Err($crate::PanicError::new( "closing an iterator with an error should yield the error", ) .into()), @@ -281,7 +283,7 @@ impl IteratorConstructor { // 12.a. Set next to Completion(IteratorStepValue(inputIter)). // 12.b. IfAbruptCloseIterators(next, iters). while let Some(next) = - if_abrupt_close_iterators!(input_iter.step_value(context), iters, context) + if_abrupt_close_iterators!(input_iter.step_value(context), iters.iter(), context) { // 12.c. If next is not done, then // 12.c.i. Let iter be Completion(GetIteratorFlattenable(next, reject-primitives)). @@ -289,7 +291,7 @@ impl IteratorConstructor { // 12.c.iii. Append iter to iters. let iter = if_abrupt_close_iterators!( get_iterator_flattenable(&next, false, context), - iters, + std::iter::once(&input_iter).chain(iters.iter()), context ); iters.push(iter); @@ -343,7 +345,7 @@ impl IteratorConstructor { // 12.b. IfAbruptCloseIterators(desc, iters). let Some(desc) = if_abrupt_close_iterators!( iterables.__get_own_property__(&key, &mut context.into()), - iters, + iters.iter(), context ) else { continue; @@ -357,8 +359,11 @@ impl IteratorConstructor { // 12.c.i. Let value be Completion(Get(iterables, key)). // 12.c.ii. IfAbruptCloseIterators(value, iters). // 12.c.iii. If value is not undefined, then - let value = - if_abrupt_close_iterators!(iterables.get(key.clone(), context), iters, context); + let value = if_abrupt_close_iterators!( + iterables.get(key.clone(), context), + iters.iter(), + context + ); if value.is_undefined() { continue; } @@ -370,7 +375,7 @@ impl IteratorConstructor { // 12.c.iii.3. IfAbruptCloseIterators(iter, iters). let iter = if_abrupt_close_iterators!( get_iterator_flattenable(&value, false, context), - iters, + iters.iter(), context ); @@ -465,7 +470,7 @@ fn build_padding_zip( // 14.b.ii. IfAbruptCloseIterators(paddingIter, iters). let mut padding_iter = if_abrupt_close_iterators!( padding_option.get_iterator(IteratorHint::Sync, context), - iters, + iters.iter(), context ); let mut padding = Vec::new(); @@ -484,7 +489,7 @@ fn build_padding_zip( // 14.b.iv.1.a. Set next to Completion(IteratorStepValue(paddingIter)). // 14.b.iv.1.b. IfAbruptCloseIterators(next, iters). if let Some(next) = - if_abrupt_close_iterators!(padding_iter.step_value(context), iters, context) + if_abrupt_close_iterators!(padding_iter.step_value(context), iters.iter(), context) { // 14.b.iv.1.d. Else, // 14.b.iv.1.d.i. Append next to padding. @@ -504,7 +509,7 @@ fn build_padding_zip( // 14.b.iv.2.v.2. IfAbruptCloseIterators(completion, iters). if_abrupt_close_iterators!( padding_iter.close(Ok(JsValue::undefined()), context), - iters, + iters.iter(), context ); } @@ -541,8 +546,11 @@ fn build_padding_zip_keyed( for key in keys { // 14.b.i.1. Let value be Completion(Get(paddingOption, key)). // 14.b.i.2. IfAbruptCloseIterators(value, iters). - let value = - if_abrupt_close_iterators!(padding_option.get(key.clone(), context), iters, context); + let value = if_abrupt_close_iterators!( + padding_option.get(key.clone(), context), + iters.iter(), + context + ); // 14.b.i.3. Append value to padding. padding.push(value); diff --git a/core/engine/src/builtins/iterable/iterator_helper/mod.rs b/core/engine/src/builtins/iterable/iterator_helper/mod.rs index d0877c3c8c6..07dab4039e5 100644 --- a/core/engine/src/builtins/iterable/iterator_helper/mod.rs +++ b/core/engine/src/builtins/iterable/iterator_helper/mod.rs @@ -10,7 +10,7 @@ //! //! [spec]: https://tc39.es/ecma262/#sec-iterator-helper-objects -use std::ops::ControlFlow; +use std::{mem, ops::ControlFlow}; use crate::{ Context, JsData, JsResult, JsValue, @@ -67,6 +67,15 @@ pub(crate) use take::Take; #[cfg(feature = "experimental")] pub(crate) use zip::{Zip, ZipMode, ZipResultKind}; +#[derive(Debug, Finalize, Trace)] +#[boa_gc(unsafe_no_drop)] +enum IteratorHelperState { + Executing, + Completed, + SuspendedStart(NativeCoroutine), + SuspendedYield(NativeCoroutine), +} + /// The internal representation of an `Iterator Helper` object. /// /// More information: @@ -75,7 +84,7 @@ pub(crate) use zip::{Zip, ZipMode, ZipResultKind}; /// [spec]: https://tc39.es/ecma262/#sec-iterator-helper-objects #[derive(Debug, Finalize, Trace, JsData)] pub(crate) struct IteratorHelper { - pub(crate) coroutine: Option, + coroutine: IteratorHelperState, } impl IntrinsicObject for IteratorHelper { @@ -127,16 +136,27 @@ impl IteratorHelper { // 5. Let state be generator.[[GeneratorState]]. // 6. If state is executing, throw a TypeError exception. // 7. Return state. - let coroutine = helper - .borrow_mut() - .data_mut() - .coroutine - .take() - .ok_or_else(|| { - js_error!( + let coroutine = mem::replace( + &mut helper.borrow_mut().data_mut().coroutine, + IteratorHelperState::Executing, + ); + let coroutine = match coroutine { + IteratorHelperState::Executing => { + return Err(js_error!( TypeError: "Iterator Helper is already executing" - ) - })?; + )); + } + IteratorHelperState::Completed => { + helper.borrow_mut().data_mut().coroutine = IteratorHelperState::Completed; + return Ok(create_iter_result_object( + JsValue::undefined(), + true, + context, + )); + } + IteratorHelperState::SuspendedStart(coro) + | IteratorHelperState::SuspendedYield(coro) => coro, + }; // 3. Assert: state is either suspended-start or suspended-yield. // 4. Let genContext be generator.[[GeneratorContext]]. @@ -156,18 +176,26 @@ impl IteratorHelper { // the code below as "suspending" the underlying generator or returning // if the result is available. let result = match coroutine.call(CompletionRecord::Normal(JsValue::undefined()), context) { - ControlFlow::Continue(value) => Ok(create_iter_result_object(value, false, context)), + ControlFlow::Continue(value) => { + helper.borrow_mut().data_mut().coroutine = + IteratorHelperState::SuspendedYield(coroutine); + Ok(create_iter_result_object(value, false, context)) + } // 2. If state is completed, return CreateIteratorResultObject(undefined, true). - ControlFlow::Break(Ok(())) => Ok(create_iter_result_object( - JsValue::undefined(), - true, - context, - )), - ControlFlow::Break(Err(err)) => Err(err), + ControlFlow::Break(Ok(())) => { + helper.borrow_mut().data_mut().coroutine = IteratorHelperState::Completed; + Ok(create_iter_result_object( + JsValue::undefined(), + true, + context, + )) + } + ControlFlow::Break(Err(err)) => { + helper.borrow_mut().data_mut().coroutine = IteratorHelperState::Completed; + Err(err) + } }; - helper.borrow_mut().data_mut().coroutine = Some(coroutine); - // 11. Return ? result. result } @@ -210,16 +238,30 @@ impl IteratorHelper { // 5. Let state be generator.[[GeneratorState]]. // 6. If state is executing, throw a TypeError exception. // 7. Return state. - let coroutine = helper - .borrow_mut() - .data_mut() - .coroutine - .take() - .ok_or_else(|| { - js_error!( + let coroutine = mem::replace( + &mut helper.borrow_mut().data_mut().coroutine, + IteratorHelperState::Executing, + ); + let coroutine = match coroutine { + IteratorHelperState::Executing => { + return Err(js_error!( TypeError: "Iterator Helper is already executing" - ) - })?; + )); + } + IteratorHelperState::Completed => { + helper.borrow_mut().data_mut().coroutine = IteratorHelperState::Completed; + return Ok(create_iter_result_object( + JsValue::undefined(), + true, + context, + )); + } + IteratorHelperState::SuspendedStart(coro) => { + helper.borrow_mut().data_mut().coroutine = IteratorHelperState::Completed; + coro + } + IteratorHelperState::SuspendedYield(coro) => coro, + }; // 2. If state is suspended-start, then // a. Set generator.[[GeneratorState]] to completed. @@ -256,17 +298,21 @@ impl IteratorHelper { ) .into()), // Step 3.a - ControlFlow::Break(Ok(())) => Ok(create_iter_result_object( - JsValue::undefined(), - true, - context, - )), + ControlFlow::Break(Ok(())) => { + helper.borrow_mut().data_mut().coroutine = IteratorHelperState::Completed; + Ok(create_iter_result_object( + JsValue::undefined(), + true, + context, + )) + } // Step 3.b - ControlFlow::Break(Err(err)) => Err(err), + ControlFlow::Break(Err(err)) => { + helper.borrow_mut().data_mut().coroutine = IteratorHelperState::Completed; + Err(err) + } }; - helper.borrow_mut().data_mut().coroutine = Some(coroutine); - // 12. Return ? result. result } @@ -307,7 +353,7 @@ impl IteratorHelper { .iterator_prototypes() .iterator_helper(), Self { - coroutine: Some(op), + coroutine: IteratorHelperState::SuspendedStart(op), }, ) .upcast() From 6af1564e5e184f4a93becca0954267b48f5e1fe1 Mon Sep 17 00:00:00 2001 From: jedel1043 Date: Mon, 31 Aug 2026 09:54:14 -0600 Subject: [PATCH 2/4] do not remove iterator-includes flag --- test262_config.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test262_config.toml b/test262_config.toml index 28314715c06..3dc3a8a8572 100644 --- a/test262_config.toml +++ b/test262_config.toml @@ -43,6 +43,10 @@ features = [ # https://github.com/tc39/proposal-immutable-arraybuffer "immutable-arraybuffer", + # Iterator Includes + # https://github.com/tc39/proposal-iterator-includes + "iterator-includes", + # Iterator Chunking # https://github.com/tc39/proposal-iterator-chunking "iterator-chunking", From 24b018e7e45e5a2c344570ae88462a2706e09bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Juli=C3=A1n=20Espina?= Date: Mon, 31 Aug 2026 10:56:32 -0600 Subject: [PATCH 3/4] update to spec --- .../builtins/iterable/iterator_constructor.rs | 23 +++------- .../builtins/iterable/iterator_helper/mod.rs | 2 - .../builtins/iterable/iterator_helper/zip.rs | 45 ++++++++++--------- core/engine/src/builtins/iterable/mod.rs | 1 - 4 files changed, 29 insertions(+), 42 deletions(-) diff --git a/core/engine/src/builtins/iterable/iterator_constructor.rs b/core/engine/src/builtins/iterable/iterator_constructor.rs index 6237c4de1e5..ad37a24bc3f 100644 --- a/core/engine/src/builtins/iterable/iterator_constructor.rs +++ b/core/engine/src/builtins/iterable/iterator_constructor.rs @@ -33,13 +33,11 @@ use super::{ wrap_for_valid_iterator::WrapForValidIterator, }; -#[cfg(feature = "experimental")] use super::{ IteratorHint, iterator_helper::{ZipMode, ZipResultKind}, }; -#[cfg(feature = "experimental")] use crate::{JsVariant, builtins::options::get_options_object, property::PropertyKey}; /// [`IfAbruptCloseIterators ( value, iteratorRecords )`][spec] @@ -48,7 +46,6 @@ use crate::{JsVariant, builtins::options::get_options_object, property::Property /// use a list of Iterator Records. /// /// [spec]: https://tc39.es/proposal-joint-iteration/#sec-ifabruptcloseiterators -#[cfg(feature = "experimental")] macro_rules! if_abrupt_close_iterators { ($value:expr, $iterators:expr, $context:expr) => { // 1. Assert: value is a Completion Record. @@ -87,18 +84,13 @@ pub(crate) struct IteratorConstructor; impl IntrinsicObject for IteratorConstructor { fn init(realm: &Realm) { let iterator_prototype = realm.intrinsics().constructors().iterator().prototype(); - let builder = BuiltInBuilder::from_standard_constructor::(realm) + BuiltInBuilder::from_standard_constructor::(realm) .inherits(Some(iterator_prototype.clone())) // Static methods .static_method(Self::from, js_string!("from"), 1) - .static_method(Self::concat, js_string!("concat"), 0); - - #[cfg(feature = "experimental")] - let builder = builder + .static_method(Self::concat, js_string!("concat"), 0) .static_method(Self::zip, js_string!("zip"), 1) - .static_method(Self::zip_keyed, js_string!("zipKeyed"), 1); - - builder + .static_method(Self::zip_keyed, js_string!("zipKeyed"), 1) .static_property(PROTOTYPE, iterator_prototype, Attribute::empty()) .build_without_prototype(); } @@ -255,8 +247,7 @@ impl IteratorConstructor { /// More information: /// - [TC39 proposal][spec] /// - /// [spec]: https://tc39.es/proposal-joint-iteration/#sec-iterator.zip - #[cfg(feature = "experimental")] + /// [spec]: https://tc39.es/ecma262/#sec-iterator.zip fn zip(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { let iterables = args.get_or_undefined(0); let options = args.get_or_undefined(1); @@ -314,8 +305,7 @@ impl IteratorConstructor { /// More information: /// - [TC39 proposal][spec] /// - /// [spec]: https://tc39.es/proposal-joint-iteration/#sec-iterator.zipkeyed - #[cfg(feature = "experimental")] + /// [spec]: https://tc39.es/ecma262/#sec-iterator.zipkeyed fn zip_keyed(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { let iterables = args.get_or_undefined(0); let options = args.get_or_undefined(1); @@ -404,7 +394,6 @@ impl IteratorConstructor { } /// Parses the `mode` option from the options object. -#[cfg(feature = "experimental")] fn parse_options( options: &JsValue, context: &mut Context, @@ -444,7 +433,6 @@ fn parse_options( } /// Builds the padding list for "longest" mode on zip -#[cfg(feature = "experimental")] fn build_padding_zip( mode: ZipMode, padding_option: Option, @@ -518,7 +506,6 @@ fn build_padding_zip( } /// Builds the padding list for "longest" mode on zipKeyed -#[cfg(feature = "experimental")] fn build_padding_zip_keyed( mode: ZipMode, padding_option: Option, diff --git a/core/engine/src/builtins/iterable/iterator_helper/mod.rs b/core/engine/src/builtins/iterable/iterator_helper/mod.rs index 07dab4039e5..d15f596d25f 100644 --- a/core/engine/src/builtins/iterable/iterator_helper/mod.rs +++ b/core/engine/src/builtins/iterable/iterator_helper/mod.rs @@ -55,7 +55,6 @@ mod filter; mod flat_map; mod map; mod take; -#[cfg(feature = "experimental")] mod zip; pub(crate) use concat::{Concat, IterableRecord}; @@ -64,7 +63,6 @@ pub(crate) use filter::Filter; pub(crate) use flat_map::FlatMap; pub(crate) use map::Map; pub(crate) use take::Take; -#[cfg(feature = "experimental")] pub(crate) use zip::{Zip, ZipMode, ZipResultKind}; #[derive(Debug, Finalize, Trace)] diff --git a/core/engine/src/builtins/iterable/iterator_helper/zip.rs b/core/engine/src/builtins/iterable/iterator_helper/zip.rs index 98e90d60b15..00d2800747b 100644 --- a/core/engine/src/builtins/iterable/iterator_helper/zip.rs +++ b/core/engine/src/builtins/iterable/iterator_helper/zip.rs @@ -49,6 +49,9 @@ pub(crate) enum Zip { } impl Zip { + /// [`IteratorZip ( iters, mode, padding, finishResults )`][spec] + /// + /// [spec]: https://tc39.es/ecma262/#sec-iteratorzip #[allow( clippy::new_ret_no_self, reason = "slightly cleaner to have this be a `new` method" @@ -77,8 +80,8 @@ impl Zip { if iters.is_empty() { return ControlFlow::Break(Ok(())); } - // 3.b.vi. If completion is an abrupt completion, then - // 3.b.vi.1. Return ? IteratorCloseAll(openIters, completion). + // 3.b.v. Let completion be Completion(Yield(results)). + // 3.b.vi. IfAbruptCloseIterators(completion, openIters). match completion { CompletionRecord::Return(v) => { return ControlFlow::Break(iterator_close_all( @@ -151,7 +154,7 @@ impl Zip { match mode { // 3.b.iii.3.d.ii. If mode is "shortest", then ZipMode::Shortest => { - // 3.b.iii.3.d.ii.i. Return ? IteratorCloseAll(openIters, ReturnCompletion(undefined)). + // 3.b.iii.3.d.ii.1. Return ? IteratorCloseAll(openIters, ReturnCompletion(undefined)). return ControlFlow::Break(iterator_close_all( iters.into_iter().flatten(), Ok(JsValue::undefined()), @@ -160,9 +163,9 @@ impl Zip { } // 3.b.iii.3.d.iii. Else if mode is "strict", then ZipMode::Strict => { - // 3.b.iii.3.d.iii.i. If i ≠ 0, then + // 3.b.iii.3.d.iii.1. If i ≠ 0, then if i != 0 { - // 3.b.iii.3.d.iii.i.i. Return ?IteratorCloseAll(openIters, ThrowCompletion(a newly created TypeError object)). + // 3.b.iii.3.d.iii.1.a. Return ?IteratorCloseAll(openIters, ThrowCompletion(a newly created TypeError object)). return ControlFlow::Break(iterator_close_all( iters.into_iter().flatten(), Err(js_error!( @@ -172,23 +175,23 @@ impl Zip { context, )); } - // 3.b.iii.3.d.iii.ii. For each integer k such that 1 ≤ k < iterCount, in ascending order, do + // 3.b.iii.3.d.iii.2. For each integer k such that 1 ≤ k < iterCount, in ascending order, do for i in 1..iters.len() { - // 3.b.iii.3.d.iii.ii.i. Assert: iters[k] is not null. + // 3.b.iii.3.d.iii.2.a. Assert: iters[k] is not null. let Some(iter) = iters.get_mut(i) else { continue; }; let Some(inner_iter) = iter else { continue; }; - // 3.b.iii.3.d.iii.ii.ii. Let open be Completion(IteratorStep(iters[k])). + // 3.b.iii.3.d.iii.2.b. Let open be Completion(IteratorStep(iters[k])). let open = match inner_iter.step(context) { Ok(v) => v, - // 3.b.iii.3.d.iii.ii.iii. If open is an abrupt completion, then + // 3.b.iii.3.d.iii.2.c. If open is an abrupt completion, then Err(err) => { - // 3.b.iii.3.d.iii.ii.iii.i. Remove iters[k] from openIters. + // 3.b.iii.3.d.iii.2.c.i. Remove iters[k] from openIters. iter.take(); - // 3.b.iii.3.d.iii.ii.iii.ii. Return ? IteratorCloseAll(openIters, open). + // 3.b.iii.3.d.iii.2.c.ii. Return ? IteratorCloseAll(openIters, open). return ControlFlow::Break(iterator_close_all( iters.into_iter().flatten(), Err(err), @@ -196,15 +199,15 @@ impl Zip { )); } }; - // 3.b.iii.3.d.iii.ii.iv. Set open to ! open. - // 3.b.iii.3.d.iii.ii.v. If open is done, then + // 3.b.iii.3.d.iii.2.d. Set open to ! open. + // 3.b.iii.3.d.iii.2.e. If open is done, then if open { - // 3.b.iii.3.d.iii.ii.v.i. Remove iters[k] from openIters. + // 3.b.iii.3.d.iii.2.e.i. Remove iters[k] from openIters. iter.take(); } - // 3.b.iii.3.d.iii.ii.vi. Else, + // 3.b.iii.3.d.iii.2.f. Else, else { - // 3.b.iii.3.d.iii.ii.vi.i. Return ? IteratorCloseAll(openIters, ThrowCompletion(a newly created TypeError object)). + // 3.b.iii.3.d.iii.2.f.i. Return ? IteratorCloseAll(openIters, ThrowCompletion(a newly created TypeError object)). return ControlFlow::Break(iterator_close_all( iters.into_iter().flatten(), Err(js_error!( @@ -216,18 +219,18 @@ impl Zip { } } - // 3.b.iii.3.d.iii.iii. Return ReturnCompletion(undefined). + // 3.b.iii.3.d.iii.3. Return ReturnCompletion(undefined). return ControlFlow::Break(Ok(())); } // 3.b.iii.3.d.iv. Else, ZipMode::Longest => { - // 3.b.iii.3.d.iv.i. Assert: mode is "longest". - // 3.b.iii.3.d.iv.ii. If openIters is empty, return ReturnCompletion(undefined). + // 3.b.iii.3.d.iv.1. Assert: mode is "longest". + // 3.b.iii.3.d.iv.2. If openIters is empty, return ReturnCompletion(undefined). if iters.iter().all(Option::is_none) { return ControlFlow::Break(Ok(())); } - // 3.b.iii.3.d.iv.iii. Set iters[i] to null. - // 3.b.iii.3.d.iv.iv. Set result to padding[i]. + // 3.b.iii.3.d.iv.3. Set iters[i] to null. + // 3.b.iii.3.d.iv.4. Set result to padding[i]. results.push( padding .get(i) diff --git a/core/engine/src/builtins/iterable/mod.rs b/core/engine/src/builtins/iterable/mod.rs index 951309cf31b..4c132b38ee8 100644 --- a/core/engine/src/builtins/iterable/mod.rs +++ b/core/engine/src/builtins/iterable/mod.rs @@ -820,7 +820,6 @@ pub(crate) fn get_iterator_flattenable( } /// -#[cfg(feature = "experimental")] pub(crate) fn iterator_close_all( iters: impl IntoIterator, mut completion: JsResult, From a9bf5cf7518e5b2cdb68c0179c4e7f4d894b67ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Juli=C3=A1n=20Espina?= Date: Mon, 31 Aug 2026 11:49:19 -0600 Subject: [PATCH 4/4] fix build --- core/engine/src/builtins/mod.rs | 2 -- core/engine/src/builtins/options.rs | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/engine/src/builtins/mod.rs b/core/engine/src/builtins/mod.rs index 6b6e8470ec3..d4f3cc37abf 100644 --- a/core/engine/src/builtins/mod.rs +++ b/core/engine/src/builtins/mod.rs @@ -49,8 +49,6 @@ pub mod escape; #[cfg(feature = "intl")] pub mod intl; -// TODO: remove `cfg` when `Temporal` gets to stage 4. -#[cfg(any(feature = "intl", feature = "temporal"))] pub(crate) mod options; #[cfg(feature = "temporal")] diff --git a/core/engine/src/builtins/options.rs b/core/engine/src/builtins/options.rs index ba5d805874f..59b49729de8 100644 --- a/core/engine/src/builtins/options.rs +++ b/core/engine/src/builtins/options.rs @@ -1,4 +1,8 @@ //! Utilities to parse, validate and get options in builtins. +#![allow( + unused, + reason = "easier to allow unused items than to split the module apart" +)] use std::{fmt, str::FromStr};