Skip to content

Commit 04a4edb

Browse files
fonspstevengj
andauthored
Use checked_mul in length(::ProductIterator) (#43429)
Co-authored-by: Steven G. Johnson <stevenj@mit.edu>
1 parent c46834b commit 04a4edb

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

base/iterators.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@ using .Base:
1414
@propagate_inbounds, @isdefined, @boundscheck, @inbounds, Generator,
1515
AbstractRange, AbstractUnitRange, UnitRange, LinearIndices,
1616
(:), |, +, -, *, !==, !, ==, !=, <=, <, >, >=, missing,
17-
any, _counttuple, eachindex, ntuple, zero, prod, in, firstindex, lastindex,
17+
any, _counttuple, eachindex, ntuple, zero, prod, reduce, in, firstindex, lastindex,
1818
tail, fieldtypes, min, max, minimum, zero, oneunit, promote, promote_shape
1919
using Core: @doc
2020

2121
if Base !== Core.Compiler
2222
using .Base:
2323
cld, fld, SubArray, view, resize!, IndexCartesian
24+
using .Base.Checked: checked_mul
25+
else
26+
# Checked.checked_mul is not available during bootstrapping:
27+
const checked_mul = *
2428
end
2529

2630
import .Base:
@@ -1055,7 +1059,7 @@ _prod_axes1(a, A) =
10551059
throw(ArgumentError("Cannot compute indices for object of type $(typeof(a))"))
10561060

10571061
ndims(p::ProductIterator) = length(axes(p))
1058-
length(P::ProductIterator) = prod(size(P))
1062+
length(P::ProductIterator) = reduce(checked_mul, size(P); init=1)
10591063

10601064
IteratorEltype(::Type{ProductIterator{Tuple{}}}) = HasEltype()
10611065
IteratorEltype(::Type{ProductIterator{Tuple{I}}}) where {I} = IteratorEltype(I)

test/iterators.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,21 +336,25 @@ let a = 1:2,
336336
c = Int32(1):Int32(0)
337337

338338
# length
339+
@test length(product()) == 1
339340
@test length(product(a)) == 2
340341
@test length(product(a, b)) == 20
341342
@test length(product(a, b, c)) == 0
342343

343344
# size
345+
@test size(product()) == tuple()
344346
@test size(product(a)) == (2,)
345347
@test size(product(a, b)) == (2, 10)
346348
@test size(product(a, b, c)) == (2, 10, 0)
347349

348350
# eltype
351+
@test eltype(product()) == Tuple{}
349352
@test eltype(product(a)) == Tuple{Int}
350353
@test eltype(product(a, b)) == Tuple{Int, Float64}
351354
@test eltype(product(a, b, c)) == Tuple{Int, Float64, Int32}
352355

353356
# ndims
357+
@test ndims(product()) == 0
354358
@test ndims(product(a)) == 1
355359
@test ndims(product(a, b)) == 2
356360
@test ndims(product(a, b, c)) == 3
@@ -425,6 +429,8 @@ let a = 1:2,
425429
@test_throws ArgumentError size(product(itr))
426430
@test_throws ArgumentError ndims(product(itr))
427431
end
432+
433+
@test_throws OverflowError length(product(1:typemax(Int), 1:typemax(Int)))
428434
end
429435

430436
# IteratorSize trait business

0 commit comments

Comments
 (0)