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

JuliaLang / julia / #37477

pending completion
#37477

push

local

web-flow
Allow external lattice elements to properly union split (#49030)

Currently `MustAlias` is the only lattice element that is allowed
to widen to union types. However, there are others in external
packages. Expand the support we have for this in order to allow
union splitting of lattice elements.

Co-authored-by: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com>

26 of 26 new or added lines in 5 files covered. (100.0%)

71476 of 82705 relevant lines covered (86.42%)

34756248.54 hits per line

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

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

3
## Binary arithmetic operators ##
4

5
for f in (:+, :-)
6
    @eval function ($f)(A::AbstractArray, B::AbstractArray)
118,541✔
7
        promote_shape(A, B) # check size compatibility
169,963✔
8
        broadcast_preserving_zero_d($f, A, B)
118,540✔
9
    end
10
end
11

12
function +(A::Array, Bs::Array...)
10,931✔
13
    for B in Bs
10,931✔
14
        promote_shape(A, B) # check size compatibility
11,066✔
15
    end
11,196✔
16
    broadcast_preserving_zero_d(+, A, Bs...)
10,926✔
17
end
18

19
for f in (:/, :\, :*)
20
    if f !== :/
21
        @eval ($f)(A::Number, B::AbstractArray) = broadcast_preserving_zero_d($f, A, B)
10,782✔
22
    end
23
    if f !== :\
24
        @eval ($f)(A::AbstractArray, B::Number) = broadcast_preserving_zero_d($f, A, B)
2,964✔
25
    end
26
end
27

28
## data movement ##
29

30
"""
31
    reverse(A; dims=:)
32

33
Reverse `A` along dimension `dims`, which can be an integer (a
34
single dimension), a tuple of integers (a tuple of dimensions)
35
or `:` (reverse along all the dimensions, the default).  See
36
also [`reverse!`](@ref) for in-place reversal.
37

38
# Examples
39
```jldoctest
40
julia> b = Int64[1 2; 3 4]
41
2×2 Matrix{Int64}:
42
 1  2
43
 3  4
44

45
julia> reverse(b, dims=2)
46
2×2 Matrix{Int64}:
47
 2  1
48
 4  3
49

50
julia> reverse(b)
51
2×2 Matrix{Int64}:
52
 4  3
53
 2  1
54
```
55

56
!!! compat "Julia 1.6"
57
    Prior to Julia 1.6, only single-integer `dims` are supported in `reverse`.
58
"""
59
reverse(A::AbstractArray; dims=:) = _reverse(A, dims)
44✔
60
_reverse(A, dims) = reverse!(copymutable(A); dims)
17✔
61

62
"""
63
    reverse!(A; dims=:)
64

65
Like [`reverse`](@ref), but operates in-place in `A`.
66

67
!!! compat "Julia 1.6"
68
    Multidimensional `reverse!` requires Julia 1.6.
69
"""
70
reverse!(A::AbstractArray; dims=:) = _reverse!(A, dims)
38✔
71
_reverse!(A::AbstractArray{<:Any,N}, ::Colon) where {N} = _reverse!(A, ntuple(identity, Val{N}()))
2✔
72
_reverse!(A, dim::Integer) = _reverse!(A, (Int(dim),))
17✔
73
_reverse!(A, dims::NTuple{M,Integer}) where {M} = _reverse!(A, Int.(dims))
×
74
function _reverse!(A::AbstractArray{<:Any,N}, dims::NTuple{M,Int}) where {N,M}
20✔
75
    dimrev = ntuple(k -> k in dims, Val{N}()) # boolean tuple indicating reversed dims
108✔
76

77
    if N < M || M != sum(dimrev)
20✔
78
        throw(ArgumentError("invalid dimensions $dims in reverse!"))
×
79
    end
80
    M == 0 && return A # nothing to reverse
20✔
81

82
    # swapping loop only needs to traverse ≈half of the array
83
    halfsz = ntuple(k -> k == dims[1] ? size(A,k) ÷ 2 : size(A,k), Val{N}())
106✔
84

85
    last1 = ntuple(k -> lastindex(A,k)+firstindex(A,k), Val{N}()) # offset for reversed index
68✔
86
    for i in CartesianIndices(ntuple(k -> firstindex(A,k):firstindex(A,k)-1+@inbounds(halfsz[k]), Val{N}()))
89✔
87
        iₜ = Tuple(i)
1,492✔
88
        iᵣ = CartesianIndex(ifelse.(dimrev, last1 .- iₜ, iₜ))
1,492✔
89
        @inbounds A[iᵣ], A[i] = A[i], A[iᵣ]
1,492✔
90
    end
1,511✔
91
    if M > 1 && isodd(size(A, dims[1]))
20✔
92
        # middle slice for odd dimensions must be recursively flipped
93
        mid = firstindex(A, dims[1]) + (size(A, dims[1]) ÷ 2)
1✔
94
        midslice = CartesianIndices(ntuple(k -> k == dims[1] ? (mid:mid) : (firstindex(A,k):lastindex(A,k)), Val{N}()))
3✔
95
        _reverse!(view(A, midslice), dims[2:end])
1✔
96
    end
97
    return A
20✔
98
end
99
# fix ambiguity with array.jl:
100
_reverse!(A::AbstractVector, dim::Tuple{Int}) = _reverse!(A, first(dim))
×
101

102

103
"""
104
    rotl90(A)
105

106
Rotate matrix `A` left 90 degrees.
107

108
# Examples
109
```jldoctest
110
julia> a = [1 2; 3 4]
111
2×2 Matrix{Int64}:
112
 1  2
113
 3  4
114

115
julia> rotl90(a)
116
2×2 Matrix{Int64}:
117
 2  4
118
 1  3
119
```
120
"""
121
function rotl90(A::AbstractMatrix)
4✔
122
    ind1, ind2 = axes(A)
4✔
123
    B = similar(A, (ind2,ind1))
5✔
124
    n = first(ind2)+last(ind2)
4✔
125
    for i=axes(A,1), j=ind2
46✔
126
        B[n-j,i] = A[i,j]
712✔
127
    end
750✔
128
    return B
4✔
129
end
130

131
"""
132
    rotr90(A)
133

134
Rotate matrix `A` right 90 degrees.
135

136
# Examples
137
```jldoctest
138
julia> a = [1 2; 3 4]
139
2×2 Matrix{Int64}:
140
 1  2
141
 3  4
142

143
julia> rotr90(a)
144
2×2 Matrix{Int64}:
145
 3  1
146
 4  2
147
```
148
"""
149
function rotr90(A::AbstractMatrix)
4✔
150
    ind1, ind2 = axes(A)
4✔
151
    B = similar(A, (ind2,ind1))
5✔
152
    m = first(ind1)+last(ind1)
4✔
153
    for i=ind1, j=axes(A,2)
46✔
154
        B[j,m-i] = A[i,j]
712✔
155
    end
750✔
156
    return B
4✔
157
end
158
"""
159
    rot180(A)
160

161
Rotate matrix `A` 180 degrees.
162

163
# Examples
164
```jldoctest
165
julia> a = [1 2; 3 4]
166
2×2 Matrix{Int64}:
167
 1  2
168
 3  4
169

170
julia> rot180(a)
171
2×2 Matrix{Int64}:
172
 4  3
173
 2  1
174
```
175
"""
176
function rot180(A::AbstractMatrix)
2✔
177
    B = similar(A)
2✔
178
    ind1, ind2 = axes(A,1), axes(A,2)
2✔
179
    m, n = first(ind1)+last(ind1), first(ind2)+last(ind2)
2✔
180
    for j=ind2, i=ind1
42✔
181
        B[m-i,n-j] = A[i,j]
680✔
182
    end
718✔
183
    return B
2✔
184
end
185
"""
186
    rotl90(A, k)
187

188
Left-rotate matrix `A` 90 degrees counterclockwise an integer `k` number of times.
189
If `k` is a multiple of four (including zero), this is equivalent to a `copy`.
190

191
# Examples
192
```jldoctest
193
julia> a = [1 2; 3 4]
194
2×2 Matrix{Int64}:
195
 1  2
196
 3  4
197

198
julia> rotl90(a,1)
199
2×2 Matrix{Int64}:
200
 2  4
201
 1  3
202

203
julia> rotl90(a,2)
204
2×2 Matrix{Int64}:
205
 4  3
206
 2  1
207

208
julia> rotl90(a,3)
209
2×2 Matrix{Int64}:
210
 3  1
211
 4  2
212

213
julia> rotl90(a,4)
214
2×2 Matrix{Int64}:
215
 1  2
216
 3  4
217
```
218
"""
219
function rotl90(A::AbstractMatrix, k::Integer)
14✔
220
    k = mod(k, 4)
14✔
221
    k == 1 ? rotl90(A) :
14✔
222
    k == 2 ? rot180(A) :
223
    k == 3 ? rotr90(A) : copy(A)
224
end
225
"""
226
    rotr90(A, k)
227

228
Right-rotate matrix `A` 90 degrees clockwise an integer `k` number of times.
229
If `k` is a multiple of four (including zero), this is equivalent to a `copy`.
230

231
# Examples
232
```jldoctest
233
julia> a = [1 2; 3 4]
234
2×2 Matrix{Int64}:
235
 1  2
236
 3  4
237

238
julia> rotr90(a,1)
239
2×2 Matrix{Int64}:
240
 3  1
241
 4  2
242

243
julia> rotr90(a,2)
244
2×2 Matrix{Int64}:
245
 4  3
246
 2  1
247

248
julia> rotr90(a,3)
249
2×2 Matrix{Int64}:
250
 2  4
251
 1  3
252

253
julia> rotr90(a,4)
254
2×2 Matrix{Int64}:
255
 1  2
256
 3  4
257
```
258
"""
259
rotr90(A::AbstractMatrix, k::Integer) = rotl90(A,-k)
3✔
260
"""
261
    rot180(A, k)
262

263
Rotate matrix `A` 180 degrees an integer `k` number of times.
264
If `k` is even, this is equivalent to a `copy`.
265

266
# Examples
267
```jldoctest
268
julia> a = [1 2; 3 4]
269
2×2 Matrix{Int64}:
270
 1  2
271
 3  4
272

273
julia> rot180(a,1)
274
2×2 Matrix{Int64}:
275
 4  3
276
 2  1
277

278
julia> rot180(a,2)
279
2×2 Matrix{Int64}:
280
 1  2
281
 3  4
282
```
283
"""
284
rot180(A::AbstractMatrix, k::Integer) = mod(k, 2) == 1 ? rot180(A) : copy(A)
2✔
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

© 2025 Coveralls, Inc