From f70006ea162141543efcdc4f2678bc4208428e2b Mon Sep 17 00:00:00 2001 From: Benjamin Woodruff Date: Mon, 7 Oct 2024 15:05:54 -0700 Subject: [PATCH] refactor(turbopack/next-core): Remove uses of generic vc collections (#70815) Removes the uses of generic vc collections in `next-core/src/app_structure.rs` and it's callsites. ## Why? Rather than extended support for `Vc` generics to `ResolvedVc`, I plan to remove support for them entirely. That means fixing all the callsites (there's not many). Removing this is needed to get us to a point where 100% of structs can be `ResolvedValue`, because structs using these fields cannot otherwise be ported over to `ResolvedVc`. ## Okay, but Why? Explained here: https://github.com/vercel/turborepo/pull/8843#issuecomment-2253158412 I expect removing support for this will decrease the overall size of the codebase, as the logic for supporting generics is rather complicated. --- crates/next-api/src/app.rs | 8 +++---- crates/next-core/src/app_structure.rs | 34 +++++++++++++++++++-------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/crates/next-api/src/app.rs b/crates/next-api/src/app.rs index 6469ec953672b..65600fc7f29eb 100644 --- a/crates/next-api/src/app.rs +++ b/crates/next-api/src/app.rs @@ -5,7 +5,7 @@ use next_core::{ app_segment_config::NextSegmentConfig, app_structure::{ get_entrypoints, AppPageLoaderTree, Entrypoint as AppEntrypoint, - Entrypoints as AppEntrypoints, MetadataItem, + Entrypoints as AppEntrypoints, FileSystemPathVec, MetadataItem, }, get_edge_resolve_options_context, get_next_package, next_app::{ @@ -705,7 +705,7 @@ enum AppEndpointType { }, Route { path: Vc, - root_layouts: Vc>>, + root_layouts: Vc, }, Metadata { metadata: MetadataItem, @@ -737,7 +737,7 @@ impl AppEndpoint { async fn app_route_entry( &self, path: Vc, - root_layouts: Vc>>, + root_layouts: Vc, next_config: Vc, ) -> Result> { let root_layouts = root_layouts.await?; @@ -747,7 +747,7 @@ impl AppEndpoint { let mut config = NextSegmentConfig::default(); for layout in root_layouts.iter().rev() { - let source = Vc::upcast(FileSource::new(*layout)); + let source = Vc::upcast(FileSource::new(**layout)); let layout_config = parse_segment_config_from_source(source); config.apply_parent_config(&*layout_config.await?); } diff --git a/crates/next-core/src/app_structure.rs b/crates/next-core/src/app_structure.rs index 7c3cf03bc4fde..f317eddf09da4 100644 --- a/crates/next-core/src/app_structure.rs +++ b/crates/next-core/src/app_structure.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use tracing::Instrument; use turbo_tasks::{ debug::ValueDebugFormat, trace::TraceRawVcs, RcStr, ResolvedVc, TaskInput, TryJoinIterExt, - ValueToString, Vc, + ValueDefault, ValueToString, Vc, }; use turbo_tasks_fs::{DirectoryContent, DirectoryEntry, FileSystemEntryType, FileSystemPath}; use turbopack_core::issue::{ @@ -467,6 +467,17 @@ impl AppPageLoaderTree { } } +#[turbo_tasks::value(transparent)] +pub struct FileSystemPathVec(Vec>); + +#[turbo_tasks::value_impl] +impl ValueDefault for FileSystemPathVec { + #[turbo_tasks::function] + fn value_default() -> Vc { + Vc::cell(Vec::new()) + } +} + #[derive( Clone, PartialEq, @@ -487,7 +498,7 @@ pub enum Entrypoint { AppRoute { page: AppPage, path: ResolvedVc, - root_layouts: ResolvedVc>>, + root_layouts: ResolvedVc, }, AppMetadata { page: AppPage, @@ -615,7 +626,7 @@ fn add_app_route( result: &mut IndexMap, page: AppPage, path: ResolvedVc, - root_layouts: ResolvedVc>>, + root_layouts: ResolvedVc, ) { let e = match result.entry(page.clone().into()) { Entry::Occupied(e) => e, @@ -709,7 +720,7 @@ fn directory_tree_to_entrypoints( app_dir: Vc, directory_tree: Vc, global_metadata: Vc, - root_layouts: Vc>>, + root_layouts: Vc, ) -> Vc { directory_tree_to_entrypoints_internal( app_dir, @@ -792,6 +803,9 @@ fn check_duplicate( } } +#[turbo_tasks::value(transparent)] +struct AppPageLoaderTreeOption(Option>); + /// creates the loader tree for a specific route (pathname / [AppPath]) #[turbo_tasks::function] async fn directory_tree_to_loader_tree( @@ -802,7 +816,7 @@ async fn directory_tree_to_loader_tree( app_page: AppPage, // the page this loader tree is constructed for for_app_path: AppPath, -) -> Result>>> { +) -> Result> { let plain_tree = &*directory_tree.into_plain().await?; let tree = directory_tree_to_loader_tree_internal( @@ -814,7 +828,7 @@ async fn directory_tree_to_loader_tree( for_app_path, )?; - Ok(Vc::cell(tree.map(|tree| tree.cell()))) + Ok(Vc::cell(tree.map(AppPageLoaderTree::resolved_cell))) } fn directory_tree_to_loader_tree_internal( @@ -1044,7 +1058,7 @@ async fn directory_tree_to_entrypoints_internal( directory_name: RcStr, directory_tree: Vc, app_page: AppPage, - root_layouts: ResolvedVc>>, + root_layouts: ResolvedVc, ) -> Result> { let span = tracing::info_span!("build layout trees", name = display(&app_page)); directory_tree_to_entrypoints_internal_untraced( @@ -1065,7 +1079,7 @@ async fn directory_tree_to_entrypoints_internal_untraced( directory_name: RcStr, directory_tree: Vc, app_page: AppPage, - root_layouts: ResolvedVc>>, + root_layouts: ResolvedVc, ) -> Result> { let mut result = IndexMap::new(); @@ -1078,8 +1092,8 @@ async fn directory_tree_to_entrypoints_internal_untraced( // segment config. https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes#segment-runtime-option // Pass down layouts from each tree to apply segment config when adding route. let root_layouts = if let Some(layout) = modules.layout { - let mut layouts = (*root_layouts.await?).clone(); - layouts.push(layout); + let mut layouts = root_layouts.await?.clone_value(); + layouts.push(layout.to_resolved().await?); ResolvedVc::cell(layouts) } else { root_layouts