GitoxideLabs/gitoxide · error
expect a function
Error message
expect a function
What it means
The `momo` proc-macro can only transform function items. When the annotated item is anything else (struct, impl block, etc.), it cannot proceed and emits this compile error at the item's span. This is a usage constraint of the attribute, not a runtime failure.
Solutions
- Move the attribute to the function item it is meant to transform.
- Remove the attribute entirely if no function should be transformed.
- Check that the macro isn't accidentally applied to a mod/impl due to indentation or placement errors.
Example fix
// before: attribute on a non-function
#[momo]
struct Repo { ... }
// after: attribute on a function
struct Repo { ... }
#[momo]
fn open(path: impl Into<PathBuf>) -> Repo { ... } Defensive patterns
Strategy: validation
Prevention
- Attach the momo attribute only to `fn` items.
- After refactors, verify attribute placement moved with the function.
- Let rust-analyzer's attribute diagnostics flag misplaced attributes early.
When it happens
Trigger: Applying the momo-based attribute macro to a non-function item such as a struct, enum, module, or impl block.
Common situations: Placement mistakes — attribute attached to the wrong item after refactoring; editor auto-import adding the attribute at the wrong scope level.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Couldn't apply a single conversion - momo is ineffective…
- ' ' is not a valid configuration key
- Cannot use iter_v1() on index of type
- Cannot use iter_v2() on index of type
- BUG: tries to obtain object id from symbolic target
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/bdcd2ecd36e7e9a3.
Report an issue: GitHub.
Appendix: source
Thrown at gix-macros/src/momo.rs:95
quote!(#new_item #new_inner_item)
} else {
// Put the new inner function within the function block
// to avoid duplicate function name and support associated
// function that doesn't use `self` or `Self`.
let new_item = Item::Fn(ItemFn {
attrs: item_fn.attrs,
vis: item_fn.vis,
sig: outer_sig,
block: parse_quote!({
#new_inner_item
#inner_ident(#argexprs)
}),
});
quote!(#new_item)
}
} else {
Error::new(fn_item.span(), "expect a function").to_compile_error()
}
}
#[derive(Copy, Clone)]
// All conversions we support. Check references to this type for an idea how to add more.
enum Conversion {
Into,
AsRef,
AsMut,
}
impl Conversion {
fn conversion_expr(&self, i: &Ident) -> Expr {
match *self {
Conversion::Into => parse_quote!(#i.into()),
Conversion::AsRef => parse_quote!(#i.as_ref()),
Conversion::AsMut => parse_quote!(#i.as_mut()),
}View on GitHub (pinned to e73179060b)