mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
Fixes #95125 in two ways The OP admits that they misread the message in a few ways, but we can fix all of them 1. Be specific about what function might need an annotation in the error message. A user with a nearby `path.join` might think that that is where the annotation belongs instead of on the function with the warning. 2. Be more flexible with how these `ignore` comments are interpreted `fs.readFileSync(path.join(process.cwd(), someVar))` shouldn't require 2 annotations. Handle this by checking for and detecting `turbopackIgnore` comments in all expressions! This will then bubble up through the linker and just cause us to ignore corresponding fs access apis.
184 lines
6.1 KiB
Rust
184 lines
6.1 KiB
Rust
#![feature(arbitrary_self_types)]
|
|
#![feature(arbitrary_self_types_pointers)]
|
|
#![allow(clippy::needless_return)] // tokio macro-generated code doesn't respect this
|
|
|
|
use anyhow::Result;
|
|
use turbo_tasks::{ReadRef, ResolvedVc, TraitRef, Vc};
|
|
use turbo_tasks_testing::{Registration, register, run_once};
|
|
|
|
static REGISTRATION: Registration = register!();
|
|
|
|
#[turbo_tasks::value]
|
|
struct Wrapper(u32);
|
|
|
|
#[turbo_tasks::function]
|
|
fn returns_int(value: u32) -> Vc<u32> {
|
|
Vc::cell(value)
|
|
}
|
|
|
|
#[turbo_tasks::function]
|
|
fn assert_resolved(input: ResolvedVc<u32>) {
|
|
// double-check that this `ResolvedVc` is *actually* resolved
|
|
let input_vc: Vc<u32> = *input;
|
|
assert!(input_vc.is_resolved());
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_conversion() -> Result<()> {
|
|
// pass a nonce to re-run the test body on every turbo-tasks restart
|
|
let mut nonce = 0;
|
|
run_once(®ISTRATION, move || {
|
|
nonce += 1;
|
|
async move {
|
|
#[turbo_tasks::function(operation, root)]
|
|
async fn test_operation(nonce: u32) -> Result<Vc<()>> {
|
|
let _ = nonce; // ensure the nonce is part of our cache key
|
|
let unresolved: Vc<u32> = Vc::cell(42);
|
|
let resolved: ResolvedVc<u32> = unresolved.to_resolved().await?;
|
|
let _: Vc<u32> = *resolved;
|
|
let _: ReadRef<u32> = resolved.await?;
|
|
let _: ReadRef<u32> = (&resolved).await?;
|
|
let _: u32 = *resolved.await?;
|
|
let _: u32 = *(&resolved).await?;
|
|
Ok(Vc::cell(()))
|
|
}
|
|
test_operation(nonce).read_strongly_consistent().await
|
|
}
|
|
})
|
|
.await
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_cell_construction() -> Result<()> {
|
|
let mut nonce = 0;
|
|
run_once(®ISTRATION, move || {
|
|
nonce += 1;
|
|
async move {
|
|
#[turbo_tasks::function(operation, root)]
|
|
async fn test_operation(nonce: u32) -> Result<Vc<()>> {
|
|
let _ = nonce;
|
|
let a: ResolvedVc<u32> = ResolvedVc::cell(42);
|
|
assert_eq!(*a.await?, 42);
|
|
let b: ResolvedVc<Wrapper> = Wrapper(42).resolved_cell();
|
|
assert_eq!(b.await?.0, 42);
|
|
Ok(Vc::cell(()))
|
|
}
|
|
test_operation(nonce).read_strongly_consistent().await
|
|
}
|
|
})
|
|
.await
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_resolved_vc_as_arg() -> Result<()> {
|
|
let mut nonce = 0;
|
|
run_once(®ISTRATION, move || {
|
|
nonce += 1;
|
|
async move {
|
|
#[turbo_tasks::function(operation, root)]
|
|
async fn test_operation(nonce: u32) -> Result<Vc<()>> {
|
|
dbg!(nonce);
|
|
let _ = nonce;
|
|
let unresolved: Vc<u32> = returns_int(42);
|
|
assert!(!unresolved.is_resolved());
|
|
// calling a function should cause it's arguments to get resolved automatically
|
|
assert_resolved(unresolved).await?;
|
|
Ok(Vc::cell(()))
|
|
}
|
|
test_operation(nonce).read_strongly_consistent().await
|
|
}
|
|
})
|
|
.await
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_into_future() -> Result<()> {
|
|
let mut nonce = 0;
|
|
run_once(®ISTRATION, move || {
|
|
nonce += 1;
|
|
async move {
|
|
#[turbo_tasks::function(operation, root)]
|
|
async fn test_operation(nonce: u32) -> Result<Vc<()>> {
|
|
let _ = nonce;
|
|
let mut resolved = ResolvedVc::cell(42);
|
|
let _: ReadRef<u32> = resolved.await?;
|
|
let _: ReadRef<u32> = (&resolved).await?;
|
|
let _: ReadRef<u32> = (&mut resolved).await?;
|
|
let mut unresolved = Vc::cell(42);
|
|
let _: ReadRef<u32> = unresolved.await?;
|
|
let _: ReadRef<u32> = (&unresolved).await?;
|
|
let _: ReadRef<u32> = (&mut unresolved).await?;
|
|
Ok(Vc::cell(()))
|
|
}
|
|
test_operation(nonce).read_strongly_consistent().await
|
|
}
|
|
})
|
|
.await
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_sidecast() -> Result<()> {
|
|
run_once(®ISTRATION, || async {
|
|
let concrete_value = ImplementsAAndB.resolved_cell();
|
|
let as_a = ResolvedVc::upcast::<Box<dyn TraitA>>(concrete_value);
|
|
let as_b = ResolvedVc::try_sidecast::<Box<dyn TraitB>>(as_a);
|
|
assert!(as_b.is_some());
|
|
let as_c = ResolvedVc::try_sidecast::<Box<dyn TraitC>>(as_a);
|
|
assert!(as_c.is_none());
|
|
Ok(())
|
|
})
|
|
.await
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_trait_ref_downcast() -> Result<()> {
|
|
run_once(®ISTRATION, || async {
|
|
let as_base: Vc<Box<dyn BaseTrait>> = Vc::upcast(ImplementsSubImplemented.cell());
|
|
let ref_base = as_base.into_trait_ref().await?;
|
|
// The concrete value implements SubImplemented, so downcasting the already-read
|
|
// trait ref to it succeeds without another cell read.
|
|
assert!(TraitRef::try_downcast::<Box<dyn SubImplemented>>(ref_base.clone()).is_some());
|
|
// It does not implement SubNotImplemented, so the downcast returns None.
|
|
assert!(TraitRef::try_downcast::<Box<dyn SubNotImplemented>>(ref_base).is_none());
|
|
Ok(())
|
|
})
|
|
.await
|
|
}
|
|
|
|
#[turbo_tasks::value_trait]
|
|
trait TraitA {}
|
|
|
|
#[turbo_tasks::value_trait]
|
|
trait TraitB {}
|
|
|
|
#[turbo_tasks::value_trait]
|
|
trait TraitC {}
|
|
|
|
#[turbo_tasks::value]
|
|
struct ImplementsAAndB;
|
|
|
|
#[turbo_tasks::value_impl]
|
|
impl TraitA for ImplementsAAndB {}
|
|
|
|
#[turbo_tasks::value_impl]
|
|
impl TraitB for ImplementsAAndB {}
|
|
|
|
#[turbo_tasks::value_trait]
|
|
trait BaseTrait {}
|
|
|
|
// Two sub-traits of `BaseTrait`; the test's value implements only the first.
|
|
#[turbo_tasks::value_trait]
|
|
trait SubImplemented: BaseTrait {}
|
|
|
|
#[turbo_tasks::value_trait]
|
|
trait SubNotImplemented: BaseTrait {}
|
|
|
|
#[turbo_tasks::value]
|
|
struct ImplementsSubImplemented;
|
|
|
|
#[turbo_tasks::value_impl]
|
|
impl BaseTrait for ImplementsSubImplemented {}
|
|
|
|
#[turbo_tasks::value_impl]
|
|
impl SubImplemented for ImplementsSubImplemented {}
|