in starlark_derive/src/parse.rs [247:324]
fn parse_fun(func: ItemFn) -> syn::Result<StarStmt> {
let span = func.span();
let sig_span = func.sig.span();
let ProcessedAttributes {
is_attribute,
type_attribute,
speculative_exec_safe,
docstring,
attrs,
} = process_attributes(func.span(), func.attrs)?;
let (return_type, return_type_arg) = match func.sig.output {
ReturnType::Default => {
return Err(syn::Error::new(span, "Function must have a return type"));
}
ReturnType::Type(_, x) => match is_anyhow_result(&x) {
Some(return_arg_type) => (x, return_arg_type),
None => {
return Err(syn::Error::new(
span,
"Function return type must be precisely `anyhow::Result<...>`",
));
}
},
};
let mut args: Vec<_> = func
.sig
.inputs
.into_iter()
.map(parse_arg)
.collect::<Result<_, _>>()?;
if is_attribute {
if args.len() != 1 {
return Err(syn::Error::new(
sig_span,
"Attribute function must have single parameter",
));
}
let arg = args.pop().unwrap();
if !arg.is_this() {
return Err(syn::Error::new(
sig_span,
"Attribute function must have `this` as the only parameter",
));
}
if arg.default.is_some() {
return Err(syn::Error::new(
sig_span,
"Attribute function `this` parameter have no default value",
));
}
Ok(StarStmt::Attr(StarAttr {
name: func.sig.ident,
arg: arg.ty,
attrs,
return_type: *return_type,
return_type_arg,
speculative_exec_safe,
body: *func.block,
docstring,
}))
} else {
Ok(StarStmt::Fun(StarFun {
name: func.sig.ident,
type_attribute,
attrs,
args,
return_type: *return_type,
return_type_arg,
speculative_exec_safe,
body: *func.block,
source: StarFunSource::Unknown,
docstring,
}))
}
}