Skip to content

Commit 479c9a3

Browse files
committed
broadcast: disable nospecialize logic for outer method signature
This removes the dependence on inlining for performance, so we also remove `@inline`, since it can harm performance.
1 parent eae29c7 commit 479c9a3

File tree

2 files changed

+73
-80
lines changed

2 files changed

+73
-80
lines changed

base/broadcast.jl

Lines changed: 73 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,12 @@ Base.similar(::Broadcasted{ArrayConflict}, ::Type{ElType}, dims) where ElType =
219219
Base.similar(::Broadcasted{ArrayConflict}, ::Type{Bool}, dims) =
220220
similar(BitArray, dims)
221221

222-
@inline Base.axes(bc::Broadcasted) = _axes(bc, bc.axes)
222+
Base.axes(bc::Broadcasted) = _axes(bc, bc.axes)
223223
_axes(::Broadcasted, axes::Tuple) = axes
224-
@inline _axes(bc::Broadcasted, ::Nothing) = combine_axes(bc.args...)
224+
_axes(bc::Broadcasted, ::Nothing) = combine_axes(bc.args...)
225225
_axes(bc::Broadcasted{<:AbstractArrayStyle{0}}, ::Nothing) = ()
226226

227-
@inline Base.axes(bc::Broadcasted{<:Any, <:NTuple{N}}, d::Integer) where N =
227+
Base.axes(bc::Broadcasted{<:Any, <:NTuple{N}}, d::Integer) where N =
228228
d <= N ? axes(bc)[d] : OneTo(1)
229229

230230
BroadcastStyle(::Type{<:Broadcasted{Style}}) where {Style} = Style()
@@ -234,7 +234,7 @@ BroadcastStyle(::Type{<:Broadcasted{S}}) where {S<:Union{Nothing,Unknown}} =
234234
argtype(::Type{Broadcasted{Style,Axes,F,Args}}) where {Style,Axes,F,Args} = Args
235235
argtype(bc::Broadcasted) = argtype(typeof(bc))
236236

237-
@inline Base.eachindex(bc::Broadcasted) = _eachindex(axes(bc))
237+
Base.eachindex(bc::Broadcasted) = _eachindex(axes(bc))
238238
_eachindex(t::Tuple{Any}) = t[1]
239239
_eachindex(t::Tuple) = CartesianIndices(t)
240240

@@ -276,7 +276,7 @@ Custom [`BroadcastStyle`](@ref)s may override this default in cases where it is
276276
to compute and verify the resulting `axes` on-demand, leaving the `axis` field
277277
of the `Broadcasted` object empty (populated with [`nothing`](@ref)).
278278
"""
279-
@inline function instantiate(bc::Broadcasted{Style}) where {Style}
279+
function instantiate(bc::Broadcasted{Style}) where {Style}
280280
if bc.axes isa Nothing # Not done via dispatch to make it easier to extend instantiate(::Broadcasted{Style})
281281
axes = combine_axes(bc.args...)
282282
else
@@ -338,8 +338,8 @@ _isflat(args::NestedTuple) = false
338338
_isflat(args::Tuple) = _isflat(tail(args))
339339
_isflat(args::Tuple{}) = true
340340

341-
cat_nested(t::Broadcasted, rest...) = (cat_nested(t.args...)..., cat_nested(rest...)...)
342-
cat_nested(t::Any, rest...) = (t, cat_nested(rest...)...)
341+
cat_nested(t::Broadcasted, rest::Vararg{Any,N}) where {N} = (cat_nested(t.args...)..., cat_nested(rest...)...)
342+
cat_nested(t::Any, rest::Vararg{Any,N}) where {N} = (t, cat_nested(rest...)...)
343343
cat_nested() = ()
344344

345345
"""
@@ -358,7 +358,9 @@ by `t`).
358358
@inline make_makeargs(makeargs_tail, t::Tuple{}) = makeargs_tail
359359
@inline function make_makeargs(makeargs_tail, t::Tuple)
360360
makeargs = make_makeargs(makeargs_tail, tail(t))
361-
(head, tail...)->(head, makeargs(tail...)...)
361+
return @inline function(head, tail::Vararg{Any,N}) where {N}
362+
(head, makeargs(tail...)...)
363+
end
362364
end
363365
function make_makeargs(makeargs_tail, t::Tuple{<:Broadcasted, Vararg{Any}})
364366
bc = t[1]
@@ -434,7 +436,7 @@ function combine_styles end
434436
combine_styles() = DefaultArrayStyle{0}()
435437
combine_styles(c) = result_style(BroadcastStyle(typeof(c)))
436438
combine_styles(c1, c2) = result_style(combine_styles(c1), combine_styles(c2))
437-
@inline combine_styles(c1, c2, cs...) = result_style(combine_styles(c1), combine_styles(c2, cs...))
439+
combine_styles(c1, c2, cs::Vararg{Any,N}) where {N} = result_style(combine_styles(c1), combine_styles(c2, cs...))
438440

439441
"""
440442
result_style(s1::BroadcastStyle[, s2::BroadcastStyle]) -> BroadcastStyle
@@ -495,13 +497,13 @@ julia> Broadcast.combine_axes(1, 1, 1)
495497
()
496498
```
497499
"""
498-
@inline combine_axes(A, B...) = broadcast_shape(axes(A), combine_axes(B...))
499-
@inline combine_axes(A, B) = broadcast_shape(axes(A), axes(B))
500+
combine_axes(A, B::Vararg{Any,N}) where {N} = broadcast_shape(axes(A), combine_axes(B...))
501+
combine_axes(A, B) = broadcast_shape(axes(A), axes(B))
500502
combine_axes(A) = axes(A)
501503

502504
# shape (i.e., tuple-of-indices) inputs
503505
broadcast_shape(shape::Tuple) = shape
504-
broadcast_shape(shape::Tuple, shape1::Tuple, shapes::Tuple...) = broadcast_shape(_bcs(shape, shape1), shapes...)
506+
broadcast_shape(shape::Tuple, shape1::Tuple, shapes::Vararg{Tuple,N}) where {N} = broadcast_shape(_bcs(shape, shape1), shapes...)
505507
# _bcs consolidates two shapes into a single output shape
506508
_bcs(::Tuple{}, ::Tuple{}) = ()
507509
_bcs(::Tuple{}, newshape::Tuple) = (newshape[1], _bcs((), tail(newshape))...)
@@ -540,9 +542,9 @@ function check_broadcast_shape(shp, Ashp::Tuple)
540542
_bcsm(shp[1], Ashp[1]) || throw(DimensionMismatch("array could not be broadcast to match destination"))
541543
check_broadcast_shape(tail(shp), tail(Ashp))
542544
end
543-
@inline check_broadcast_axes(shp, A) = check_broadcast_shape(shp, axes(A))
545+
check_broadcast_axes(shp, A) = check_broadcast_shape(shp, axes(A))
544546
# comparing many inputs
545-
@inline function check_broadcast_axes(shp, A, As...)
547+
function check_broadcast_axes(shp, A, As::Vararg{Any,N}) where {N}
546548
check_broadcast_axes(shp, A)
547549
check_broadcast_axes(shp, As...)
548550
end
@@ -572,21 +574,21 @@ Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple{}) = (ax[1][1], _newindex
572574
Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple{}) = ()
573575

574576
# If dot-broadcasting were already defined, this would be `ifelse.(keep, I, Idefault)`.
575-
@inline newindex(I::CartesianIndex, keep, Idefault) = CartesianIndex(_newindex(I.I, keep, Idefault))
576-
@inline newindex(i::Integer, keep::Tuple, idefault) = ifelse(keep[1], i, idefault[1])
577-
@inline newindex(i::Integer, keep::Tuple{}, idefault) = CartesianIndex(())
578-
@inline _newindex(I, keep, Idefault) =
577+
newindex(I::CartesianIndex, keep, Idefault) = CartesianIndex(_newindex(I.I, keep, Idefault))
578+
newindex(i::Integer, keep::Tuple, idefault) = ifelse(keep[1], i, idefault[1])
579+
newindex(i::Integer, keep::Tuple{}, idefault) = CartesianIndex(())
580+
_newindex(I, keep, Idefault) =
579581
(ifelse(keep[1], I[1], Idefault[1]), _newindex(tail(I), tail(keep), tail(Idefault))...)
580-
@inline _newindex(I, keep::Tuple{}, Idefault) = () # truncate if keep is shorter than I
581-
@inline _newindex(I::Tuple{}, keep, Idefault) = () # or I is shorter
582-
@inline _newindex(I::Tuple{}, keep::Tuple{}, Idefault) = () # or both
582+
_newindex(I, keep::Tuple{}, Idefault) = () # truncate if keep is shorter than I
583+
_newindex(I::Tuple{}, keep, Idefault) = () # or I is shorter
584+
_newindex(I::Tuple{}, keep::Tuple{}, Idefault) = () # or both
583585

584586
# newindexer(A) generates `keep` and `Idefault` (for use by `newindex` above)
585587
# for a particular array `A`; `shapeindexer` does so for its axes.
586-
@inline newindexer(A) = shapeindexer(axes(A))
587-
@inline shapeindexer(ax) = _newindexer(ax)
588-
@inline _newindexer(indsA::Tuple{}) = (), ()
589-
@inline function _newindexer(indsA::Tuple)
588+
newindexer(A) = shapeindexer(axes(A))
589+
shapeindexer(ax) = _newindexer(ax)
590+
_newindexer(indsA::Tuple{}) = (), ()
591+
function _newindexer(indsA::Tuple)
590592
ind1 = indsA[1]
591593
keep, Idefault = _newindexer(tail(indsA))
592594
(Base.length(ind1)::Integer != 1, keep...), (first(ind1), Idefault...)
@@ -600,12 +602,12 @@ Base.@propagate_inbounds Base.getindex(
600602
bc::Broadcasted,
601603
i1::Union{Integer,CartesianIndex},
602604
i2::Union{Integer,CartesianIndex},
603-
I::Union{Integer,CartesianIndex}...,
604-
) =
605+
I::Vararg{Union{Integer,CartesianIndex},N}
606+
) where {N} =
605607
bc[CartesianIndex((i1, i2, I...))]
606608
Base.@propagate_inbounds Base.getindex(bc::Broadcasted) = bc[CartesianIndex(())]
607609

608-
@inline Base.checkbounds(bc::Broadcasted, I::Union{Integer,CartesianIndex}) =
610+
Base.checkbounds(bc::Broadcasted, I::Union{Integer,CartesianIndex}) =
609611
Base.checkbounds_indices(Bool, axes(bc), (I,)) || Base.throw_boundserror(bc, (I,))
610612

611613

@@ -632,7 +634,7 @@ struct Extruded{T, K, D}
632634
keeps::K # A tuple of booleans, specifying which indices should be passed normally
633635
defaults::D # A tuple of integers, specifying the index to use when keeps[i] is false (as defaults[i])
634636
end
635-
@inline axes(b::Extruded) = axes(b.x)
637+
axes(b::Extruded) = axes(b.x)
636638
Base.@propagate_inbounds _broadcast_getindex(b::Extruded, i) = b.x[newindex(i, b.keeps, b.defaults)]
637639
extrude(x::AbstractArray) = Extruded(x, newindexer(x)...)
638640
extrude(x) = x
@@ -667,7 +669,7 @@ Base.@propagate_inbounds _getindex(args::Tuple, I) = (_broadcast_getindex(args[1
667669
Base.@propagate_inbounds _getindex(args::Tuple{Any}, I) = (_broadcast_getindex(args[1], I),)
668670
Base.@propagate_inbounds _getindex(args::Tuple{}, I) = ()
669671

670-
@inline _broadcast_getindex_evalf(f::Tf, args::Vararg{Any,N}) where {Tf,N} = f(args...) # not propagate_inbounds
672+
_broadcast_getindex_evalf(f::Tf, args::Vararg{Any,N}) where {Tf,N} = f(args...) # not propagate_inbounds
671673

672674
"""
673675
Broadcast.broadcastable(x)
@@ -711,7 +713,7 @@ _broadcast_getindex_eltype(A) = eltype(A) # Tuple, Array, etc.
711713
eltypes(::Tuple{}) = Tuple{}
712714
eltypes(t::Tuple{Any}) = Tuple{_broadcast_getindex_eltype(t[1])}
713715
eltypes(t::Tuple{Any,Any}) = Tuple{_broadcast_getindex_eltype(t[1]), _broadcast_getindex_eltype(t[2])}
714-
eltypes(t::Tuple) = Tuple{_broadcast_getindex_eltype(t[1]), eltypes(tail(t)).types...}
716+
eltypes(t::Tuple) = Tuple{map(_broadcast_getindex_eltype, t)...}
715717

716718
# Inferred eltype of result of broadcast(f, args...)
717719
combine_eltypes(f, args::Tuple) =
@@ -795,11 +797,11 @@ julia> string.(("one","two","three","four"), ": ", 1:4)
795797
796798
```
797799
"""
798-
broadcast(f::Tf, As...) where {Tf} = materialize(broadcasted(f, As...))
800+
broadcast(f::Tf, As::Vararg{Any,N}) where {Tf,N} = materialize(broadcasted(f, As...))
799801

800802
# special cases defined for performance
801-
@inline broadcast(f, x::Number...) = f(x...)
802-
@inline broadcast(f, t::NTuple{N,Any}, ts::Vararg{NTuple{N,Any}}) where {N} = map(f, t, ts...)
803+
broadcast(f, x::Number...) = f(x...)
804+
broadcast(f, t::NTuple{N,Any}, ts::Vararg{NTuple{N,Any}}) where {N} = map(f, t, ts...)
803805

804806
"""
805807
broadcast!(f, dest, As...)
@@ -844,41 +846,41 @@ Like [`broadcast`](@ref), except in the case of a 0-dimensional result where it
844846
Broadcast automatically unwraps zero-dimensional results to be just the element itself,
845847
but in some cases it is necessary to always return a container — even in the 0-dimensional case.
846848
"""
847-
@inline function broadcast_preserving_zero_d(f, As...)
849+
function broadcast_preserving_zero_d(f, As...)
848850
bc = broadcasted(f, As...)
849851
r = materialize(bc)
850852
return length(axes(bc)) == 0 ? fill!(similar(bc, typeof(r)), r) : r
851853
end
852-
@inline broadcast_preserving_zero_d(f) = fill(f())
853-
@inline broadcast_preserving_zero_d(f, as::Number...) = fill(f(as...))
854+
broadcast_preserving_zero_d(f) = fill(f())
855+
broadcast_preserving_zero_d(f, as::Number...) = fill(f(as...))
854856

855857
"""
856858
Broadcast.materialize(bc)
857859
858860
Take a lazy `Broadcasted` object and compute the result
859861
"""
860-
@inline materialize(bc::Broadcasted) = copy(instantiate(bc))
862+
materialize(bc::Broadcasted) = copy(instantiate(bc))
861863
materialize(x) = x
862864

863-
@inline function materialize!(dest, x)
865+
function materialize!(dest, x)
864866
return materialize!(dest, instantiate(Broadcasted(identity, (x,), axes(dest))))
865867
end
866868

867-
@inline function materialize!(dest, bc::Broadcasted{Style}) where {Style}
869+
function materialize!(dest, bc::Broadcasted{Style}) where {Style}
868870
return materialize!(combine_styles(dest, bc), dest, bc)
869871
end
870-
@inline function materialize!(::BroadcastStyle, dest, bc::Broadcasted{Style}) where {Style}
872+
function materialize!(::BroadcastStyle, dest, bc::Broadcasted{Style}) where {Style}
871873
return copyto!(dest, instantiate(Broadcasted{Style}(bc.f, bc.args, axes(dest))))
872874
end
873875

874876
## general `copy` methods
875-
@inline copy(bc::Broadcasted{<:AbstractArrayStyle{0}}) = bc[CartesianIndex()]
877+
copy(bc::Broadcasted{<:AbstractArrayStyle{0}}) = bc[CartesianIndex()]
876878
copy(bc::Broadcasted{<:Union{Nothing,Unknown}}) =
877879
throw(ArgumentError("broadcasting requires an assigned BroadcastStyle"))
878880

879881
const NonleafHandlingStyles = Union{DefaultArrayStyle,ArrayConflict}
880882

881-
@inline function copy(bc::Broadcasted{Style}) where {Style}
883+
function copy(bc::Broadcasted{Style}) where {Style}
882884
ElType = combine_eltypes(bc.f, bc.args)
883885
if Base.isconcretetype(ElType)
884886
# We can trust it and defer to the simpler `copyto!`
@@ -910,10 +912,10 @@ end
910912
## general `copyto!` methods
911913
# The most general method falls back to a method that replaces Style->Nothing
912914
# This permits specialization on typeof(dest) without introducing ambiguities
913-
@inline copyto!(dest::AbstractArray, bc::Broadcasted) = copyto!(dest, convert(Broadcasted{Nothing}, bc))
915+
copyto!(dest::AbstractArray, bc::Broadcasted) = copyto!(dest, convert(Broadcasted{Nothing}, bc))
914916

915917
# Performance optimization for the common identity scalar case: dest .= val
916-
@inline function copyto!(dest::AbstractArray, bc::Broadcasted{<:AbstractArrayStyle{0}})
918+
function copyto!(dest::AbstractArray, bc::Broadcasted{<:AbstractArrayStyle{0}})
917919
# Typically, we must independently execute bc for every storage location in `dest`, but:
918920
# IF we're in the common no-op identity case with no nested args (like `dest .= val`),
919921
if bc.f === identity && bc.args isa Tuple{Any} && isflat(bc)
@@ -937,15 +939,15 @@ broadcast_unalias(::Nothing, src) = src
937939
# Preprocessing a `Broadcasted` does two things:
938940
# * unaliases any arguments from `dest`
939941
# * "extrudes" the arguments where it is advantageous to pre-compute the broadcasted indices
940-
@inline preprocess(dest, bc::Broadcasted{Style}) where {Style} = Broadcasted{Style}(bc.f, preprocess_args(dest, bc.args), bc.axes)
942+
preprocess(dest, bc::Broadcasted{Style}) where {Style} = Broadcasted{Style}(bc.f, preprocess_args(dest, bc.args), bc.axes)
941943
preprocess(dest, x) = extrude(broadcast_unalias(dest, x))
942944

943-
@inline preprocess_args(dest, args::Tuple) = (preprocess(dest, args[1]), preprocess_args(dest, tail(args))...)
944-
@inline preprocess_args(dest, args::Tuple{Any}) = (preprocess(dest, args[1]),)
945-
@inline preprocess_args(dest, args::Tuple{}) = ()
945+
preprocess_args(dest, args::Tuple) = (preprocess(dest, args[1]), preprocess_args(dest, tail(args))...)
946+
preprocess_args(dest, args::Tuple{Any}) = (preprocess(dest, args[1]),)
947+
preprocess_args(dest, args::Tuple{}) = ()
946948

947949
# Specialize this method if all you want to do is specialize on typeof(dest)
948-
@inline function copyto!(dest::AbstractArray, bc::Broadcasted{Nothing})
950+
function copyto!(dest::AbstractArray, bc::Broadcasted{Nothing})
949951
axes(dest) == axes(bc) || throwdm(axes(dest), axes(bc))
950952
# Performance optimization: broadcast!(identity, dest, A) is equivalent to copyto!(dest, A) if indices match
951953
if bc.f === identity && bc.args isa Tuple{AbstractArray} # only a single input argument to broadcast!
@@ -965,7 +967,7 @@ end
965967

966968
# Performance optimization: for BitArray outputs, we cache the result
967969
# in a "small" Vector{Bool}, and then copy in chunks into the output
968-
@inline function copyto!(dest::BitArray, bc::Broadcasted{Nothing})
970+
function copyto!(dest::BitArray, bc::Broadcasted{Nothing})
969971
axes(dest) == axes(bc) || throwdm(axes(dest), axes(bc))
970972
ischunkedbroadcast(dest, bc) && return chunkedcopyto!(dest, bc)
971973
length(dest) < 256 && return invoke(copyto!, Tuple{AbstractArray, Broadcasted{Nothing}}, dest, bc)
@@ -1019,9 +1021,9 @@ liftchunks(args::Tuple{<:BitArray,Vararg{Any}}) = (args[1].chunks, liftchunks(ta
10191021
# Transform scalars to repeated scalars the size of a chunk
10201022
liftchunks(args::Tuple{<:Bool,Vararg{Any}}) = (ifelse(args[1], typemax(UInt64), UInt64(0)), liftchunks(tail(args))...)
10211023
ithchunk(i) = ()
1022-
Base.@propagate_inbounds ithchunk(i, c::Vector{UInt64}, args...) = (c[i], ithchunk(i, args...)...)
1023-
Base.@propagate_inbounds ithchunk(i, b::UInt64, args...) = (b, ithchunk(i, args...)...)
1024-
@inline function chunkedcopyto!(dest::BitArray, bc::Broadcasted)
1024+
Base.@propagate_inbounds ithchunk(i, c::Vector{UInt64}, args::Vararg{Any,N}) where {N} = (c[i], ithchunk(i, args...)...)
1025+
Base.@propagate_inbounds ithchunk(i, b::UInt64, args::Vararg{Any,N}) where {N} = (b, ithchunk(i, args...)...)
1026+
function chunkedcopyto!(dest::BitArray, bc::Broadcasted)
10251027
isempty(dest) && return dest
10261028
f = flatten(liftfuncs(bc))
10271029
args = liftchunks(f.args)
@@ -1068,7 +1070,7 @@ end
10681070

10691071
## Tuple methods
10701072

1071-
@inline function copy(bc::Broadcasted{Style{Tuple}})
1073+
function copy(bc::Broadcasted{Style{Tuple}})
10721074
dim = axes(bc)
10731075
length(dim) == 1 || throw(DimensionMismatch("tuple only supports one dimension"))
10741076
N = length(dim[1])
@@ -1163,15 +1165,15 @@ struct BitMaskedBitArray{N,M}
11631165
mask::BitArray{M}
11641166
BitMaskedBitArray{N,M}(parent, mask) where {N,M} = new(parent, mask)
11651167
end
1166-
@inline function BitMaskedBitArray(parent::BitArray{N}, mask::BitArray{M}) where {N,M}
1168+
function BitMaskedBitArray(parent::BitArray{N}, mask::BitArray{M}) where {N,M}
11671169
@boundscheck checkbounds(parent, mask)
11681170
BitMaskedBitArray{N,M}(parent, mask)
11691171
end
11701172
Base.@propagate_inbounds dotview(B::BitArray, i::BitArray) = BitMaskedBitArray(B, i)
11711173
Base.show(io::IO, B::BitMaskedBitArray) = foreach(arg->show(io, arg), (typeof(B), (B.parent, B.mask)))
11721174
# Override materialize! to prevent the BitMaskedBitArray from escaping to an overrideable method
1173-
@inline materialize!(B::BitMaskedBitArray, bc::Broadcasted{<:Any,<:Any,typeof(identity),Tuple{Bool}}) = fill!(B, bc.args[1])
1174-
@inline materialize!(B::BitMaskedBitArray, bc::Broadcasted{<:Any}) = materialize!(SubArray(B.parent, to_indices(B.parent, (B.mask,))), bc)
1175+
materialize!(B::BitMaskedBitArray, bc::Broadcasted{<:Any,<:Any,typeof(identity),Tuple{Bool}}) = fill!(B, bc.args[1])
1176+
materialize!(B::BitMaskedBitArray, bc::Broadcasted{<:Any}) = materialize!(SubArray(B.parent, to_indices(B.parent, (B.mask,))), bc)
11751177
function Base.fill!(B::BitMaskedBitArray, b::Bool)
11761178
Bc = B.parent.chunks
11771179
Ic = B.mask.chunks
@@ -1197,7 +1199,7 @@ end
11971199
# explicit calls to view. (All of this can go away if slices
11981200
# are changed to generate views by default.)
11991201

1200-
Base.@propagate_inbounds dotview(args...) = Base.maybeview(args...)
1202+
Base.@propagate_inbounds dotview(args::Vararg{Any,N}) where {N} = Base.maybeview(args...)
12011203

12021204
############################################################
12031205
# The parser turns @. into a call to the __dot__ macro,
@@ -1276,33 +1278,34 @@ macro __dot__(x)
12761278
esc(__dot__(x))
12771279
end
12781280

1279-
@inline function broadcasted_kwsyntax(f, args...; kwargs...)
1281+
1282+
function broadcasted_kwsyntax(f, args::Vararg{Any,N}; kwargs...) where N
12801283
if isempty(kwargs) # some BroadcastStyles dispatch on `f`, so try to preserve its type
12811284
return broadcasted(f, args...)
12821285
else
12831286
return broadcasted((args...) -> f(args...; kwargs...), args...)
12841287
end
12851288
end
1286-
@inline function broadcasted(f, args...)
1287-
args′ = map(broadcastable, args)
1288-
broadcasted(combine_styles(args′...), f, args′...)
1289+
function broadcasted(f)
1290+
args′ = map(broadcastable, ())
1291+
return broadcasted(combine_styles(args′...), f, args′...)
12891292
end
12901293
# Due to the current Type{T}/DataType specialization heuristics within Tuples,
12911294
# the totally generic varargs broadcasted(f, args...) method above loses Type{T}s in
12921295
# mapping broadcastable across the args. These additional methods with explicit
12931296
# arguments ensure we preserve Type{T}s in the first or second argument position.
1294-
@inline function broadcasted(f, arg1, args...)
1297+
function broadcasted(f, arg1)
12951298
arg1′ = broadcastable(arg1)
1296-
args′ = map(broadcastable, args)
1297-
broadcasted(combine_styles(arg1′, args′...), f, arg1′, args′...)
1299+
args′ = map(broadcastable, ())
1300+
return broadcasted(combine_styles(arg1′, args′...), f, arg1′, args′...)
12981301
end
1299-
@inline function broadcasted(f, arg1, arg2, args...)
1302+
function broadcasted(f, arg1, arg2, args::Vararg{Any,N}) where N
13001303
arg1′ = broadcastable(arg1)
13011304
arg2′ = broadcastable(arg2)
13021305
args′ = map(broadcastable, args)
1303-
broadcasted(combine_styles(arg1′, arg2′, args′...), f, arg1′, arg2′, args′...)
1306+
return broadcasted(combine_styles(arg1′, arg2′, args′...), f, arg1′, arg2′, args′...)
13041307
end
1305-
@inline broadcasted(::S, f, args...) where S<:BroadcastStyle = Broadcasted{S}(f, args)
1308+
broadcasted(::S, f, args::Vararg{Any,N}) where {S<:BroadcastStyle,N} = Broadcasted{S}(f, args)
13061309

13071310
"""
13081311
BroadcastFunction{F} <: Function
@@ -1334,7 +1337,7 @@ struct BroadcastFunction{F} <: Function
13341337
f::F
13351338
end
13361339

1337-
@inline (op::BroadcastFunction)(x...; kwargs...) = op.f.(x...; kwargs...)
1340+
(op::BroadcastFunction)(args::Vararg{Any,N}; kwargs...) where {N} = op.f.(args...; kwargs...)
13381341

13391342
function Base.show(io::IO, op::BroadcastFunction)
13401343
print(io, BroadcastFunction, '(')

0 commit comments

Comments
 (0)