diesel-rs/diesel · error · syn::Error
function body should not be empty for auto_type
Error message
function body should not be empty for auto_type
What it means
#[auto_type] needs at least one statement in the function body: it inspects the last statement to determine the return type and build the type alias. An empty body (`fn f() -> _ {}`) leaves `block.stmts.last()` as None, so the macro errors with this message instead of silently generating nothing.
Solutions
- Add at least one expression statement / return expression to the function body.
- Remove #[auto_type] from the empty stub until the body is implemented.
- Give the function a concrete return type and drop the macro if it must remain empty.
Example fix
// before
#[auto_type]
fn f() -> _ {}
// after
#[auto_type]
fn f() -> _ { 0i32 } Defensive patterns
Strategy: validation
Validate before calling
fn ensure_nonempty(body: &[syn::Stmt]) -> Result<(), ()> { if body.is_empty() { Err(()) } else { Ok(()) } } Prevention
- Don't attach #[auto_type] to stub/TODO functions.
- Implement the body before adding the attribute.
When it happens
Trigger: `#[auto_type] fn f() -> _ {}` — a function whose block contains no statements at all.
Common situations: Scaffolding a stub function and adding #[auto_type] before writing the body; or commenting out the entire body while keeping the attribute during debugging.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- references are not supported in `Queryable` types consider…
- invalid variadic argument count: not enough function…
- unsupported expression for auto_type, please provide a type…
- auto_type: unexpected double type ascription
- auto_type: tuple let assignment and its type ascription…
AI-assisted analysis of diesel-rs/diesel@6fa6ed01b2 (2026-09-07).
Data as JSON: /api/errors/2c1c3a81b86de016.
Report an issue: GitHub.
Appendix: source
Thrown at dsl_auto_type/src/auto_type/mod.rs:122
let last_statement = input_function.block.stmts.last().ok_or_else(|| {
syn::Error::new(
input_function.span(),
"function body should not be empty for auto_type",
)
})?;
let mut errors = Vec::new();
let return_type = match input_function.sig.output {
syn::ReturnType::Type(_, return_type) => {
let return_expression = match last_statement {
syn::Stmt::Expr(expr, None) => expr,
syn::Stmt::Expr(
syn::Expr::Return(syn::ExprReturn {
expr: Some(expr), ..
}),
_,
) => &**expr,
_ => {
return Err(syn::Error::new(
last_statement.span(),
"last statement should be an expression for auto_type",
)
.into());
}
};
// Build a map of local variables, and get the function parameters in there
let mut local_variables_map = LocalVariablesMap {
inferrer_settings: &inferrer_settings,
inner: LocalVariablesMapInner {
map: Default::default(),
parent: None,
},
};
for const_generic in input_function.sig.generics.const_params() {
local_variables_map.process_const_generic(const_generic);
}View on GitHub (pinned to 6fa6ed01b2)