diff --git a/Cargo.lock b/Cargo.lock index 1ac38bdc1738..f9ba0cbfca4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9833,6 +9833,7 @@ dependencies = [ "futures", "indexmap 2.13.0", "inventory", + "mime", "parking_lot", "pin-project-lite", "rayon", diff --git a/crates/next-api/src/next_server_nft.rs b/crates/next-api/src/next_server_nft.rs index dad21b243f25..9b8480bae36f 100644 --- a/crates/next-api/src/next_server_nft.rs +++ b/crates/next-api/src/next_server_nft.rs @@ -7,7 +7,7 @@ use next_core::{get_next_package, next_server::get_tracing_compile_time_info}; use serde_json::{Value, json}; use turbo_rcstr::RcStr; use turbo_tasks::{ - NonLocalValue, ResolvedVc, TaskInput, TryFlatJoinIterExt, TryJoinIterExt, Vc, + IsTransient, NonLocalValue, ResolvedVc, TaskInput, TryFlatJoinIterExt, TryJoinIterExt, Vc, trace::TraceRawVcs, }; use turbo_tasks_fs::{ @@ -32,7 +32,17 @@ use crate::{ }; #[derive( - PartialEq, Eq, TraceRawVcs, NonLocalValue, Debug, Clone, Hash, TaskInput, Encode, Decode, + PartialEq, + Eq, + TraceRawVcs, + NonLocalValue, + Debug, + Clone, + Hash, + TaskInput, + IsTransient, + Encode, + Decode, )] enum ServerNftType { Minimal, diff --git a/crates/next-api/src/operation.rs b/crates/next-api/src/operation.rs index 2422329114d1..f751a058f3a6 100644 --- a/crates/next-api/src/operation.rs +++ b/crates/next-api/src/operation.rs @@ -2,7 +2,7 @@ use anyhow::Result; use bincode::{Decode, Encode}; use turbo_rcstr::RcStr; use turbo_tasks::{ - FxIndexMap, NonLocalValue, OperationValue, OperationVc, ResolvedVc, TaskInput, Vc, + FxIndexMap, IsTransient, NonLocalValue, OperationValue, OperationVc, ResolvedVc, TaskInput, Vc, debug::ValueDebugFormat, take_effects, trace::TraceRawVcs, }; use turbopack_core::issue::CollectibleIssuesExt; @@ -112,6 +112,7 @@ fn pick_route(entrypoints: OperationVc, key: RcStr, route: &Route) Debug, Clone, TaskInput, + IsTransient, TraceRawVcs, PartialEq, Eq, diff --git a/crates/next-api/src/pages.rs b/crates/next-api/src/pages.rs index 1d5425ddd9e0..d58d42cede3c 100644 --- a/crates/next-api/src/pages.rs +++ b/crates/next-api/src/pages.rs @@ -30,8 +30,8 @@ use next_core::{ use tracing::Instrument; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - Completion, FxIndexMap, NonLocalValue, ResolvedVc, TaskInput, ValueToString, Vc, fxindexmap, - fxindexset, trace::TraceRawVcs, + Completion, FxIndexMap, IsTransient, NonLocalValue, ResolvedVc, TaskInput, ValueToString, Vc, + fxindexmap, fxindexset, trace::TraceRawVcs, }; use turbo_tasks_fs::{ self, File, FileContent, FileSystem, FileSystemPath, FileSystemPathOption, VirtualFileSystem, @@ -586,7 +586,18 @@ struct PageEndpoint { } #[derive( - Copy, Clone, PartialEq, Eq, Hash, Debug, TaskInput, TraceRawVcs, NonLocalValue, Encode, Decode, + Copy, + Clone, + PartialEq, + Eq, + Hash, + Debug, + TaskInput, + IsTransient, + TraceRawVcs, + NonLocalValue, + Encode, + Decode, )] enum PageEndpointType { Api, @@ -598,14 +609,18 @@ enum PageEndpointType { SsrOnly, } -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TaskInput, TraceRawVcs, Encode, Decode)] +#[derive( + Copy, Clone, PartialEq, Eq, Hash, Debug, TaskInput, IsTransient, TraceRawVcs, Encode, Decode, +)] enum SsrChunkType { Page, Data, Api, } -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TaskInput, TraceRawVcs, Encode, Decode)] +#[derive( + Copy, Clone, Debug, PartialEq, Eq, Hash, TaskInput, IsTransient, TraceRawVcs, Encode, Decode, +)] enum EmitManifests { /// Don't emit any manifests None, diff --git a/crates/next-api/src/project.rs b/crates/next-api/src/project.rs index 56cded9abe4b..91fd6d9faddb 100644 --- a/crates/next-api/src/project.rs +++ b/crates/next-api/src/project.rs @@ -34,9 +34,9 @@ use serde::{Deserialize, Serialize}; use tracing::{Instrument, field::Empty}; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - Completion, Completions, FxIndexMap, NonLocalValue, OperationValue, OperationVc, ReadRef, - ResolvedVc, State, TaskInput, TransientInstance, TryFlatJoinIterExt, TryJoinIterExt, Vc, - debug::ValueDebugFormat, fxindexmap, trace::TraceRawVcs, + Completion, Completions, FxIndexMap, IsTransient, NonLocalValue, OperationValue, OperationVc, + ReadRef, ResolvedVc, State, TaskInput, TransientInstance, TryFlatJoinIterExt, TryJoinIterExt, + Vc, debug::ValueDebugFormat, fxindexmap, trace::TraceRawVcs, }; use turbo_tasks_env::{EnvMap, ProcessEnv}; use turbo_tasks_fs::{ @@ -107,6 +107,7 @@ use crate::{ Deserialize, Clone, TaskInput, + IsTransient, PartialEq, Eq, Hash, @@ -131,6 +132,7 @@ pub struct DraftModeOptions { Copy, Clone, TaskInput, + IsTransient, PartialEq, Eq, Hash, @@ -157,6 +159,7 @@ pub struct WatchOptions { Deserialize, Clone, TaskInput, + IsTransient, PartialEq, Eq, Hash, @@ -179,6 +182,7 @@ pub struct DebugBuildPaths { Copy, Clone, TaskInput, + IsTransient, PartialEq, Eq, Hash, @@ -427,6 +431,7 @@ pub struct PartialProjectOptions { Deserialize, Clone, TaskInput, + IsTransient, PartialEq, Eq, Hash, diff --git a/crates/next-core/src/app_structure.rs b/crates/next-core/src/app_structure.rs index 4fccb7f9c930..91f12af7f37c 100644 --- a/crates/next-core/src/app_structure.rs +++ b/crates/next-core/src/app_structure.rs @@ -8,8 +8,9 @@ use rustc_hash::FxHashMap; use tracing::Instrument; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - FxIndexMap, FxIndexSet, NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, ValueDefault, - ValueToStringRef, Vc, debug::ValueDebugFormat, fxindexmap, trace::TraceRawVcs, turbobail, + FxIndexMap, FxIndexSet, IsTransient, NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, + ValueDefault, ValueToStringRef, Vc, debug::ValueDebugFormat, fxindexmap, trace::TraceRawVcs, + turbobail, }; use turbo_tasks_fs::{DirectoryContent, DirectoryEntry, FileSystemEntryType, FileSystemPath}; use turbopack_core::issue::{Issue, IssueExt, IssueSeverity, IssueStage, StyledString}; @@ -85,7 +86,17 @@ pub enum MetadataWithAltItem { /// A single metadata file. #[derive( - Clone, Debug, Hash, PartialEq, Eq, TaskInput, TraceRawVcs, NonLocalValue, Encode, Decode, + Clone, + Debug, + Hash, + PartialEq, + Eq, + TaskInput, + IsTransient, + TraceRawVcs, + NonLocalValue, + Encode, + Decode, )] pub enum MetadataItem { Static { path: FileSystemPath }, @@ -570,6 +581,7 @@ impl ValueDefault for FileSystemPathVec { ValueDebugFormat, Debug, TaskInput, + IsTransient, NonLocalValue, Encode, Decode, diff --git a/crates/next-core/src/mode.rs b/crates/next-core/src/mode.rs index f6a0496f8660..b705e92a2fa7 100644 --- a/crates/next-core/src/mode.rs +++ b/crates/next-core/src/mode.rs @@ -1,12 +1,11 @@ use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::TaskInput; use turbopack_ecmascript_runtime::RuntimeType; use crate::next_shared::webpack_rules::WebpackLoaderBuiltinCondition; /// The mode in which Next.js is running. -#[turbo_tasks::value(shared)] -#[derive(Debug, Copy, Clone, TaskInput, Ord, PartialOrd, Hash)] +#[turbo_tasks::value(shared, task_input)] +#[derive(Debug, Copy, Clone, Ord, PartialOrd, Hash)] pub enum NextMode { /// `next dev --turbopack` Development, diff --git a/crates/next-core/src/next_app/mod.rs b/crates/next-core/src/next_app/mod.rs index cd4ed30f744b..7c498ed967e2 100644 --- a/crates/next-core/src/next_app/mod.rs +++ b/crates/next-core/src/next_app/mod.rs @@ -14,7 +14,7 @@ use std::{ use anyhow::{Result, bail}; use bincode::{Decode, Encode}; use turbo_rcstr::RcStr; -use turbo_tasks::{NonLocalValue, TaskInput, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, TaskInput, trace::TraceRawVcs}; pub use crate::next_app::{ app_client_references_chunks::{ClientReferencesChunks, get_app_client_references_chunks}, @@ -34,6 +34,7 @@ pub use crate::next_app::{ PartialOrd, Ord, TaskInput, + IsTransient, TraceRawVcs, NonLocalValue, Encode, @@ -139,6 +140,7 @@ impl Display for PageSegment { PartialOrd, Ord, TaskInput, + IsTransient, TraceRawVcs, NonLocalValue, Encode, @@ -169,6 +171,7 @@ impl Display for PageType { Eq, Default, TaskInput, + IsTransient, TraceRawVcs, NonLocalValue, Encode, @@ -365,6 +368,7 @@ impl PartialOrd for AppPage { PartialOrd, Ord, TaskInput, + IsTransient, TraceRawVcs, NonLocalValue, Encode, @@ -417,6 +421,7 @@ impl Display for PathSegment { Eq, Default, TaskInput, + IsTransient, TraceRawVcs, NonLocalValue, Encode, diff --git a/crates/next-core/src/next_client/context.rs b/crates/next-core/src/next_client/context.rs index cc8843d1f40f..5033fbb3c07d 100644 --- a/crates/next-core/src/next_client/context.rs +++ b/crates/next-core/src/next_client/context.rs @@ -3,7 +3,7 @@ use std::collections::BTreeSet; use anyhow::Result; use bincode::{Decode, Encode}; use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::{ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; use turbo_tasks_fs::FileSystemPath; use turbopack::module_options::{ CssOptionsContext, EcmascriptOptionsContext, JsxTransformOptions, ModuleRule, @@ -135,8 +135,8 @@ pub async fn get_client_compile_time_info( .await } -#[turbo_tasks::value(shared)] -#[derive(Debug, Clone, Hash, TaskInput)] +#[turbo_tasks::value(shared, task_input)] +#[derive(Debug, Clone, Hash)] pub enum ClientContextType { Pages { pages_dir: FileSystemPath }, App { app_dir: FileSystemPath }, @@ -454,7 +454,9 @@ pub async fn get_client_module_options_context( Ok(module_options_context) } -#[derive(Clone, Debug, PartialEq, Eq, Hash, TaskInput, TraceRawVcs, Encode, Decode)] +#[derive( + Clone, Debug, PartialEq, Eq, Hash, TaskInput, IsTransient, TraceRawVcs, Encode, Decode, +)] pub struct ClientChunkingContextOptions { pub mode: Vc, pub root_path: FileSystemPath, diff --git a/crates/next-core/src/next_config.rs b/crates/next-core/src/next_config.rs index c409d0331a6a..9dd295bc1254 100644 --- a/crates/next-core/src/next_config.rs +++ b/crates/next-core/src/next_config.rs @@ -8,8 +8,8 @@ use serde_json::Value as JsonValue; use turbo_esregex::EsRegex; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - FxIndexMap, NonLocalValue, OperationValue, ResolvedVc, TaskInput, Vc, debug::ValueDebugFormat, - trace::TraceRawVcs, + FxIndexMap, IsTransient, NonLocalValue, OperationValue, ResolvedVc, TaskInput, Vc, + debug::ValueDebugFormat, trace::TraceRawVcs, }; use turbo_tasks_env::EnvMap; use turbo_tasks_fetch::FetchClientConfig; @@ -358,6 +358,7 @@ pub struct OptionOutputType(Option); Ord, PartialOrd, TaskInput, + IsTransient, TraceRawVcs, Serialize, Deserialize, diff --git a/crates/next-core/src/next_edge/context.rs b/crates/next-core/src/next_edge/context.rs index c5fa24f9d275..81e2512dc958 100644 --- a/crates/next-core/src/next_edge/context.rs +++ b/crates/next-core/src/next_edge/context.rs @@ -1,7 +1,7 @@ use anyhow::Result; use bincode::{Decode, Encode}; use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::{ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; use turbo_tasks_fs::FileSystemPath; use turbopack_browser::BrowserChunkingContext; use turbopack_core::{ @@ -183,7 +183,9 @@ pub async fn get_edge_resolve_options_context( .cell()) } -#[derive(Clone, Debug, PartialEq, Eq, Hash, TaskInput, TraceRawVcs, Encode, Decode)] +#[derive( + Clone, Debug, PartialEq, Eq, Hash, TaskInput, IsTransient, TraceRawVcs, Encode, Decode, +)] pub struct EdgeChunkingContextOptions { pub mode: Vc, pub root_path: FileSystemPath, diff --git a/crates/next-core/src/next_font/google/options.rs b/crates/next-core/src/next_font/google/options.rs index 00d738b7e843..13d4315478d6 100644 --- a/crates/next-core/src/next_font/google/options.rs +++ b/crates/next-core/src/next_font/google/options.rs @@ -3,7 +3,8 @@ use bincode::{Decode, Encode}; use serde::Deserialize; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - FxIndexMap, FxIndexSet, NonLocalValue, TaskInput, Vc, fxindexset, trace::TraceRawVcs, + FxIndexMap, FxIndexSet, IsTransient, NonLocalValue, TaskInput, Vc, fxindexset, + trace::TraceRawVcs, }; use super::request::{NextFontRequest, OneOrManyStrings}; @@ -12,8 +13,8 @@ const ALLOWED_DISPLAY_VALUES: &[&str] = &["auto", "block", "swap", "fallback", " pub(super) type FontData = FxIndexMap; -#[turbo_tasks::value] -#[derive(Clone, Debug, PartialOrd, Ord, Hash, TaskInput)] +#[turbo_tasks::value(task_input)] +#[derive(Clone, Debug, PartialOrd, Ord, Hash)] pub(super) struct NextFontGoogleOptions { /// Name of the requested font from Google. Contains literal spaces. pub font_family: RcStr, @@ -56,6 +57,7 @@ impl NextFontGoogleOptions { TraceRawVcs, NonLocalValue, TaskInput, + IsTransient, Encode, Decode, )] diff --git a/crates/next-core/src/next_font/local/options.rs b/crates/next-core/src/next_font/local/options.rs index 9a3b6dcfa92a..38418198cfa6 100644 --- a/crates/next-core/src/next_font/local/options.rs +++ b/crates/next-core/src/next_font/local/options.rs @@ -3,7 +3,7 @@ use std::{fmt::Display, str::FromStr}; use anyhow::{Context, Result}; use bincode::{Decode, Encode}; use turbo_rcstr::RcStr; -use turbo_tasks::{NonLocalValue, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, TaskInput, Vc, trace::TraceRawVcs}; use crate::next_font::local::request::{ AdjustFontFallback, NextFontLocalDeclaration, NextFontLocalRequest, @@ -12,8 +12,8 @@ use crate::next_font::local::request::{ /// A normalized, Vc-friendly struct derived from validating and transforming /// [[NextFontLocalRequest]] -#[turbo_tasks::value] -#[derive(Clone, Debug, PartialOrd, Ord, Hash, TaskInput)] +#[turbo_tasks::value(task_input)] +#[derive(Clone, Debug, PartialOrd, Ord, Hash)] pub(super) struct NextFontLocalOptions { pub fonts: FontDescriptors, pub default_weight: Option, @@ -63,6 +63,7 @@ impl NextFontLocalOptions { TraceRawVcs, NonLocalValue, TaskInput, + IsTransient, Encode, Decode, )] @@ -105,6 +106,7 @@ impl FontDescriptor { TraceRawVcs, NonLocalValue, TaskInput, + IsTransient, Encode, Decode, )] @@ -128,6 +130,7 @@ pub(super) enum FontDescriptors { TraceRawVcs, NonLocalValue, TaskInput, + IsTransient, Encode, Decode, )] diff --git a/crates/next-core/src/next_font/local/request.rs b/crates/next-core/src/next_font/local/request.rs index aaa2442a895a..971433b3d888 100644 --- a/crates/next-core/src/next_font/local/request.rs +++ b/crates/next-core/src/next_font/local/request.rs @@ -1,7 +1,7 @@ use bincode::{Decode, Encode}; use serde::{Deserialize, Serialize}; use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::{NonLocalValue, TaskInput, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, TaskInput, trace::TraceRawVcs}; /// The top-most structure encoded into the query param in requests to /// `next/font/local` generated by the next/font swc transform. e.g. @@ -22,6 +22,7 @@ pub(super) struct NextFontLocalRequest { Ord, Hash, TaskInput, + IsTransient, Deserialize, TraceRawVcs, NonLocalValue, @@ -81,6 +82,7 @@ pub(super) struct SrcDescriptor { TraceRawVcs, NonLocalValue, TaskInput, + IsTransient, Encode, Decode, )] diff --git a/crates/next-core/src/next_image/module.rs b/crates/next-core/src/next_image/module.rs index a202d4f6c273..9f1746083ba3 100644 --- a/crates/next-core/src/next_image/module.rs +++ b/crates/next-core/src/next_image/module.rs @@ -1,7 +1,9 @@ use anyhow::{Result, bail}; use bincode::{Decode, Encode}; use turbo_rcstr::rcstr; -use turbo_tasks::{NonLocalValue, ResolvedVc, TaskInput, Vc, fxindexmap, trace::TraceRawVcs}; +use turbo_tasks::{ + IsTransient, NonLocalValue, ResolvedVc, TaskInput, Vc, fxindexmap, trace::TraceRawVcs, +}; use turbopack::{ModuleAssetContext, module_options::CustomModuleType}; use turbopack_core::{ context::AssetContext, module::Module, reference_type::ReferenceType, source::Source, @@ -21,6 +23,7 @@ use super::source_asset::StructuredImageFileSource; Ord, Hash, TaskInput, + IsTransient, TraceRawVcs, NonLocalValue, Encode, diff --git a/crates/next-core/src/next_manifests/mod.rs b/crates/next-core/src/next_manifests/mod.rs index 72b997f50ec4..89b2af30ab9f 100644 --- a/crates/next-core/src/next_manifests/mod.rs +++ b/crates/next-core/src/next_manifests/mod.rs @@ -8,8 +8,8 @@ use bincode::{Decode, Encode}; use serde::{Deserialize, Serialize}; use turbo_rcstr::RcStr; use turbo_tasks::{ - FxIndexMap, NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryFlatJoinIterExt, TryJoinIterExt, - Vc, trace::TraceRawVcs, + FxIndexMap, IsTransient, NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryFlatJoinIterExt, + TryJoinIterExt, Vc, trace::TraceRawVcs, }; use turbo_tasks_fs::{File, FileContent, FileSystemPath}; use turbopack_core::{ @@ -243,6 +243,7 @@ impl Default for MiddlewaresManifest { Ord, PartialOrd, TaskInput, + IsTransient, TraceRawVcs, Serialize, Deserialize, @@ -427,6 +428,7 @@ pub enum ActionManifestModuleId<'a> { Ord, PartialOrd, TaskInput, + IsTransient, TraceRawVcs, Serialize, Deserialize, diff --git a/crates/next-core/src/next_server/context.rs b/crates/next-core/src/next_server/context.rs index bfea0490e034..6b1291cdc172 100644 --- a/crates/next-core/src/next_server/context.rs +++ b/crates/next-core/src/next_server/context.rs @@ -3,7 +3,7 @@ use std::collections::BTreeSet; use anyhow::{Result, bail}; use bincode::{Decode, Encode}; use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::{ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; use turbo_tasks_fs::FileSystemPath; use turbopack::{ module_options::{ @@ -78,8 +78,8 @@ use crate::{ }, }; -#[turbo_tasks::value(shared)] -#[derive(Debug, Clone, Hash, TaskInput)] +#[turbo_tasks::value(shared, task_input)] +#[derive(Debug, Clone, Hash)] pub enum ServerContextType { Pages { pages_dir: FileSystemPath, @@ -1002,7 +1002,9 @@ fn client_disallowed_directive_transform_plugin(error_proxy_module: RcStr) -> Vc )) as Box) } -#[derive(Clone, Debug, PartialEq, Eq, Hash, TaskInput, TraceRawVcs, Encode, Decode)] +#[derive( + Clone, Debug, PartialEq, Eq, Hash, TaskInput, IsTransient, TraceRawVcs, Encode, Decode, +)] pub struct ServerChunkingContextOptions { pub mode: Vc, pub root_path: FileSystemPath, diff --git a/crates/next-core/src/next_shared/transforms/next_strip_page_exports.rs b/crates/next-core/src/next_shared/transforms/next_strip_page_exports.rs index 2eb4a1a20e3d..7a38b3909a18 100644 --- a/crates/next-core/src/next_shared/transforms/next_strip_page_exports.rs +++ b/crates/next-core/src/next_shared/transforms/next_strip_page_exports.rs @@ -6,7 +6,7 @@ use next_custom_transforms::transforms::strip_page_exports::{ }; use swc_core::ecma::ast::Program; use turbo_rcstr::RcStr; -use turbo_tasks::{ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; use turbo_tasks_fs::FileSystemPath; use turbopack::module_options::{ModuleRule, ModuleRuleEffect, RuleCondition}; use turbopack_ecmascript::{ @@ -16,7 +16,9 @@ use turbopack_ecmascript::{ use super::module_rule_match_js_no_url; /// A [`TaskInput`]-compatible mirror of [`ExportFilter`]. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TaskInput, TraceRawVcs, Encode, Decode)] +#[derive( + Clone, Copy, Debug, PartialEq, Eq, Hash, TaskInput, IsTransient, TraceRawVcs, Encode, Decode, +)] enum ExportFilterInput { StripDataExports, StripDefaultExport, diff --git a/crates/next-core/src/next_shared/transforms/server_actions.rs b/crates/next-core/src/next_shared/transforms/server_actions.rs index 35e43e3dcc60..7d14f80e53af 100644 --- a/crates/next-core/src/next_shared/transforms/server_actions.rs +++ b/crates/next-core/src/next_shared/transforms/server_actions.rs @@ -6,7 +6,7 @@ use next_custom_transforms::transforms::server_actions::{ }; use swc_core::{common::FileName, ecma::ast::Program}; use turbo_rcstr::RcStr; -use turbo_tasks::{ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; use turbopack::module_options::{ModuleRule, ModuleRuleEffect}; use turbopack_ecmascript::{ CustomTransformer, EcmascriptInputTransform, TransformContext, TransformPlugin, @@ -15,7 +15,9 @@ use turbopack_ecmascript::{ use super::module_rule_match_js_no_url; use crate::{mode::NextMode, next_config::CacheKinds}; -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TaskInput, TraceRawVcs, Encode, Decode)] +#[derive( + Clone, Copy, Debug, PartialEq, Eq, Hash, TaskInput, IsTransient, TraceRawVcs, Encode, Decode, +)] pub enum ActionsTransform { /// Browser and SSR Client, diff --git a/crates/next-core/src/next_shared/transforms/swc_ecma_transform_plugins.rs b/crates/next-core/src/next_shared/transforms/swc_ecma_transform_plugins.rs index 250fdcb6a7dd..63299f835bdc 100644 --- a/crates/next-core/src/next_shared/transforms/swc_ecma_transform_plugins.rs +++ b/crates/next-core/src/next_shared/transforms/swc_ecma_transform_plugins.rs @@ -26,12 +26,9 @@ impl std::hash::Hash for JsonValue { } // Manual impl because `serde_json::Value` doesn't implement `TaskInput`, but `JsonValue` can -// never contain any `Vc` types, so `is_transient` is always `false`. -impl turbo_tasks::TaskInput for JsonValue { - fn is_transient(&self) -> bool { - false - } -} +// never contain any `Vc` types, so `is_transient` is always `false` (via the default). +impl turbo_tasks::TaskInput for JsonValue {} +impl turbo_tasks::IsTransient for JsonValue {} pub async fn get_swc_ecma_transform_plugin_rule( next_config: Vc, diff --git a/crates/next-core/src/next_shared/webpack_rules/mod.rs b/crates/next-core/src/next_shared/webpack_rules/mod.rs index 7733e2412366..2e05b1262af3 100644 --- a/crates/next-core/src/next_shared/webpack_rules/mod.rs +++ b/crates/next-core/src/next_shared/webpack_rules/mod.rs @@ -5,7 +5,9 @@ use async_trait::async_trait; use bincode::{Decode, Encode}; use serde::Deserialize; use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::{NonLocalValue, OperationValue, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{ + IsTransient, NonLocalValue, OperationValue, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs, +}; use turbo_tasks_fs::FileSystemPath; use turbopack::module_options::{ WebpackLoaderBuiltinConditionSet, WebpackLoaderBuiltinConditionSetMatch, WebpackLoadersOptions, @@ -44,6 +46,7 @@ pub(crate) mod sass; Hash, Deserialize, TaskInput, + IsTransient, TraceRawVcs, NonLocalValue, OperationValue, diff --git a/crates/next-core/src/segment_config.rs b/crates/next-core/src/segment_config.rs index 2a6147be0332..489ee39cf429 100644 --- a/crates/next-core/src/segment_config.rs +++ b/crates/next-core/src/segment_config.rs @@ -18,8 +18,8 @@ use swc_core::{ }; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, ValueDefault, Vc, trace::TraceRawVcs, - util::WrapFuture, + IsTransient, NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, ValueDefault, Vc, + trace::TraceRawVcs, util::WrapFuture, }; use turbo_tasks_fs::FileSystemPath; use turbopack_core::{ @@ -289,7 +289,18 @@ impl Issue for NextSegmentConfigParsingIssue { } #[derive( - Debug, Clone, Copy, PartialEq, Eq, Hash, TaskInput, NonLocalValue, TraceRawVcs, Encode, Decode, + Debug, + Clone, + Copy, + PartialEq, + Eq, + Hash, + TaskInput, + IsTransient, + NonLocalValue, + TraceRawVcs, + Encode, + Decode, )] pub enum ParseSegmentMode { Base, diff --git a/crates/next-core/src/util.rs b/crates/next-core/src/util.rs index e976abe84b5a..03e45af5bfd7 100644 --- a/crates/next-core/src/util.rs +++ b/crates/next-core/src/util.rs @@ -6,7 +6,8 @@ use next_taskless::{expand_next_js_template, expand_next_js_template_no_imports} use serde::{Deserialize, de::DeserializeOwned}; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - FxIndexMap, NonLocalValue, TaskInput, Vc, fxindexset, trace::TraceRawVcs, turbobail, + FxIndexMap, IsTransient, NonLocalValue, TaskInput, Vc, fxindexset, trace::TraceRawVcs, + turbobail, }; use turbo_tasks_fs::{File, FileContent, FileJsonContent, FileSystem, FileSystemPath, rope::Rope}; use turbopack::module_options::RuleCondition; @@ -205,7 +206,9 @@ pub fn free_var_references_with_vercel_system_env_warnings( FreeVarReferences(entries) } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TaskInput, TraceRawVcs, Encode, Decode)] +#[derive( + Debug, Clone, Copy, PartialEq, Eq, Hash, TaskInput, IsTransient, TraceRawVcs, Encode, Decode, +)] pub enum PathType { PagesPage, PagesApi, @@ -340,6 +343,7 @@ pub fn pages_function_name(page: impl Display) -> String { PartialOrd, Ord, TaskInput, + IsTransient, NonLocalValue, Encode, Decode, diff --git a/crates/next-napi-bindings/src/next_api/project.rs b/crates/next-napi-bindings/src/next_api/project.rs index 6d4466ee4719..faed57f0b667 100644 --- a/crates/next-napi-bindings/src/next_api/project.rs +++ b/crates/next-napi-bindings/src/next_api/project.rs @@ -47,9 +47,9 @@ use tracing::Instrument; use tracing_subscriber::{Registry, layer::SubscriberExt, util::SubscriberInitExt}; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - Effects, FxIndexSet, NonLocalValue, OperationValue, OperationVc, PrettyPrintError, ReadRef, - ResolvedVc, TaskInput, TransientInstance, TryJoinIterExt, TurboTasksApi, TurboTasksCallApi, - UpdateInfo, Vc, mark_top_level_task, + Effects, FxIndexSet, IsTransient, NonLocalValue, OperationValue, OperationVc, PrettyPrintError, + ReadRef, ResolvedVc, TaskInput, TransientInstance, TryJoinIterExt, TurboTasksApi, + TurboTasksCallApi, UpdateInfo, Vc, mark_top_level_task, message_queue::{CompilationEvent, Severity}, take_effects, trace::TraceRawVcs, @@ -1051,6 +1051,7 @@ pub struct NapiDebugBuildPaths { OperationValue, PartialEq, TaskInput, + IsTransient, TraceRawVcs, Encode, Decode, @@ -2182,6 +2183,7 @@ pub fn project_compilation_events_subscribe( OperationValue, PartialEq, TaskInput, + IsTransient, TraceRawVcs, Encode, Decode, diff --git a/scripts/bench-build.sh b/scripts/bench-build.sh new file mode 100755 index 000000000000..cfbcce9288c3 --- /dev/null +++ b/scripts/bench-build.sh @@ -0,0 +1,270 @@ +#!/usr/bin/env bash +# Run `pnpm next build` N times in the current working directory, capturing +# wall / user / sys time and MaxRSS per run. Prints a summary table at the end. +# +# Designed to complement hyperfine — hyperfine times the wall clock well but +# doesn't track memory. +# +# Usage: +# sudo scripts/bench-build.sh # 5 runs + 1 warmup, default cmd +# sudo scripts/bench-build.sh -r 15 -w 2 +# sudo scripts/bench-build.sh -c 'pnpm next build --experimental-build-mode=compile' +# sudo scripts/bench-build.sh -o /tmp/my-baseline.txt # named output log +# +# Defaults match a typical hyperfine invocation: TURBOPACK_PERSISTENT_CACHE=0, +# experimental compile mode, `rm -rf .next` between runs. +# +# Requires sudo so the script can: +# - lower nice (-20) for the build (real scheduling-priority bump) +# - toggle Spotlight indexing off for the run +# - toggle Low Power Mode off for the run +# All of these are reverted on exit. + +set -euo pipefail + +RUNS=5 +WARMUP=1 +CMD='TURBOPACK_PERSISTENT_CACHE=0 pnpm next build --experimental-build-mode=compile' +OUT="" +PREPARE='rm -rf .next' +COOLDOWN=5 + +usage() { + sed -n '2,22p' "$0" | sed 's/^# \{0,1\}//' + exit 1 +} + +while getopts "r:w:c:o:p:t:h" opt; do + case "$opt" in + r) RUNS="$OPTARG" ;; + w) WARMUP="$OPTARG" ;; + c) CMD="$OPTARG" ;; + o) OUT="$OPTARG" ;; + p) PREPARE="$OPTARG" ;; + t) COOLDOWN="$OPTARG" ;; + h|*) usage ;; + esac +done + +if [[ $EUID -ne 0 ]]; then + echo "error: must run under sudo (needed for nice -n -20 and pmset/mdutil)" >&2 + exit 1 +fi + +# /usr/bin/time -l is the BSD time; the bash builtin doesn't support -l. +TIME=/usr/bin/time +if [[ ! -x "$TIME" ]]; then + echo "error: $TIME not found (need BSD time -l for MaxRSS)" >&2 + exit 1 +fi + +# Run the build itself as the invoking user, not root. pnpm/node configuration, +# the user's pnpm store, ~/.cache, etc. all live under $HOME and would be +# polluted by root if we didn't drop privilege. +RUNUSER="${SUDO_USER:?must run via sudo, not as root directly}" +RUNUSER_HOME="$(eval echo "~$RUNUSER")" +RUN_AS=(sudo -E -u "$RUNUSER" -H) + +if [[ -z "$OUT" ]]; then + OUT="$(pwd)/.bench-build-$(date +%Y%m%d-%H%M%S).log" +fi + +echo "==> bench-build" +echo " cwd : $(pwd)" +echo " user : $RUNUSER (home: $RUNUSER_HOME)" +echo " cmd : $CMD" +echo " prepare : $PREPARE" +echo " warmup : $WARMUP" +echo " runs : $RUNS" +echo " cooldown : ${COOLDOWN}s between runs" +echo " log : $OUT" +: > "$OUT" +chown "$RUNUSER" "$OUT" + +# --- Environment hardening ----------------------------------------------------- + +ORIG_LOWPOWER_AC="" +ORIG_LOWPOWER_BAT="" +restore_env() { + echo "==> restoring environment" + if [[ -n "$ORIG_LOWPOWER_AC" ]]; then + pmset -c lowpowermode "$ORIG_LOWPOWER_AC" 2>/dev/null || true + fi + if [[ -n "$ORIG_LOWPOWER_BAT" ]]; then + pmset -b lowpowermode "$ORIG_LOWPOWER_BAT" 2>/dev/null || true + fi + mdutil -a -i on >/dev/null 2>&1 || true +} +trap restore_env EXIT + +ORIG_LOWPOWER_AC="$(pmset -g custom 2>/dev/null | awk '/^AC Power/,/^Battery/' | awk '/lowpowermode/ {print $2}' | head -1 || true)" +ORIG_LOWPOWER_BAT="$(pmset -g custom 2>/dev/null | awk '/^Battery/,0' | awk '/lowpowermode/ {print $2}' | head -1 || true)" +pmset -c lowpowermode 0 2>/dev/null || true +pmset -b lowpowermode 0 2>/dev/null || true + +# Pause Spotlight; index churn is a known stall source on large repos. +mdutil -a -i off >/dev/null 2>&1 || true + +# Per-run capture file used inside the loop; each run rewrites it. +PER_RUN="$(mktemp -t bench-build-run.XXXXXX)" +trap 'rm -f "$PER_RUN"' EXIT + +# Arrays for the real (non-warmup) runs. +# user/sys come from /usr/bin/time -lp's `user`/`sys` lines, which aggregate +# CPU time across the whole process tree (same RUSAGE_CHILDREN source as +# MaxRSS). They're typically less noisy than wall time because they +# excludes scheduler/IO jitter. +declare -a WALL_S USER_S SYS_S MAXRSS_B + +# Returns "" if the field isn't present. +extract_field() { + # $1 = file, $2 = field text (e.g. "maximum resident set size") + # BSD time -l format: field + awk -v want="$2" ' + { + # find the literal field anywhere after column 1 + idx = index($0, want) + if (idx > 0) { + # the number is the first whitespace-separated token before "want" + # i.e. the leading column + n = $1 + gsub(/[^0-9]/, "", n) + if (n != "") { print n; exit } + } + }' "$1" +} + +run_once() { + local label="$1" + local run_idx="$2" + echo "==> $label run $run_idx" + echo " prepare: $PREPARE" + "${RUN_AS[@]}" bash -c "$PREPARE" >>"$OUT" 2>&1 + + if (( COOLDOWN > 0 )); then + echo " cooldown ${COOLDOWN}s ..." + sleep "$COOLDOWN" + fi + + echo " running ..." + + # Capture: time + memory stats from /usr/bin/time -lp. + # -lp uses the POSIX one-token-per-line format ("real " / "user " / + # "sys ") which is much easier to parse than the default ` real + # user sys` block. -l still adds the rusage block below. + # + # Wrapping: + # caffeinate -dimsu — prevent display/idle/disk sleep during the run + # nice -n -20 — highest scheduling priority (requires root, which we have) + # sudo -E -u — drop privilege so pnpm/node use the user's HOME/caches + # /usr/bin/time -lp — gather wall/user/sys + rusage block (sudo passes args through) + # + # We must `nice` *before* dropping privilege: nice -n -20 needs root. + # `sudo -u ` preserves the nice value into the child. + # stderr (time's report) is captured to PER_RUN; stdout (build output) appends to OUT. + local rc=0 + caffeinate -dimsu nice -n -20 \ + "${RUN_AS[@]}" "$TIME" -lp bash -c "$CMD" \ + >>"$OUT" 2>"$PER_RUN" || rc=$? + + if [[ $rc -ne 0 ]]; then + echo " build failed (rc=$rc); tail of log:" >&2 + tail -30 "$OUT" >&2 + echo " time -l output:" >&2 + cat "$PER_RUN" >&2 + exit "$rc" + fi + + # -lp emits "real " / "user " / "sys " as the first three lines. + local real_s user_s sys_s + real_s="$(awk '$1=="real" {print $2; exit}' "$PER_RUN")" + user_s="$(awk '$1=="user" {print $2; exit}' "$PER_RUN")" + sys_s="$(awk '$1=="sys" {print $2; exit}' "$PER_RUN")" + # MaxRSS aggregates across the whole process tree via RUSAGE_CHILDREN, so it + # captures the real `pnpm -> node -> next build` cost. We deliberately + # *don't* read `peak memory footprint`: that field is reported only for the + # single direct child PID (the short-lived shell wrapper), not the tree. + local maxrss + maxrss="$(extract_field "$PER_RUN" "maximum resident set size")" + + printf ' real=%ss user=%ss sys=%ss maxrss=%s\n' \ + "$real_s" "$user_s" "$sys_s" "$(human_bytes "$maxrss")" + + # Append the full time -l block to the main log for auditability. + { + echo + echo "--- $label run $run_idx ---" + cat "$PER_RUN" + } >>"$OUT" + + if [[ "$label" == "run" ]]; then + WALL_S+=("$real_s") + USER_S+=("$user_s") + SYS_S+=("$sys_s") + MAXRSS_B+=("$maxrss") + fi +} + +human_bytes() { + local b="$1" + [[ -z "$b" ]] && { echo "?"; return; } + awk -v b="$b" 'BEGIN { + if (b < 1024) printf "%d B", b + else if (b < 1024*1024) printf "%.1f KB", b/1024 + else if (b < 1024*1024*1024) printf "%.1f MB", b/1024/1024 + else printf "%.2f GB", b/1024/1024/1024 + }' +} + +stats() { + # arr_name unit_label divisor decimals + local name="$1" unit="$2" div="$3" dec="$4" + local -n arr="$name" + awk -v n="${#arr[@]}" -v dec="$dec" -v div="$div" -v unit="$unit" ' + BEGIN { sum=0; min=1e30; max=0 } + { v=$1+0; vals[NR]=v; sum+=v; if (vmax) max=v } + END { + if (n==0) { print " (no data)"; exit } + mean = sum/n + sd = 0 + for (i=1;i<=n;i++) { d=vals[i]-mean; sd += d*d } + sd = (n>1) ? sqrt(sd/(n-1)) : 0 + printf " mean %10.*f %s\n", dec, mean/div, unit + printf " stddev %10.*f %s (%.1f%%)\n", dec, sd/div, unit, (mean>0?100*sd/mean:0) + printf " min %10.*f %s\n", dec, min/div, unit + printf " max %10.*f %s\n", dec, max/div, unit + }' < <(printf '%s\n' "${arr[@]}") +} + +# --- Run ----------------------------------------------------------------------- + +for ((i=1; i<=WARMUP; i++)); do + run_once warmup "$i" +done + +for ((i=1; i<=RUNS; i++)); do + run_once run "$i" +done + +# --- Summary ------------------------------------------------------------------- + +echo +echo "==> summary across $RUNS runs" +echo "wall time (s):" +stats WALL_S "s" 1 3 +echo "user time (s):" +stats USER_S "s" 1 3 +echo "sys time (s):" +stats SYS_S "s" 1 3 +echo "MaxRSS:" +stats MAXRSS_B "MB" $((1024*1024)) 1 +echo +echo "per-run csv:" +echo " run,wall_s,user_s,sys_s,maxrss_bytes" +for ((i=0; i done (full log: $OUT)" diff --git a/scripts/bench-quiet.sh b/scripts/bench-quiet.sh new file mode 100755 index 000000000000..cd567eb94e1f --- /dev/null +++ b/scripts/bench-quiet.sh @@ -0,0 +1,197 @@ +#!/usr/bin/env bash +# Quiet, low-noise A/B Criterion bench runner for turbo-tasks-backend. +# +# Runs the same Cargo bench twice — once on a baseline ref (default: canary), +# once on the current working tree — under caffeinate + nice, with thermal/ +# frequency telemetry recorded alongside each run. +# +# Usage: +# sudo scripts/bench-quiet.sh # baseline=canary, filter=task_overhead/turbo +# sudo scripts/bench-quiet.sh -b origin/canary +# sudo scripts/bench-quiet.sh -f 'task_overhead/turbo-uncached' +# sudo scripts/bench-quiet.sh -p turbo-tasks-backend -B mod -s 200 +# +# Requires sudo for `nice -n -20` and `powermetrics`. + +set -euo pipefail + +PACKAGE="turbo-tasks-backend" +BENCH="mod" +FILTER="task_overhead/turbo" +SAMPLE_SIZE=200 +BASELINE_REF="canary" +WARMUP_SECS=30 +KEEP_GOING=0 + +usage() { + sed -n '2,15p' "$0" | sed 's/^# \{0,1\}//' + exit 1 +} + +while getopts "p:B:f:s:b:w:kh" opt; do + case "$opt" in + p) PACKAGE="$OPTARG" ;; + B) BENCH="$OPTARG" ;; + f) FILTER="$OPTARG" ;; + s) SAMPLE_SIZE="$OPTARG" ;; + b) BASELINE_REF="$OPTARG" ;; + w) WARMUP_SECS="$OPTARG" ;; + k) KEEP_GOING=1 ;; + h|*) usage ;; + esac +done + +if [[ $EUID -ne 0 ]]; then + echo "error: must run under sudo (needed for nice -n -20 and powermetrics)" >&2 + exit 1 +fi + +REPO_ROOT="$(git rev-parse --show-toplevel)" +cd "$REPO_ROOT" + +# Use SUDO_USER for the actual user's environment so cargo finds the right target dir, rustup toolchain, etc. +RUNUSER="${SUDO_USER:?must run via sudo, not as root directly}" +RUN_AS="sudo -E -u $RUNUSER" + +OUT_DIR="$REPO_ROOT/.bench-runs/$(date +%Y%m%d-%H%M%S)" +mkdir -p "$OUT_DIR" +chown "$RUNUSER" "$OUT_DIR" + +START_BRANCH="$(git rev-parse --abbrev-ref HEAD)" +START_SHA="$(git rev-parse HEAD)" +BASELINE_SHA="$(git rev-parse "$BASELINE_REF")" + +if ! git diff --quiet || ! git diff --cached --quiet; then + echo "error: working tree is dirty; commit or stash before running" >&2 + exit 1 +fi + +echo "==> bench-quiet starting" +echo " package : $PACKAGE" +echo " bench : $BENCH" +echo " filter : $FILTER" +echo " samples : $SAMPLE_SIZE" +echo " baseline : $BASELINE_REF ($BASELINE_SHA)" +echo " branch HEAD: $START_BRANCH ($START_SHA)" +echo " out dir : $OUT_DIR" + +# --- Environment hardening ----------------------------------------------------- + +ORIG_LOWPOWER_AC="" +ORIG_LOWPOWER_BAT="" +restore_env() { + echo "==> restoring environment" + if [[ -n "$ORIG_LOWPOWER_AC" ]]; then + pmset -c lowpowermode "$ORIG_LOWPOWER_AC" 2>/dev/null || true + fi + if [[ -n "$ORIG_LOWPOWER_BAT" ]]; then + pmset -b lowpowermode "$ORIG_LOWPOWER_BAT" 2>/dev/null || true + fi + mdutil -a -i on >/dev/null 2>&1 || true + if [[ "$(git rev-parse --abbrev-ref HEAD)" != "$START_BRANCH" ]]; then + echo " git: returning to $START_BRANCH" + git checkout -q "$START_BRANCH" || echo " warning: failed to return to $START_BRANCH" >&2 + fi +} +trap restore_env EXIT + +# Capture and disable low-power mode (best effort) +ORIG_LOWPOWER_AC="$(pmset -g custom 2>/dev/null | awk '/^AC Power/,/^Battery/' | awk '/lowpowermode/ {print $2}' | head -1 || true)" +ORIG_LOWPOWER_BAT="$(pmset -g custom 2>/dev/null | awk '/^Battery/,0' | awk '/lowpowermode/ {print $2}' | head -1 || true)" +pmset -c lowpowermode 0 2>/dev/null || true +pmset -b lowpowermode 0 2>/dev/null || true + +# Pause Spotlight; index churn is a known stall source. +mdutil -a -i off >/dev/null 2>&1 || true + +# --- Helpers ------------------------------------------------------------------- + +start_powermetrics() { + local logfile="$1" + # 1 Hz sample; smc=fan/temps, cpu_power=freq + active residency. + powermetrics --samplers smc,cpu_power -i 1000 -o "$logfile" >/dev/null 2>&1 & + echo $! +} + +stop_powermetrics() { + local pid="$1" + kill "$pid" 2>/dev/null || true + wait "$pid" 2>/dev/null || true +} + +thermal_summary() { + local logfile="$1" + echo " thermal pressure events:" + if grep -Eq 'CPU Thermal level|Thermal pressure: [^N]' "$logfile" 2>/dev/null; then + grep -E 'CPU Thermal level|Thermal pressure: [^N]' "$logfile" | sort -u | head -5 | sed 's/^/ /' + else + echo " none recorded" + fi + echo " pmset post-run therm state:" + pmset -g therm | sed 's/^/ /' +} + +run_one() { + local label="$1" # "baseline" | "branch" + local ref="$2" + local sha="$3" + local criterion_arg="$4" # --save-baseline NAME for baseline, --baseline NAME for branch + + echo + echo "==> [$label] checking out $ref ($sha)" + git checkout -q "$ref" + + echo "==> [$label] building bench (no instrumentation; release)" + # Build first so the bench step is pure measurement. + $RUN_AS cargo build --release -p "$PACKAGE" --bench "$BENCH" 2>&1 \ + | tee "$OUT_DIR/$label.build.log" | tail -3 + + echo "==> [$label] cooldown ${WARMUP_SECS}s (let SoC settle)" + sleep "$WARMUP_SECS" + + local pm_log="$OUT_DIR/$label.powermetrics.log" + local bench_log="$OUT_DIR/$label.bench.log" + echo "==> [$label] running bench (sample-size=$SAMPLE_SIZE, filter=$FILTER)" + local pm_pid + pm_pid="$(start_powermetrics "$pm_log")" + + # Bench args: + # --save-baseline N baseline run: store under name N + # --baseline N branch run: diff against previously-saved baseline N + # (Criterion prints `change:` lines only with --baseline) + # -- $FILTER criterion filter (positional after --) + # --sample-size N widen sample count for tighter CIs + local rc=0 + caffeinate -dimsu nice -n -20 \ + $RUN_AS cargo bench -p "$PACKAGE" --bench "$BENCH" -- \ + "$FILTER" --sample-size "$SAMPLE_SIZE" $criterion_arg \ + >"$bench_log" 2>&1 || rc=$? + + stop_powermetrics "$pm_pid" + + if [[ $rc -ne 0 ]]; then + echo " bench exited with rc=$rc; tail of $bench_log:" >&2 + tail -20 "$bench_log" >&2 + if [[ $KEEP_GOING -eq 0 ]]; then exit "$rc"; fi + fi + + thermal_summary "$pm_log" +} + +# --- Run ----------------------------------------------------------------------- + +BASELINE_NAME="bench-quiet-baseline" +run_one baseline "$BASELINE_REF" "$BASELINE_SHA" "--save-baseline $BASELINE_NAME" +run_one branch "$START_BRANCH" "$START_SHA" "--baseline $BASELINE_NAME" + +# --- Summary ------------------------------------------------------------------- + +echo +echo "==> done" +echo " artifacts: $OUT_DIR" +echo " re-diff later with:" +echo " cargo bench -p $PACKAGE --bench $BENCH -- $FILTER --baseline $BASELINE_NAME" +echo +echo " comparison ('change' line per benchmark, branch vs baseline):" +grep -E '^(test |task_overhead/| +time:| +change:|Performance has)' "$OUT_DIR/branch.bench.log" \ + | sed 's/^/ /' | head -120 || true diff --git a/turbopack/crates/turbo-tasks-backend/fuzz/src/graph.rs b/turbopack/crates/turbo-tasks-backend/fuzz/src/graph.rs index 24e57465d134..e6580c404345 100644 --- a/turbopack/crates/turbo-tasks-backend/fuzz/src/graph.rs +++ b/turbopack/crates/turbo-tasks-backend/fuzz/src/graph.rs @@ -3,7 +3,9 @@ use std::sync::{Arc, LazyLock}; use anyhow::Result; use arbitrary::Arbitrary; use bincode::{Decode, Encode}; -use turbo_tasks::{self, NonLocalValue, State, TaskInput, TurboTasks, Vc, trace::TraceRawVcs}; +use turbo_tasks::{ + self, IsTransient, NonLocalValue, State, TaskInput, TurboTasks, Vc, trace::TraceRawVcs, +}; use turbo_tasks_malloc::TurboMalloc; #[derive( @@ -16,6 +18,7 @@ use turbo_tasks_malloc::TurboMalloc; NonLocalValue, TraceRawVcs, TaskInput, + IsTransient, Encode, Decode, )] @@ -36,6 +39,7 @@ pub struct TaskReferenceSpec { NonLocalValue, TraceRawVcs, TaskInput, + IsTransient, Encode, Decode, )] diff --git a/turbopack/crates/turbo-tasks-backend/tests/all_in_one.rs b/turbopack/crates/turbo-tasks-backend/tests/all_in_one.rs index b67042c7745b..2455f0ed500d 100644 --- a/turbopack/crates/turbo-tasks-backend/tests/all_in_one.rs +++ b/turbopack/crates/turbo-tasks-backend/tests/all_in_one.rs @@ -4,7 +4,7 @@ use anyhow::{Result, bail}; use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::{ResolvedVc, TaskInput, ValueToString, Vc}; +use turbo_tasks::{ResolvedVc, ValueToString, Vc}; use turbo_tasks_testing::{Registration, register, run_once}; static REGISTRATION: Registration = register!(); @@ -80,8 +80,8 @@ async fn test_all_in_one_operation(nonce: u32) -> Result> { #[derive(Debug, Clone, Hash)] struct MyTransparentValue(u32); -#[turbo_tasks::value(shared)] -#[derive(Debug, Clone, Hash, TaskInput)] +#[turbo_tasks::value(shared, task_input)] +#[derive(Debug, Clone, Hash)] enum MyEnumValue { Yeah(u32), Nah, diff --git a/turbopack/crates/turbo-tasks-backend/tests/bug2.rs b/turbopack/crates/turbo-tasks-backend/tests/bug2.rs index 89ef590845c4..174c4ae38d8b 100644 --- a/turbopack/crates/turbo-tasks-backend/tests/bug2.rs +++ b/turbopack/crates/turbo-tasks-backend/tests/bug2.rs @@ -6,13 +6,23 @@ use std::sync::Arc; use anyhow::Result; use bincode::{Decode, Encode}; -use turbo_tasks::{NonLocalValue, State, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, State, TaskInput, Vc, trace::TraceRawVcs}; use turbo_tasks_testing::{Registration, register, run_once}; static REGISTRATION: Registration = register!(); #[derive( - Clone, Debug, PartialEq, Eq, Hash, NonLocalValue, TraceRawVcs, TaskInput, Encode, Decode, + Clone, + Debug, + PartialEq, + Eq, + Hash, + NonLocalValue, + TraceRawVcs, + TaskInput, + IsTransient, + Encode, + Decode, )] pub struct TaskReferenceSpec { task: u16, @@ -22,7 +32,17 @@ pub struct TaskReferenceSpec { } #[derive( - Clone, Debug, PartialEq, Eq, Hash, NonLocalValue, TraceRawVcs, TaskInput, Encode, Decode, + Clone, + Debug, + PartialEq, + Eq, + Hash, + NonLocalValue, + TraceRawVcs, + TaskInput, + IsTransient, + Encode, + Decode, )] pub struct TaskSpec { references: Vec, diff --git a/turbopack/crates/turbo-tasks-backend/tests/trace_transient.rs b/turbopack/crates/turbo-tasks-backend/tests/trace_transient.rs index 5a95cb6c2fb4..79e0b91fa152 100644 --- a/turbopack/crates/turbo-tasks-backend/tests/trace_transient.rs +++ b/turbopack/crates/turbo-tasks-backend/tests/trace_transient.rs @@ -3,7 +3,7 @@ use anyhow::Result; use bincode::{Decode, Encode}; -use turbo_tasks::{NonLocalValue, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; use turbo_tasks_testing::{Registration, register, run_once_without_cache_check}; static REGISTRATION: Registration = register!(); @@ -76,8 +76,5 @@ async fn read_incorrect_task_input(value: IncorrectTaskInput) -> Result> #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TraceRawVcs, Encode, Decode, NonLocalValue)] struct IncorrectTaskInput(ResolvedVc); -impl TaskInput for IncorrectTaskInput { - fn is_transient(&self) -> bool { - false - } -} +impl TaskInput for IncorrectTaskInput {} +impl IsTransient for IncorrectTaskInput {} diff --git a/turbopack/crates/turbo-tasks-backend/tests/transient_collectible.rs b/turbopack/crates/turbo-tasks-backend/tests/transient_collectible.rs index ddbcb6e5d694..4a891c664dfd 100644 --- a/turbopack/crates/turbo-tasks-backend/tests/transient_collectible.rs +++ b/turbopack/crates/turbo-tasks-backend/tests/transient_collectible.rs @@ -2,7 +2,7 @@ #![feature(arbitrary_self_types_pointers)] use bincode::{Decode, Encode}; -use turbo_tasks::{NonLocalValue, ResolvedVc, TaskInput, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, ResolvedVc, TaskInput, trace::TraceRawVcs}; use turbo_tasks_testing::{Registration, register, run_once_without_cache_check}; static REGISTRATION: Registration = register!(); @@ -33,11 +33,8 @@ fn emit_incorrect_task_input_operation(value: IncorrectTaskInput) { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TraceRawVcs, Encode, Decode, NonLocalValue)] struct IncorrectTaskInput(ResolvedVc); -impl TaskInput for IncorrectTaskInput { - fn is_transient(&self) -> bool { - false - } -} +impl TaskInput for IncorrectTaskInput {} +impl IsTransient for IncorrectTaskInput {} #[turbo_tasks::value_trait] trait Number {} diff --git a/turbopack/crates/turbo-tasks-backend/tests/transient_vc.rs b/turbopack/crates/turbo-tasks-backend/tests/transient_vc.rs index 3ee97c1f0993..cfbc36c7a516 100644 --- a/turbopack/crates/turbo-tasks-backend/tests/transient_vc.rs +++ b/turbopack/crates/turbo-tasks-backend/tests/transient_vc.rs @@ -1,7 +1,7 @@ #![feature(arbitrary_self_types)] use anyhow::Result; -use turbo_tasks::{TaskInput, TransientValue, Vc}; +use turbo_tasks::{IsTransient, TransientValue, Vc}; use turbo_tasks_testing::{Registration, register, run_without_cache_check}; static REGISTRATION: Registration = register!(); diff --git a/turbopack/crates/turbo-tasks-fs/src/glob.rs b/turbopack/crates/turbo-tasks-fs/src/glob.rs index 41964620dfbb..6f8c2e8e5aee 100644 --- a/turbopack/crates/turbo-tasks-fs/src/glob.rs +++ b/turbopack/crates/turbo-tasks-fs/src/glob.rs @@ -10,7 +10,7 @@ use bincode::{ }; use regex::bytes::{Regex, RegexBuilder}; use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::{TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, TaskInput, Vc, trace::TraceRawVcs}; use crate::globset::parse; @@ -71,7 +71,18 @@ impl Decode for Glob { impl_borrow_decode!(Glob); #[derive( - Copy, Clone, PartialEq, Eq, Hash, Default, TaskInput, TraceRawVcs, Debug, Encode, Decode, + Copy, + Clone, + PartialEq, + Eq, + Hash, + Default, + TaskInput, + IsTransient, + TraceRawVcs, + Debug, + Encode, + Decode, )] pub struct GlobOptions { diff --git a/turbopack/crates/turbo-tasks-fs/src/json.rs b/turbopack/crates/turbo-tasks-fs/src/json.rs index eab740287012..d56dce531f53 100644 --- a/turbopack/crates/turbo-tasks-fs/src/json.rs +++ b/turbopack/crates/turbo-tasks-fs/src/json.rs @@ -3,11 +3,11 @@ use std::fmt::{Display, Formatter, Write}; use anyhow::Result; use serde::Deserialize; use turbo_rcstr::RcStr; -use turbo_tasks::{NonLocalValue, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, trace::TraceRawVcs}; use crate::{rope::Rope, source_context::get_source_context}; -#[derive(Debug, Clone, PartialEq, Eq, Hash, TraceRawVcs, NonLocalValue)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, TraceRawVcs, NonLocalValue, IsTransient)] pub struct UnparsableJson { pub message: RcStr, pub path: Option, diff --git a/turbopack/crates/turbo-tasks-fs/src/lib.rs b/turbopack/crates/turbo-tasks-fs/src/lib.rs index 573bd530c478..5f1d56d2899f 100644 --- a/turbopack/crates/turbo-tasks-fs/src/lib.rs +++ b/turbopack/crates/turbo-tasks-fs/src/lib.rs @@ -62,9 +62,10 @@ use tokio::{ use tracing::Instrument; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - Completion, Effect, EffectStateStorage, InvalidationReason, NonLocalValue, ReadRef, ResolvedVc, - TaskInput, TurboTasksApi, ValueToString, ValueToStringRef, Vc, debug::ValueDebugFormat, - emit_effect, parallel, trace::TraceRawVcs, turbo_tasks_weak, turbobail, turbofmt, + Completion, Effect, EffectStateStorage, InvalidationReason, IsTransient, NonLocalValue, + ReadRef, ResolvedVc, TurboTasksApi, ValueToString, ValueToStringRef, Vc, + debug::ValueDebugFormat, emit_effect, parallel, trace::TraceRawVcs, turbo_tasks_weak, + turbobail, turbofmt, }; use turbo_tasks_hash::{ DeterministicHash, DeterministicHasher, HashAlgorithm, deterministic_hash, hash_xxh3_hash64, @@ -1428,8 +1429,8 @@ fn remove_symbolic_link_dir_helper(path: &Path) -> io::Result<()> { } } -#[derive(Debug, Clone, Hash, TaskInput)] -#[turbo_tasks::value(shared)] +#[derive(Debug, Clone, Hash)] +#[turbo_tasks::value(shared, task_input)] pub struct FileSystemPath { pub fs: ResolvedVc>, pub path: RcStr, @@ -1901,7 +1902,9 @@ pub struct RealPathResult { /// Errors that can occur when resolving a path with symlinks. /// Many of these can be transient conditions that might happen when package managers are running. -#[derive(Debug, Clone, Hash, Eq, PartialEq, NonLocalValue, TraceRawVcs, Encode, Decode)] +#[derive( + Debug, Clone, Hash, Eq, PartialEq, NonLocalValue, IsTransient, TraceRawVcs, Encode, Decode, +)] pub enum RealPathResultError { TooManySymlinks, CycleDetected, @@ -1941,7 +1944,7 @@ impl RealPathResultError { } } -#[derive(Clone, Copy, Debug, Default, DeterministicHash, PartialOrd, Ord)] +#[derive(Clone, Copy, Debug, Default, DeterministicHash, PartialOrd, Ord, IsTransient)] #[turbo_tasks::value(shared)] pub enum Permissions { Readable, @@ -2008,7 +2011,7 @@ impl From for FileContent { /// the actual data is not available. `PersistedFileContent` provides the full data so that /// [`DiskFileSystem::write`] can retrieve it without re-reading from disk. #[turbo_tasks::value(shared)] -#[derive(Clone, Debug, DeterministicHash, PartialOrd, Ord)] +#[derive(Clone, Debug, DeterministicHash, PartialOrd, Ord, IsTransient)] pub enum PersistedFileContent { Content(File), NotFound, @@ -2081,7 +2084,7 @@ bitflags! { #[derive( Default, TraceRawVcs, - NonLocalValue, + NonLocalValue, IsTransient, DeterministicHash, Encode, Decode, @@ -2098,7 +2101,7 @@ bitflags! { /// creating a new link, we always create junction points, because symlink creation may fail if /// Windows "developer mode" is not enabled and we're running in an unprivileged environment. #[turbo_tasks::value(shared)] -#[derive(Debug, DeterministicHash)] +#[derive(Debug, DeterministicHash, IsTransient)] pub enum LinkContent { /// A valid symbolic link pointing to `target`. /// @@ -2121,7 +2124,7 @@ pub enum LinkContent { } #[turbo_tasks::value(shared)] -#[derive(Clone, DeterministicHash, PartialOrd, Ord)] +#[derive(Clone, DeterministicHash, PartialOrd, Ord, IsTransient)] pub struct File { #[turbo_tasks(debug_ignore)] content: Rope, @@ -2253,7 +2256,7 @@ impl File { } #[turbo_tasks::value(shared)] -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, IsTransient)] pub struct FileMeta { // Size of the file // len: u64, @@ -2556,7 +2559,9 @@ pub enum FileLinesContent { NotFound, } -#[derive(Hash, Clone, Debug, PartialEq, Eq, TraceRawVcs, NonLocalValue, Encode, Decode)] +#[derive( + Hash, Clone, Debug, PartialEq, Eq, TraceRawVcs, NonLocalValue, IsTransient, Encode, Decode, +)] pub enum RawDirectoryEntry { File, Directory, @@ -2565,7 +2570,9 @@ pub enum RawDirectoryEntry { Other, } -#[derive(Hash, Clone, Debug, PartialEq, Eq, TraceRawVcs, NonLocalValue, Encode, Decode)] +#[derive( + Hash, Clone, Debug, PartialEq, Eq, TraceRawVcs, NonLocalValue, IsTransient, Encode, Decode, +)] pub enum DirectoryEntry { File(FileSystemPath), Directory(FileSystemPath), @@ -2909,7 +2916,7 @@ async fn realpath_with_links(path: FileSystemPath) -> Result> /// Wrapper to convert [`anyhow::Error`] to `impl std::error::Error` for use in [`Effect::apply`]. // TODO(bgw): use a structured error type instead of anyhow for write/write_link -#[derive(TraceRawVcs, NonLocalValue)] +#[derive(TraceRawVcs, NonLocalValue, IsTransient)] pub(crate) struct AnyhowWrapper(anyhow::Error); impl fmt::Display for AnyhowWrapper { diff --git a/turbopack/crates/turbo-tasks-fs/src/rope.rs b/turbopack/crates/turbo-tasks-fs/src/rope.rs index 7745fe703eab..abe2d3ec8d2b 100644 --- a/turbopack/crates/turbo-tasks-fs/src/rope.rs +++ b/turbopack/crates/turbo-tasks-fs/src/rope.rs @@ -22,6 +22,7 @@ use bytes::Bytes; use futures::Stream; use tokio::io::{AsyncRead, ReadBuf}; use triomphe::Arc; +use turbo_tasks::IsTransient; use turbo_tasks_hash::{DeterministicHash, DeterministicHasher}; static EMPTY_BUF: &[u8] = &[]; @@ -43,6 +44,9 @@ pub struct Rope { data: InnerRope, } +// Contains no VCs so default impl works +impl IsTransient for Rope {} + /// An Arc container for ropes. This indirection allows for easily sharing the /// contents between Ropes (and also RopeBuilders/RopeReaders). #[derive(Clone, Debug)] diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/task_input.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/task_input.rs index b067e98ce5a0..3f77913103d1 100644 --- a/turbopack/crates/turbo-tasks-macros-tests/tests/task_input.rs +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/task_input.rs @@ -1,16 +1,18 @@ -//! Tests for the `#[derive(TaskInput)]` macro are in `turbo_tasks` itself. +//! Tests for the `#[derive(TaskInput, IsTransient)]` macro are in `turbo_tasks` itself. //! However, we keep one test here as an integration test between the derive //! macro and the `#[turbo_tasks::function]` macro. #![allow(clippy::needless_return)] // tokio macro-generated code doesn't respect this use anyhow::Result; use bincode::{Decode, Encode}; -use turbo_tasks::{Completion, ReadRef, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{Completion, IsTransient, ReadRef, TaskInput, Vc, trace::TraceRawVcs}; use turbo_tasks_testing::{Registration, register, run_once}; static REGISTRATION: Registration = register!(); -#[derive(Clone, TaskInput, Debug, PartialEq, Eq, Hash, Encode, Decode, TraceRawVcs)] +#[derive( + Clone, TaskInput, IsTransient, Debug, PartialEq, Eq, Hash, Encode, Decode, TraceRawVcs, +)] struct OneUnnamedField(u32); #[turbo_tasks::function] diff --git a/turbopack/crates/turbo-tasks-macros/src/derive/is_transient_macro.rs b/turbopack/crates/turbo-tasks-macros/src/derive/is_transient_macro.rs new file mode 100644 index 000000000000..bbd21bc41330 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/derive/is_transient_macro.rs @@ -0,0 +1,67 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{DeriveInput, parse_macro_input}; + +use crate::{ + derive::check_supported_generics, + expand::{generate_exhaustive_destructuring, match_expansion}, +}; + +pub fn derive_is_transient(input: TokenStream) -> TokenStream { + let derive_input = parse_macro_input!(input as DeriveInput); + let ident = &derive_input.ident; + let generics = &derive_input.generics; + + check_supported_generics(generics, "IsTransient"); + + let is_transient_impl = match_expansion( + &derive_input, + &|_ident, fields| { + let (capture, fields) = generate_exhaustive_destructuring(fields.named.iter()); + ( + capture, + quote! { + {#( + turbo_tasks::IsTransient::is_transient(#fields) || + )* false} + }, + ) + }, + &|_ident, fields| { + let (capture, fields) = generate_exhaustive_destructuring(fields.unnamed.iter()); + ( + capture, + quote! { + {#( + turbo_tasks::IsTransient::is_transient(#fields) || + )* false} + }, + ) + }, + &|_ident| quote! {false}, + ); + + let generic_params: Vec<_> = generics + .params + .iter() + .filter_map(|param| match param { + syn::GenericParam::Type(param) => Some(param), + _ => None, + }) + .collect(); + + quote! { + #[automatically_derived] + impl #generics turbo_tasks::IsTransient for #ident #generics + where + #(#generic_params: turbo_tasks::IsTransient,)* + { + #[allow(non_snake_case)] + #[allow(unreachable_code)] // can occur for enums with no variants + fn is_transient(&self) -> bool { + #is_transient_impl + } + } + } + .into() +} diff --git a/turbopack/crates/turbo-tasks-macros/src/derive/mod.rs b/turbopack/crates/turbo-tasks-macros/src/derive/mod.rs index cbb654ab5000..1a75a2e2ce9b 100644 --- a/turbopack/crates/turbo-tasks-macros/src/derive/mod.rs +++ b/turbopack/crates/turbo-tasks-macros/src/derive/mod.rs @@ -1,4 +1,5 @@ mod deterministic_hash_macro; +mod is_transient_macro; mod non_local_value_macro; mod operation_value_macro; mod task_input_macro; @@ -9,6 +10,7 @@ mod value_debug_macro; pub(crate) mod value_to_string_macro; pub use deterministic_hash_macro::derive_deterministic_hash; +pub use is_transient_macro::derive_is_transient; pub use non_local_value_macro::derive_non_local_value; pub use operation_value_macro::derive_operation_value; use syn::{Attribute, Meta, Token, punctuated::Punctuated, spanned::Spanned}; @@ -18,6 +20,58 @@ pub use trace_raw_vcs_macro::derive_trace_raw_vcs; pub use value_debug_format_macro::derive_value_debug_format; pub use value_debug_macro::derive_value_debug; +/// Emits compile errors for unsupported generic parameter shapes shared by the `TaskInput` and +/// `IsTransient` derives. Both derives need plain type parameters with no bounds (the impl will +/// add the trait bound itself) and no lifetimes or const generics. +/// +/// `derive_name` is the human-readable derive name used in error messages ("TaskInput", +/// "IsTransient", etc.). +pub(crate) fn check_supported_generics(generics: &syn::Generics, derive_name: &str) { + if let Some(where_clause) = &generics.where_clause { + where_clause + .span() + .unwrap() + .error(format!( + "the {derive_name} derive macro does not support where clauses yet" + )) + .emit(); + } + for param in &generics.params { + match param { + syn::GenericParam::Type(param) => { + if !param.bounds.is_empty() { + param + .span() + .unwrap() + .error(format!( + "the {derive_name} derive macro does not support generic parameters \ + bounds yet" + )) + .emit(); + } + } + syn::GenericParam::Lifetime(param) => { + param + .span() + .unwrap() + .error(format!( + "the {derive_name} derive macro does not support generic lifetimes" + )) + .emit(); + } + syn::GenericParam::Const(param) => { + param + .span() + .unwrap() + .error(format!( + "the {derive_name} derive macro does not support const generics yet" + )) + .emit(); + } + } + } +} + struct FieldAttributes { trace_ignore: bool, debug_ignore: bool, diff --git a/turbopack/crates/turbo-tasks-macros/src/derive/task_input_macro.rs b/turbopack/crates/turbo-tasks-macros/src/derive/task_input_macro.rs index bba2261e051d..70a6615722ee 100644 --- a/turbopack/crates/turbo-tasks-macros/src/derive/task_input_macro.rs +++ b/turbopack/crates/turbo-tasks-macros/src/derive/task_input_macro.rs @@ -1,56 +1,18 @@ use proc_macro::TokenStream; use quote::quote; -use syn::{DeriveInput, parse_macro_input, spanned::Spanned}; +use syn::{DeriveInput, parse_macro_input}; -use crate::expand::{generate_exhaustive_destructuring, match_expansion}; +use crate::{ + derive::check_supported_generics, + expand::{generate_exhaustive_destructuring, match_expansion}, +}; pub fn derive_task_input(input: TokenStream) -> TokenStream { let derive_input = parse_macro_input!(input as DeriveInput); let ident = &derive_input.ident; let generics = &derive_input.generics; - if let Some(where_clause) = &generics.where_clause { - // NOTE(alexkirsz) We could support where clauses and generic parameters bounds - // in the future, but for simplicity's sake, we don't support them yet. - where_clause - .span() - .unwrap() - .error("the TaskInput derive macro does not support where clauses yet") - .emit(); - } - - for param in &generics.params { - match param { - syn::GenericParam::Type(param) => { - if !param.bounds.is_empty() { - // NOTE(alexkirsz) See where clause above. - param - .span() - .unwrap() - .error( - "the TaskInput derive macro does not support generic parameters \ - bounds yet", - ) - .emit(); - } - } - syn::GenericParam::Lifetime(param) => { - param - .span() - .unwrap() - .error("the TaskInput derive macro does not support generic lifetimes") - .emit(); - } - syn::GenericParam::Const(param) => { - // NOTE(alexkirsz) Ditto: not supported yet for simplicity's sake. - param - .span() - .unwrap() - .error("the TaskInput derive macro does not support const generics yet") - .emit(); - } - } - } + check_supported_generics(generics, "TaskInput"); let is_resolved_impl = match_expansion( &derive_input, @@ -78,32 +40,6 @@ pub fn derive_task_input(input: TokenStream) -> TokenStream { }, &|_ident| quote! {true}, ); - let is_transient_impl = match_expansion( - &derive_input, - &|_ident, fields| { - let (capture, fields) = generate_exhaustive_destructuring(fields.named.iter()); - ( - capture, - quote! { - {#( - turbo_tasks::TaskInput::is_transient(#fields) || - )* false} - }, - ) - }, - &|_ident, fields| { - let (capture, fields) = generate_exhaustive_destructuring(fields.unnamed.iter()); - ( - capture, - quote! { - {#( - turbo_tasks::TaskInput::is_transient(#fields) || - )* false} - }, - ) - }, - &|_ident| quote! {false}, - ); let resolve_impl = match_expansion( &derive_input, &|ident, fields| { @@ -162,12 +98,6 @@ pub fn derive_task_input(input: TokenStream) -> TokenStream { #is_resolved_impl } - #[allow(non_snake_case)] - #[allow(unreachable_code)] // This can occur for enums with no variants. - fn is_transient(&self) -> bool { - #is_transient_impl - } - #[allow(non_snake_case)] #[allow(unreachable_code)] // This can occur for enums with no variants. #[allow(clippy::manual_async_fn)] // some impls need the manual return type to work :( diff --git a/turbopack/crates/turbo-tasks-macros/src/lib.rs b/turbopack/crates/turbo-tasks-macros/src/lib.rs index e5ec3eff0ae0..e0ad86c86695 100644 --- a/turbopack/crates/turbo-tasks-macros/src/lib.rs +++ b/turbopack/crates/turbo-tasks-macros/src/lib.rs @@ -57,6 +57,11 @@ pub fn derive_task_input(input: TokenStream) -> TokenStream { derive::derive_task_input(input) } +#[proc_macro_derive(IsTransient, attributes(turbo_tasks))] +pub fn derive_is_transient(input: TokenStream) -> TokenStream { + derive::derive_is_transient(input) +} + /// Derive macro for `ValueToString`. Also generates `ValueToStringify for &T`. #[doc = include_str!("../../turbo-tasks/FORMATTING.md")] #[proc_macro_derive(ValueToString, attributes(value_to_string))] diff --git a/turbopack/crates/turbo-tasks-macros/src/value_macro.rs b/turbopack/crates/turbo-tasks-macros/src/value_macro.rs index 306110994faa..b9b2cee5281e 100644 --- a/turbopack/crates/turbo-tasks-macros/src/value_macro.rs +++ b/turbopack/crates/turbo-tasks-macros/src/value_macro.rs @@ -133,6 +133,11 @@ struct ValueArguments { transparent: bool, /// Should we `#[derive(turbo_tasks::OperationValue)]`? operation: Option, + /// Set by `task_input` arg: emit an `impl TaskInput` and derive `IsTransient`. Opt-in + /// because the vast majority of `#[turbo_tasks::value]` types are output-only and don't + /// satisfy `TaskInput`'s supertrait bounds (`Clone + Eq + Hash + Encode + Decode + ...`). + /// Add this flag to types intended to be passed as `#[turbo_tasks::function]` arguments. + task_input: bool, } impl Parse for ValueArguments { @@ -146,6 +151,7 @@ impl Parse for ValueArguments { manual_hash: false, transparent: false, operation: None, + task_input: false, }; let punctuated = input.parse_terminated(Meta::parse, Token![,])?; for meta in punctuated { @@ -234,13 +240,16 @@ impl Parse for ValueArguments { ("operation", Meta::Path(path)) => { result.operation = Some(path.span()); } + ("task_input", Meta::Path(_)) => { + result.task_input = true; + } (_, meta) => { return Err(Error::new_spanned( &meta, format!( "unexpected {meta:?}, expected \"shared\", \"into\", \ \"serialization\", \"evict\", \"cell\", \"eq\", \"hash\", \ - \"transparent\", or \"operation\"" + \"transparent\", \"operation\", or \"task_input\"" ), )); } @@ -262,6 +271,7 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream { manual_hash, transparent, operation, + task_input, } = parse_macro_input!(args as ValueArguments); // `serialization = "hash"` only makes sense with `cell = "compare"` (the default). @@ -305,11 +315,24 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream { .into(); } + // Opt in to the `TaskInput` impl + `IsTransient` derive with `task_input`. The vast + // majority of `#[turbo_tasks::value]` types are output-only (cell contents produced by + // tasks, never passed as task arguments) and either can't satisfy `TaskInput`'s supertrait + // bounds or simply have no need to. Only types intended for use as + // `#[turbo_tasks::function]` arguments add `task_input` here, at which point the macro + // emits an `impl TaskInput` (using the trait defaults — `is_resolved = true` and + // `resolve_input` returns a `CloneReady` future) and adds `IsTransient` to the derive list. + let derives_for_task_input = if task_input { + quote! { , turbo_tasks::IsTransient } + } else { + quote! {} + }; let mut struct_attributes = vec![quote! { #[derive( turbo_tasks::ShrinkToFit, turbo_tasks::trace::TraceRawVcs, - turbo_tasks::NonLocalValue, + turbo_tasks::NonLocalValue + #derives_for_task_input )] #[shrink_to_fit(crate = "turbo_tasks::macro_helpers::shrink_to_fit")] }]; @@ -550,6 +573,19 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream { has_serialization, ); + // Emit an `impl TaskInput for X {}` only when opted in with + // `#[turbo_tasks::value(task_input)]`. The impl uses all trait defaults: `is_resolved = + // true` (correct because `NonLocalValue` guarantees no unresolved Vcs) and `resolve_input` + // returning a `CloneReady` future (8 bytes, no async-fn envelope). + let task_input_impl = if task_input { + quote! { + #[automatically_derived] + impl turbo_tasks::TaskInput for #ident {} + } + } else { + quote! {} + }; + let expanded = quote! { #(#struct_attributes)* #item @@ -558,6 +594,8 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream { #cell_struct } + #task_input_impl + #value_type_and_register_code #value_debug_impl diff --git a/turbopack/crates/turbo-tasks/Cargo.toml b/turbopack/crates/turbo-tasks/Cargo.toml index 619576daf694..f81604f69f8f 100644 --- a/turbopack/crates/turbo-tasks/Cargo.toml +++ b/turbopack/crates/turbo-tasks/Cargo.toml @@ -58,6 +58,7 @@ turbo-tasks-hash = { workspace = true } turbo-tasks-macros = { workspace = true } turbo-tasks-malloc = { workspace = true } unsize = { workspace = true } +mime = { workspace = true } [dev-dependencies] criterion = { workspace = true, features = ["async_tokio"] } diff --git a/turbopack/crates/turbo-tasks/src/lib.rs b/turbopack/crates/turbo-tasks/src/lib.rs index 4bbef82bef5d..e41d33639e48 100644 --- a/turbopack/crates/turbo-tasks/src/lib.rs +++ b/turbopack/crates/turbo-tasks/src/lib.rs @@ -105,8 +105,8 @@ pub use crate::{ spawn::{JoinHandle, block_for_future, block_in_place, spawn, spawn_blocking, spawn_thread}, state::{State, parking_lot_mutex_bincode}, task::{ - SharedReference, TypedSharedReference, - task_input::{EitherTaskInput, TaskInput}, + IsTransient, SharedReference, TypedSharedReference, + task_input::{CloneReady, EitherTaskInput, TaskInput}, }, task_execution_reason::TaskExecutionReason, tiny_vec::TinyVec, @@ -395,6 +395,9 @@ pub use turbo_tasks_macros::task_storage; #[rustfmt::skip] pub use turbo_tasks_macros::TaskInput; +/// Derive macro that emits a field-walking [`IsTransient`] impl. +pub use turbo_tasks_macros::IsTransient; + pub type TaskIdSet = AutoSet, 2>; pub mod test_helpers { diff --git a/turbopack/crates/turbo-tasks/src/task/is_transient.rs b/turbopack/crates/turbo-tasks/src/task/is_transient.rs new file mode 100644 index 000000000000..dd0706033631 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/task/is_transient.rs @@ -0,0 +1,300 @@ +//! The [`IsTransient`] trait and its implementations for common types. +//! +//! Split out from [`TaskInput`][crate::TaskInput] so the same "does this value transitively +//! reference a transient task?" question can be answered without committing to the full +//! `TaskInput` interface. This lets [`NonLocalValue`][crate::NonLocalValue] types use the +//! blanket [`TaskInput`][crate::TaskInput] impl without each one having to re-implement +//! `is_transient` through `TaskInput`'s now-empty interface. + +use std::{ + collections::{BTreeMap, BTreeSet}, + sync::{Arc, OnceLock}, + time::Duration, +}; + +use either::Either; +use turbo_frozenmap::{FrozenMap, FrozenSet}; +use turbo_rcstr::RcStr; +use turbo_tasks_hash::HashAlgorithm; + +use crate::{ + ReadRef, ResolvedVc, TaskId, TransientInstance, TransientValue, ValueTypeId, Vc, + task::task_input::EitherTaskInput, vc::OperationVc, +}; + +/// Returns whether a value transitively references a transient task. +/// +/// Any task whose inputs include a transient value becomes transient itself: it's not cached +/// persistently and is dropped when the surrounding [`run_once`][crate::run_once] scope ends. +/// +/// The default impl returns `false`, which is correct for leaf types containing no +/// [`Vc`]/[`ResolvedVc`]/[`OperationVc`]. The `#[derive(IsTransient)]` macro emits a +/// field-walking implementation; container impls below delegate to their element types. +pub trait IsTransient { + fn is_transient(&self) -> bool { + false + } +} + +// ---- Leaf types (no Vc, never transient) ---- + +macro_rules! impl_is_transient_leaf { + ($($t:ty),* $(,)?) => { + $( + impl IsTransient for $t {} + )* + }; +} + +impl_is_transient_leaf! { + (), bool, char, + u8, u16, u32, u64, u128, usize, + i8, i16, i32, i64, i128, isize, + f32, f64, + String, RcStr, Duration, HashAlgorithm, + TaskId, ValueTypeId, + std::path::PathBuf, std::path::Path, + anyhow::Error, + mime::Mime, +} + +// ---- Vc-shaped types: defer to RawVc's transient bit ---- + +impl IsTransient for Vc { + fn is_transient(&self) -> bool { + self.node.is_transient() + } +} + +impl IsTransient for ResolvedVc { + fn is_transient(&self) -> bool { + self.node.node.is_transient() + } +} + +impl IsTransient for OperationVc { + fn is_transient(&self) -> bool { + // OperationVc.node: Vc, Vc.node: RawVc + self.node.node.is_transient() + } +} + +// ---- Transient-by-construction wrappers ---- + +impl IsTransient for TransientValue { + fn is_transient(&self) -> bool { + true + } +} + +impl IsTransient for TransientInstance { + fn is_transient(&self) -> bool { + true + } +} + +// ---- Container types: any-of recursion ---- + +impl IsTransient for Vec { + fn is_transient(&self) -> bool { + self.iter().any(IsTransient::is_transient) + } +} + +impl IsTransient for Box { + fn is_transient(&self) -> bool { + (**self).is_transient() + } +} + +impl IsTransient for Arc { + fn is_transient(&self) -> bool { + (**self).is_transient() + } +} + +impl IsTransient for OnceLock { + fn is_transient(&self) -> bool { + self.get().is_some_and(IsTransient::is_transient) + } +} + +impl IsTransient for std::result::Result { + fn is_transient(&self) -> bool { + match self { + Ok(t) => t.is_transient(), + Err(e) => e.is_transient(), + } + } +} + +impl IsTransient for std::sync::Mutex { + fn is_transient(&self) -> bool { + match self.lock() { + Ok(guard) => guard.is_transient(), + Err(_) => false, + } + } +} + +impl IsTransient for parking_lot::Mutex { + fn is_transient(&self) -> bool { + self.lock().is_transient() + } +} + +impl IsTransient for Option { + fn is_transient(&self) -> bool { + match self { + Some(value) => value.is_transient(), + None => false, + } + } +} + +impl IsTransient for BTreeSet { + fn is_transient(&self) -> bool { + self.iter().any(IsTransient::is_transient) + } +} + +impl IsTransient for BTreeMap { + fn is_transient(&self) -> bool { + self.iter() + .any(|(k, v)| k.is_transient() || v.is_transient()) + } +} + +// Hash/index containers used by `#[turbo_tasks::value]` types. Mirror the set the +// `impl_auto_marker_trait!` macro covers for `NonLocalValue`, since any field that can be +// `NonLocalValue` should also be checkable for transience. +impl IsTransient for std::collections::HashSet { + fn is_transient(&self) -> bool { + self.iter().any(IsTransient::is_transient) + } +} + +impl IsTransient for std::collections::HashMap { + fn is_transient(&self) -> bool { + self.iter() + .any(|(k, v)| k.is_transient() || v.is_transient()) + } +} + +impl IsTransient for indexmap::IndexSet { + fn is_transient(&self) -> bool { + self.iter().any(IsTransient::is_transient) + } +} + +impl IsTransient for indexmap::IndexMap { + fn is_transient(&self) -> bool { + self.iter() + .any(|(k, v)| k.is_transient() || v.is_transient()) + } +} + +impl IsTransient for auto_hash_map::AutoSet { + fn is_transient(&self) -> bool { + self.iter().any(IsTransient::is_transient) + } +} + +impl IsTransient + for auto_hash_map::AutoMap +{ + fn is_transient(&self) -> bool { + self.iter() + .any(|(k, v)| k.is_transient() || v.is_transient()) + } +} + +impl IsTransient for smallvec::SmallVec<[T; N]> { + fn is_transient(&self) -> bool { + self.iter().any(IsTransient::is_transient) + } +} + +impl IsTransient for [T; N] { + fn is_transient(&self) -> bool { + self.iter().any(IsTransient::is_transient) + } +} + +impl IsTransient for [T] { + fn is_transient(&self) -> bool { + self.iter().any(IsTransient::is_transient) + } +} + +impl IsTransient for &T { + fn is_transient(&self) -> bool { + (**self).is_transient() + } +} + +impl IsTransient for std::borrow::Cow<'_, B> { + fn is_transient(&self) -> bool { + (**self).is_transient() + } +} + +impl IsTransient for std::marker::PhantomData {} + +impl IsTransient for FrozenSet { + fn is_transient(&self) -> bool { + self.iter().any(IsTransient::is_transient) + } +} + +impl IsTransient for FrozenMap { + fn is_transient(&self) -> bool { + self.iter() + .any(|(k, v)| k.is_transient() || v.is_transient()) + } +} + +// ReadRef wraps a value whose raw form may contain Vc; check via as_raw_ref. The bound mirrors +// the existing `TaskInput for ReadRef` shape — `as_raw_ref` returns a `&T`, so `T: IsTransient` +// is needed for method resolution. +impl IsTransient for ReadRef { + fn is_transient(&self) -> bool { + Self::as_raw_ref(self).is_transient() + } +} + +impl IsTransient for EitherTaskInput { + fn is_transient(&self) -> bool { + match self.as_ref() { + Either::Left(l) => l.is_transient(), + Either::Right(r) => r.is_transient(), + } + } +} + +// ---- Tuple impls (1..=12) ---- + +macro_rules! impl_is_transient_tuple { + ( $( $name:ident )+ ) => { + impl<$($name: IsTransient),+> IsTransient for ($($name,)+) { + #[allow(non_snake_case)] + fn is_transient(&self) -> bool { + let ($($name,)+) = self; + $($name.is_transient() ||)+ false + } + } + }; +} + +impl_is_transient_tuple! { A } +impl_is_transient_tuple! { A B } +impl_is_transient_tuple! { A B C } +impl_is_transient_tuple! { A B C D } +impl_is_transient_tuple! { A B C D E } +impl_is_transient_tuple! { A B C D E F } +impl_is_transient_tuple! { A B C D E F G } +impl_is_transient_tuple! { A B C D E F G H } +impl_is_transient_tuple! { A B C D E F G H I } +impl_is_transient_tuple! { A B C D E F G H I J } +impl_is_transient_tuple! { A B C D E F G H I J K } +impl_is_transient_tuple! { A B C D E F G H I J K L } diff --git a/turbopack/crates/turbo-tasks/src/task/mod.rs b/turbopack/crates/turbo-tasks/src/task/mod.rs index 2d9f74ec9cde..752fab5c3e28 100644 --- a/turbopack/crates/turbo-tasks/src/task/mod.rs +++ b/turbopack/crates/turbo-tasks/src/task/mod.rs @@ -1,5 +1,6 @@ mod from_task_input; pub(crate) mod function; +pub(crate) mod is_transient; pub mod local_task; pub(crate) mod shared_reference; pub(crate) mod task_input; @@ -7,6 +8,7 @@ pub(crate) mod task_output; pub use from_task_input::FromTaskInput; pub use function::{TaskFn, TaskFnInputs}; +pub use is_transient::IsTransient; pub use shared_reference::{SharedReference, TypedSharedReference}; pub use task_input::TaskInput; pub use task_output::TaskOutput; diff --git a/turbopack/crates/turbo-tasks/src/task/task_input.rs b/turbopack/crates/turbo-tasks/src/task/task_input.rs index 2789250a0cb9..be134c7f3307 100644 --- a/turbopack/crates/turbo-tasks/src/task/task_input.rs +++ b/turbopack/crates/turbo-tasks/src/task/task_input.rs @@ -4,7 +4,9 @@ use std::{ future::Future, hash::Hash, ops::{Deref, DerefMut}, + pin::Pin, sync::Arc, + task::{Context, Poll}, time::Duration, }; @@ -22,12 +24,42 @@ use turbo_tasks_hash::HashAlgorithm; // This import is necessary for derive macros to work, as their expansion refers to the crate // name directly. -use crate::{self as turbo_tasks, ReadRef}; +use crate::{self as turbo_tasks, IsTransient, ReadRef}; use crate::{ DynTaskInputs, ResolvedVc, TaskId, TransientInstance, TransientValue, ValueTypeId, Vc, trace::TraceRawVcs, }; +/// An 8-byte hand-rolled [`Future`] that immediately resolves to `Ok(self.clone())` of the +/// referenced value. +/// +/// Emitted by the [`TaskInput`] derive macro for types annotated with +/// `#[turbo_tasks(already_resolved)]` to replace what would otherwise be a generated async +/// block with embedded `.await?` calls. As a child `__awaitee` in a caller's coroutine, this +/// occupies only `size_of::<&T>() = 8` bytes (no enum discriminant, no captured cloned state) +/// regardless of `T`'s size. +/// +/// This is internal to the derive macro and not intended to be named directly by users. +#[doc(hidden)] +pub struct CloneReady<'a, T> { + pub inner: Option<&'a T>, +} + +impl<'a, T: Clone> Future for CloneReady<'a, T> { + type Output = Result; + + fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { + Poll::Ready(Ok(self + .inner + .take() + .expect("future already polled") + .clone())) + } +} + +// `CloneReady` holds only a shared reference; it has no self-referential state. +impl<'a, T> Unpin for CloneReady<'a, T> {} + /// Trait to implement in order for a type to be accepted as a /// [`#[turbo_tasks::function]`][crate::function] argument. /// @@ -65,7 +97,7 @@ use crate::{ /// Structs or enums can be made into task inputs by deriving `TaskInput`: /// /// ```rust -/// #[derive(TaskInput)] +/// #[derive(TaskInput, IsTransient)] /// struct MyStruct { /// // Fields go here... /// } @@ -81,13 +113,28 @@ use crate::{ /// space. If an [`Arc`] points to a large type, consider wrapping that type in [`Vc`], so that only /// one copy of the value will be serialized. pub trait TaskInput: - Send + Sync + Clone + Debug + PartialEq + Eq + Hash + TraceRawVcs + Encode + Decode<()> + Send + + Sync + + Clone + + Debug + + PartialEq + + Eq + + Hash + + TraceRawVcs + + Encode + + Decode<()> + + IsTransient { /// This method should resolve any [`Vc`]s nested inside of this object, cloning the object in /// the process. If the input is unresolved ([`TaskInput::is_resolved`]) a "local" resolution /// task is created that runs this method. + /// + /// The default returns a [`CloneReady`] future — an 8-byte named future that holds only + /// `&Self` and returns `Ok(self.clone())` on first poll. This is structurally equivalent to + /// an `async { Ok(self.clone()) }` block but produces a smaller, named child `__awaitee` in + /// caller coroutines (no enum discriminant). fn resolve_input(&self) -> impl Future> + Send + '_ { - async { Ok(self.clone()) } + CloneReady { inner: Some(self) } } /// This should return `true` if there are any unresolved [`Vc`]s in the type. @@ -104,27 +151,12 @@ pub trait TaskInput: fn is_resolved(&self) -> bool { true } - - /// This should return true if this object contains a [`Vc`] (or any subtype of [`Vc`]) pointing - /// to a cell owned by a transient task. - /// - /// Any function called with a transient `TaskInput` will be transient. Any [`Vc`] constructed - /// in a transient task or in a top-level [`run_once`][crate::run_once] closure will be - /// transient. - /// - /// Internally, a [`Vc`] can be determined to be transient by comparing the owning task's id - /// with the [`TRANSIENT_TASK_BIT`][crate::TRANSIENT_TASK_BIT] mask. - fn is_transient(&self) -> bool; } macro_rules! impl_task_input { ($($t:ty),*) => { $( - impl TaskInput for $t { - fn is_transient(&self) -> bool { - false - } - } + impl TaskInput for $t {} )* }; } @@ -154,10 +186,6 @@ where self.iter().all(TaskInput::is_resolved) } - fn is_transient(&self) -> bool { - self.iter().any(TaskInput::is_transient) - } - async fn resolve_input(&self) -> Result { let mut resolved = Vec::with_capacity(self.len()); for value in self { @@ -175,10 +203,6 @@ where self.as_ref().is_resolved() } - fn is_transient(&self) -> bool { - self.as_ref().is_transient() - } - async fn resolve_input(&self) -> Result { Ok(Box::new(Box::pin(self.as_ref().resolve_input()).await?)) } @@ -192,10 +216,6 @@ where self.as_ref().is_resolved() } - fn is_transient(&self) -> bool { - self.as_ref().is_transient() - } - async fn resolve_input(&self) -> Result { Ok(Arc::new(Box::pin(self.as_ref().resolve_input()).await?)) } @@ -209,10 +229,6 @@ where Self::as_raw_ref(self).is_resolved() } - fn is_transient(&self) -> bool { - Self::as_raw_ref(self).is_transient() - } - async fn resolve_input(&self) -> Result { Ok(ReadRef::new_owned( Box::pin(Self::as_raw_ref(self).resolve_input()).await?, @@ -231,13 +247,6 @@ where } } - fn is_transient(&self) -> bool { - match self { - Some(value) => value.is_transient(), - None => false, - } - } - async fn resolve_input(&self) -> Result { match self { Some(value) => Ok(Some(value.resolve_input().await?)), @@ -254,10 +263,6 @@ where Vc::is_resolved(*self) } - fn is_transient(&self) -> bool { - self.node.is_transient() - } - fn resolve_input(&self) -> impl Future> + Send + '_ { // It isn't ideal to use this function but it exactly matches this usecase (resolved but // still a Vc) @@ -274,19 +279,11 @@ where fn is_resolved(&self) -> bool { true } - - fn is_transient(&self) -> bool { - self.node.is_transient() - } } -impl TaskInput for TransientValue -where - T: DynTaskInputs + Clone + Debug + Hash + Eq + TraceRawVcs + 'static, +impl TaskInput for TransientValue where + T: DynTaskInputs + Clone + Debug + Hash + Eq + TraceRawVcs + 'static { - fn is_transient(&self) -> bool { - true - } } impl Encode for TransientValue { @@ -301,14 +298,7 @@ impl Decode for TransientValue { } } -impl TaskInput for TransientInstance -where - T: Sync + Send + TraceRawVcs + 'static, -{ - fn is_transient(&self) -> bool { - true - } -} +impl TaskInput for TransientInstance where T: Sync + Send + TraceRawVcs + 'static {} impl Encode for TransientInstance { fn encode(&self, _encoder: &mut E) -> Result<(), EncodeError> { @@ -342,11 +332,6 @@ where self.iter() .all(|(k, v)| TaskInput::is_resolved(k) && TaskInput::is_resolved(v)) } - - fn is_transient(&self) -> bool { - self.iter() - .any(|(k, v)| TaskInput::is_transient(k) || TaskInput::is_transient(v)) - } } impl TaskInput for BTreeSet @@ -364,10 +349,6 @@ where fn is_resolved(&self) -> bool { self.iter().all(TaskInput::is_resolved) } - - fn is_transient(&self) -> bool { - self.iter().any(TaskInput::is_transient) - } } impl TaskInput for FrozenMap @@ -391,11 +372,6 @@ where self.iter() .all(|(k, v)| TaskInput::is_resolved(k) && TaskInput::is_resolved(v)) } - - fn is_transient(&self) -> bool { - self.iter() - .any(|(k, v)| TaskInput::is_transient(k) || TaskInput::is_transient(v)) - } } impl TaskInput for FrozenSet @@ -413,10 +389,6 @@ where fn is_resolved(&self) -> bool { self.iter().all(TaskInput::is_resolved) } - - fn is_transient(&self) -> bool { - self.iter().any(TaskInput::is_transient) - } } /// A thin wrapper around [`Either`] that implements the traits required by [`TaskInput`], notably @@ -474,11 +446,6 @@ where self.as_ref() .either(TaskInput::is_resolved, TaskInput::is_resolved) } - - fn is_transient(&self) -> bool { - self.as_ref() - .either(TaskInput::is_transient, TaskInput::is_transient) - } } macro_rules! tuple_impls { @@ -492,12 +459,6 @@ macro_rules! tuple_impls { $($name.is_resolved() &&)+ true } - #[allow(non_snake_case)] - fn is_transient(&self) -> bool { - let ($($name,)+) = self; - $($name.is_transient() ||)+ false - } - #[allow(non_snake_case)] async fn resolve_input(&self) -> Result { let ($($name,)+) = self; @@ -536,7 +497,9 @@ mod tests { #[test] fn test_no_fields() -> Result<()> { - #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs)] + #[derive( + Clone, TaskInput, IsTransient, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs, + )] struct NoFields; assert_task_input(NoFields); @@ -545,7 +508,9 @@ mod tests { #[test] fn test_one_unnamed_field() -> Result<()> { - #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs)] + #[derive( + Clone, TaskInput, IsTransient, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs, + )] struct OneUnnamedField(u32); assert_task_input(OneUnnamedField(42)); @@ -554,7 +519,9 @@ mod tests { #[test] fn test_multiple_unnamed_fields() -> Result<()> { - #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs)] + #[derive( + Clone, TaskInput, IsTransient, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs, + )] struct MultipleUnnamedFields(u32, RcStr); assert_task_input(MultipleUnnamedFields(42, rcstr!("42"))); @@ -563,7 +530,9 @@ mod tests { #[test] fn test_one_named_field() -> Result<()> { - #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs)] + #[derive( + Clone, TaskInput, IsTransient, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs, + )] struct OneNamedField { named: u32, } @@ -574,7 +543,9 @@ mod tests { #[test] fn test_multiple_named_fields() -> Result<()> { - #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs)] + #[derive( + Clone, TaskInput, IsTransient, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs, + )] struct MultipleNamedFields { named: u32, other: RcStr, @@ -589,7 +560,9 @@ mod tests { #[test] fn test_generic_field() -> Result<()> { - #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs)] + #[derive( + Clone, TaskInput, IsTransient, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs, + )] struct GenericField(T); assert_task_input(GenericField(42)); @@ -597,7 +570,9 @@ mod tests { Ok(()) } - #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs)] + #[derive( + Clone, TaskInput, IsTransient, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs, + )] enum OneVariant { Variant, } @@ -610,7 +585,9 @@ mod tests { #[test] fn test_multiple_variants() -> Result<()> { - #[derive(Clone, TaskInput, PartialEq, Eq, Hash, Debug, Encode, Decode, TraceRawVcs)] + #[derive( + Clone, TaskInput, IsTransient, PartialEq, Eq, Hash, Debug, Encode, Decode, TraceRawVcs, + )] enum MultipleVariants { Variant1, Variant2, @@ -620,7 +597,9 @@ mod tests { Ok(()) } - #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs)] + #[derive( + Clone, TaskInput, IsTransient, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs, + )] enum MultipleVariantsAndHeterogeneousFields { Variant1, Variant2(u32), @@ -640,7 +619,9 @@ mod tests { #[test] fn test_nested_variants() -> Result<()> { - #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs)] + #[derive( + Clone, TaskInput, IsTransient, Eq, PartialEq, Hash, Debug, Encode, Decode, TraceRawVcs, + )] enum NestedVariants { Variant1, Variant2(MultipleVariantsAndHeterogeneousFields), diff --git a/turbopack/crates/turbo-tasks/src/vc/operation.rs b/turbopack/crates/turbo-tasks/src/vc/operation.rs index 8a02be6fe720..9315a70a9785 100644 --- a/turbopack/crates/turbo-tasks/src/vc/operation.rs +++ b/turbopack/crates/turbo-tasks/src/vc/operation.rs @@ -230,14 +230,8 @@ where // NOTE: This uses the default implementation of `is_resolved` which returns `true` because we don't // want `OperationVc` arguments to get resolved when passed to a `#[turbo_tasks::function]`. -impl TaskInput for OperationVc -where - T: ?Sized + Send + Sync, -{ - fn is_transient(&self) -> bool { - self.node.is_transient() - } -} +// `is_transient` is provided via the `IsTransient` supertrait impl in `task/is_transient.rs`. +impl TaskInput for OperationVc where T: ?Sized + Send + Sync {} impl TryFrom for OperationVc where diff --git a/turbopack/crates/turbopack-browser/src/chunking_context.rs b/turbopack/crates/turbopack-browser/src/chunking_context.rs index 9ef0aeb168e5..cf49b28c6532 100644 --- a/turbopack/crates/turbopack-browser/src/chunking_context.rs +++ b/turbopack/crates/turbopack-browser/src/chunking_context.rs @@ -1,7 +1,7 @@ use anyhow::{Context, Result, bail}; use tracing::Instrument; use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::{FxIndexMap, ResolvedVc, TaskInput, TryJoinIterExt, Upcast, ValueToString, Vc}; +use turbo_tasks::{FxIndexMap, ResolvedVc, TryJoinIterExt, Upcast, ValueToString, Vc}; use turbo_tasks_fs::FileSystemPath; use turbo_tasks_hash::HashAlgorithm; use turbopack_core::{ @@ -40,7 +40,7 @@ use crate::ecmascript::{ }; #[turbo_tasks::value] -#[derive(Debug, Clone, Copy, Hash, TaskInput)] +#[derive(Debug, Clone, Copy, Hash)] pub enum CurrentChunkMethod { StringLiteral, DocumentCurrentScript, diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/list/asset.rs b/turbopack/crates/turbopack-browser/src/ecmascript/list/asset.rs index 05377b56a88a..1911afff4899 100644 --- a/turbopack/crates/turbopack-browser/src/ecmascript/list/asset.rs +++ b/turbopack/crates/turbopack-browser/src/ecmascript/list/asset.rs @@ -2,7 +2,9 @@ use anyhow::Result; use bincode::{Decode, Encode}; use serde::{Deserialize, Serialize}; use turbo_rcstr::rcstr; -use turbo_tasks::{NonLocalValue, ResolvedVc, TaskInput, ValueToString, Vc, trace::TraceRawVcs}; +use turbo_tasks::{ + IsTransient, NonLocalValue, ResolvedVc, TaskInput, ValueToString, Vc, trace::TraceRawVcs, +}; use turbo_tasks_fs::FileSystemPath; use turbopack_core::{ asset::{Asset, AssetContent}, @@ -122,6 +124,7 @@ impl Asset for EcmascriptDevChunkList { Copy, Hash, TaskInput, + IsTransient, NonLocalValue, TraceRawVcs, Serialize, diff --git a/turbopack/crates/turbopack-cli/src/arguments.rs b/turbopack/crates/turbopack-cli/src/arguments.rs index c8a094853f36..9ac0b492033f 100644 --- a/turbopack/crates/turbopack-cli/src/arguments.rs +++ b/turbopack/crates/turbopack-cli/src/arguments.rs @@ -7,7 +7,7 @@ use std::{ use anyhow::anyhow; use bincode::{Decode, Encode}; use clap::{Args, Parser, ValueEnum}; -use turbo_tasks::{NonLocalValue, TaskInput, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, TaskInput, trace::TraceRawVcs}; use turbopack_core::issue::IssueSeverity; #[derive(Debug, Parser)] @@ -44,6 +44,7 @@ impl Arguments { Eq, Hash, TaskInput, + IsTransient, NonLocalValue, TraceRawVcs, Encode, diff --git a/turbopack/crates/turbopack-cli/src/util.rs b/turbopack/crates/turbopack-cli/src/util.rs index c9c87ae28d36..25715c38779a 100644 --- a/turbopack/crates/turbopack-cli/src/util.rs +++ b/turbopack/crates/turbopack-cli/src/util.rs @@ -4,11 +4,21 @@ use anyhow::{Context, Result}; use bincode::{Decode, Encode}; use dunce::canonicalize; use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::{NonLocalValue, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, TaskInput, Vc, trace::TraceRawVcs}; use turbo_tasks_fs::{DiskFileSystem, FileSystem}; #[derive( - Clone, Debug, TaskInput, Hash, PartialEq, Eq, NonLocalValue, TraceRawVcs, Encode, Decode, + Clone, + Debug, + TaskInput, + IsTransient, + Hash, + PartialEq, + Eq, + NonLocalValue, + TraceRawVcs, + Encode, + Decode, )] pub enum EntryRequest { Relative(RcStr), diff --git a/turbopack/crates/turbopack-core/src/chunk/availability_info.rs b/turbopack/crates/turbopack-core/src/chunk/availability_info.rs index 03c369bc3ccb..4676349608cc 100644 --- a/turbopack/crates/turbopack-core/src/chunk/availability_info.rs +++ b/turbopack/crates/turbopack-core/src/chunk/availability_info.rs @@ -2,19 +2,30 @@ use anyhow::Result; use bincode::{Decode, Encode}; use bitfield::bitfield; use turbo_rcstr::RcStr; -use turbo_tasks::{NonLocalValue, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; use crate::chunk::available_modules::{AvailableModules, AvailableModulesSet}; bitfield! { - #[derive(Clone, Copy, Default, TaskInput, TraceRawVcs, NonLocalValue, PartialEq, Eq, Hash, Encode, Decode)] + #[derive(Clone, Copy, Default, TaskInput, IsTransient, TraceRawVcs, NonLocalValue, PartialEq, Eq, Hash, Encode, Decode)] pub struct AvailabilityFlags(u8); impl Debug; pub is_in_async_module, set_is_in_async_module: 0; } #[derive( - Eq, PartialEq, Hash, Clone, Copy, Debug, TaskInput, TraceRawVcs, NonLocalValue, Encode, Decode, + Eq, + PartialEq, + Hash, + Clone, + Copy, + Debug, + TaskInput, + IsTransient, + TraceRawVcs, + NonLocalValue, + Encode, + Decode, )] pub struct AvailabilityInfo { flags: AvailabilityFlags, diff --git a/turbopack/crates/turbopack-core/src/chunk/available_modules.rs b/turbopack/crates/turbopack-core/src/chunk/available_modules.rs index 152f433260bd..3152fcdbe7cb 100644 --- a/turbopack/crates/turbopack-core/src/chunk/available_modules.rs +++ b/turbopack/crates/turbopack-core/src/chunk/available_modules.rs @@ -1,8 +1,8 @@ use anyhow::Result; use bincode::{Decode, Encode}; use turbo_tasks::{ - FxIndexSet, NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryJoinIterExt, ValueToString, Vc, - trace::TraceRawVcs, turbofmt, + FxIndexSet, IsTransient, NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryJoinIterExt, + ValueToString, Vc, trace::TraceRawVcs, turbofmt, }; use turbo_tasks_hash::Xxh3Hash64Hasher; @@ -13,7 +13,18 @@ use crate::{ }; #[derive( - Debug, Copy, Clone, Hash, PartialEq, Eq, TraceRawVcs, NonLocalValue, TaskInput, Encode, Decode, + Debug, + Copy, + Clone, + Hash, + PartialEq, + Eq, + TraceRawVcs, + NonLocalValue, + TaskInput, + IsTransient, + Encode, + Decode, )] pub enum AvailableModuleItem { Module(ResolvedVc>), diff --git a/turbopack/crates/turbopack-core/src/chunk/chunk_item_batch.rs b/turbopack/crates/turbopack-core/src/chunk/chunk_item_batch.rs index 119b4d18b52e..daf41f408a8d 100644 --- a/turbopack/crates/turbopack-core/src/chunk/chunk_item_batch.rs +++ b/turbopack/crates/turbopack-core/src/chunk/chunk_item_batch.rs @@ -6,8 +6,8 @@ use either::Either; use rustc_hash::FxHashMap; use smallvec::{SmallVec, smallvec}; use turbo_tasks::{ - FxIndexMap, NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryFlatJoinIterExt, TryJoinIterExt, - Vc, trace::TraceRawVcs, + FxIndexMap, IsTransient, NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryFlatJoinIterExt, + TryJoinIterExt, Vc, trace::TraceRawVcs, }; use crate::{ @@ -61,7 +61,17 @@ pub async fn attach_async_info_to_chunkable_module( } #[derive( - Debug, Clone, PartialEq, Eq, Hash, TraceRawVcs, NonLocalValue, TaskInput, Encode, Decode, + Debug, + Clone, + PartialEq, + Eq, + Hash, + TraceRawVcs, + NonLocalValue, + TaskInput, + IsTransient, + Encode, + Decode, )] pub enum ChunkItemOrBatchWithAsyncModuleInfo { ChunkItem(ChunkItemWithAsyncModuleInfo), @@ -119,7 +129,7 @@ impl ChunkItemOrBatchWithAsyncModuleInfo { } #[turbo_tasks::value] -#[derive(Debug, Clone, Hash, TaskInput)] +#[derive(Debug, Clone, Hash)] pub struct ChunkItemBatchWithAsyncModuleInfo { pub chunk_items: Vec, pub chunk_groups: Option, diff --git a/turbopack/crates/turbopack-core/src/chunk/chunking/mod.rs b/turbopack/crates/turbopack-core/src/chunk/chunking/mod.rs index 3da412942ac7..a3e4b8e5a15d 100644 --- a/turbopack/crates/turbopack-core/src/chunk/chunking/mod.rs +++ b/turbopack/crates/turbopack-core/src/chunk/chunking/mod.rs @@ -7,8 +7,8 @@ use smallvec::{SmallVec, smallvec}; use tracing::{Instrument, Level}; use turbo_rcstr::RcStr; use turbo_tasks::{ - FxIndexMap, FxIndexSet, NonLocalValue, ReadRef, ResolvedVc, TryJoinIterExt, ValueToString, Vc, - debug::ValueDebugFormat, trace::TraceRawVcs, + FxIndexMap, FxIndexSet, IsTransient, NonLocalValue, ReadRef, ResolvedVc, TryJoinIterExt, + ValueToString, Vc, debug::ValueDebugFormat, trace::TraceRawVcs, }; use crate::{ @@ -49,7 +49,9 @@ struct BatchChunkItemsWithInfo( FxHashMap>, ); -#[derive(Clone, PartialEq, Eq, TraceRawVcs, NonLocalValue, ValueDebugFormat, Encode, Decode)] +#[derive( + Clone, PartialEq, Eq, TraceRawVcs, NonLocalValue, IsTransient, ValueDebugFormat, Encode, Decode, +)] enum ChunkItemOrBatchWithInfo { ChunkItem { chunk_item: ChunkItemWithAsyncModuleInfo, diff --git a/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs b/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs index a11a7e3d1f76..53c732880447 100644 --- a/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs +++ b/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs @@ -4,7 +4,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use serde::{Deserialize, Serialize}; use turbo_rcstr::RcStr; use turbo_tasks::{ - NonLocalValue, ResolvedVc, TaskInput, Upcast, Vc, trace::TraceRawVcs, turbobail, + IsTransient, NonLocalValue, ResolvedVc, TaskInput, Upcast, Vc, trace::TraceRawVcs, turbobail, }; use turbo_tasks_fs::FileSystemPath; use turbo_tasks_hash::DeterministicHash; @@ -32,6 +32,7 @@ use crate::{ #[derive( Debug, TaskInput, + IsTransient, Clone, Copy, PartialEq, @@ -50,8 +51,8 @@ pub enum MangleType { Deterministic, } -#[turbo_tasks::value(shared)] -#[derive(Debug, TaskInput, Clone, Copy, Hash, DeterministicHash, Deserialize)] +#[turbo_tasks::value(shared, task_input)] +#[derive(Debug, Clone, Copy, Hash, DeterministicHash, Deserialize)] pub enum MinifyType { // TODO instead of adding a new property here, // refactor that to Minify(MinifyOptions) to allow defaults on MinifyOptions @@ -67,8 +68,8 @@ impl Default for MinifyType { } } -#[turbo_tasks::value(shared)] -#[derive(Debug, Default, TaskInput, Clone, Copy, Hash, DeterministicHash)] +#[turbo_tasks::value(shared, task_input)] +#[derive(Debug, Default, Clone, Copy, Hash, DeterministicHash)] pub enum SourceMapsType { /// Extracts source maps from input files and writes source maps for output files. #[default] @@ -108,6 +109,7 @@ pub struct UrlBehavior { #[derive( Debug, TaskInput, + IsTransient, Clone, Copy, PartialEq, @@ -258,6 +260,7 @@ pub struct EntryChunkGroupResult { TraceRawVcs, NonLocalValue, TaskInput, + IsTransient, Encode, Decode, )] @@ -287,7 +290,7 @@ pub struct ChunkingConfig { pub struct ChunkingConfigs(FxHashMap>, ChunkingConfig>); #[turbo_tasks::value(shared)] -#[derive(Debug, Clone, Copy, Hash, TaskInput, Default, Deserialize)] +#[derive(Debug, Clone, Copy, Hash, Default, Deserialize)] pub enum SourceMapSourceType { AbsoluteFileUri, RelativeUri, diff --git a/turbopack/crates/turbopack-core/src/chunk/mod.rs b/turbopack/crates/turbopack-core/src/chunk/mod.rs index 856b1a121b9e..19052aeafda8 100644 --- a/turbopack/crates/turbopack-core/src/chunk/mod.rs +++ b/turbopack/crates/turbopack-core/src/chunk/mod.rs @@ -16,7 +16,7 @@ use bincode::{Decode, Encode}; use serde::{Deserialize, Serialize}; use turbo_rcstr::RcStr; use turbo_tasks::{ - FxIndexSet, NonLocalValue, ResolvedVc, TaskInput, Upcast, ValueToString, Vc, + FxIndexSet, IsTransient, NonLocalValue, ResolvedVc, TaskInput, Upcast, ValueToString, Vc, debug::ValueDebugFormat, trace::TraceRawVcs, }; use turbo_tasks_hash::DeterministicHash; @@ -49,6 +49,7 @@ use crate::{ #[derive( Debug, TaskInput, + IsTransient, Clone, Copy, PartialEq, @@ -72,7 +73,7 @@ pub enum ContentHashing { } #[turbo_tasks::value(shared)] -#[derive(Debug, Default, Clone, Copy, Hash, Serialize, Deserialize, TaskInput)] +#[derive(Debug, Default, Clone, Copy, Hash, Serialize, Deserialize)] #[serde(rename_all = "kebab-case")] pub enum CrossOrigin { #[default] @@ -187,7 +188,18 @@ impl MergeableModules { /// Whether a given module needs to be exposed (depending on how it is imported by other modules) #[derive( - Copy, Clone, Debug, PartialEq, Eq, TraceRawVcs, NonLocalValue, TaskInput, Hash, Encode, Decode, + Copy, + Clone, + Debug, + PartialEq, + Eq, + TraceRawVcs, + NonLocalValue, + TaskInput, + IsTransient, + Hash, + Encode, + Decode, )] pub enum MergeableModuleExposure { // This module is only used from within the current group, and only individual exports are @@ -512,7 +524,18 @@ impl AsyncModuleInfo { } #[derive( - Debug, Clone, Copy, PartialEq, Eq, Hash, TraceRawVcs, TaskInput, NonLocalValue, Encode, Decode, + Debug, + Clone, + Copy, + PartialEq, + Eq, + Hash, + TraceRawVcs, + TaskInput, + IsTransient, + NonLocalValue, + Encode, + Decode, )] pub struct ChunkItemWithAsyncModuleInfo { pub chunk_item: ResolvedVc>, diff --git a/turbopack/crates/turbopack-core/src/environment.rs b/turbopack/crates/turbopack-core/src/environment.rs index 663d18b28d0a..5054324ab076 100644 --- a/turbopack/crates/turbopack-core/src/environment.rs +++ b/turbopack/crates/turbopack-core/src/environment.rs @@ -7,7 +7,7 @@ use anyhow::{Context, Result, anyhow, bail}; use browserslist::Distrib; use swc_core::ecma::preset_env::{Version, Versions}; use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::{ResolvedVc, TaskInput, Vc}; +use turbo_tasks::{ResolvedVc, Vc}; use turbo_tasks_env::ProcessEnv; use turbo_tasks_fs::FileSystemPathOption; @@ -16,7 +16,7 @@ use crate::target::CompileTarget; static DEFAULT_NODEJS_VERSION: &str = "18.0.0"; #[turbo_tasks::value] -#[derive(Clone, Copy, Default, Hash, TaskInput, Debug)] +#[derive(Clone, Copy, Default, Hash, Debug)] pub enum Rendering { #[default] None, @@ -53,8 +53,8 @@ impl Environment { } } -#[turbo_tasks::value] -#[derive(Debug, Hash, Clone, Copy, TaskInput)] +#[turbo_tasks::value(task_input)] +#[derive(Debug, Hash, Clone, Copy)] pub enum ExecutionEnvironment { NodeJsBuildTime(ResolvedVc), NodeJsLambda(ResolvedVc), diff --git a/turbopack/crates/turbopack-core/src/ident.rs b/turbopack/crates/turbopack-core/src/ident.rs index d7c12ea723ef..49ba9d3ec69f 100644 --- a/turbopack/crates/turbopack-core/src/ident.rs +++ b/turbopack/crates/turbopack-core/src/ident.rs @@ -5,8 +5,8 @@ use bincode::{Decode, Encode}; use regex::Regex; use turbo_rcstr::RcStr; use turbo_tasks::{ - NonLocalValue, ReadRef, ResolvedVc, TaskInput, ValueToString, ValueToStringRef, Vc, - trace::TraceRawVcs, turbofmt, + IsTransient, NonLocalValue, ReadRef, ResolvedVc, TaskInput, ValueToString, ValueToStringRef, + Vc, trace::TraceRawVcs, turbofmt, }; use turbo_tasks_fs::FileSystemPath; use turbo_tasks_hash::{DeterministicHash, Xxh3Hash64Hasher, encode_base38, hash_xxh3_hash64}; @@ -17,6 +17,7 @@ use crate::resolve::ModulePart; #[derive( Clone, TaskInput, + IsTransient, Hash, Debug, DeterministicHash, @@ -59,8 +60,8 @@ impl Layer { } } -#[turbo_tasks::value] -#[derive(Clone, Debug, Hash, TaskInput)] +#[turbo_tasks::value(task_input)] +#[derive(Clone, Debug, Hash)] pub struct AssetIdent { /// The primary path of the asset pub path: FileSystemPath, diff --git a/turbopack/crates/turbopack-core/src/issue/mod.rs b/turbopack/crates/turbopack-core/src/issue/mod.rs index fac44de3b6e4..8d55b02826c1 100644 --- a/turbopack/crates/turbopack-core/src/issue/mod.rs +++ b/turbopack/crates/turbopack-core/src/issue/mod.rs @@ -16,9 +16,9 @@ use serde::{Deserialize, Serialize}; use turbo_esregex::EsRegex; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - CollectiblesSource, NonLocalValue, OperationVc, RawVc, ReadRef, ResolvedVc, TaskInput, - TransientValue, TryFlatJoinIterExt, TryJoinIterExt, Upcast, ValueDefault, ValueToString, - ValueToStringRef, Vc, emit, trace::TraceRawVcs, + CollectiblesSource, IsTransient, NonLocalValue, OperationVc, RawVc, ReadRef, ResolvedVc, + TaskInput, TransientValue, TryFlatJoinIterExt, TryJoinIterExt, Upcast, ValueDefault, + ValueToString, ValueToStringRef, Vc, emit, trace::TraceRawVcs, }; use turbo_tasks_fs::{ FileContent, FileLine, FileLinesContent, FileSystem, FileSystemPath, glob::Glob, @@ -36,10 +36,8 @@ use crate::{ source_pos::SourcePos, }; -#[turbo_tasks::value(shared)] -#[derive( - PartialOrd, Ord, Copy, Clone, Hash, Debug, DeterministicHash, TaskInput, Serialize, Deserialize, -)] +#[turbo_tasks::value(shared, task_input)] +#[derive(PartialOrd, Ord, Copy, Clone, Hash, Debug, DeterministicHash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum IssueSeverity { Bug, @@ -439,7 +437,18 @@ impl CapturedIssues { } #[derive( - Clone, Copy, Debug, PartialEq, Eq, Hash, TaskInput, TraceRawVcs, NonLocalValue, Encode, Decode, + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + TaskInput, + IsTransient, + TraceRawVcs, + NonLocalValue, + Encode, + Decode, )] pub struct IssueSource { source: ResolvedVc>, @@ -448,7 +457,18 @@ pub struct IssueSource { /// The end position is the first character after the range #[derive( - Clone, Copy, Debug, PartialEq, Eq, Hash, TaskInput, TraceRawVcs, NonLocalValue, Encode, Decode, + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + TaskInput, + IsTransient, + TraceRawVcs, + NonLocalValue, + Encode, + Decode, )] enum SourceRange { LineColumn(SourcePos, SourcePos), diff --git a/turbopack/crates/turbopack-core/src/loader.rs b/turbopack/crates/turbopack-core/src/loader.rs index aa4b31018edc..0bad80c53882 100644 --- a/turbopack/crates/turbopack-core/src/loader.rs +++ b/turbopack/crates/turbopack-core/src/loader.rs @@ -2,7 +2,7 @@ use std::hash::{Hash, Hasher}; use bincode::{Decode, Encode}; use serde::{Deserialize, Serialize}; -use turbo_tasks::{NonLocalValue, OperationValue, TaskInput, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, OperationValue, TaskInput, trace::TraceRawVcs}; use turbo_tasks_fs::FileSystemPath; #[derive( @@ -36,11 +36,8 @@ impl Hash for WebpackLoaderItem { } } -impl TaskInput for WebpackLoaderItem { - fn is_transient(&self) -> bool { - false - } -} +impl TaskInput for WebpackLoaderItem {} +impl IsTransient for WebpackLoaderItem {} /// Like `WebpackLoaderItem`, but with the loader path already resolved to a `FileSystemPath`. #[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, NonLocalValue, Encode, Decode)] @@ -58,11 +55,8 @@ impl Hash for ResolvedWebpackLoaderItem { } } -impl TaskInput for ResolvedWebpackLoaderItem { - fn is_transient(&self) -> bool { - false - } -} +impl TaskInput for ResolvedWebpackLoaderItem {} +impl IsTransient for ResolvedWebpackLoaderItem {} #[derive(Debug, Clone)] #[turbo_tasks::value(shared, transparent)] diff --git a/turbopack/crates/turbopack-core/src/module.rs b/turbopack/crates/turbopack-core/src/module.rs index 103489838a5b..f33ced1c3e1c 100644 --- a/turbopack/crates/turbopack-core/src/module.rs +++ b/turbopack/crates/turbopack-core/src/module.rs @@ -1,9 +1,9 @@ use turbo_rcstr::RcStr; -use turbo_tasks::{ResolvedVc, TaskInput, ValueToString, Vc}; +use turbo_tasks::{ResolvedVc, ValueToString, Vc}; use crate::{ident::AssetIdent, reference::ModuleReferences, source::OptionSource}; -#[derive(Clone, Copy, Debug, TaskInput, Hash)] +#[derive(Clone, Copy, Debug, Hash)] #[turbo_tasks::value(shared)] pub enum StyleType { IsolatedStyle, diff --git a/turbopack/crates/turbopack-core/src/module_graph/chunk_group_info.rs b/turbopack/crates/turbopack-core/src/module_graph/chunk_group_info.rs index 8f23276c715e..bcb5ffd5cbe3 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/chunk_group_info.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/chunk_group_info.rs @@ -12,8 +12,8 @@ use rustc_hash::FxHashMap; use tracing::Instrument; use turbo_rcstr::RcStr; use turbo_tasks::{ - FxIndexMap, FxIndexSet, NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, ValueToString, - Vc, debug::ValueDebugFormat, trace::TraceRawVcs, turbofmt, + FxIndexMap, FxIndexSet, IsTransient, NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, + ValueToString, Vc, debug::ValueDebugFormat, trace::TraceRawVcs, turbofmt, }; use crate::{ @@ -30,11 +30,8 @@ pub struct RoaringBitmapWrapper( pub RoaringBitmap, ); -impl TaskInput for RoaringBitmapWrapper { - fn is_transient(&self) -> bool { - false - } -} +impl TaskInput for RoaringBitmapWrapper {} +impl IsTransient for RoaringBitmapWrapper {} impl RoaringBitmapWrapper { /// Whether `self` contains bits that are not in `other` @@ -128,7 +125,17 @@ impl ChunkGroupInfo { /// See [ChunkGroup] for documentation #[derive( - Debug, Clone, Hash, TaskInput, PartialEq, Eq, TraceRawVcs, NonLocalValue, Encode, Decode, + Debug, + Clone, + Hash, + TaskInput, + IsTransient, + PartialEq, + Eq, + TraceRawVcs, + NonLocalValue, + Encode, + Decode, )] pub enum ChunkGroupEntry { Entry(Vec>>), @@ -161,7 +168,9 @@ impl ChunkGroupEntry { } } -#[derive(Debug, Clone, Hash, TaskInput, PartialEq, Eq, TraceRawVcs, Encode, Decode)] +#[derive( + Debug, Clone, Hash, TaskInput, IsTransient, PartialEq, Eq, TraceRawVcs, Encode, Decode, +)] pub enum ChunkGroup { /// The entry chunk group of the compilation, e.g. src/index.js for a SPA, or app/foo/page.js /// for Next.js. diff --git a/turbopack/crates/turbopack-core/src/module_graph/module_batch.rs b/turbopack/crates/turbopack-core/src/module_graph/module_batch.rs index fe6c5a829be3..771fe5164c61 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/module_batch.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/module_batch.rs @@ -5,7 +5,7 @@ use bincode::{Decode, Encode}; use serde::{Deserialize, Serialize}; use turbo_rcstr::RcStr; use turbo_tasks::{ - NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryJoinIterExt, ValueToString, Vc, + IsTransient, NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryJoinIterExt, ValueToString, Vc, trace::TraceRawVcs, }; @@ -25,6 +25,7 @@ use crate::{ TraceRawVcs, NonLocalValue, TaskInput, + IsTransient, Encode, Decode, )] @@ -47,7 +48,18 @@ impl ModuleOrBatch { } #[derive( - Debug, Copy, Clone, Hash, PartialEq, Eq, TraceRawVcs, NonLocalValue, TaskInput, Encode, Decode, + Debug, + Copy, + Clone, + Hash, + PartialEq, + Eq, + TraceRawVcs, + NonLocalValue, + TaskInput, + IsTransient, + Encode, + Decode, )] pub enum ChunkableModuleOrBatch { Module(ResolvedVc>), diff --git a/turbopack/crates/turbopack-core/src/module_graph/module_batches.rs b/turbopack/crates/turbopack-core/src/module_graph/module_batches.rs index 3a21313b654d..00d0c5acceb3 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/module_batches.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/module_batches.rs @@ -13,8 +13,8 @@ use serde::{Deserialize, Serialize}; use tracing::Instrument; use turbo_prehash::BuildHasherExt; use turbo_tasks::{ - FxIndexMap, FxIndexSet, NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, ValueToString, - Vc, trace::TraceRawVcs, turbobail, + FxIndexMap, FxIndexSet, NonLocalValue, ResolvedVc, TryJoinIterExt, ValueToString, Vc, + trace::TraceRawVcs, turbobail, }; use crate::{ @@ -27,8 +27,8 @@ use crate::{ traced_di_graph::{TracedDiGraph, iter_neighbors_rev}, }, }; -#[turbo_tasks::value] -#[derive(Debug, Clone, Default, TaskInput, Hash)] +#[turbo_tasks::value(task_input)] +#[derive(Debug, Clone, Default, Hash)] pub struct BatchingConfig { /// Use a heuristic based on the module path to create batches. It aims for batches of a good /// size. diff --git a/turbopack/crates/turbopack-core/src/module_graph/style_groups.rs b/turbopack/crates/turbopack-core/src/module_graph/style_groups.rs index 9fd61ebc9dca..63f59acc5c98 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/style_groups.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/style_groups.rs @@ -6,7 +6,8 @@ use bincode::{Decode, Encode}; use turbo_tasks::{ - FxIndexMap, NonLocalValue, OperationValue, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs, + FxIndexMap, IsTransient, NonLocalValue, OperationValue, ResolvedVc, TaskInput, Vc, + trace::TraceRawVcs, }; use crate::chunk::{ChunkItemBatchWithAsyncModuleInfo, ChunkItemWithAsyncModuleInfo}; @@ -17,6 +18,7 @@ use crate::chunk::{ChunkItemBatchWithAsyncModuleInfo, ChunkItemWithAsyncModuleIn /// `u32` directly. #[derive( TaskInput, + IsTransient, Debug, Clone, Copy, @@ -41,8 +43,8 @@ impl F32TaskInput { } /// Selects the algorithm used to compute [`StyleGroups`]. -#[turbo_tasks::value(shared, operation)] -#[derive(Clone, Debug, Default, Hash, TaskInput)] +#[turbo_tasks::value(shared, operation, task_input)] +#[derive(Clone, Debug, Default, Hash)] pub enum StyleGroupsAlgorithm { /// Default ("loose") algorithm, see /// [`crate::module_graph::style_groups_loose::compute_style_groups`]. @@ -69,7 +71,17 @@ impl StyleGroupsAlgorithm { } #[derive( - TaskInput, Debug, Clone, PartialEq, Eq, Hash, NonLocalValue, TraceRawVcs, Encode, Decode, + TaskInput, + IsTransient, + Debug, + Clone, + PartialEq, + Eq, + Hash, + NonLocalValue, + TraceRawVcs, + Encode, + Decode, )] pub struct StyleGroupsConfig { pub max_chunk_size: usize, @@ -78,7 +90,17 @@ pub struct StyleGroupsConfig { /// Per-item metadata produced by the style chunking algorithms. #[derive( - Debug, Clone, PartialEq, Eq, Hash, NonLocalValue, TraceRawVcs, Encode, Decode, TaskInput, + Debug, + Clone, + PartialEq, + Eq, + Hash, + NonLocalValue, + TraceRawVcs, + Encode, + Decode, + TaskInput, + IsTransient, )] pub struct StyleItemInfo { /// Stable sort key applied by the production-chunking pass when ordering chunks within a chunk diff --git a/turbopack/crates/turbopack-core/src/reference_type.rs b/turbopack/crates/turbopack-core/src/reference_type.rs index 2193c8b7dcf2..f8367e977666 100644 --- a/turbopack/crates/turbopack-core/src/reference_type.rs +++ b/turbopack/crates/turbopack-core/src/reference_type.rs @@ -3,7 +3,9 @@ use std::fmt::Display; use anyhow::Result; use bincode::{Decode, Encode}; use turbo_rcstr::RcStr; -use turbo_tasks::{FxIndexMap, NonLocalValue, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{ + FxIndexMap, IsTransient, NonLocalValue, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs, +}; use crate::{loader::ResolvedWebpackLoaderItem, module::Module, resolve::ModulePart}; @@ -41,6 +43,7 @@ impl InnerAssets { Copy, Hash, TaskInput, + IsTransient, Encode, Decode, )] @@ -51,7 +54,18 @@ pub enum CommonJsReferenceSubType { } #[derive( - PartialEq, Eq, TraceRawVcs, NonLocalValue, Debug, Clone, Copy, Hash, TaskInput, Encode, Decode, + PartialEq, + Eq, + TraceRawVcs, + NonLocalValue, + Debug, + Clone, + Copy, + Hash, + TaskInput, + IsTransient, + Encode, + Decode, )] pub enum ImportWithType { Json, @@ -68,6 +82,7 @@ pub enum ImportWithType { Clone, Hash, TaskInput, + IsTransient, Encode, Decode, )] @@ -216,6 +231,7 @@ impl ImportContext { Copy, Hash, TaskInput, + IsTransient, Encode, Decode, )] @@ -244,6 +260,7 @@ pub enum CssReferenceSubType { Copy, Hash, TaskInput, + IsTransient, Encode, Decode, )] @@ -256,7 +273,18 @@ pub enum UrlReferenceSubType { } #[derive( - PartialEq, Eq, TraceRawVcs, NonLocalValue, Debug, Clone, Copy, Hash, TaskInput, Encode, Decode, + PartialEq, + Eq, + TraceRawVcs, + NonLocalValue, + Debug, + Clone, + Copy, + Hash, + TaskInput, + IsTransient, + Encode, + Decode, )] pub enum TypeScriptReferenceSubType { Custom(u8), @@ -264,7 +292,18 @@ pub enum TypeScriptReferenceSubType { } #[derive( - PartialEq, Eq, TraceRawVcs, NonLocalValue, Debug, Clone, Copy, Hash, TaskInput, Encode, Decode, + PartialEq, + Eq, + TraceRawVcs, + NonLocalValue, + Debug, + Clone, + Copy, + Hash, + TaskInput, + IsTransient, + Encode, + Decode, )] pub enum WorkerReferenceSubType { WebWorker, @@ -278,7 +317,18 @@ pub enum WorkerReferenceSubType { // TODO(sokra) this was next.js specific values. We want to solve this in a // different way. #[derive( - PartialEq, Eq, TraceRawVcs, NonLocalValue, Debug, Clone, Copy, Hash, TaskInput, Encode, Decode, + PartialEq, + Eq, + TraceRawVcs, + NonLocalValue, + Debug, + Clone, + Copy, + Hash, + TaskInput, + IsTransient, + Encode, + Decode, )] pub enum EntryReferenceSubType { Web, @@ -307,6 +357,7 @@ pub enum EntryReferenceSubType { Clone, Hash, TaskInput, + IsTransient, Encode, Decode, )] @@ -373,7 +424,17 @@ impl ReferenceType { /// `ReferenceTypeCondition::Url(Some(UrlReferenceSubType::EcmaScriptNewUrl))` matching /// `ReferenceType::Url(UrlReferenceSubType::EcmaScriptNewUrl)` #[derive( - PartialEq, Eq, TraceRawVcs, NonLocalValue, Debug, Clone, Hash, TaskInput, Encode, Decode, + PartialEq, + Eq, + TraceRawVcs, + NonLocalValue, + Debug, + Clone, + Hash, + TaskInput, + IsTransient, + Encode, + Decode, )] pub enum ReferenceTypeCondition { CommonJs(Option), diff --git a/turbopack/crates/turbopack-core/src/resolve/mod.rs b/turbopack/crates/turbopack-core/src/resolve/mod.rs index 42745cc4b9ab..5d0881631882 100644 --- a/turbopack/crates/turbopack-core/src/resolve/mod.rs +++ b/turbopack/crates/turbopack-core/src/resolve/mod.rs @@ -17,8 +17,8 @@ use tracing::{Instrument, Level}; use turbo_frozenmap::{FrozenMap, FrozenSet}; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - FxIndexMap, NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryFlatJoinIterExt, TryJoinIterExt, - ValueToString, ValueToStringRef, Vc, trace::TraceRawVcs, + FxIndexMap, IsTransient, NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryFlatJoinIterExt, + TryJoinIterExt, ValueToString, ValueToStringRef, Vc, trace::TraceRawVcs, }; use turbo_tasks_fs::{FileSystemEntryType, FileSystemPath}; use turbo_unix_path::normalize_request; @@ -68,8 +68,8 @@ pub use alias_map::{ pub use remap::{ResolveAliasMap, SubpathValue}; /// Controls how resolve errors are handled. -#[turbo_tasks::value(shared)] -#[derive(Debug, Clone, Copy, Default, Hash, TaskInput)] +#[turbo_tasks::value(shared, task_input)] +#[derive(Debug, Clone, Copy, Default, Hash)] pub enum ResolveErrorMode { /// Emit an error issue (default behavior) #[default] @@ -453,6 +453,7 @@ impl ModuleResolveResult { PartialEq, Eq, TaskInput, + IsTransient, Hash, NonLocalValue, TraceRawVcs, @@ -486,6 +487,7 @@ impl Display for ExternalTraced { Deserialize, TraceRawVcs, TaskInput, + IsTransient, NonLocalValue, Encode, Decode, @@ -538,8 +540,8 @@ pub enum ResolveResultItem { /// A primary factor is the actual request string, but there are /// other factors like exports conditions that can affect resolving and become /// part of the key (assuming the condition is unknown at compile time) -#[derive(Clone, Debug, Default, Hash, TaskInput)] -#[turbo_tasks::value] +#[derive(Clone, Debug, Default, Hash)] +#[turbo_tasks::value(task_input)] pub struct RequestKey { pub request: Option, pub conditions: FrozenMap, @@ -1350,7 +1352,7 @@ pub async fn find_context_file_or_package_key( Ok(find_context_file(lookup_path.parent(), names, false)) } -#[derive(Clone, PartialEq, Eq, TraceRawVcs, Debug, NonLocalValue, Encode, Decode)] +#[derive(Clone, PartialEq, Eq, TraceRawVcs, Debug, NonLocalValue, IsTransient, Encode, Decode)] enum FindPackageItem { PackageDirectory { name: RcStr, dir: FileSystemPath }, PackageFile { name: RcStr, file: FileSystemPath }, @@ -3378,6 +3380,7 @@ async fn resolve_package_internal_with_imports_field( Hash, TraceRawVcs, TaskInput, + IsTransient, NonLocalValue, Encode, Decode, diff --git a/turbopack/crates/turbopack-core/src/resolve/options.rs b/turbopack/crates/turbopack-core/src/resolve/options.rs index 1309e5a8a295..1d819bc7061e 100644 --- a/turbopack/crates/turbopack-core/src/resolve/options.rs +++ b/turbopack/crates/turbopack-core/src/resolve/options.rs @@ -4,7 +4,7 @@ use anyhow::{Result, bail}; use bincode::{Decode, Encode}; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - FxIndexSet, NonLocalValue, ResolvedVc, TryJoinIterExt, ValueToString, Vc, + FxIndexSet, IsTransient, NonLocalValue, ResolvedVc, TryJoinIterExt, ValueToString, Vc, debug::ValueDebugFormat, trace::TraceRawVcs, turbofmt, }; use turbo_tasks_fs::{FileSystemPath, glob::Glob}; @@ -26,7 +26,17 @@ pub struct ExcludedExtensions(#[bincode(with = "turbo_bincode::indexset")] pub F /// A location where to resolve modules. #[derive( - TraceRawVcs, Hash, PartialEq, Eq, Clone, Debug, ValueDebugFormat, NonLocalValue, Encode, Decode, + TraceRawVcs, + Hash, + PartialEq, + Eq, + Clone, + Debug, + ValueDebugFormat, + NonLocalValue, + IsTransient, + Encode, + Decode, )] pub enum ResolveModules { /// when inside of path, use the list of directories to diff --git a/turbopack/crates/turbopack-core/src/resolve/pattern.rs b/turbopack/crates/turbopack-core/src/resolve/pattern.rs index d8c38a677ce1..ac074d069cdd 100644 --- a/turbopack/crates/turbopack-core/src/resolve/pattern.rs +++ b/turbopack/crates/turbopack-core/src/resolve/pattern.rs @@ -10,15 +10,13 @@ use regex::Regex; use rustc_hash::{FxHashMap, FxHashSet}; use tracing::Instrument; use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::{ - NonLocalValue, TaskInput, ValueToString, Vc, debug::ValueDebugFormat, trace::TraceRawVcs, -}; +use turbo_tasks::{NonLocalValue, ValueToString, Vc, debug::ValueDebugFormat, trace::TraceRawVcs}; use turbo_tasks_fs::{ FileSystemPath, LinkContent, LinkType, RawDirectoryContent, RawDirectoryEntry, }; use turbo_unix_path::normalize_path; -#[turbo_tasks::value] +#[turbo_tasks::value(task_input)] #[derive(Hash, Clone, Debug, Default, ValueToString)] #[value_to_string(self.describe_as_string())] pub enum Pattern { @@ -30,16 +28,6 @@ pub enum Pattern { Concatenation(Vec), } -/// manually implement TaskInput to avoid recursion in the implementation of `resolve_input` in the -/// derived implementation. We can instead use the default implementation since `Pattern` contains -/// no VCs. -impl TaskInput for Pattern { - fn is_transient(&self) -> bool { - // We contain no vcs so they cannot be transient. - false - } -} - fn concatenation_push_or_merge_item(list: &mut Vec, pat: Pattern) { if let Pattern::Constant(ref s) = pat && let Some(Pattern::Constant(last)) = list.last_mut() diff --git a/turbopack/crates/turbopack-core/src/source_pos.rs b/turbopack/crates/turbopack-core/src/source_pos.rs index c367fe7e4f2e..791013cac539 100644 --- a/turbopack/crates/turbopack-core/src/source_pos.rs +++ b/turbopack/crates/turbopack-core/src/source_pos.rs @@ -1,6 +1,6 @@ use bincode::{Decode, Encode}; use serde::Serialize; -use turbo_tasks::{NonLocalValue, TaskInput, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, TaskInput, trace::TraceRawVcs}; use turbo_tasks_hash::DeterministicHash; /// LINE FEED (LF), one of the basic JS line terminators. @@ -19,6 +19,7 @@ const U8_CR: u8 = 0x0D; PartialOrd, Ord, TaskInput, + IsTransient, TraceRawVcs, Serialize, DeterministicHash, diff --git a/turbopack/crates/turbopack-core/src/target.rs b/turbopack/crates/turbopack-core/src/target.rs index 7ce7bd73eb4b..544dd10d692b 100644 --- a/turbopack/crates/turbopack-core/src/target.rs +++ b/turbopack/crates/turbopack-core/src/target.rs @@ -2,7 +2,7 @@ use std::fmt::Display; use bincode::{Decode, Encode}; use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::{NonLocalValue, ValueToString, Vc, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, ValueToString, Vc, trace::TraceRawVcs}; #[turbo_tasks::value(shared)] #[derive(Hash, Debug, Copy, Clone, ValueToString)] @@ -174,7 +174,9 @@ impl CompileTarget { } } -#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, NonLocalValue, Encode, Decode)] +#[derive( + PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, NonLocalValue, IsTransient, Encode, Decode, +)] #[repr(u8)] #[non_exhaustive] pub enum Arch { @@ -215,7 +217,9 @@ impl Display for Arch { } } -#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, NonLocalValue, Encode, Decode)] +#[derive( + PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, NonLocalValue, IsTransient, Encode, Decode, +)] #[repr(u8)] #[non_exhaustive] pub enum Platform { @@ -281,7 +285,9 @@ impl Display for Endianness { } } -#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, NonLocalValue, Encode, Decode)] +#[derive( + PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, NonLocalValue, IsTransient, Encode, Decode, +)] #[repr(u8)] pub enum Libc { Glibc, diff --git a/turbopack/crates/turbopack-css/src/lib.rs b/turbopack/crates/turbopack-css/src/lib.rs index 513fb17a146f..ad0b167f87ca 100644 --- a/turbopack/crates/turbopack-css/src/lib.rs +++ b/turbopack/crates/turbopack-css/src/lib.rs @@ -12,7 +12,7 @@ pub(crate) mod process; pub(crate) mod references; use bincode::{Decode, Encode}; -use turbo_tasks::{NonLocalValue, TaskInput, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, TaskInput, trace::TraceRawVcs}; use crate::references::import::ImportAssetReference; pub use crate::{asset::CssModule, module_asset::EcmascriptCssModule, process::*}; @@ -28,6 +28,7 @@ pub use crate::{asset::CssModule, module_asset::EcmascriptCssModule, process::*} Clone, Default, TaskInput, + IsTransient, TraceRawVcs, NonLocalValue, Encode, @@ -45,8 +46,8 @@ pub enum CssModuleType { /// /// Both fields are raw `Features` bitmasks. `include` bits are OR-ed into the /// default feature set; `exclude` bits are masked off. -#[turbo_tasks::value(shared, serialization = "auto")] -#[derive(PartialOrd, Ord, Hash, Copy, Clone, Debug, Default, TaskInput)] +#[turbo_tasks::value(shared, serialization = "auto", task_input)] +#[derive(PartialOrd, Ord, Hash, Copy, Clone, Debug, Default)] pub struct LightningCssFeatureFlags { pub include: u32, pub exclude: u32, diff --git a/turbopack/crates/turbopack-dev-server/src/html.rs b/turbopack/crates/turbopack-dev-server/src/html.rs index ec60b04e118e..c2aed62173b8 100644 --- a/turbopack/crates/turbopack-dev-server/src/html.rs +++ b/turbopack/crates/turbopack-dev-server/src/html.rs @@ -3,7 +3,8 @@ use bincode::{Decode, Encode}; use mime_guess::mime::TEXT_HTML_UTF_8; use turbo_rcstr::RcStr; use turbo_tasks::{ - NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryJoinIterExt, Vc, trace::TraceRawVcs, + IsTransient, NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryJoinIterExt, Vc, + trace::TraceRawVcs, }; use turbo_tasks_fs::{File, FileContent, FileSystemPath}; use turbo_tasks_hash::{Xxh3Hash64Hasher, encode_base64}; @@ -20,7 +21,17 @@ use turbopack_core::{ }; #[derive( - Clone, Debug, Eq, Hash, NonLocalValue, PartialEq, TaskInput, TraceRawVcs, Encode, Decode, + Clone, + Debug, + Eq, + Hash, + NonLocalValue, + PartialEq, + TaskInput, + IsTransient, + TraceRawVcs, + Encode, + Decode, )] pub struct DevHtmlEntry { pub chunkable_module: ResolvedVc>, diff --git a/turbopack/crates/turbopack-dev-server/src/source/headers.rs b/turbopack/crates/turbopack-dev-server/src/source/headers.rs index 98ff12dcb9c1..8de946ab82db 100644 --- a/turbopack/crates/turbopack-dev-server/src/source/headers.rs +++ b/turbopack/crates/turbopack-dev-server/src/source/headers.rs @@ -1,7 +1,7 @@ use std::{collections::BTreeMap, hash::Hash, mem::replace, ops::DerefMut}; use bincode::{Decode, Encode}; -use turbo_tasks::{NonLocalValue, TaskInput, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, TaskInput, trace::TraceRawVcs}; /// A parsed query string from a http request #[derive( @@ -14,6 +14,7 @@ use turbo_tasks::{NonLocalValue, TaskInput, trace::TraceRawVcs}; TraceRawVcs, NonLocalValue, TaskInput, + IsTransient, Encode, Decode, )] @@ -22,7 +23,17 @@ pub struct Headers(BTreeMap); /// The value of an http header. HTTP headers might contain non-utf-8 bytes. An /// header might also occur multiple times. #[derive( - Clone, Debug, PartialEq, Eq, Hash, TraceRawVcs, NonLocalValue, TaskInput, Encode, Decode, + Clone, + Debug, + PartialEq, + Eq, + Hash, + TraceRawVcs, + NonLocalValue, + TaskInput, + IsTransient, + Encode, + Decode, )] pub enum HeaderValue { SingleString(String), diff --git a/turbopack/crates/turbopack-dev-server/src/source/mod.rs b/turbopack/crates/turbopack-dev-server/src/source/mod.rs index 2db0d5417663..e3f11b09d1fe 100644 --- a/turbopack/crates/turbopack-dev-server/src/source/mod.rs +++ b/turbopack/crates/turbopack-dev-server/src/source/mod.rs @@ -18,8 +18,8 @@ use bincode::{Decode, Encode}; use futures::{TryStreamExt, stream::Stream as StreamTrait}; use turbo_rcstr::RcStr; use turbo_tasks::{ - Completion, NonLocalValue, OperationVc, ResolvedVc, TaskInput, Upcast, Vc, trace::TraceRawVcs, - util::SharedError, + Completion, IsTransient, NonLocalValue, OperationVc, ResolvedVc, TaskInput, Upcast, Vc, + trace::TraceRawVcs, util::SharedError, }; use turbo_tasks_bytes::{Bytes, Stream, StreamRead}; use turbo_tasks_fs::FileSystemPath; @@ -168,6 +168,7 @@ impl HeaderList { Hash, Default, TaskInput, + IsTransient, Encode, Decode, )] diff --git a/turbopack/crates/turbopack-dev-server/src/source/query.rs b/turbopack/crates/turbopack-dev-server/src/source/query.rs index d483453812e9..1b4ac4e1a699 100644 --- a/turbopack/crates/turbopack-dev-server/src/source/query.rs +++ b/turbopack/crates/turbopack-dev-server/src/source/query.rs @@ -24,11 +24,8 @@ pub struct Query(BTreeMap); // This type contains no VCs so the default implementation works. // Query is also recursive through QueryValue so the derive macro doesnt work -impl TaskInput for Query { - fn is_transient(&self) -> bool { - false - } -} +impl TaskInput for Query {} +impl turbo_tasks::IsTransient for Query {} impl Query { pub fn filter_with(&mut self, filter: &ContentSourceDataFilter) { diff --git a/turbopack/crates/turbopack-dev-server/src/source/route_tree.rs b/turbopack/crates/turbopack-dev-server/src/source/route_tree.rs index 28d36ffffb4e..033f4dbefb6e 100644 --- a/turbopack/crates/turbopack-dev-server/src/source/route_tree.rs +++ b/turbopack/crates/turbopack-dev-server/src/source/route_tree.rs @@ -4,8 +4,8 @@ use anyhow::Result; use bincode::{Decode, Encode}; use turbo_rcstr::RcStr; use turbo_tasks::{ - FxIndexMap, NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryJoinIterExt, ValueToString, Vc, - fxindexmap, trace::TraceRawVcs, + FxIndexMap, IsTransient, NonLocalValue, ReadRef, ResolvedVc, TaskInput, TryJoinIterExt, + ValueToString, Vc, fxindexmap, trace::TraceRawVcs, }; use crate::source::{GetContentSourceContent, GetContentSourceContents}; @@ -13,7 +13,17 @@ use crate::source::{GetContentSourceContent, GetContentSourceContents}; /// The type of the route. This will decide about the remaining segments of the /// route after the base. #[derive( - TaskInput, Clone, Debug, PartialEq, Eq, Hash, TraceRawVcs, NonLocalValue, Encode, Decode, + TaskInput, + IsTransient, + Clone, + Debug, + PartialEq, + Eq, + Hash, + TraceRawVcs, + NonLocalValue, + Encode, + Decode, )] pub enum RouteType { Exact, @@ -24,7 +34,17 @@ pub enum RouteType { /// Some normal segment of a route. #[derive( - TaskInput, Clone, Debug, PartialEq, Eq, Hash, TraceRawVcs, NonLocalValue, Encode, Decode, + TaskInput, + IsTransient, + Clone, + Debug, + PartialEq, + Eq, + Hash, + TraceRawVcs, + NonLocalValue, + Encode, + Decode, )] pub enum BaseSegment { Static(RcStr), diff --git a/turbopack/crates/turbopack-ecmascript-runtime/src/runtime_type.rs b/turbopack/crates/turbopack-ecmascript-runtime/src/runtime_type.rs index 29ce57e034d6..7b40bc8018eb 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/src/runtime_type.rs +++ b/turbopack/crates/turbopack-ecmascript-runtime/src/runtime_type.rs @@ -1,8 +1,7 @@ use serde::Deserialize; -use turbo_tasks::TaskInput; -#[turbo_tasks::value(shared)] -#[derive(Debug, Clone, Copy, Hash, TaskInput, Deserialize)] +#[turbo_tasks::value(shared, task_input)] +#[derive(Debug, Clone, Copy, Hash, Deserialize)] pub enum RuntimeType { Development, Production, diff --git a/turbopack/crates/turbopack-ecmascript/src/chunk/batch.rs b/turbopack/crates/turbopack-ecmascript/src/chunk/batch.rs index 5da8288a98ff..7ddb6346dee7 100644 --- a/turbopack/crates/turbopack-ecmascript/src/chunk/batch.rs +++ b/turbopack/crates/turbopack-ecmascript/src/chunk/batch.rs @@ -1,6 +1,8 @@ use anyhow::Result; use bincode::{Decode, Encode}; -use turbo_tasks::{NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, Vc, trace::TraceRawVcs}; +use turbo_tasks::{ + IsTransient, NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, Vc, trace::TraceRawVcs, +}; use turbopack_core::{ chunk::{ ChunkItemBatchGroup, ChunkItemBatchWithAsyncModuleInfo, ChunkItemOrBatchWithAsyncModuleInfo, @@ -11,7 +13,17 @@ use turbopack_core::{ use crate::chunk::EcmascriptChunkItemWithAsyncInfo; #[derive( - Debug, Clone, Hash, PartialEq, Eq, TraceRawVcs, NonLocalValue, TaskInput, Encode, Decode, + Debug, + Clone, + Hash, + PartialEq, + Eq, + TraceRawVcs, + NonLocalValue, + TaskInput, + IsTransient, + Encode, + Decode, )] pub enum EcmascriptChunkItemOrBatchWithAsyncInfo { ChunkItem(EcmascriptChunkItemWithAsyncInfo), diff --git a/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs b/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs index b805049d07f1..8879566c9b1e 100644 --- a/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs @@ -6,7 +6,7 @@ use bincode::{Decode, Encode}; use smallvec::SmallVec; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - NonLocalValue, PrettyPrintError, ResolvedVc, TaskInput, Upcast, ValueToString, Vc, + IsTransient, NonLocalValue, PrettyPrintError, ResolvedVc, TaskInput, Upcast, ValueToString, Vc, trace::TraceRawVcs, }; use turbo_tasks_fs::{FileSystemPath, rope::Rope}; @@ -40,6 +40,7 @@ use crate::{ Hash, TraceRawVcs, TaskInput, + IsTransient, NonLocalValue, Default, Encode, @@ -228,7 +229,17 @@ pub struct EcmascriptChunkItemOptions { } #[derive( - Debug, Clone, PartialEq, Eq, Hash, TraceRawVcs, TaskInput, NonLocalValue, Encode, Decode, + Debug, + Clone, + PartialEq, + Eq, + Hash, + TraceRawVcs, + TaskInput, + IsTransient, + NonLocalValue, + Encode, + Decode, )] pub struct EcmascriptChunkItemWithAsyncInfo { pub chunk_item: ResolvedVc>, diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index c0eb5f227ea4..657a304ba7b6 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -77,9 +77,9 @@ use swc_core::{ use tracing::{Instrument, Level, instrument}; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - FxDashMap, FxIndexMap, NonLocalValue, ReadRef, ResolvedVc, SerializationInvalidator, TaskInput, - TryJoinIterExt, Upcast, ValueToString, Vc, get_serialization_invalidator, - parking_lot_mutex_bincode, trace::TraceRawVcs, turbofmt, + FxDashMap, FxIndexMap, IsTransient, NonLocalValue, ReadRef, ResolvedVc, + SerializationInvalidator, TaskInput, TryJoinIterExt, Upcast, ValueToString, Vc, + get_serialization_invalidator, parking_lot_mutex_bincode, trace::TraceRawVcs, turbofmt, }; use turbo_tasks_fs::{FileJsonContent, FileSystemPath, glob::Glob, rope::Rope}; use turbopack_core::{ @@ -139,6 +139,7 @@ pub use crate::{ Copy, Default, TaskInput, + IsTransient, TraceRawVcs, NonLocalValue, Deserialize, @@ -164,6 +165,7 @@ pub enum SpecifiedModuleType { Default, Deserialize, TaskInput, + IsTransient, TraceRawVcs, NonLocalValue, Encode, @@ -188,6 +190,7 @@ pub enum TreeShakingMode { Default, Deserialize, TaskInput, + IsTransient, TraceRawVcs, NonLocalValue, Encode, @@ -225,7 +228,18 @@ pub struct OptionTreeShaking(pub Option); /// The constant to replace `typeof window` with. #[derive( - Copy, Clone, PartialEq, Eq, Debug, Hash, TraceRawVcs, NonLocalValue, TaskInput, Encode, Decode, + Copy, + Clone, + PartialEq, + Eq, + Debug, + Hash, + TraceRawVcs, + NonLocalValue, + TaskInput, + IsTransient, + Encode, + Decode, )] pub enum TypeofWindow { Object, @@ -273,8 +287,8 @@ pub struct EcmascriptOptions { pub infer_module_side_effects: bool, } -#[turbo_tasks::value] -#[derive(Hash, Debug, Copy, Clone, TaskInput)] +#[turbo_tasks::value(task_input)] +#[derive(Hash, Debug, Copy, Clone)] pub enum EcmascriptModuleAssetType { /// Module with EcmaScript code Ecmascript, @@ -988,7 +1002,7 @@ pub struct EcmascriptModuleContent { } #[turbo_tasks::value(shared)] -#[derive(Clone, Debug, Hash, TaskInput)] +#[derive(Clone, Debug, Hash)] pub struct EcmascriptModuleContentOptions { module: ResolvedVc>, parsed: Option>, diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/url.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/url.rs index 0975b543ef5e..91a5685ae444 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/url.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/url.rs @@ -5,7 +5,7 @@ use swc_core::{ quote, }; use turbo_tasks::{ - NonLocalValue, ResolvedVc, TaskInput, ValueToString, Vc, debug::ValueDebugFormat, + IsTransient, NonLocalValue, ResolvedVc, TaskInput, ValueToString, Vc, debug::ValueDebugFormat, trace::TraceRawVcs, }; use turbopack_core::{ @@ -34,7 +34,18 @@ use crate::{ /// This allows to construct url depends on the different building context, /// e.g. SSR, CSR, or Node.js. #[derive( - Copy, Clone, Debug, Eq, PartialEq, Hash, TraceRawVcs, TaskInput, NonLocalValue, Encode, Decode, + Copy, + Clone, + Debug, + Eq, + PartialEq, + Hash, + TraceRawVcs, + TaskInput, + IsTransient, + NonLocalValue, + Encode, + Decode, )] pub enum UrlRewriteBehavior { /// Omits base, resulting in a relative URL. diff --git a/turbopack/crates/turbopack-ecmascript/src/references/external_module.rs b/turbopack/crates/turbopack-ecmascript/src/references/external_module.rs index 024662c20bb0..e0c982b218a7 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/external_module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/external_module.rs @@ -4,7 +4,8 @@ use anyhow::{Context, Result}; use bincode::{Decode, Encode}; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, ValueToStringRef, Vc, trace::TraceRawVcs, + IsTransient, NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, ValueToStringRef, Vc, + trace::TraceRawVcs, }; use turbo_tasks_fs::{FileSystem, FileSystemPath, LinkType, VirtualFileSystem, rope::RopeBuilder}; use turbo_tasks_hash::{encode_hex, hash_xxh3_hash64}; @@ -44,7 +45,18 @@ use crate::{ }; #[derive( - Copy, Clone, Debug, Eq, PartialEq, TraceRawVcs, TaskInput, Hash, NonLocalValue, Encode, Decode, + Copy, + Clone, + Debug, + Eq, + PartialEq, + TraceRawVcs, + TaskInput, + IsTransient, + Hash, + NonLocalValue, + Encode, + Decode, )] pub enum CachedExternalType { CommonJs, @@ -55,7 +67,17 @@ pub enum CachedExternalType { } #[derive( - Clone, Debug, Eq, PartialEq, TraceRawVcs, TaskInput, Hash, NonLocalValue, Encode, Decode, + Clone, + Debug, + Eq, + PartialEq, + TraceRawVcs, + TaskInput, + IsTransient, + Hash, + NonLocalValue, + Encode, + Decode, )] /// Whether to add a traced reference to the external module using the given context and resolve /// origin. diff --git a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs index e6085bda4888..3b242afc0169 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs @@ -3710,11 +3710,8 @@ pub struct AstPath( Vec, ); -impl TaskInput for AstPath { - fn is_transient(&self) -> bool { - false - } -} +impl TaskInput for AstPath {} +impl turbo_tasks::IsTransient for AstPath {} unsafe impl NonLocalValue for AstPath {} impl Deref for AstPath { diff --git a/turbopack/crates/turbopack-ecmascript/src/references/pattern_mapping.rs b/turbopack/crates/turbopack-ecmascript/src/references/pattern_mapping.rs index f38db658bdd4..965074c22104 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/pattern_mapping.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/pattern_mapping.rs @@ -12,8 +12,8 @@ use swc_core::{ }; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - FxIndexMap, NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, Vc, debug::ValueDebugFormat, - trace::TraceRawVcs, + FxIndexMap, IsTransient, NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, Vc, + debug::ValueDebugFormat, trace::TraceRawVcs, }; use turbopack_core::{ chunk::{ChunkableModule, ChunkingContext, ModuleChunkItemIdExt, ModuleId}, @@ -89,7 +89,18 @@ pub(crate) enum PatternMapping { } #[derive( - Copy, Clone, Debug, Eq, PartialEq, Hash, TraceRawVcs, TaskInput, NonLocalValue, Encode, Decode, + Copy, + Clone, + Debug, + Eq, + PartialEq, + Hash, + TraceRawVcs, + TaskInput, + IsTransient, + NonLocalValue, + Encode, + Decode, )] pub(crate) enum ResolveType { AsyncChunkLoader, diff --git a/turbopack/crates/turbopack-ecmascript/src/utils.rs b/turbopack/crates/turbopack-ecmascript/src/utils.rs index f30d80912612..314818500f30 100644 --- a/turbopack/crates/turbopack-ecmascript/src/utils.rs +++ b/turbopack/crates/turbopack-ecmascript/src/utils.rs @@ -242,11 +242,8 @@ pub struct AstSyntaxContext( SyntaxContext, ); -impl TaskInput for AstSyntaxContext { - fn is_transient(&self) -> bool { - false - } -} +impl TaskInput for AstSyntaxContext {} +impl turbo_tasks::IsTransient for AstSyntaxContext {} unsafe impl NonLocalValue for AstSyntaxContext {} impl Deref for AstSyntaxContext { diff --git a/turbopack/crates/turbopack-ecmascript/src/worker_chunk/worker_type.rs b/turbopack/crates/turbopack-ecmascript/src/worker_chunk/worker_type.rs index ab28cdb35242..111fa3f42e56 100644 --- a/turbopack/crates/turbopack-ecmascript/src/worker_chunk/worker_type.rs +++ b/turbopack/crates/turbopack-ecmascript/src/worker_chunk/worker_type.rs @@ -1,10 +1,21 @@ use bincode::{Decode, Encode}; use turbo_rcstr::{RcStr, rcstr}; -use turbo_tasks::{NonLocalValue, TaskInput, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, TaskInput, trace::TraceRawVcs}; use turbopack_core::reference_type::{ReferenceType, WorkerReferenceSubType}; #[derive( - Debug, Clone, Copy, Hash, PartialEq, Eq, Encode, Decode, TraceRawVcs, NonLocalValue, TaskInput, + Debug, + Clone, + Copy, + Hash, + PartialEq, + Eq, + Encode, + Decode, + TraceRawVcs, + NonLocalValue, + TaskInput, + IsTransient, )] pub enum WorkerType { WebWorker, diff --git a/turbopack/crates/turbopack-node/src/evaluate.rs b/turbopack/crates/turbopack-node/src/evaluate.rs index 111b35e8ef44..fc6f5c38fb34 100644 --- a/turbopack/crates/turbopack-node/src/evaluate.rs +++ b/turbopack/crates/turbopack-node/src/evaluate.rs @@ -9,8 +9,8 @@ use serde::{Deserialize, Serialize, de::DeserializeOwned}; use serde_json::Value as JsonValue; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - Completion, FxIndexMap, NonLocalValue, OperationVc, PrettyPrintError, ResolvedVc, TaskInput, - TryJoinIterExt, ValueToString, Vc, duration_span, fxindexmap, mark_top_level_task, + Completion, FxIndexMap, IsTransient, NonLocalValue, OperationVc, PrettyPrintError, ResolvedVc, + TaskInput, TryJoinIterExt, ValueToString, Vc, duration_span, fxindexmap, mark_top_level_task, parallel::available_parallelism, take_effects, trace::TraceRawVcs, }; use turbo_tasks_env::{EnvMap, ProcessEnv}; @@ -207,7 +207,18 @@ async fn create_evaluate_pool_assets_operation( } #[derive( - Clone, Copy, Hash, Debug, PartialEq, Eq, TaskInput, NonLocalValue, TraceRawVcs, Encode, Decode, + Clone, + Copy, + Hash, + Debug, + PartialEq, + Eq, + TaskInput, + IsTransient, + NonLocalValue, + TraceRawVcs, + Encode, + Decode, )] pub enum EnvVarTracking { WholeEnvTracked, diff --git a/turbopack/crates/turbopack-node/src/transforms/postcss.rs b/turbopack/crates/turbopack-node/src/transforms/postcss.rs index aad16fd1a636..36a204926cf6 100644 --- a/turbopack/crates/turbopack-node/src/transforms/postcss.rs +++ b/turbopack/crates/turbopack-node/src/transforms/postcss.rs @@ -4,8 +4,8 @@ use indoc::formatdoc; use serde::Deserialize; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - Completion, Completions, NonLocalValue, ResolvedVc, TaskInput, TryFlatJoinIterExt, Vc, - fxindexmap, trace::TraceRawVcs, + Completion, Completions, IsTransient, NonLocalValue, ResolvedVc, TaskInput, TryFlatJoinIterExt, + Vc, fxindexmap, trace::TraceRawVcs, }; use turbo_tasks_fs::{ File, FileContent, FileSystemEntryType, FileSystemPath, json::parse_json_with_source_context, @@ -55,6 +55,7 @@ struct PostCssProcessingResult { Debug, TraceRawVcs, TaskInput, + IsTransient, NonLocalValue, Encode, Decode, diff --git a/turbopack/crates/turbopack-node/src/transforms/webpack.rs b/turbopack/crates/turbopack-node/src/transforms/webpack.rs index 498fecbd3f2d..fe0bff281cb3 100644 --- a/turbopack/crates/turbopack-node/src/transforms/webpack.rs +++ b/turbopack/crates/turbopack-node/src/transforms/webpack.rs @@ -12,8 +12,8 @@ use serde_with::serde_as; use tracing::Instrument; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - Completion, OperationVc, ReadRef, ResolvedVc, TaskInput, TryJoinIterExt, ValueToString, - ValueToStringRef, Vc, trace::TraceRawVcs, + Completion, IsTransient, OperationVc, ReadRef, ResolvedVc, TaskInput, TryJoinIterExt, + ValueToString, ValueToStringRef, Vc, trace::TraceRawVcs, }; use turbo_tasks_env::ProcessEnv; use turbo_tasks_fs::{ @@ -438,7 +438,17 @@ pub enum InfoMessage { } #[derive( - Debug, Clone, TaskInput, Hash, PartialEq, Eq, Deserialize, TraceRawVcs, Encode, Decode, + Debug, + Clone, + TaskInput, + IsTransient, + Hash, + PartialEq, + Eq, + Deserialize, + TraceRawVcs, + Encode, + Decode, )] #[serde(rename_all = "camelCase")] pub struct WebpackResolveOptions { @@ -495,7 +505,9 @@ pub enum ResponseMessage { }, } -#[derive(Clone, PartialEq, Eq, Hash, TaskInput, Debug, TraceRawVcs, Encode, Decode)] +#[derive( + Clone, PartialEq, Eq, Hash, TaskInput, IsTransient, Debug, TraceRawVcs, Encode, Decode, +)] pub struct WebpackLoaderContext { pub entries: ResolvedVc, pub cwd: FileSystemPath, diff --git a/turbopack/crates/turbopack-tests/tests/execution.rs b/turbopack/crates/turbopack-tests/tests/execution.rs index 098625168615..c1916db2394c 100644 --- a/turbopack/crates/turbopack-tests/tests/execution.rs +++ b/turbopack/crates/turbopack-tests/tests/execution.rs @@ -14,8 +14,8 @@ use serde::Deserialize; use tracing_subscriber::{Registry, layer::SubscriberExt, util::SubscriberInitExt}; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ - Completion, Effects, NonLocalValue, OperationVc, ReadRef, ResolvedVc, TaskInput, TurboTasks, - Vc, debug::ValueDebugFormat, fxindexmap, take_effects, trace::TraceRawVcs, + Completion, Effects, IsTransient, NonLocalValue, OperationVc, ReadRef, ResolvedVc, TaskInput, + TurboTasks, Vc, debug::ValueDebugFormat, fxindexmap, take_effects, trace::TraceRawVcs, }; use turbo_tasks_backend::{BackendOptions, TurboTasksBackend, noop_backing_storage}; use turbo_tasks_env::CommandLineProcessEnv; @@ -82,7 +82,7 @@ struct JsResult { } #[turbo_tasks::value] -#[derive(Copy, Clone, Debug, Hash, TaskInput)] +#[derive(Copy, Clone, Debug, Hash)] enum IssueSnapshotMode { Snapshots, NoSnapshots, diff --git a/turbopack/crates/turbopack-wasm/src/source.rs b/turbopack/crates/turbopack-wasm/src/source.rs index 0a9e4ffc92a1..4e293fab3762 100644 --- a/turbopack/crates/turbopack-wasm/src/source.rs +++ b/turbopack/crates/turbopack-wasm/src/source.rs @@ -1,7 +1,7 @@ use anyhow::Result; use bincode::{Decode, Encode}; use turbo_rcstr::RcStr; -use turbo_tasks::{NonLocalValue, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; +use turbo_tasks::{IsTransient, NonLocalValue, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs}; use turbo_tasks_fs::{File, FileContent}; use turbopack_core::{ asset::{Asset, AssetContent}, @@ -19,6 +19,7 @@ use turbopack_core::{ Copy, Clone, TaskInput, + IsTransient, TraceRawVcs, NonLocalValue, Encode,