Skip to content

Commit

Permalink
perf(turbo-tasks): Filter out and do not cache unused arguments (#75261)
Browse files Browse the repository at this point in the history
For trait methods, we often have underscore-prefixed arguments that are unused in method implementations, but must exist on the method signature because the trait requires it.

For example, look at `code_generation`: https://github.com/search?q=repo%3Avercel%2Fnext.js%20fn%20code_generation&type=code

We can filter those arguments as soon as we resolve the real method, and avoid storing them as part of the task's cache key.

This should mean less data stored per task, and better cache hit rates (so less tasks overall).

This appears to give a roughly 5% memory win:

![Screenshot 2025-01-28 at 11.54.37 AM.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/HAZVitxRNnZz8QMiPn4a/3459c25e-c73b-4d56-92cc-f44479b2d016.png)

(Spreadsheet: https://docs.google.com/spreadsheets/d/1fz9Q-tDE6LebS9p4Mci8vZG7jkBSajiMYF1WbZEPnts/edit?usp=sharing)

Full data:

<details>
Tested with next-site in front.

Command run:

```
rm -rf .next && TURBOPACK=1 TURBOPACK_BUILD=1 TURBO_ENGINE_READ_ONLY=1 /bin/time -v pnpm next build --experimental-build-mode=compile
```


# Before, run 1

Compiled in: 19.3s

```
        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 121.88
        System time (seconds): 16.74
        Percent of CPU this job got: 501%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:27.61
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5607868
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 58
        Minor (reclaiming a frame) page faults: 1816374
        Voluntary context switches: 1280636
        Involuntary context switches: 361414
        Swaps: 0
        File system inputs: 102088
        File system outputs: 738000
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
```


# Before, run 2

Compiled in: 19.3s

```
        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 124.34
        System time (seconds): 16.97
        Percent of CPU this job got: 516%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:27.36
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5455968
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 8
        Minor (reclaiming a frame) page faults: 2014509
        Voluntary context switches: 1267794
        Involuntary context switches: 358175
        Swaps: 0
        File system inputs: 6496
        File system outputs: 737296
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
```


# Before, run 3

Compiled in: 18.4s

```
        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 117.81
        System time (seconds): 15.86
        Percent of CPU this job got: 505%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:26.46
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5655912
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 5
        Minor (reclaiming a frame) page faults: 1868540
        Voluntary context switches: 1271444
        Involuntary context switches: 337236
        Swaps: 0
        File system inputs: 7784
        File system outputs: 737480
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status:
```


# Before, run 4

Compiled in: 18.2s

```
        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 116.98
        System time (seconds): 15.09
        Percent of CPU this job got: 504%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:26.15
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5962764
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 1861147
        Voluntary context switches: 1253759
        Involuntary context switches: 333116
        Swaps: 0
        File system inputs: 0
        File system outputs: 737304
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
```


# Before, run 5

Compiled in: 17.9s

```
        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 119.02
        System time (seconds): 14.84
        Percent of CPU this job got: 516%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:25.92
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5745780
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 1542655
        Voluntary context switches: 1238600
        Involuntary context switches: 357049
        Swaps: 0
        File system inputs: 0
        File system outputs: 737000
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
```


# After, run 1

Compiled in: 19.0s

```
        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 121.85
        System time (seconds): 16.69
        Percent of CPU this job got: 508%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:27.22
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5402708
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 41
        Minor (reclaiming a frame) page faults: 1822829
        Voluntary context switches: 1221091
        Involuntary context switches: 361604
        Swaps: 0
        File system inputs: 110200
        File system outputs: 737048
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
```


# After, run 2

Compiled in: 18.5s

```
        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 119.46
        System time (seconds): 15.32
        Percent of CPU this job got: 506%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:26.60
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5413980
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 1
        Minor (reclaiming a frame) page faults: 1695775
        Voluntary context switches: 1269774
        Involuntary context switches: 328448
        Swaps: 0
        File system inputs: 800
        File system outputs: 736952
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
```


# After, run 3

Compiled in: 18.5s

```
        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 118.15
        System time (seconds): 15.12
        Percent of CPU this job got: 503%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:26.48
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5312528
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 1893778
        Voluntary context switches: 1277325
        Involuntary context switches: 324591
        Swaps: 0
        File system inputs: 128
        File system outputs: 737304
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
```


# After, run 4

Compiled in: 18.2s

```
        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 115.60
        System time (seconds): 15.30
        Percent of CPU this job got: 499%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:26.22
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5240892
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 1
        Minor (reclaiming a frame) page faults: 1514837
        Voluntary context switches: 1296049
        Involuntary context switches: 312076
        Swaps: 0
        File system inputs: 32
        File system outputs: 737664
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
```


# After, run 5

Compiled in: 19.4s

```
        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 125.91
        System time (seconds): 15.63
        Percent of CPU this job got: 514%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:27.50
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5346672
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 1
        Minor (reclaiming a frame) page faults: 1839175
        Voluntary context switches: 1280293
        Involuntary context switches: 358863
        Swaps: 0
        File system inputs: 32
        File system outputs: 737720
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
```
</details>
  • Loading branch information
bgw authored Jan 29, 2025
1 parent 5f47bb1 commit 8ed8716
Show file tree
Hide file tree
Showing 13 changed files with 244 additions and 94 deletions.
154 changes: 124 additions & 30 deletions turbopack/crates/turbo-tasks-macros/src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub struct TurboFn<'a> {

output: Type,
this: Option<Input>,
inputs: Vec<Input>,
exposed_inputs: Vec<Input>,
/// Should we return `OperationVc` and require that all arguments are `NonLocalValue`s?
operation: bool,
/// Should this function use `TaskPersistence::LocalCells`?
Expand Down Expand Up @@ -75,7 +75,7 @@ impl TurboFn<'_> {

let mut raw_inputs = orig_signature.inputs.iter();
let mut this = None;
let mut inputs = Vec::with_capacity(raw_inputs.len());
let mut exposed_inputs = Vec::with_capacity(raw_inputs.len());

if let Some(possibly_receiver) = raw_inputs.next() {
match possibly_receiver {
Expand Down Expand Up @@ -218,7 +218,7 @@ impl TurboFn<'_> {
}
let ident = ident.ident.clone();

inputs.push(Input {
exposed_inputs.push(Input {
ident,
ty: (*typed.ty).clone(),
});
Expand All @@ -227,7 +227,7 @@ impl TurboFn<'_> {
// We can't support destructuring patterns (or other kinds of patterns).
let ident = Ident::new("arg1", typed.pat.span());

inputs.push(Input {
exposed_inputs.push(Input {
ident,
ty: (*typed.ty).clone(),
});
Expand All @@ -249,7 +249,7 @@ impl TurboFn<'_> {
Ident::new(&format!("arg{}", i + 2), typed.pat.span())
};

inputs.push(Input {
exposed_inputs.push(Input {
ident,
ty: (*typed.ty).clone(),
});
Expand All @@ -272,7 +272,7 @@ impl TurboFn<'_> {
ident: orig_ident,
output,
this,
inputs,
exposed_inputs,
operation: args.operation.is_some(),
local: args.local.is_some(),
inline_ident,
Expand All @@ -286,7 +286,7 @@ impl TurboFn<'_> {
.this
.as_ref()
.into_iter()
.chain(self.inputs.iter())
.chain(self.exposed_inputs.iter())
.map(|input| {
FnArg::Typed(PatType {
attrs: Vec::new(),
Expand Down Expand Up @@ -348,6 +348,15 @@ impl TurboFn<'_> {
.orig_signature
.inputs
.iter()
.filter(|arg| {
let FnArg::Typed(pat_type) = arg else {
return true;
};
let Pat::Ident(pat_id) = &*pat_type.pat else {
return true;
};
inline_inputs_identifier_filter(&pat_id.ident)
})
.enumerate()
.map(|(idx, arg)| match arg {
FnArg::Receiver(_) => (arg.clone(), None),
Expand Down Expand Up @@ -470,12 +479,59 @@ impl TurboFn<'_> {
&self.inline_ident
}

fn input_idents(&self) -> impl Iterator<Item = &Ident> {
self.inputs.iter().map(|Input { ident, .. }| ident)
fn inline_input_idents(&self) -> impl Iterator<Item = &Ident> {
self.exposed_input_idents()
.filter(|id| inline_inputs_identifier_filter(id))
}

fn exposed_input_idents(&self) -> impl Iterator<Item = &Ident> {
self.exposed_inputs.iter().map(|Input { ident, .. }| ident)
}

pub fn input_types(&self) -> Vec<&Type> {
self.inputs.iter().map(|Input { ty, .. }| ty).collect()
pub fn exposed_input_types(&self) -> impl Iterator<Item = Cow<'_, Type>> {
self.exposed_inputs
.iter()
.map(|Input { ty, .. }| expand_task_input_type(ty))
}

pub fn filter_trait_call_args(&self) -> Option<FilterTraitCallArgsTokens> {
// we only need to do this on trait methods, but we're doing it on all methods because we
// don't know if we're a trait method or not (we could pass this information down)
if self.is_method() {
let inline_input_idents: Vec<_> = self.inline_input_idents().collect();
if inline_input_idents.len() != self.exposed_inputs.len() {
let exposed_input_idents: Vec<_> = self.exposed_input_idents().collect();
let exposed_input_types: Vec<_> = self.exposed_input_types().collect();
return Some(FilterTraitCallArgsTokens {
filter_owned: quote! {
|magic_any| {
let (#(#exposed_input_idents,)*) =
*turbo_tasks::macro_helpers
::downcast_args_owned::<(#(#exposed_input_types,)*)>(magic_any);
::std::boxed::Box::new((#(#inline_input_idents,)*))
}
},
filter_and_resolve: quote! {
|magic_any| {
Box::pin(async move {
let (#(#exposed_input_idents,)*) = turbo_tasks::macro_helpers
::downcast_args_ref::<(#(#exposed_input_types,)*)>(magic_any);
let resolved = (#(
<_ as turbo_tasks::TaskInput>::resolve(
#inline_input_idents
).await?,
)*);
Ok(
::std::boxed::Box::new(resolved)
as ::std::boxed::Box<dyn turbo_tasks::MagicAny>
)
})
}
},
});
}
}
None
}

pub fn persistence(&self) -> impl ToTokens {
Expand Down Expand Up @@ -557,7 +613,7 @@ impl TurboFn<'_> {
let ident = &self.ident;
let output = &self.output;
let assertions = self.get_assertions();
let inputs = self.input_idents();
let inputs = self.exposed_input_idents();
let persistence = self.persistence_with_this();
parse_quote! {
{
Expand All @@ -582,7 +638,7 @@ impl TurboFn<'_> {
/// given native function.
pub fn static_block(&self, native_function_id_ident: &Ident) -> Block {
let output = &self.output;
let inputs = self.input_idents();
let inputs = self.inline_input_idents();
let assertions = self.get_assertions();
let mut block = if let Some(converted_this) = self.converted_this() {
let persistence = self.persistence_with_this();
Expand Down Expand Up @@ -1031,46 +1087,79 @@ impl DefinitionContext {
}
}

#[derive(Debug)]
pub struct FilterTraitCallArgsTokens {
filter_owned: TokenStream,
filter_and_resolve: TokenStream,
}

#[derive(Debug)]
pub struct NativeFn {
pub function_path_string: String,
pub function_path: ExprPath,
pub is_method: bool,
pub filter_trait_call_args: Option<FilterTraitCallArgsTokens>,
pub local: bool,
pub local_cells: bool,
}

impl NativeFn {
pub fn ty(&self) -> Type {
parse_quote! { turbo_tasks::NativeFunction }
parse_quote! { turbo_tasks::macro_helpers::NativeFunction }
}

pub fn definition(&self) -> TokenStream {
let Self {
function_path_string,
function_path,
is_method,
filter_trait_call_args,
local,
local_cells,
} = self;

let constructor = if *is_method {
quote! { new_method }
if *is_method {
let arg_filter = if let Some(filter) = filter_trait_call_args {
let FilterTraitCallArgsTokens {
filter_owned,
filter_and_resolve,
} = filter;
quote! {
::std::option::Option::Some((
#filter_owned,
#filter_and_resolve,
))
}
} else {
quote! { ::std::option::Option::None }
};
quote! {
{
#[allow(deprecated)]
turbo_tasks::macro_helpers::NativeFunction::new_method(
#function_path_string.to_owned(),
turbo_tasks::macro_helpers::FunctionMeta {
local: #local,
local_cells: #local_cells,
},
#arg_filter,
#function_path,
)
}
}
} else {
quote! { new_function }
};

quote! {
{
#[allow(deprecated)]
turbo_tasks::NativeFunction::#constructor(
#function_path_string.to_owned(),
turbo_tasks::FunctionMeta {
local: #local,
local_cells: #local_cells,
},
#function_path,
)
quote! {
{
#[allow(deprecated)]
turbo_tasks::macro_helpers::NativeFunction::new_function(
#function_path_string.to_owned(),
turbo_tasks::macro_helpers::FunctionMeta {
local: #local,
local_cells: #local_cells,
},
#function_path,
)
}
}
}
}
Expand All @@ -1095,3 +1184,8 @@ pub fn filter_inline_attributes<'a>(
.filter(|attr| attr.path.get_ident().is_none_or(|id| id != "doc"))
.collect()
}

pub fn inline_inputs_identifier_filter(arg_ident: &Ident) -> bool {
// filter out underscore-prefixed (unused) arguments, we don't need to cache these
!arg_ident.to_string().starts_with('_')
}
1 change: 1 addition & 0 deletions turbopack/crates/turbo-tasks-macros/src/function_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub fn function(args: TokenStream, input: TokenStream) -> TokenStream {
function_path_string: ident.to_string(),
function_path: parse_quote! { #inline_function_ident },
is_method: turbo_fn.is_method(),
filter_trait_call_args: None, // not a trait method
local,
local_cells,
};
Expand Down
2 changes: 2 additions & 0 deletions turbopack/crates/turbo-tasks-macros/src/value_impl_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ pub fn value_impl(args: TokenStream, input: TokenStream) -> TokenStream {
function_path_string: format!("{ty}::{ident}", ty = ty.to_token_stream()),
function_path: parse_quote! { <#ty>::#inline_function_ident },
is_method: turbo_fn.is_method(),
filter_trait_call_args: None, // not a trait method
local,
local_cells,
};
Expand Down Expand Up @@ -252,6 +253,7 @@ pub fn value_impl(args: TokenStream, input: TokenStream) -> TokenStream {
<#ty as #inline_extension_trait_ident>::#inline_function_ident
},
is_method: turbo_fn.is_method(),
filter_trait_call_args: turbo_fn.filter_trait_call_args(),
local,
local_cells,
};
Expand Down
3 changes: 2 additions & 1 deletion turbopack/crates/turbo-tasks-macros/src/value_trait_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub fn value_trait(args: TokenStream, input: TokenStream) -> TokenStream {
};

let turbo_signature = turbo_fn.signature();
let arg_types = turbo_fn.input_types();
let arg_types = turbo_fn.exposed_input_types();
let dynamic_block = turbo_fn.dynamic_block(&trait_type_id_ident);
dynamic_trait_fns.push(quote! {
#turbo_signature #dynamic_block
Expand All @@ -120,6 +120,7 @@ pub fn value_trait(args: TokenStream, input: TokenStream) -> TokenStream {
<Box<dyn #trait_ident> as #inline_extension_trait_ident>::#inline_function_ident
},
is_method: turbo_fn.is_method(),
filter_trait_call_args: turbo_fn.filter_trait_call_args(),
// `local` and `local_cells` are currently unsupported here because:
// - The `#[turbo_tasks::function]` macro needs to be present for us to read this
// argument. (This could be fixed)
Expand Down
9 changes: 6 additions & 3 deletions turbopack/crates/turbo-tasks-testing/tests/collectibles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ async fn my_multi_emitting_function() -> Result<Vc<Thing>> {
}

#[turbo_tasks::function(operation)]
async fn my_transitive_emitting_function(key: RcStr, _key2: RcStr) -> Result<Vc<Thing>> {
async fn my_transitive_emitting_function(key: RcStr, key2: RcStr) -> Result<Vc<Thing>> {
let _ = key2;
my_emitting_function(key).await?;
Ok(Thing::cell(Thing(0)))
}
Expand All @@ -219,8 +220,9 @@ async fn my_transitive_emitting_function_collectibles(
async fn my_transitive_emitting_function_with_child_scope(
key: RcStr,
key2: RcStr,
_key3: RcStr,
key3: RcStr,
) -> Result<Vc<Thing>> {
let _ = key3;
let thing_op = my_transitive_emitting_function(key, key2);
let thing_vc = thing_op.connect();
thing_vc.await?;
Expand All @@ -230,7 +232,8 @@ async fn my_transitive_emitting_function_with_child_scope(
}

#[turbo_tasks::function]
async fn my_emitting_function(_key: RcStr) -> Result<()> {
async fn my_emitting_function(key: RcStr) -> Result<()> {
let _ = key;
sleep(Duration::from_millis(100)).await;
emit(ResolvedVc::upcast::<Box<dyn ValueToString>>(Thing::new(
123,
Expand Down
9 changes: 4 additions & 5 deletions turbopack/crates/turbo-tasks-testing/tests/performance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,8 @@ struct Value {
}

#[turbo_tasks::function]
async fn calls_many_children(
_i: TransientInstance<()>,
j: Option<TransientInstance<()>>,
) -> Vc<()> {
async fn calls_many_children(i: TransientInstance<()>, j: Option<TransientInstance<()>>) -> Vc<()> {
let _ = i;
let _ = many_children(j);
Vc::cell(())
}
Expand All @@ -325,7 +323,8 @@ fn many_children_inner(_i: u32) -> Vc<()> {
}

#[turbo_tasks::function]
async fn calls_big_graph(mut counts: Vec<u32>, _i: TransientInstance<()>) -> Vc<()> {
async fn calls_big_graph(mut counts: Vec<u32>, i: TransientInstance<()>) -> Vc<()> {
let _ = i;
counts.reverse();
let _ = big_graph(counts, vec![]);
Vc::cell(())
Expand Down
1 change: 0 additions & 1 deletion turbopack/crates/turbo-tasks/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ pub use manager::{
CurrentCellRef, ReadConsistency, TaskPersistence, TurboTasks, TurboTasksApi,
TurboTasksBackendApi, TurboTasksBackendApiExt, TurboTasksCallApi, Unused, UpdateInfo,
};
pub use native_function::{FunctionMeta, NativeFunction};
pub use output::OutputContent;
pub use raw_vc::{CellId, RawVc, ReadRawVcFuture, ResolveTypeError};
pub use read_ref::ReadRef;
Expand Down
9 changes: 5 additions & 4 deletions turbopack/crates/turbo-tasks/src/macro_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ pub use once_cell::sync::{Lazy, OnceCell};
pub use serde;
pub use tracing;

pub use super::{
magic_any::MagicAny,
manager::{find_cell_by_type, notify_scheduled_tasks, spawn_detached_for_testing},
};
use crate::{
debug::ValueDebugFormatString, shrink_to_fit::ShrinkToFit, task::TaskOutput, NonLocalValue,
RawVc, TaskInput, TaskPersistence, Vc,
};
pub use crate::{
magic_any::MagicAny,
manager::{find_cell_by_type, notify_scheduled_tasks, spawn_detached_for_testing},
native_function::{downcast_args_owned, downcast_args_ref, FunctionMeta, NativeFunction},
};

#[inline(never)]
pub async fn value_debug_format_field(value: ValueDebugFormatString<'_>) -> String {
Expand Down
Loading

0 comments on commit 8ed8716

Please sign in to comment.