JuliaArrays / StaticArrays.jl

Statically sized arrays for Julia
Other
761 stars 147 forks source link

`MethodError: no method matching StaticArrays.Size(::TypeVar)` introduced with `v1.4.5` #1047

Closed ferrolho closed 2 years ago

ferrolho commented 2 years ago

Hi! I have just run into this issue - https://github.com/JuliaRobotics/MeshCatMechanisms.jl/issues/68 - and after some trial and error downgrading StaticArrays, it seems that it started happening with the changes introduced in StaticArrays.jl@v1.4.5. Below is a MWE and the error it is triggering.

] add StaticArrays@v1.4.4  # up until this version, it works
] add StaticArrays@v1.4.5  # from this version, it does not work
using MeshCat
using RigidBodyDynamics
using MeshCatMechanisms

vis = Visualizer()
urdf = joinpath(dirname(pathof(MeshCatMechanisms)), "..", "test", "urdf", "Acrobot.urdf")
robot = parse_urdf(urdf)
mvis = MechanismVisualizer(robot, URDFVisuals(urdf), vis)
set_configuration!(mvis, [0.0, 0.0])
state = MechanismState(robot, randn(2), randn(2))
t, q, v = simulate(state, 1.0)
animation = Animation(mvis, t, q)  # <--- this is where the error shows up
ERROR: MethodError: no method matching StaticArrays.Size(::TypeVar)
Closest candidates are:
  StaticArrays.Size(::Union{StaticArrays.Dynamic, Int64}...) at ~/.julia/packages/StaticArrays/0T5rI/src/traits.jl:67
  StaticArrays.Size(::StaticArrays.TSize{S}) where S at ~/.julia/packages/StaticArrays/0T5rI/src/matrix_multiply_add.jl:194
  StaticArrays.Size(::Tuple{Vararg{Union{StaticArrays.Dynamic, Int64}}}) at ~/.julia/packages/StaticArrays/0T5rI/src/traits.jl:66
  ...
Stacktrace:
  [1] call
    @ ~/.julia/packages/Cassette/34vIw/src/context.jl:456 [inlined]
  [2] fallback
    @ ~/.julia/packages/Cassette/34vIw/src/context.jl:454 [inlined]
  [3] _overdub_fallback(::Any, ::Vararg{Any})
    @ ~/.julia/packages/Cassette/34vIw/src/overdub.jl:586 [inlined]
  [4] overdub
    @ ~/.julia/packages/Cassette/34vIw/src/overdub.jl:586 [inlined]
  [5] StaticArrays.Size(::Type{StaticArrays.SVector})
    @ ~/.julia/packages/StaticArrays/0T5rI/src/traits.jl:90 [inlined]
  [6] overdub
    @ ~/.julia/packages/StaticArrays/0T5rI/src/traits.jl:90 [inlined]
  [7] overdub(::Cassette.Context{nametype(AnimationCtx), Tuple{Animation, Int64}, Nothing, Cassette.var"##PassType#301", Nothing, Nothing}, ::Type{StaticArrays.Size}, ::Type{StaticArrays.SVector})
    @ Cassette ~/.julia/packages/Cassette/34vIw/src/overdub.jl:0
  [8] size(::Type{StaticArrays.SVector})
    @ ~/.julia/packages/StaticArrays/0T5rI/src/abstractarray.jl:4 [inlined]
  [9] overdub
    @ ~/.julia/packages/StaticArrays/0T5rI/src/abstractarray.jl:4 [inlined]
 [10] overdub(::Cassette.Context{nametype(AnimationCtx), Tuple{Animation, Int64}, Nothing, Cassette.var"##PassType#301", Nothing, Nothing}, ::typeof(size), ::Type{StaticArrays.SVector})
    @ Cassette ~/.julia/packages/Cassette/34vIw/src/overdub.jl:0
 [11] overdub
    @ ~/.julia/packages/StaticArrays/0T5rI/src/convert.jl:114 [inlined]
 [12] overdub(::Cassette.Context{nametype(AnimationCtx), Tuple{Animation, Int64}, Nothing, Cassette.var"##PassType#301", Nothing, Nothing}, ::typeof(StaticArrays.length_match_size), ::Type{StaticArrays.SVector}, ::StaticArrays.Args{Tuple{Float64, Float64, Float64}})
    @ Cassette ~/.julia/packages/Cassette/34vIw/src/overdub.jl:0
 [13] adapt_size(::Type{StaticArrays.SVector}, ::StaticArrays.Args{Tuple{Float64, Float64, Float64}})
    @ ~/.julia/packages/StaticArrays/0T5rI/src/convert.jl:86 [inlined]
 [14] overdub
    @ ~/.julia/packages/StaticArrays/0T5rI/src/convert.jl:86 [inlined]
 [15] overdub(::Cassette.Context{nametype(AnimationCtx), Tuple{Animation, Int64}, Nothing, Cassette.var"##PassType#301", Nothing, Nothing}, ::typeof(StaticArrays.adapt_size), ::Type{StaticArrays.SVector}, ::StaticArrays.Args{Tuple{Float64, Float64, Float64}})
    @ Cassette ~/.julia/packages/Cassette/34vIw/src/overdub.jl:0
 [16] construct_type(::Type{StaticArrays.SVector}, ::StaticArrays.Args{Tuple{Float64, Float64, Float64}})
    @ ~/.julia/packages/StaticArrays/0T5rI/src/convert.jl:79 [inlined]
 [17] overdub
    @ ~/.julia/packages/StaticArrays/0T5rI/src/convert.jl:79 [inlined]
 [18] overdub(::Cassette.Context{nametype(AnimationCtx), Tuple{Animation, Int64}, Nothing, Cassette.var"##PassType#301", Nothing, Nothing}, ::typeof(StaticArrays.construct_type), ::Type{StaticArrays.SVector}, ::StaticArrays.Args{Tuple{Float64, Float64, Float64}})
    @ Cassette ~/.julia/packages/Cassette/34vIw/src/overdub.jl:0
 [19] (StaticArrays.SVector)(::Float64, ::Float64, ::Float64)
    @ ~/.julia/packages/StaticArrays/0T5rI/src/convert.jl:152 [inlined]
 [20] overdub
    @ ~/.julia/packages/StaticArrays/0T5rI/src/convert.jl:152 [inlined]
 [21] translation(::Transform3D{Float64})
    @ ~/.julia/packages/RigidBodyDynamics/8B04X/src/spatial/transform3d.jl:50 [inlined]
 [22] overdub
    @ ~/.julia/packages/RigidBodyDynamics/8B04X/src/spatial/transform3d.jl:50 [inlined]
 [23] overdub
    @ ~/.julia/packages/RigidBodyDynamics/8B04X/src/spatial/transform3d.jl:68 [inlined]
 [24] overdub(::Cassette.Context{nametype(AnimationCtx), Tuple{Animation, Int64}, Nothing, Cassette.var"##PassType#301", Nothing, Nothing}, ::typeof(inv), ::Transform3D{Float64})
    @ Cassette ~/.julia/packages/Cassette/34vIw/src/overdub.jl:0
 [25] overdub
    @ ~/.julia/packages/RigidBodyDynamics/8B04X/src/mechanism_state.jl:1013 [inlined]
 [26] overdub(::Cassette.Context{nametype(AnimationCtx), Tuple{Animation, Int64}, Nothing, Cassette.var"##PassType#301", Nothing, Nothing}, ::typeof(relative_transform), ::MechanismState{Float64, Float64, Float64, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{Joint{Float64, Revolute{Float64}}}}, 1}}, ::CartesianFrame3D, ::CartesianFrame3D)
    @ Cassette ~/.julia/packages/Cassette/34vIw/src/overdub.jl:0
 [27] overdub
    @ ~/.julia/packages/MeshCatMechanisms/PfrGE/src/visualizer.jl:146 [inlined]
 [28] overdub(::Cassette.Context{nametype(AnimationCtx), Tuple{Animation, Int64}, Nothing, Cassette.var"##PassType#301", Nothing, Nothing}, ::typeof(MeshCatMechanisms._render_state!), ::MechanismVisualizer{MechanismState{Float64, Float64, Float64, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{Joint{Float64, Revolute{Float64}}}}, 1}}, Visualizer}, ::MechanismState{Float64, Float64, Float64, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{Joint{Float64, Revolute{Float64}}}}, 1}})
    @ Cassette ~/.julia/packages/Cassette/34vIw/src/overdub.jl:0
 [29] _render_state!(::MechanismVisualizer{MechanismState{Float64, Float64, Float64, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{Joint{Float64, Revolute{Float64}}}}, 1}}, Visualizer})
    @ ~/.julia/packages/MeshCatMechanisms/PfrGE/src/visualizer.jl:135 [inlined]
 [30] overdub
    @ ~/.julia/packages/MeshCatMechanisms/PfrGE/src/visualizer.jl:135 [inlined]
 [31] overdub
    @ ~/.julia/packages/MeshCatMechanisms/PfrGE/src/visualizer.jl:168 [inlined]
 [32] overdub(::Cassette.Context{nametype(AnimationCtx), Tuple{Animation, Int64}, Nothing, Cassette.var"##PassType#301", Nothing, Nothing}, ::typeof(set_configuration!), ::MechanismVisualizer{MechanismState{Float64, Float64, Float64, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{Joint{Float64, Revolute{Float64}}}}, 1}}, Visualizer}, ::Vector{Float64})
    @ Cassette ~/.julia/packages/Cassette/34vIw/src/overdub.jl:0
 [33] (::MeshCatMechanisms.var"
    @ ~/.julia/packages/MeshCatMechanisms/PfrGE/src/animate.jl:45 [inlined]
 [34] overdub
    @ ~/.julia/packages/MeshCatMechanisms/PfrGE/src/animate.jl:45 [inlined]
 [35] overdub(overdub_context#299::Cassette.Context{nametype(AnimationCtx), Tuple{Animation, Int64}, Nothing, Cassette.var"##PassType#301", Nothing, Nothing}, overdub_arguments#300::MeshCatMechanisms.var"#5#6"{MechanismVisualizer{MechanismState{Float64, Float64, Float64, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{Joint{Float64, Revolute{Float64}}}}, 1}}, Visualizer}, Interpolations.GriddedInterpolation{Vector{Float64}, 1, SegmentedVector{JointID, Float64, Base.OneTo{JointID}, Vector{Float64}}, Interpolations.Gridded{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{Vector{Float64}}}, Float64})
    @ Cassette ~/.julia/packages/Cassette/34vIw/src/overdub.jl:0
 [36] atframe
    @ ~/.julia/packages/MeshCat/oC0sL/src/atframe.jl:100 [inlined]
 [37] Animation(mvis::MechanismVisualizer{MechanismState{Float64, Float64, Float64, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{Joint{Float64, Revolute{Float64}}}}, 1}}, Visualizer}, times::Vector{Float64}, configurations::Vector{SegmentedVector{JointID, Float64, Base.OneTo{JointID}, Vector{Float64}}}; fps::Int64)
    @ MeshCatMechanisms ~/.julia/packages/MeshCatMechanisms/PfrGE/src/animate.jl:44
 [38] Animation(mvis::MechanismVisualizer{MechanismState{Float64, Float64, Float64, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{Joint{Float64, Revolute{Float64}}}}, 1}}, Visualizer}, times::Vector{Float64}, configurations::Vector{SegmentedVector{JointID, Float64, Base.OneTo{JointID}, Vector{Float64}}})
    @ MeshCatMechanisms ~/.julia/packages/MeshCatMechanisms/PfrGE/src/animate.jl:37
 [39] top-level scope
    @ REPL[19]:1

Any ideas on how to fix this? Thanks!

ferrolho commented 2 years ago

The stacktrace goes through the following StaticArrays.jl files:

Looking at the diff between versions https://github.com/JuliaArrays/StaticArrays.jl/compare/v1.4.4...v1.4.5, /src/traits.jl and /src/abstractarray.jl seem to have been left unchanged. However, /src/convert.jl was heavily modified, so I suspect something is missing in there?

mateuszbaran commented 2 years ago

I'm almost sure it's a Cassette bug, the same one as this: https://github.com/JuliaLabs/Cassette.jl/issues/198 .

mateuszbaran commented 2 years ago

If there is no chance of having it fixed in Cassette then we may be able to fix it in StaticArrays.jl.

mtfishman commented 2 years ago

I'm seeing a similar (?) issue when loading ITensors.jl and any version of StaticArrays since 1.4.5:

using Pkg
Pkg.activate(; temp=true)
Pkg.add(name="StaticArrays", version="1.4.5")
Pkg.add(name="ITensors")
using ITensors
using StaticArrays

With this setup I get:

julia> @MVector zeros(2)
ERROR: The size of type `MVector{N, 2} where N` is not known.

If you were trying to construct (or `convert` to) a `StaticArray` you
may need to add the size explicitly as a type parameter so its size is
inferrable to the Julia compiler (or performance would be terrible). For
example, you might try

    m = zeros(3,3)
    SMatrix(m)            # this error
    SMatrix{3,3}(m)       # correct - size is inferrable
    SArray{Tuple{3,3}}(m) # correct, note Tuple{3,3}

Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:33
 [2] missing_size_error(#unused#::Type{MVector{N, 2} where N})
   @ StaticArrays ~/.julia/packages/StaticArrays/G7IlJ/src/traits.jl:73
 [3] Size(#unused#::Type{MVector{N, 2} where N})
   @ StaticArrays ~/.julia/packages/StaticArrays/G7IlJ/src/traits.jl:90
 [4] zeros(#unused#::Type{MVector{N, 2} where N})
   @ StaticArrays ~/.julia/packages/StaticArrays/G7IlJ/src/arraymath.jl:1
 [5] top-level scope
   @ REPL[7]:1

julia> @MVector zeros(Int, 2)
ERROR: TypeError: in Type, in parameter, expected Type, got a value of type Tuple{DataType}
Stacktrace:
 [1] Size(s::Type{Tuple{Int64}})
   @ StaticArrays ~/.julia/packages/StaticArrays/G7IlJ/src/traits.jl:68
 [2] Size
   @ ~/.julia/packages/StaticArrays/G7IlJ/src/traits.jl:90 [inlined]
 [3] zeros(#unused#::Type{MVector{Int64, 2}})
   @ StaticArrays ~/.julia/packages/StaticArrays/G7IlJ/src/arraymath.jl:1
 [4] top-level scope
   @ REPL[8]:1

While with StaticArrays version 1.4.4 and below it works fine:

using Pkg
Pkg.activate(; temp=true)
Pkg.add(name="StaticArrays", version="1.4.4")
Pkg.add(name="ITensors")
using ITensors
using StaticArrays
@MVector zeros(2)
@MVector zeros(Int, 2)

I get as expected:

julia> @MVector zeros(2)
2-element MVector{2, Float64} with indices SOneTo(2):
 0.0
 0.0

julia> @MVector zeros(Int, 2)
2-element MVector{2, Int64} with indices SOneTo(2):
 0
 0

EDIT: Version information:

julia> versioninfo()
Julia Version 1.7.3
Commit 742b9abb4d (2022-05-06 12:58 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Xeon(R) E-2176M  CPU @ 2.70GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.1 (ORCJIT, skylake)
Environment:
  JULIA_EDITOR = vim
mateuszbaran commented 2 years ago

Now this is seriously weird:

julia> g(::Type{U}) where {U} = U
g (generic function with 2 methods)

julia> g(MVector)
MVector{N, T} where {T, N} (alias for MArray{Tuple{N}, T, 1, N} where {T, N})

julia> MVector
MVector (alias for MArray{Tuple{S}, T, 1, S} where {S, T})

Passing a type to a function makes it a different type?

mateuszbaran commented 2 years ago

Hm, at least it seems to work on Julia 1.8-rc1, so perhaps it's a Julia bug.

mtfishman commented 2 years ago

@mateuszbaran indeed, the issue I reported above is fixed in Julia 1.8-rc1 (the test above was using Julia 1.7.3).

mateuszbaran commented 2 years ago

@ferrolho could you check if adding this method:

@pure StaticArrays.has_size(::Type{SVector}) = false

solves your problem?

ferrolho commented 2 years ago

Yes! Yes, it does. Just tried it on StaticArrays.jl v1.5.0 and Julia 1.7.2. I can't understand if this means it is a bug with StaticArrays.jl, Julia itself, or something else. Should I include this somewhere within my code for now, as a workaround?

mateuszbaran commented 2 years ago

It looks like a Cessette bug. I think I will just make a patch to StaticArrays.jl with this method, other people may encounter it too so this seems to be the best we can do.

ferrolho commented 2 years ago

Thank you!

mateuszbaran commented 2 years ago

You're welcome :slightly_smiling_face: .

ferrolho commented 2 years ago

Fixed in v1.5.1 with #1051. Thanks, @mateuszbaran!

mtfishman commented 2 years ago

@mateuszbaran looks like this also fixes the issue I reported above, thanks!