You just need one more set of parentheses to ensure that AbstractArray{T, 1} where T is parsed as the return type, rather than trying to apply the where T to the entire function definition:
julia> function ff( A::AbstractArray{T1, 2} where T1, x::AbstractArray{T2, 1} where T2)::(AbstractArray{T,1} where T)
y = A*x;
return y;
end
ff (generic function with 1 method)
julia> ff(zeros(2, 2), zeros(2))
2-element Array{Float64,1}:
0.0
0.0
It’s also worth noting that the return type annotation will probably have no performance benefit at all, particularly since it’s an abstract type. If it helps you organize and document your code, then that’s totally fine, but you can safely remove it if it makes your life harder.