Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "ChainRulesCore"
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
version = "1.26.7"
version = "1.27.0"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand Down
8 changes: 8 additions & 0 deletions src/tangent_types/structural_tangent.jl
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,14 @@ function Base.indexed_iterate(tangent::Tangent{P,<:Tuple}, i::Int, state=1) wher
return Base.indexed_iterate(backing(tangent), i, state)
end

# Whether a structural tangent should broadcast as a container (e.g. a tuple broadcast) or
# as a scalar (e.g. a 0-dim broadcast with a struct-valued output) depends on the broadcast,
# and in general can't be determined from the tangent alone (e.g. for `Tangent{Any}`)
function Base.Broadcast.broadcastable(::StructuralTangent)
msg = "broadcasting over structural tangents is not supported; use `map` or arithmetic"
return throw(ArgumentError(msg))
end

function Base.map(f, tangent::Tangent{P,<:Tuple}) where {P}
vals::Tuple = map(f, backing(tangent))
return Tangent{P,typeof(vals)}(vals)
Expand Down
9 changes: 9 additions & 0 deletions test/tangent_types/structural_tangent.jl
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,15 @@ end
@inferred _unpack2tuple(ctup)
@test _unpack2tuple(ctup) === (2.0, 3)

# Test broadcasting is not supported
@test_throws ArgumentError ctup .* 2
@test_throws ArgumentError Tangent{Any}(1.0, [2.0]) .* 2
@test_throws ArgumentError ctup .+ [1, 2]
@test_throws ArgumentError Tangent{Foo}(; y=2.0, x=1.0) .* 2
@test_throws ArgumentError Tangent{Dict}(Dict(:a => 1.0)) .* 2
@test_throws ArgumentError MutableTangent{MFoo}(; x=1.5, y=1.5) .* 2
@test_throws ArgumentError @thunk(ctup) .* 2

# Test getproperty is inferrable
_unpacknamedtuple = tangent -> (tangent.x, tangent.y)
@inferred _unpacknamedtuple(Tangent{Foo}(; x=2, y=3.0))
Expand Down
Loading