Skip to content

Commit 97eb25d

Browse files
committed
Fix an additional Reciever handling issue
1 parent 21f7a77 commit 97eb25d

File tree

2 files changed

+107
-74
lines changed

2 files changed

+107
-74
lines changed

turbopack/crates/turbo-tasks-fs/src/watcher.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::{
99
time::Duration,
1010
};
1111

12-
use anyhow::{Context, Result};
12+
use anyhow::Result;
1313
use notify::{
1414
event::{MetadataKind, ModifyKind, RenameMode},
1515
Config, EventKind, PollWatcher, RecommendedWatcher, RecursiveMode, Watcher,

turbopack/crates/turbo-tasks-macros/src/func.rs

Lines changed: 106 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,32 @@ impl TurboFn<'_> {
317317
orig_block: &'a Block,
318318
) -> (Signature, Cow<'a, Block>) {
319319
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+
}
320346
let (inputs, transform_stmts): (Punctuated<_, _>, Vec<Option<_>>) = self
321347
.orig_signature
322348
.inputs
@@ -331,84 +357,91 @@ impl TurboFn<'_> {
331357
inline_inputs_identifier_filter(&pat_id.ident)
332358
})
333359
.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 {
360378
attrs: Vec::new(),
361-
by_ref: None,
362379
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+
});
369383

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+
});
388435

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);
410442

411-
(arg, transform_stmt)
443+
(arg, Some(transform_stmt))
444+
}
412445
}
413446
})
414447
.unzip();

0 commit comments

Comments
 (0)