• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #38028

15 Mar 2025 07:57AM UTC coverage: 20.131% (+0.1%) from 19.998%
#38028

push

local

web-flow
lowering: Don't closure-convert in `import` or `using` (#57774)

Fixes #57702. We're calling cl-convert- on `using` and `import`
statements when we shouldn't, so if there's a nearby local that gets
boxed (recursive function definition in this case), and the local shares
a name with something in an import statement, we get a box access where
we want a raw symbol.

Before:
```
julia> let; let; import SHA: R; end; let; R(x...) = R(x); end; end
ERROR: TypeError: in import, expected Symbol, got a value of type Expr
Stacktrace:
 [1] top-level scope
   @ REPL[1]:1
```

After:
```
julia> let; let; import SHA: R; end; let; R(x...) = R(x); end; end
(::var"#R#R##0") (generic function with 1 method)
```

Previously, symbols in `import`/`using` statements would be wrapped with
`outerref`, which cl-convert- wouldn't peek into. This protected us from
this problem in 1.11.

9803 of 48697 relevant lines covered (20.13%)

120021.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/base/abstractarraymath.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
 ## Basic functions ##
4

5
isreal(x::AbstractArray) = all(isreal,x)
×
6
iszero(x::AbstractArray) = all(iszero,x)
×
7
isreal(x::AbstractArray{<:Real}) = true
×
8

9
## Constructors ##
10

11
"""
12
    vec(a::AbstractArray) -> AbstractVector
13

14
Reshape the array `a` as a one-dimensional column vector. Return `a` if it is
15
already an `AbstractVector`. The resulting array
16
shares the same underlying data as `a`, so it will only be mutable if `a` is
17
mutable, in which case modifying one will also modify the other.
18

19
# Examples
20
```jldoctest
21
julia> a = [1 2 3; 4 5 6]
22
2×3 Matrix{Int64}:
23
 1  2  3
24
 4  5  6
25

26
julia> vec(a)
27
6-element Vector{Int64}:
28
 1
29
 4
30
 2
31
 5
32
 3
33
 6
34

35
julia> vec(1:3)
36
1:3
37
```
38

39
See also [`reshape`](@ref), [`dropdims`](@ref).
40
"""
41
vec(a::AbstractArray) = reshape(a,length(a))
×
42
vec(a::AbstractVector) = a
×
43

44
_sub(::Tuple{}, ::Tuple{}) = ()
×
45
_sub(t::Tuple, ::Tuple{}) = t
×
46
_sub(t::Tuple, s::Tuple) = _sub(tail(t), tail(s))
×
47

48
"""
49
    dropdims(A; dims)
50

51
Return an array with the same data as `A`, but with the dimensions specified by
52
`dims` removed. `size(A,d)` must equal 1 for every `d` in `dims`,
53
and repeated dimensions or numbers outside `1:ndims(A)` are forbidden.
54

55
The result shares the same underlying data as `A`, such that the
56
result is mutable if and only if `A` is mutable, and setting elements of one
57
alters the values of the other.
58

59
See also: [`reshape`](@ref), [`vec`](@ref).
60

61
# Examples
62
```jldoctest
63
julia> a = reshape(Vector(1:4),(2,2,1,1))
64
2×2×1×1 Array{Int64, 4}:
65
[:, :, 1, 1] =
66
 1  3
67
 2  4
68

69
julia> b = dropdims(a; dims=3)
70
2×2×1 Array{Int64, 3}:
71
[:, :, 1] =
72
 1  3
73
 2  4
74

75
julia> b[1,1,1] = 5; a
76
2×2×1×1 Array{Int64, 4}:
77
[:, :, 1, 1] =
78
 5  3
79
 2  4
80
```
81
"""
82
dropdims(A; dims) = _dropdims(A, dims)
×
83
function _dropdims(A::AbstractArray, dims::Dims)
×
84
    for i in eachindex(dims)
×
85
        1 <= dims[i] <= ndims(A) || throw(ArgumentError("dropped dims must be in range 1:ndims(A)"))
×
86
        length(axes(A, dims[i])) == 1 || throw(ArgumentError("dropped dims must all be size 1"))
×
87
        for j = 1:i-1
×
88
            dims[j] == dims[i] && throw(ArgumentError("dropped dims must be unique"))
×
89
        end
×
90
    end
×
91
    ax = _foldoneto((ds, d) -> d in dims ? ds : (ds..., axes(A,d)), (), Val(ndims(A)))
×
92
    reshape(A, ax::typeof(_sub(axes(A), dims)))
×
93
end
94
_dropdims(A::AbstractArray, dim::Integer) = _dropdims(A, (Int(dim),))
×
95

96

97
"""
98
    insertdims(A; dims)
99

100
Inverse of [`dropdims`](@ref); return an array with new singleton dimensions
101
at every dimension in `dims`.
102

103
Repeated dimensions are forbidden and the largest entry in `dims` must be
104
less than or equal than `ndims(A) + length(dims)`.
105

106
The result shares the same underlying data as `A`, such that the
107
result is mutable if and only if `A` is mutable, and setting elements of one
108
alters the values of the other.
109

110
See also: [`dropdims`](@ref), [`reshape`](@ref), [`vec`](@ref).
111
# Examples
112
```jldoctest
113
julia> x = [1 2 3; 4 5 6]
114
2×3 Matrix{Int64}:
115
 1  2  3
116
 4  5  6
117

118
julia> insertdims(x, dims=3)
119
2×3×1 Array{Int64, 3}:
120
[:, :, 1] =
121
 1  2  3
122
 4  5  6
123

124
julia> insertdims(x, dims=(1,2,5)) == reshape(x, 1, 1, 2, 3, 1)
125
true
126

127
julia> dropdims(insertdims(x, dims=(1,2,5)), dims=(1,2,5))
128
2×3 Matrix{Int64}:
129
 1  2  3
130
 4  5  6
131
```
132

133
!!! compat "Julia 1.12"
134
    Requires Julia 1.12 or later.
135
"""
136
insertdims(A; dims) = _insertdims(A, dims)
×
137
function _insertdims(A::AbstractArray{T, N}, dims::NTuple{M, Int}) where {T, N, M}
×
138
    for i in eachindex(dims)
×
139
        1 ≤ dims[i] || throw(ArgumentError("the smallest entry in dims must be ≥ 1."))
×
140
        dims[i] ≤ N+M || throw(ArgumentError("the largest entry in dims must be not larger than the dimension of the array and the length of dims added"))
×
141
        for j = 1:i-1
×
142
            dims[j] == dims[i] && throw(ArgumentError("inserted dims must be unique"))
×
143
        end
×
144
    end
×
145

146
    # acc is a tuple, where the first entry is the final shape
147
    # the second entry off acc is a counter for the axes of A
148
    inds= Base._foldoneto((acc, i) ->
×
149
                            i ∈ dims
150
                                ? ((acc[1]..., Base.OneTo(1)), acc[2])
151
                                : ((acc[1]..., axes(A, acc[2])), acc[2] + 1),
152
                            ((), 1), Val(N+M))
153
    new_shape = inds[1]
×
154
    return reshape(A, new_shape)
×
155
end
156
_insertdims(A::AbstractArray, dim::Integer) = _insertdims(A, (Int(dim),))
×
157

158

159

160
## Unary operators ##
161

162
"""
163
    conj!(A)
164

165
Transform an array to its complex conjugate in-place.
166

167
See also [`conj`](@ref).
168

169
# Examples
170
```jldoctest
171
julia> A = [1+im 2-im; 2+2im 3+im]
172
2×2 Matrix{Complex{Int64}}:
173
 1+1im  2-1im
174
 2+2im  3+1im
175

176
julia> conj!(A);
177

178
julia> A
179
2×2 Matrix{Complex{Int64}}:
180
 1-1im  2+1im
181
 2-2im  3-1im
182
```
183
"""
184
conj!(A::AbstractArray{<:Number}) = (@inbounds broadcast!(conj, A, A); A)
×
185
conj!(x::AbstractArray{<:Real}) = x
×
186
conj!(A::AbstractArray) = (foreach(conj!, A); A)
×
187

188
"""
189
    conj(A::AbstractArray)
190

191
Return an array containing the complex conjugate of each entry in array `A`.
192

193
Equivalent to `conj.(A)`, except that when `eltype(A) <: Real`
194
`A` is returned without copying, and that when `A` has zero dimensions,
195
a 0-dimensional array is returned (rather than a scalar).
196

197
# Examples
198
```jldoctest
199
julia> conj([1, 2im, 3 + 4im])
200
3-element Vector{Complex{Int64}}:
201
 1 + 0im
202
 0 - 2im
203
 3 - 4im
204

205
julia> conj(fill(2 - im))
206
0-dimensional Array{Complex{Int64}, 0}:
207
2 + 1im
208
```
209
"""
210
conj(A::AbstractArray) = broadcast_preserving_zero_d(conj, A)
×
211
conj(A::AbstractArray{<:Real}) = A
×
212

213
"""
214
    real(A::AbstractArray)
215

216
Return an array containing the real part of each entry in array `A`.
217

218
Equivalent to `real.(A)`, except that when `eltype(A) <: Real`
219
`A` is returned without copying, and that when `A` has zero dimensions,
220
a 0-dimensional array is returned (rather than a scalar).
221

222
# Examples
223
```jldoctest
224
julia> real([1, 2im, 3 + 4im])
225
3-element Vector{Int64}:
226
 1
227
 0
228
 3
229

230
julia> real(fill(2 - im))
231
0-dimensional Array{Int64, 0}:
232
2
233
```
234
"""
235
real(A::AbstractArray) = broadcast_preserving_zero_d(real, A)
×
236
real(A::AbstractArray{<:Real}) = A
×
237

238
"""
239
    imag(A::AbstractArray)
240

241
Return an array containing the imaginary part of each entry in array `A`.
242

243
Equivalent to `imag.(A)`, except that when `A` has zero dimensions,
244
a 0-dimensional array is returned (rather than a scalar).
245

246
# Examples
247
```jldoctest
248
julia> imag([1, 2im, 3 + 4im])
249
3-element Vector{Int64}:
250
 0
251
 2
252
 4
253

254
julia> imag(fill(2 - im))
255
0-dimensional Array{Int64, 0}:
256
-1
257
```
258
"""
259
imag(A::AbstractArray) = broadcast_preserving_zero_d(imag, A)
×
260
imag(A::AbstractArray{<:Real}) = zero(A)
×
261

262
"""
263
    reim(A::AbstractArray)
264

265
Return a tuple of two arrays containing respectively the real and the imaginary
266
part of each entry in `A`.
267

268
Equivalent to `(real.(A), imag.(A))`, except that when `eltype(A) <: Real`
269
`A` is returned without copying to represent the real part, and that when `A` has
270
zero dimensions, a 0-dimensional array is returned (rather than a scalar).
271

272
# Examples
273
```jldoctest
274
julia> reim([1, 2im, 3 + 4im])
275
([1, 0, 3], [0, 2, 4])
276

277
julia> reim(fill(2 - im))
278
(fill(2), fill(-1))
279
```
280
"""
281
reim(A::AbstractArray)
282

283
-(A::AbstractArray) = broadcast_preserving_zero_d(-, A)
×
284

285
+(x::AbstractArray{<:Number}) = x
×
286
*(x::AbstractArray{<:Number,2}) = x
×
287

288
# index A[:,:,...,i,:,:,...] where "i" is in dimension "d"
289

290
"""
291
    selectdim(A, d::Integer, i)
292

293
Return a view of all the data of `A` where the index for dimension `d` equals `i`.
294

295
Equivalent to `view(A,:,:,...,i,:,:,...)` where `i` is in position `d`.
296

297
See also: [`eachslice`](@ref).
298

299
# Examples
300
```jldoctest
301
julia> A = [1 2 3 4; 5 6 7 8]
302
2×4 Matrix{Int64}:
303
 1  2  3  4
304
 5  6  7  8
305

306
julia> selectdim(A, 2, 3)
307
2-element view(::Matrix{Int64}, :, 3) with eltype Int64:
308
 3
309
 7
310

311
julia> selectdim(A, 2, 3:4)
312
2×2 view(::Matrix{Int64}, :, 3:4) with eltype Int64:
313
 3  4
314
 7  8
315
```
316
"""
317
@inline selectdim(A::AbstractArray, d::Integer, i) = _selectdim(A, d, i, _setindex(i, d, map(Slice, axes(A))...))
×
318
@noinline function _selectdim(A, d, i, idxs)
×
319
    d >= 1 || throw(ArgumentError("dimension must be ≥ 1, got $d"))
×
320
    nd = ndims(A)
×
321
    d > nd && (i == 1 || throw(BoundsError(A, (ntuple(Returns(Colon()),d-1)..., i))))
×
322
    return view(A, idxs...)
×
323
end
324

325
function circshift(a::AbstractArray, shiftamt::Real)
×
326
    circshift!(similar(a), a, (Integer(shiftamt),))
×
327
end
328
circshift(a::AbstractArray, shiftamt::DimsInteger) = circshift!(similar(a), a, shiftamt)
×
329
"""
330
    circshift(A, shifts)
331

332
Circularly shift, i.e. rotate, the data in `A`. The second argument is a tuple or
333
vector giving the amount to shift in each dimension, or an integer to shift only in the
334
first dimension.
335

336
The generated code is most efficient when the shift amounts are known at compile-time, i.e.,
337
compile-time constants.
338

339
See also: [`circshift!`](@ref), [`circcopy!`](@ref), [`bitrotate`](@ref), [`<<`](@ref).
340

341
# Examples
342
```jldoctest
343
julia> b = reshape(Vector(1:16), (4,4))
344
4×4 Matrix{Int64}:
345
 1  5   9  13
346
 2  6  10  14
347
 3  7  11  15
348
 4  8  12  16
349

350
julia> circshift(b, (0,2))
351
4×4 Matrix{Int64}:
352
  9  13  1  5
353
 10  14  2  6
354
 11  15  3  7
355
 12  16  4  8
356

357
julia> circshift(b, (-1,0))
358
4×4 Matrix{Int64}:
359
 2  6  10  14
360
 3  7  11  15
361
 4  8  12  16
362
 1  5   9  13
363

364
julia> a = BitArray([true, true, false, false, true])
365
5-element BitVector:
366
 1
367
 1
368
 0
369
 0
370
 1
371

372
julia> circshift(a, 1)
373
5-element BitVector:
374
 1
375
 1
376
 1
377
 0
378
 0
379

380
julia> circshift(a, -1)
381
5-element BitVector:
382
 1
383
 0
384
 0
385
 1
386
 1
387

388
julia> x = (1, 2, 3, 4, 5)
389
(1, 2, 3, 4, 5)
390

391
julia> circshift(x, 4)
392
(2, 3, 4, 5, 1)
393

394
julia> z = (1, 'a', -7.0, 3)
395
(1, 'a', -7.0, 3)
396

397
julia> circshift(z, -1)
398
('a', -7.0, 3, 1)
399
```
400
"""
401
function circshift(a::AbstractArray, shiftamt)
×
402
    circshift!(similar(a), a, map(Integer, (shiftamt...,)))
×
403
end
404

405
## Other array functions ##
406

407
"""
408
    repeat(A::AbstractArray, counts::Integer...)
409

410
Construct an array by repeating array `A` a given number of times in each dimension, specified by `counts`.
411

412
See also: [`fill`](@ref), [`Iterators.repeated`](@ref), [`Iterators.cycle`](@ref).
413

414
# Examples
415
```jldoctest
416
julia> repeat([1, 2, 3], 2)
417
6-element Vector{Int64}:
418
 1
419
 2
420
 3
421
 1
422
 2
423
 3
424

425
julia> repeat([1, 2, 3], 2, 3)
426
6×3 Matrix{Int64}:
427
 1  1  1
428
 2  2  2
429
 3  3  3
430
 1  1  1
431
 2  2  2
432
 3  3  3
433
```
434
"""
435
function repeat(A::AbstractArray, counts...)
×
436
    return repeat(A, outer=counts)
×
437
end
438

439
"""
440
    repeat(A::AbstractArray; inner=ntuple(Returns(1), ndims(A)), outer=ntuple(Returns(1), ndims(A)))
441

442
Construct an array by repeating the entries of `A`. The i-th element of `inner` specifies
443
the number of times that the individual entries of the i-th dimension of `A` should be
444
repeated. The i-th element of `outer` specifies the number of times that a slice along the
445
i-th dimension of `A` should be repeated. If `inner` or `outer` are omitted, no repetition
446
is performed.
447

448
# Examples
449
```jldoctest
450
julia> repeat(1:2, inner=2)
451
4-element Vector{Int64}:
452
 1
453
 1
454
 2
455
 2
456

457
julia> repeat(1:2, outer=2)
458
4-element Vector{Int64}:
459
 1
460
 2
461
 1
462
 2
463

464
julia> repeat([1 2; 3 4], inner=(2, 1), outer=(1, 3))
465
4×6 Matrix{Int64}:
466
 1  2  1  2  1  2
467
 1  2  1  2  1  2
468
 3  4  3  4  3  4
469
 3  4  3  4  3  4
470
```
471
"""
472
function repeat(A::AbstractArray; inner = nothing, outer = nothing)
×
473
    return _RepeatInnerOuter.repeat(A, inner=inner, outer=outer)
×
474
end
475

476
module _RepeatInnerOuter
477

478
function repeat(arr; inner=nothing, outer=nothing)
×
479
    check(arr, inner, outer)
×
480
    arr, inner, outer = resolve(arr, inner, outer)
×
481
    repeat_inner_outer(arr, inner, outer)
×
482
end
483

484
to_tuple(t::Tuple) = t
×
485
to_tuple(x::Integer) = (x,)
×
486
to_tuple(itr) = tuple(itr...)
×
487

488
function pad(a, b)
×
489
    N = max(length(a), length(b))
×
490
    Base.fill_to_length(a, 1, Val(N)), Base.fill_to_length(b, 1, Val(N))
×
491
end
492
function pad(a, b, c)
×
493
    N = max(max(length(a), length(b)), length(c))
×
494
    Base.fill_to_length(a, 1, Val(N)), Base.fill_to_length(b, 1, Val(N)), Base.fill_to_length(c, 1, Val(N))
×
495
end
496

497
function resolve(arr::AbstractArray{<:Any, N}, inner::NTuple{N, Any}, outer::NTuple{N,Any}) where {N}
×
498
    arr, inner, outer
×
499
end
500
function resolve(arr, inner, outer)
×
501
    dims, inner, outer = pad(size(arr), to_tuple(inner), to_tuple(outer))
×
502
    reshape(arr, dims), inner, outer
×
503
end
504
function resolve(arr, inner::Nothing, outer::Nothing)
×
505
    return arr, inner, outer
×
506
end
507
function resolve(arr, inner::Nothing, outer)
×
508
    dims, outer = pad(size(arr), to_tuple(outer))
×
509
    reshape(arr, dims), inner, outer
×
510
end
511
function resolve(arr, inner, outer::Nothing)
×
512
    dims, inner = pad(size(arr), to_tuple(inner))
×
513
    reshape(arr, dims), inner, outer
×
514
end
515

516
function check(arr, inner, outer)
×
517
    if inner !== nothing
×
518
        # TODO: Currently one based indexing is demanded for inner !== nothing,
519
        # but not for outer !== nothing. Decide for something consistent.
520
        Base.require_one_based_indexing(arr)
×
521
        if !all(n -> n isa Integer, inner)
×
522
            throw(ArgumentError("repeat requires integer counts, got inner = $inner"))
×
523
        end
524
        if any(<(0), inner)
×
525
            throw(ArgumentError("no inner repetition count may be negative; got $inner"))
×
526
        end
527
        if length(inner) < ndims(arr)
×
528
            throw(ArgumentError("number of inner repetitions ($(length(inner))) cannot be less than number of dimensions of input array ($(ndims(arr)))"))
×
529
        end
530
    end
531
    if outer !== nothing
×
532
        if !all(n -> n isa Integer, outer)
×
533
            throw(ArgumentError("repeat requires integer counts, got outer = $outer"))
×
534
        end
535
        if any(<(0), outer)
×
536
            throw(ArgumentError("no outer repetition count may be negative; got $outer"))
×
537
        end
538
        if (length(outer) < ndims(arr)) && (inner !== nothing)
×
539
            throw(ArgumentError("number of outer repetitions ($(length(outer))) cannot be less than number of dimensions of input array ($(ndims(arr)))"))
×
540
        end
541
    end
542
end
543

544
repeat_inner_outer(arr, inner::Nothing, outer::Nothing) = arr
×
545
repeat_inner_outer(arr, ::Nothing, outer) = repeat_outer(arr, outer)
×
546
repeat_inner_outer(arr, inner, ::Nothing) = repeat_inner(arr, inner)
×
547
repeat_inner_outer(arr, inner, outer) = repeat_outer(repeat_inner(arr, inner), outer)
×
548

549
function repeat_outer(a::AbstractMatrix, (m,n)::NTuple{2, Any})
×
550
    o, p = size(a,1), size(a,2)
×
551
    b = similar(a, o*m, p*n)
×
552
    for j=1:n
×
553
        d = (j-1)*p+1
×
554
        R = d:d+p-1
×
555
        for i=1:m
×
556
            c = (i-1)*o+1
×
557
            @inbounds b[c:c+o-1, R] = a
×
558
        end
×
559
    end
×
560
    return b
×
561
end
562

563
function repeat_outer(a::AbstractVector, (m,)::Tuple{Any})
×
564
    o = length(a)
×
565
    b = similar(a, o*m)
×
566
    for i=1:m
×
567
        c = (i-1)*o+1
×
568
        @inbounds b[c:c+o-1] = a
×
569
    end
×
570
    return b
×
571
end
572

573
function repeat_outer(arr::AbstractArray{<:Any,N}, dims::NTuple{N,Any}) where {N}
×
574
    insize  = size(arr)
×
575
    outsize = map(*, insize, dims)
×
576
    out = similar(arr, outsize)
×
577
    for I in CartesianIndices(arr)
×
578
        for J in CartesianIndices(dims)
×
579
            TIJ = map(Tuple(I), Tuple(J), insize) do i, j, d
×
580
                i + d * (j-1)
×
581
            end
582
            IJ = CartesianIndex(TIJ)
×
583
            @inbounds out[IJ] = arr[I]
×
584
        end
×
585
    end
×
586
    return out
×
587
end
588

589
function repeat_inner(arr, inner)
×
590
    outsize = map(*, size(arr), inner)
×
591
    out = similar(arr, outsize)
×
592
    for I in CartesianIndices(arr)
×
593
        for J in CartesianIndices(inner)
×
594
            TIJ = map(Tuple(I), Tuple(J), inner) do i, j, d
×
595
                (i-1) * d + j
×
596
            end
597
            IJ = CartesianIndex(TIJ)
×
598
            @inbounds out[IJ] = arr[I]
×
599
        end
×
600
    end
×
601
    return out
×
602
end
603

604
end#module
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc