Skip to content

Commit cbf3215

Browse files
authored
fix(turbo-tasks): Implement TaskInput for ResolvedVc` (vercel#70814)
`TaskInput` isn't needed/used for a bare `ResolvedVc`, as we'll expose `ResolvedVc` arguments as `Vc`, but it is useful for structs that contain `ResolvedVc` and want to derive `TaskInput`. This PR also ports `next_core::app_structure::Entrypoint` to use `ResolvedVc` as a way of testing this.
1 parent 809cce8 commit cbf3215

File tree

4 files changed

+67
-40
lines changed

4 files changed

+67
-40
lines changed

crates/next-api/src/app.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ pub fn app_entry_point_to_route(
627627
AppEndpoint {
628628
ty: AppEndpointType::Page {
629629
ty: AppPageEndpointType::Html,
630-
loader_tree,
630+
loader_tree: *loader_tree,
631631
},
632632
app_project,
633633
page: page.clone(),
@@ -638,7 +638,7 @@ pub fn app_entry_point_to_route(
638638
AppEndpoint {
639639
ty: AppEndpointType::Page {
640640
ty: AppPageEndpointType::Rsc,
641-
loader_tree,
641+
loader_tree: *loader_tree,
642642
},
643643
app_project,
644644
page,
@@ -656,7 +656,10 @@ pub fn app_entry_point_to_route(
656656
original_name: page.to_string(),
657657
endpoint: Vc::upcast(
658658
AppEndpoint {
659-
ty: AppEndpointType::Route { path, root_layouts },
659+
ty: AppEndpointType::Route {
660+
path: *path,
661+
root_layouts: *root_layouts,
662+
},
660663
app_project,
661664
page,
662665
}

crates/next-core/src/app_structure.rs

+35-32
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use rustc_hash::FxHashMap;
1010
use serde::{Deserialize, Serialize};
1111
use tracing::Instrument;
1212
use turbo_tasks::{
13-
debug::ValueDebugFormat, trace::TraceRawVcs, RcStr, TaskInput, TryJoinIterExt, ValueToString,
14-
Vc,
13+
debug::ValueDebugFormat, trace::TraceRawVcs, RcStr, ResolvedVc, TaskInput, TryJoinIterExt,
14+
ValueToString, Vc,
1515
};
1616
use turbo_tasks_fs::{DirectoryContent, DirectoryEntry, FileSystemEntryType, FileSystemPath};
1717
use turbopack_core::issue::{
@@ -296,23 +296,22 @@ async fn get_directory_tree_internal(
296296
let entry = entry.resolve_symlink().await?;
297297
match entry {
298298
DirectoryEntry::File(file) => {
299-
let file = file.resolve().await?;
300299
// Do not process .d.ts files as routes
301300
if basename.ends_with(".d.ts") {
302301
continue;
303302
}
304303
if let Some((stem, ext)) = basename.split_once('.') {
305304
if page_extensions_value.iter().any(|e| e == ext) {
306305
match stem {
307-
"page" => modules.page = Some(file),
308-
"layout" => modules.layout = Some(file),
309-
"error" => modules.error = Some(file),
310-
"global-error" => modules.global_error = Some(file),
311-
"loading" => modules.loading = Some(file),
312-
"template" => modules.template = Some(file),
313-
"not-found" => modules.not_found = Some(file),
314-
"default" => modules.default = Some(file),
315-
"route" => modules.route = Some(file),
306+
"page" => modules.page = Some(*file),
307+
"layout" => modules.layout = Some(*file),
308+
"error" => modules.error = Some(*file),
309+
"global-error" => modules.global_error = Some(*file),
310+
"loading" => modules.loading = Some(*file),
311+
"template" => modules.template = Some(*file),
312+
"not-found" => modules.not_found = Some(*file),
313+
"default" => modules.default = Some(*file),
314+
"route" => modules.route = Some(*file),
316315
_ => {}
317316
}
318317
}
@@ -334,17 +333,17 @@ async fn get_directory_tree_internal(
334333
"opengraph-image" => &mut metadata_open_graph,
335334
"sitemap" => {
336335
if dynamic {
337-
modules.metadata.sitemap = Some(MetadataItem::Dynamic { path: file });
336+
modules.metadata.sitemap = Some(MetadataItem::Dynamic { path: *file });
338337
} else {
339-
modules.metadata.sitemap = Some(MetadataItem::Static { path: file });
338+
modules.metadata.sitemap = Some(MetadataItem::Static { path: *file });
340339
}
341340
continue;
342341
}
343342
_ => continue,
344343
};
345344

346345
if dynamic {
347-
entry.push((number, MetadataWithAltItem::Dynamic { path: file }));
346+
entry.push((number, MetadataWithAltItem::Dynamic { path: *file }));
348347
continue;
349348
}
350349

@@ -360,16 +359,15 @@ async fn get_directory_tree_internal(
360359
entry.push((
361360
number,
362361
MetadataWithAltItem::Static {
363-
path: file,
362+
path: *file,
364363
alt_path,
365364
},
366365
));
367366
}
368367
DirectoryEntry::Directory(dir) => {
369-
let dir = dir.resolve().await?;
370368
// appDir ignores paths starting with an underscore
371369
if !basename.starts_with('_') {
372-
let result = get_directory_tree(dir, page_extensions);
370+
let result = get_directory_tree(*dir, page_extensions);
373371
subdirectories.insert(basename.clone(), result);
374372
}
375373
}
@@ -484,12 +482,12 @@ impl AppPageLoaderTree {
484482
pub enum Entrypoint {
485483
AppPage {
486484
pages: Vec<AppPage>,
487-
loader_tree: Vc<AppPageLoaderTree>,
485+
loader_tree: ResolvedVc<AppPageLoaderTree>,
488486
},
489487
AppRoute {
490488
page: AppPage,
491-
path: Vc<FileSystemPath>,
492-
root_layouts: Vc<Vec<Vc<FileSystemPath>>>,
489+
path: ResolvedVc<FileSystemPath>,
490+
root_layouts: ResolvedVc<Vec<Vc<FileSystemPath>>>,
493491
},
494492
AppMetadata {
495493
page: AppPage,
@@ -557,7 +555,7 @@ fn add_app_page(
557555
app_dir: Vc<FileSystemPath>,
558556
result: &mut IndexMap<AppPath, Entrypoint>,
559557
page: AppPage,
560-
loader_tree: Vc<AppPageLoaderTree>,
558+
loader_tree: ResolvedVc<AppPageLoaderTree>,
561559
) {
562560
let mut e = match result.entry(page.clone().into()) {
563561
Entry::Occupied(e) => e,
@@ -616,8 +614,8 @@ fn add_app_route(
616614
app_dir: Vc<FileSystemPath>,
617615
result: &mut IndexMap<AppPath, Entrypoint>,
618616
page: AppPage,
619-
path: Vc<FileSystemPath>,
620-
root_layouts: Vc<Vec<Vc<FileSystemPath>>>,
617+
path: ResolvedVc<FileSystemPath>,
618+
root_layouts: ResolvedVc<Vec<Vc<FileSystemPath>>>,
621619
) {
622620
let e = match result.entry(page.clone().into()) {
623621
Entry::Occupied(e) => e,
@@ -1046,7 +1044,7 @@ async fn directory_tree_to_entrypoints_internal(
10461044
directory_name: RcStr,
10471045
directory_tree: Vc<DirectoryTree>,
10481046
app_page: AppPage,
1049-
root_layouts: Vc<Vec<Vc<FileSystemPath>>>,
1047+
root_layouts: ResolvedVc<Vec<Vc<FileSystemPath>>>,
10501048
) -> Result<Vc<Entrypoints>> {
10511049
let span = tracing::info_span!("build layout trees", name = display(&app_page));
10521050
directory_tree_to_entrypoints_internal_untraced(
@@ -1067,7 +1065,7 @@ async fn directory_tree_to_entrypoints_internal_untraced(
10671065
directory_name: RcStr,
10681066
directory_tree: Vc<DirectoryTree>,
10691067
app_page: AppPage,
1070-
root_layouts: Vc<Vec<Vc<FileSystemPath>>>,
1068+
root_layouts: ResolvedVc<Vec<Vc<FileSystemPath>>>,
10711069
) -> Result<Vc<Entrypoints>> {
10721070
let mut result = IndexMap::new();
10731071

@@ -1082,7 +1080,7 @@ async fn directory_tree_to_entrypoints_internal_untraced(
10821080
let root_layouts = if let Some(layout) = modules.layout {
10831081
let mut layouts = (*root_layouts.await?).clone();
10841082
layouts.push(layout);
1085-
Vc::cell(layouts)
1083+
ResolvedVc::cell(layouts)
10861084
} else {
10871085
root_layouts
10881086
};
@@ -1104,7 +1102,10 @@ async fn directory_tree_to_entrypoints_internal_untraced(
11041102
app_dir,
11051103
&mut result,
11061104
app_page.complete(PageType::Page)?,
1107-
loader_tree.context("loader tree should be created for a page/default")?,
1105+
loader_tree
1106+
.context("loader tree should be created for a page/default")?
1107+
.to_resolved()
1108+
.await?,
11081109
);
11091110
}
11101111

@@ -1113,7 +1114,7 @@ async fn directory_tree_to_entrypoints_internal_untraced(
11131114
app_dir,
11141115
&mut result,
11151116
app_page.complete(PageType::Route)?,
1116-
route,
1117+
route.to_resolved().await?,
11171118
root_layouts,
11181119
);
11191120
}
@@ -1191,7 +1192,7 @@ async fn directory_tree_to_entrypoints_internal_untraced(
11911192
},
11921193
modules: modules.without_leafs(),
11931194
global_metadata,
1194-
}.cell();
1195+
}.resolved_cell();
11951196

11961197
{
11971198
let app_page = app_page
@@ -1223,7 +1224,7 @@ async fn directory_tree_to_entrypoints_internal_untraced(
12231224
subdir_name.clone(),
12241225
subdirectory,
12251226
child_app_page.clone(),
1226-
root_layouts,
1227+
*root_layouts,
12271228
)
12281229
.await?;
12291230

@@ -1278,7 +1279,9 @@ async fn directory_tree_to_entrypoints_internal_untraced(
12781279
&mut result,
12791280
page.clone(),
12801281
loader_tree
1281-
.context("loader tree should be created for a page/default")?,
1282+
.context("loader tree should be created for a page/default")?
1283+
.to_resolved()
1284+
.await?,
12821285
);
12831286
}
12841287
}

turbopack/crates/turbo-tasks/src/task/task_input.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use std::{any::Any, fmt::Debug, future::Future, hash::Hash, time::Duration};
33
use anyhow::Result;
44
use serde::{Deserialize, Serialize};
55

6-
use crate::{MagicAny, RcStr, TaskId, TransientInstance, TransientValue, Value, ValueTypeId, Vc};
6+
use crate::{
7+
MagicAny, RcStr, ResolvedVc, TaskId, TransientInstance, TransientValue, Value, ValueTypeId, Vc,
8+
};
79

810
/// Trait to implement in order for a type to be accepted as a
911
/// [`#[turbo_tasks::function]`][crate::function] argument.
@@ -108,6 +110,25 @@ where
108110
}
109111
}
110112

113+
// `TaskInput` isn't needed/used for a bare `ResolvedVc`, as we'll expose `ResolvedVc` arguments as
114+
// `Vc`, but it is useful for structs that contain `ResolvedVc` and want to derive `TaskInput`.
115+
impl<T> TaskInput for ResolvedVc<T>
116+
where
117+
T: Send,
118+
{
119+
fn is_resolved(&self) -> bool {
120+
true
121+
}
122+
123+
fn is_transient(&self) -> bool {
124+
self.node.is_transient()
125+
}
126+
127+
async fn resolve(&self) -> Result<Self> {
128+
Ok(*self)
129+
}
130+
}
131+
111132
impl<T> TaskInput for Value<T>
112133
where
113134
T: Any

turbopack/crates/turbopack-core/src/resolve/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1012,9 +1012,9 @@ async fn type_exists(
10121012
for path in result.symlinks.iter() {
10131013
refs.push(Vc::upcast(FileSource::new(**path)));
10141014
}
1015-
let path = result.path.resolve().await?;
1015+
let path = result.path;
10161016
Ok(if *path.get_type().await? == ty {
1017-
Some(path)
1017+
Some(*path)
10181018
} else {
10191019
None
10201020
})
@@ -1028,7 +1028,7 @@ async fn any_exists(
10281028
for path in result.symlinks.iter() {
10291029
refs.push(Vc::upcast(FileSource::new(**path)));
10301030
}
1031-
let path = result.path.resolve().await?;
1031+
let path = result.path;
10321032
let ty = *path.get_type().await?;
10331033
Ok(
10341034
if matches!(
@@ -1037,7 +1037,7 @@ async fn any_exists(
10371037
) {
10381038
None
10391039
} else {
1040-
Some((ty, path))
1040+
Some((ty, *path))
10411041
},
10421042
)
10431043
}

0 commit comments

Comments
 (0)