@@ -317,6 +317,32 @@ impl TurboFn<'_> {
317
317
orig_block : & ' a Block ,
318
318
) -> ( Signature , Cow < ' a , Block > ) {
319
319
let mut shadow_self = None ;
320
+
321
+ fn transform_from_task_input (
322
+ span : Span ,
323
+ arg_id : Cow < ' _ , Ident > ,
324
+ orig_ty : & Type ,
325
+ pat : Pat ,
326
+ ) -> Stmt {
327
+ Stmt :: Local ( Local {
328
+ attrs : Vec :: new ( ) ,
329
+ let_token : Default :: default ( ) ,
330
+ pat,
331
+ init : Some ( LocalInit {
332
+ eq_token : Default :: default ( ) ,
333
+ // we know the argument implements `FromTaskInput` because
334
+ // `expand_task_input_type` returned `Cow::Owned`
335
+ expr : parse_quote_spanned ! {
336
+ span =>
337
+ <#orig_ty as turbo_tasks:: task:: FromTaskInput >:: from_task_input(
338
+ #arg_id
339
+ )
340
+ } ,
341
+ diverge : None ,
342
+ } ) ,
343
+ semi_token : Default :: default ( ) ,
344
+ } )
345
+ }
320
346
let ( inputs, transform_stmts) : ( Punctuated < _ , _ > , Vec < Option < _ > > ) = self
321
347
. orig_signature
322
348
. inputs
@@ -331,84 +357,91 @@ impl TurboFn<'_> {
331
357
inline_inputs_identifier_filter ( & pat_id. ident )
332
358
} )
333
359
. enumerate ( )
334
- . map ( |( idx, arg) | match arg {
335
- FnArg :: Receiver ( _) => ( arg. clone ( ) , None ) ,
336
- FnArg :: Typed ( pat_type) => {
337
- if self . operation {
338
- // operations shouldn't have their arguments rewritten, they require all
339
- // arguments are explicitly `NonLocalValue`s
340
- return ( arg. clone ( ) , None ) ;
341
- }
342
- let Cow :: Owned ( expanded_ty) = expand_task_input_type ( & pat_type. ty ) else {
343
- // common-case: skip if no type conversion is needed
344
- return ( arg. clone ( ) , None ) ;
345
- } ;
346
-
347
- let arg_id = if let Pat :: Ident ( pat_id) = & * pat_type. pat {
348
- // common case: argument is just an identifier
349
- Cow :: Borrowed ( & pat_id. ident )
350
- } else {
351
- // argument is a pattern, we need to rewrite it to a unique identifier
352
- Cow :: Owned ( Ident :: new (
353
- & format ! ( "arg{idx}" ) ,
354
- pat_type. span ( ) . resolved_at ( Span :: mixed_site ( ) ) ,
355
- ) )
356
- } ;
357
-
358
- let arg = FnArg :: Typed ( PatType {
359
- pat : Box :: new ( Pat :: Ident ( PatIdent {
360
+ . map ( |( idx, arg) | {
361
+ if self . operation {
362
+ // operations shouldn't have their arguments rewritten, they require all
363
+ // arguments are explicitly `NonLocalValue`s
364
+ return ( arg. clone ( ) , None ) ;
365
+ }
366
+ let ( FnArg :: Receiver ( Receiver { ty, .. } ) | FnArg :: Typed ( PatType { ty, .. } ) ) = arg;
367
+ let Cow :: Owned ( expanded_ty) = expand_task_input_type ( & ty) else {
368
+ // common-case: skip if no type conversion is needed
369
+ return ( arg. clone ( ) , None ) ;
370
+ } ;
371
+ match arg {
372
+ FnArg :: Receiver (
373
+ receiver @ Receiver {
374
+ attrs, self_token, ..
375
+ } ,
376
+ ) => {
377
+ let arg = FnArg :: Receiver ( Receiver {
360
378
attrs : Vec :: new ( ) ,
361
- by_ref : None ,
362
379
mutability : None ,
363
- ident : arg_id. clone ( ) . into_owned ( ) ,
364
- subpat : None ,
365
- } ) ) ,
366
- ty : Box :: new ( expanded_ty) ,
367
- ..pat_type. clone ( )
368
- } ) ;
380
+ ty : Box :: new ( expanded_ty) ,
381
+ ..receiver. clone ( )
382
+ } ) ;
369
383
370
- // We can't shadow `self` variables, so it this argument is a `self` argument,
371
- // generate a new identifier, and rewrite the body of the function later to use
372
- // that new identifier.
373
- // NOTE: arbitrary self types aren't `FnArg::Receiver` on syn 1.x (fixed in 2.x)
374
- let transform_pat = match & * pat_type. pat {
375
- Pat :: Ident ( pat_id) if pat_id. ident == "self" => {
376
- let shadow_self_id = Ident :: new (
377
- "turbo_tasks_self" ,
378
- Span :: mixed_site ( ) . located_at ( pat_id. ident . span ( ) ) ,
379
- ) ;
380
- shadow_self = Some ( shadow_self_id. clone ( ) ) ;
381
- Pat :: Ident ( PatIdent {
382
- ident : shadow_self_id,
383
- ..pat_id. clone ( )
384
- } )
385
- }
386
- pat => pat. clone ( ) ,
387
- } ;
384
+ // We can't shadow `self` variables, so it this argument is a `self`
385
+ // argument, generate a new identifier, and rewrite
386
+ // the body of the function later to use
387
+ // that new identifier.
388
+ // NOTE: arbitrary self types aren't `FnArg::Receiver` on syn 1.x (fixed in
389
+ // 2.x)
390
+ let shadow_self_id = Ident :: new (
391
+ "turbo_tasks_self" ,
392
+ Span :: mixed_site ( ) . located_at ( self_token. span ( ) ) ,
393
+ ) ;
394
+ shadow_self = Some ( shadow_self_id. clone ( ) ) ;
395
+ let shadow_self_pattern = Pat :: Ident ( PatIdent {
396
+ ident : shadow_self_id,
397
+ attrs : attrs. clone ( ) ,
398
+ mutability : None ,
399
+ by_ref : None ,
400
+ subpat : None ,
401
+ } ) ;
402
+ let self_ident = Cow :: Owned ( Ident :: new ( "self" , self_token. span ( ) ) ) ;
403
+ let transform_stmt = transform_from_task_input (
404
+ receiver. span ( ) ,
405
+ self_ident,
406
+ ty,
407
+ shadow_self_pattern,
408
+ ) ;
409
+
410
+ ( arg, Some ( transform_stmt) )
411
+ }
412
+ FnArg :: Typed ( pat_type) => {
413
+ let arg_id = if let Pat :: Ident ( pat_id) = & * pat_type. pat {
414
+ // common case: argument is just an identifier
415
+ Cow :: Borrowed ( & pat_id. ident )
416
+ } else {
417
+ // argument is a pattern, we need to rewrite it to a unique identifier
418
+ Cow :: Owned ( Ident :: new (
419
+ & format ! ( "arg{idx}" ) ,
420
+ pat_type. span ( ) . resolved_at ( Span :: mixed_site ( ) ) ,
421
+ ) )
422
+ } ;
423
+
424
+ let arg = FnArg :: Typed ( PatType {
425
+ pat : Box :: new ( Pat :: Ident ( PatIdent {
426
+ attrs : Vec :: new ( ) ,
427
+ by_ref : None ,
428
+ mutability : None ,
429
+ ident : arg_id. clone ( ) . into_owned ( ) ,
430
+ subpat : None ,
431
+ } ) ) ,
432
+ ty : Box :: new ( expanded_ty) ,
433
+ ..pat_type. clone ( )
434
+ } ) ;
388
435
389
- // convert an argument of type `FromTaskInput<T>::TaskInput` into `T`.
390
- // essentially, replace any instances of `Vc` with `ResolvedVc`.
391
- let orig_ty = & * pat_type. ty ;
392
- let transform_stmt = Some ( Stmt :: Local ( Local {
393
- attrs : Vec :: new ( ) ,
394
- let_token : Default :: default ( ) ,
395
- pat : transform_pat,
396
- init : Some ( LocalInit {
397
- eq_token : Default :: default ( ) ,
398
- // we know the argument implements `FromTaskInput` because
399
- // `expand_task_input_type` returned `Cow::Owned`
400
- expr : parse_quote_spanned ! {
401
- pat_type. span( ) =>
402
- <#orig_ty as turbo_tasks:: task:: FromTaskInput >:: from_task_input(
403
- #arg_id
404
- )
405
- } ,
406
- diverge : None ,
407
- } ) ,
408
- semi_token : Default :: default ( ) ,
409
- } ) ) ;
436
+ // convert an argument of type `FromTaskInput<T>::TaskInput` into `T`.
437
+ // essentially, replace any instances of `Vc` with `ResolvedVc`.
438
+ let orig_ty = & * pat_type. ty ;
439
+ let pat = ( & * pat_type. pat ) . clone ( ) ;
440
+ let transform_stmt =
441
+ transform_from_task_input ( pat_type. span ( ) , arg_id, orig_ty, pat) ;
410
442
411
- ( arg, transform_stmt)
443
+ ( arg, Some ( transform_stmt) )
444
+ }
412
445
}
413
446
} )
414
447
. unzip ( ) ;
0 commit comments