# Can i propagate @invoke?

**URL:** https://discourse.julialang.org/t/can-i-propagate-invoke/133074
**Category:** New to Julia
**Created:** [October 11, 2025, 5:07pm UTC](https://discourse.julialang.org/t/can-i-propagate-invoke/133074 "2025-10-11T17:07:24Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![lrnv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lrnv/32/19373_2.png) [@lrnv](https://discourse.julialang.org/u/lrnv)
#### Post date: [October 11, 2025, 5:07pm UTC](https://discourse.julialang.org/t/can-i-propagate-invoke/133074/1 "2025-10-11T17:07:24Z")

</div>

Hey,

I always thought that @invoke would not allow functions in the call stack to know the true argument’s type, but i just realised today that i am wrong:

```julia
abstract type AbstractA end
struct A <: AbstractA 
    x::Float64
end
a = A(1.2)

f(::AbstractA) = "AbstractA "
f(::A) = "A"

f(a)
@invoke f(a::AbstractA) # returns "AbstractA" as wanted. 

g(x) = f(x)
g(a)
@invoke g(a::AbstractA) # gives "A"... 

```

Is there another way to say that i want the mockup to be respected by the whole call-stack ? The issue is that I tend to write tests like :

```julia-auto
@test g(a) == @invoke g(a::AbstractA)

```

to validate the method for `a::A` against the method written for the abstract type. And thus all my test tend to pass even if they are wrong… since both side of the equality actually call the same underlying methods !

---

<div class="post-metadata">

### Author: ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)
#### Post date: [October 11, 2025, 6:00pm UTC](https://discourse.julialang.org/t/can-i-propagate-invoke/133074/2 "2025-10-11T18:00:22Z")

</div>

I’m not sure propagating `@invoke` would be a good idea, as methods could be defined for all concrete subtypes, but not the abstract supertype. E.g. in

```julia
abstract type AbstractAB end
struct A <: AbstractAB end
struct B <: AbstractAB end

f(::A) = "a"
f(::B) = "b"
# Does not make sense for AbstractAB, so we won't define f(::AbstractAB)

g(ab::AbstractAB) = f(ab) ^ 2

```

a `@propagate_invoke g(a::AbstractAB)` would use `@invoke f(a::AbstractAB)` which fails.

As another example, with

```julia
function to_Int64(i::Integer)
    return Int64(i)
end

```

(which works fine for sufficiently small `Int128` and `BigInt`) a `@propagate_invoke to_Int64(1::Integer)` would throw at `@invoke Int64(1::Integer)`.

* * *

Instead of using a `@propagate_invoke` at a higher-level function `g` which does not distinguish between `AbstractA` and `A`, you could add `@invoke` tests for the lower-level functions `f` which are actually defined separately for `AbstractA` and `A`. When all such test succeed, `g` should also work fine.

---

<div class="post-metadata">

### Author: ![lrnv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lrnv/32/19373_2.png) [@lrnv](https://discourse.julialang.org/u/lrnv)
#### Post date: [October 11, 2025, 6:08pm UTC](https://discourse.julialang.org/t/can-i-propagate-invoke/133074/3 "2025-10-11T18:08:12Z")

</div>

> [@eldee](#):
>
> I’m not sure propagating `@invoke` would be a good idea, as methods could be defined for all concrete subtypes, but not the abstract supertype.

Yeah but here I know that its defined since I have defined it myself 😉

> [@eldee](#):
>
> Instead of using a `@propagate_invoke` at a higher-level function `g` which does not distinguish between `AbstractA` and `A`, you could add `@invoke` tests for the lower-level functions `f` which are actually defined separately for `AbstractA` and `A`. When all such test succeed, `g` should also work fine.

Yes this is what I am currently doing, writing @invoke tests for the underlying functions instead. But still, my tests stood wrong for more than 2 years before me figuring it out.

---

<div class="post-metadata">

### Author: ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)
#### Post date: [October 11, 2025, 9:05pm UTC](https://discourse.julialang.org/t/can-i-propagate-invoke/133074/4 "2025-10-11T21:05:47Z")

</div>

I think this is a bit of an xy-problem. Instead of using `@invoke` to test whether your function work with some abstract type, you should just define a new type that fulfils the interface for testing purposes.  
E.g.

```julia-auto
struct MockA <: AbstractA
end
# maybe additional methods that are required

```

This would be a much stronger/meaningful test as well.
