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

  1. Move the attribute to the function item it is meant to transform.
  2. Remove the attribute entirely if no function should be transformed.
  3. 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

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


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)