Summary
hiver-aop 0.1.0-alpha.6 cannot be used from a downstream crate with the current README/API shape.
I found three separate problems while trying to compile the documented example:
- The README imports and uses
Aspect, Before, After, and Around, but the proc-macro crate exports lowercase attribute macros: aspect, before, after, and around.
- Runtime types such as
JoinPoint are not available to downstream crates because this is a proc-macro = true crate, and the runtime re-export is gated out.
- Even after switching to the lowercase macro names, applying
#[before], #[after], or #[around] to methods inside an impl block fails because the macro expansion generates an invalid impl for a function name.
There is also a documentation/model mismatch: the pointcut examples use Java/Spring package patterns such as com.example..*.*(..). That may be familiar for AspectJ users, but Rust users need either Rust path semantics (crate::service::..., module paths, attributes, traits, etc.) or clear documentation explaining what those strings actually match in Rust.
Version
hiver-aop = 0.1.0-alpha.6
rustc 1.95.0 (59807616e 2026-04-14)
cargo 1.95.0 (f2d3ce0bd 2026-03-21)
cargo info hiver-aop reports:
version: 0.1.0-alpha.6
rust-version: 1.87
repository: https://github.com/ViewWay/hiver
Reproduction 1: README example does not compile
cargo new --bin hiver-aop-readme-smoke
cd hiver-aop-readme-smoke
cargo add hiver-aop
Use the README-style code:
use hiver_aop::{After, Around, Aspect, Before};
#[Aspect]
struct LoggingAspect;
impl LoggingAspect {
#[Before("execution(* com.example..*.*(..))")]
fn log_before(&self, join_point: &JoinPoint) {
println!("Entering: {}", join_point.method_name());
}
}
fn main() {}
Then run:
Actual result:
error[E0432]: unresolved imports `hiver_aop::After`, `hiver_aop::Around`, `hiver_aop::Aspect`, `hiver_aop::Before`
|
| use hiver_aop::{After, Around, Aspect, Before};
| ^^^^^ ^^^^^^ ^^^^^^ ^^^^^^ no `Before` in the root
Reproduction 2: lowercase macro names still fail
cargo new --bin hiver-aop-real-smoke
cd hiver-aop-real-smoke
cargo add hiver-aop anyhow
Use the actually exported macro names:
use hiver_aop::{after, around, aspect, before};
#[aspect]
struct LoggingAspect;
impl LoggingAspect {
#[before("execution(* crate::service::*::*(..))")]
fn log_before(&self, join_point: &hiver_aop::JoinPoint) {
println!("Entering: {}", join_point.method_name());
}
#[after("execution(* crate::service::*::*(..))")]
fn log_after(&self, join_point: &hiver_aop::JoinPoint) {
println!("Exiting: {}", join_point.method_name());
}
#[around("execution(* crate::service::*::*(..))")]
fn log_around(&self, join_point: hiver_aop::JoinPoint) -> Result<(), anyhow::Error> {
println!("Before: {}", join_point.method_name());
let result = join_point.proceed()?;
println!("After: {}", join_point.method_name());
Ok(result)
}
}
fn main() {}
Then run:
Actual result:
error: implementation is not supported in `trait`s or `impl`s
--> src/main.rs:7:5
|
7 | #[before("execution(* crate::service::*::*(..))")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the attribute macro `before`
And the runtime type is not exported:
error[E0425]: cannot find type `JoinPoint` in crate `hiver_aop`
|
| fn log_before(&self, join_point: &hiver_aop::JoinPoint) {
| ^^^^^^^^^ not found in `hiver_aop`
|
note: found an item that was configured out
|
| #[cfg(not(proc_macro))]
| ------------ the item is gated here
Suspected cause
In hiver-aop/src/lib.rs, the crate is a proc-macro crate and the runtime re-export is gated:
#[cfg(not(proc_macro))]
pub use runtime::{
AdviceChain, AdviceType, AspectRegistry, JoinPoint, PointcutExpression, ProceedingJoinPoint,
global_registry,
};
That means downstream crates cannot import hiver_aop::JoinPoint.
The advice macro implementation also appears to generate invalid Rust. For example, before parses the annotated item as ItemFn, then expands to something shaped like this:
fn log_before(...) { ... }
impl log_before {
const POINTCUT: &str = "...";
}
log_before is a function item, not a type, so this cannot compile. When the attribute is used inside an impl block, the generated nested impl also triggers:
implementation is not supported in `trait`s or `impl`s
Expected behavior
One of these should be true:
- The README example compiles as written, including exported macro names and runtime types; or
- The README is updated to the real Rust API shape, with a working downstream compile test; and
- Runtime types are moved to a normal library crate such as
hiver-aop-runtime, while the proc macros live in a separate macro crate; and
- Pointcut documentation explains how Rust paths/modules/attributes/traits are matched, instead of only showing Java/Spring
com.example package patterns.
Extra verification
Running the crate's own tests compiles:
cargo check --manifest-path ~/.cargo/registry/src/index.crates.io-*/hiver-aop-0.1.0-alpha.6/Cargo.toml --tests
But those tests do not appear to cover the downstream README usage, so this issue is only visible from a real consumer crate.
Summary
hiver-aop 0.1.0-alpha.6cannot be used from a downstream crate with the current README/API shape.I found three separate problems while trying to compile the documented example:
Aspect,Before,After, andAround, but the proc-macro crate exports lowercase attribute macros:aspect,before,after, andaround.JoinPointare not available to downstream crates because this is aproc-macro = truecrate, and the runtime re-export is gated out.#[before],#[after], or#[around]to methods inside animplblock fails because the macro expansion generates an invalidimplfor a function name.There is also a documentation/model mismatch: the pointcut examples use Java/Spring package patterns such as
com.example..*.*(..). That may be familiar for AspectJ users, but Rust users need either Rust path semantics (crate::service::..., module paths, attributes, traits, etc.) or clear documentation explaining what those strings actually match in Rust.Version
cargo info hiver-aopreports:Reproduction 1: README example does not compile
cargo new --bin hiver-aop-readme-smoke cd hiver-aop-readme-smoke cargo add hiver-aopUse the README-style code:
Then run:
Actual result:
Reproduction 2: lowercase macro names still fail
cargo new --bin hiver-aop-real-smoke cd hiver-aop-real-smoke cargo add hiver-aop anyhowUse the actually exported macro names:
Then run:
Actual result:
And the runtime type is not exported:
Suspected cause
In
hiver-aop/src/lib.rs, the crate is a proc-macro crate and the runtime re-export is gated:That means downstream crates cannot import
hiver_aop::JoinPoint.The advice macro implementation also appears to generate invalid Rust. For example,
beforeparses the annotated item asItemFn, then expands to something shaped like this:log_beforeis a function item, not a type, so this cannot compile. When the attribute is used inside animplblock, the generated nestedimplalso triggers:Expected behavior
One of these should be true:
hiver-aop-runtime, while the proc macros live in a separate macro crate; andcom.examplepackage patterns.Extra verification
Running the crate's own tests compiles:
But those tests do not appear to cover the downstream README usage, so this issue is only visible from a real consumer crate.