I’m currently writing a package, CliffordNumbers.jl, that makes the following abstract type declaration:

```
const BaseNumber = Union{Real,Complex}
abstract type AbstractCliffordNumber{Q<:QuadraticForm,T<:BaseNumber} <: Number
end
```

Clifford algebras are defined over real or complex numbers, and I wouldn’t want to include other objects that subtype `Number`

outside of the `Real`

and `Complex`

types provided by `Base`

, such as a `Quaternion`

type. In the code, I define an alias to simplify this.

I’ve defined a concrete type:

```
struct CliffordNumber{Q,T,L} <: AbstractCliffordNumber{Q,T}
data::NTuple{L,T}
end
```

but I get some very unexpected results when I work with subtyping relationships:

```
julia> supertype(CliffordNumber)
AbstractCliffordNumber{Q,T} where {Q,T}
```

I’d think that `AbstractCliffordNumber`

would be sufficient, but the results get stranger from here:

```
julia> CliffordNumber <: AbstractCliffordNumber
false
julia> CliffordNumber{APS} <: AbstractCliffordNumber{APS}
false
julia> CliffordNumber{APS,Float64} <: AbstractCliffordNumber{APS,Float64}
true
```

From my inspection of the behavior, it seems like Julia may not infer that the type constraints on `T`

in `AbstractCliffordNumber{Q,T}`

propagate to its subtypes if `T`

is a `Union`

, because this works:

```
julia> CliffordNumber{APS,<:Any} <: AbstractCliffordNumber{APS}
true
julia> CliffordNumber{APS,<:Union{Real,Complex}} <: AbstractCliffordNumber{APS}
true
```

Is this a bug in the implementation of subtyping, or am I doing something unreasonable enough to generate these results?