---
id: IR-20
title: "plexus-macros: propagate impl generics to synthesized plugin_children (unblocks IR-17)"
status: Complete
type: implementation
blocked_by: [IR-4, IR-21]
unlocks: [IR-17]
severity: Medium
target_repo: plexus-macros
---

## Problem

CHILD-8 synthesizes `plugin_children()` for activations that use `#[plexus_macros::child]` without a hand-written override. The synthesized method emits into a **non-generic** impl block:

```rust
// plexus-macros/src/codegen/activation.rs:~586
impl #struct_name { #plugin_children_synth }   // non-generic
```

But the generated `Activation` trait impl that calls `self.plugin_children()` is **generic over the activation's impl generics**:

```rust
// plexus-macros/src/codegen/activation.rs:~177
impl #impl_generics Activation for #self_ty #where_clause {
    fn plugin_schema(&self) -> PluginSchema {
        // ... calls self.plugin_children() ...
    }
}
```

For non-generic activations (Solar), both impls are over the same type; no mismatch.

For **generic activations** (Orcha is `impl<P: HubContext> Orcha<P>`), the synthesized method lands on `Orcha<NoParent>` (the default `P`), but the `Activation for Orcha<P>` impl tries to call `plugin_children()` on arbitrary `P`. Rustc emits:

```
error[E0599]: no method named `plugin_children` found for reference `&Orcha<P>` in the current scope
```

This blocks any generic activation from migrating to `#[plexus_macros::child]` — IR-17 (Orcha migration) hit it empirically and reverted.

## Required behavior

Change the synthesized impl block from non-generic to match the Activation impl's generics:

```rust
// Before:
impl #struct_name {
    #plugin_children_synth
}

// After:
impl #impl_generics #self_ty #where_clause {
    #plugin_children_synth
}
```

Exact file: `plexus-macros/src/codegen/activation.rs:~586` (verify the line number before editing — the codebase has drifted since that reference).

## Regression requirements

- Solar (non-generic activation) continues to build — the fix is a superset of the current non-generic case.
- Any other non-generic activations using `#[plexus_macros::child]` continue to build unchanged.
- All existing plexus-macros fixtures pass.
- `cargo build -p plexus-substrate` passes.

## Tests to add

A new fixture activation with a generic parameter that uses `#[plexus_macros::child]`:

```rust
#[plexus_macros::activation(namespace = "gen_fixture", version = "1.0")]
impl<T: Default + Clone + Send + Sync + 'static> GenericFixture<T> {
    #[plexus_macros::method]
    async fn noop(&self) -> () { () }

    #[plexus_macros::child]
    fn child(&self) -> LeafChild { LeafChild::default() }
}
```

Compiles without E0599 and generates a `plugin_schema()` that returns the expected `methods` / `children` for `GenericFixture<NoParent>` (or whatever the test instantiates).

## Acceptance criteria

1. `cargo build -p plexus-macros` and `cargo test -p plexus-macros` pass.
2. The new generic-fixture test passes.
3. All existing plexus-macros fixtures (CHILD-3, CHILD-4, CHILD-7, IR-3, IR-5, etc.) pass unchanged.
4. `cargo build -p plexus-substrate` passes.

## Completion

PR against plexus-macros. One-liner code change plus the generic-fixture test. Status flipped from `Ready` to `Complete` in the same commit. IR-17 retry unblocks afterward.
