Skip to content

Commit 374c8d4

Browse files
committed
Fix invalidations from novel Integer conversions
Defining struct MyInt <: Integer x::Int end (::Type{T})(x::MyInt) where T<:Integer = T(x.x) triggers about 830 unique method invalidations. This fixes the majority of them, but it's a lot of type-annotation.
1 parent 1888e31 commit 374c8d4

File tree

18 files changed

+111
-97
lines changed

18 files changed

+111
-97
lines changed

base/arrayshow.jl

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -166,18 +166,19 @@ function print_matrix(io::IO, X::AbstractVecOrMat,
166166
vdots::AbstractString = "\u22ee",
167167
ddots::AbstractString = " \u22f1 ",
168168
hmod::Integer = 5, vmod::Integer = 5)
169+
hmod, vmod = Int(hmod)::Int, Int(vmod)::Int
169170
if !(get(io, :limit, false)::Bool)
170171
screenheight = screenwidth = typemax(Int)
171172
else
172-
sz = displaysize(io)
173+
sz = displaysize(io)::Tuple{Int,Int}
173174
screenheight, screenwidth = sz[1] - 4, sz[2]
174175
end
175-
screenwidth -= length(pre) + length(post)
176-
presp = repeat(" ", length(pre)) # indent each row to match pre string
176+
screenwidth -= length(pre)::Int + length(post)::Int
177+
presp = repeat(" ", length(pre)::Int) # indent each row to match pre string
177178
postsp = ""
178179
@assert textwidth(hdots) == textwidth(ddots)
179-
sepsize = length(sep)
180-
rowsA, colsA = UnitRange(axes(X,1)), UnitRange(axes(X,2))
180+
sepsize = length(sep)::Int
181+
rowsA, colsA = UnitRange{Int}(axes(X,1)), UnitRange{Int}(axes(X,2))
181182
m, n = length(rowsA), length(colsA)
182183
# To figure out alignments, only need to look at as many rows as could
183184
# fit down screen. If screen has at least as many rows as A, look at A.
@@ -204,14 +205,14 @@ function print_matrix(io::IO, X::AbstractVecOrMat,
204205
if i != last(rowsA); println(io); end
205206
end
206207
else # rows fit down screen but cols don't, so need horizontal ellipsis
207-
c = div(screenwidth-length(hdots)+1,2)+1 # what goes to right of ellipsis
208+
c = div(screenwidth-length(hdots)::Int+1,2)+1 # what goes to right of ellipsis
208209
Ralign = reverse(alignment(io, X, rowsA, reverse(colsA), c, c, sepsize)) # alignments for right
209-
c = screenwidth - sum(map(sum,Ralign)) - (length(Ralign)-1)*sepsize - length(hdots)
210+
c = screenwidth - sum(map(sum,Ralign)) - (length(Ralign)-1)*sepsize - length(hdots)::Int
210211
Lalign = alignment(io, X, rowsA, colsA, c, c, sepsize) # alignments for left of ellipsis
211212
for i in rowsA
212213
print(io, i == first(rowsA) ? pre : presp)
213214
print_matrix_row(io, X,Lalign,i,colsA[1:length(Lalign)],sep)
214-
print(io, (i - first(rowsA)) % hmod == 0 ? hdots : repeat(" ", length(hdots)))
215+
print(io, (i - first(rowsA)) % hmod == 0 ? hdots : repeat(" ", length(hdots)::Int))
215216
print_matrix_row(io, X, Ralign, i, (n - length(Ralign)) .+ colsA, sep)
216217
print(io, i == last(rowsA) ? post : postsp)
217218
if i != last(rowsA); println(io); end
@@ -231,15 +232,15 @@ function print_matrix(io::IO, X::AbstractVecOrMat,
231232
end
232233
end
233234
else # neither rows nor cols fit, so use all 3 kinds of dots
234-
c = div(screenwidth-length(hdots)+1,2)+1
235+
c = div(screenwidth-length(hdots)::Int+1,2)+1
235236
Ralign = reverse(alignment(io, X, rowsA, reverse(colsA), c, c, sepsize))
236-
c = screenwidth - sum(map(sum,Ralign)) - (length(Ralign)-1)*sepsize - length(hdots)
237+
c = screenwidth - sum(map(sum,Ralign)) - (length(Ralign)-1)*sepsize - length(hdots)::Int
237238
Lalign = alignment(io, X, rowsA, colsA, c, c, sepsize)
238239
r = mod((length(Ralign)-n+1),vmod) # where to put dots on right half
239240
for i in rowsA
240241
print(io, i == first(rowsA) ? pre : presp)
241242
print_matrix_row(io, X,Lalign,i,colsA[1:length(Lalign)],sep)
242-
print(io, (i - first(rowsA)) % hmod == 0 ? hdots : repeat(" ", length(hdots)))
243+
print(io, (i - first(rowsA)) % hmod == 0 ? hdots : repeat(" ", length(hdots)::Int))
243244
print_matrix_row(io, X,Ralign,i,(n-length(Ralign)).+colsA,sep)
244245
print(io, i == last(rowsA) ? post : postsp)
245246
if i != rowsA[end] || i == rowsA[halfheight]; println(io); end

base/int.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ julia> count_ones(7)
369369
3
370370
```
371371
"""
372-
count_ones(x::BitInteger) = ctpop_int(x) % Int
372+
count_ones(x::BitInteger) = (ctpop_int(x) % Int)::Int
373373

374374
"""
375375
leading_zeros(x::Integer) -> Integer
@@ -382,7 +382,7 @@ julia> leading_zeros(Int32(1))
382382
31
383383
```
384384
"""
385-
leading_zeros(x::BitInteger) = ctlz_int(x) % Int
385+
leading_zeros(x::BitInteger) = (ctlz_int(x) % Int)::Int
386386

387387
"""
388388
trailing_zeros(x::Integer) -> Integer
@@ -395,7 +395,7 @@ julia> trailing_zeros(2)
395395
1
396396
```
397397
"""
398-
trailing_zeros(x::BitInteger) = cttz_int(x) % Int
398+
trailing_zeros(x::BitInteger) = (cttz_int(x) % Int)::Int
399399

400400
"""
401401
count_zeros(x::Integer) -> Integer

base/reflection.jl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -846,18 +846,21 @@ A list of modules can also be specified as an array.
846846
At least Julia 1.4 is required for specifying a module.
847847
"""
848848
function methods(@nospecialize(f), @nospecialize(t),
849-
@nospecialize(mod::Union{Module,AbstractArray{Module},Nothing}=nothing))
850-
if mod isa Module
851-
mod = (mod,)
852-
end
849+
@nospecialize(mod::Union{Tuple{Module},AbstractArray{Module},Nothing}=nothing))
853850
if isa(f, Core.Builtin)
854851
throw(ArgumentError("argument is not a generic function"))
855852
end
856853
t = to_tuple_type(t)
857854
world = typemax(UInt)
858-
MethodList(Method[m.method for m in _methods(f, t, -1, world) if mod === nothing || m.method.module in mod],
859-
typeof(f).name.mt)
855+
# Lack of specialization => a comprehension triggers too many invalidations via _collect, so collect the methods manually
856+
ms = Method[]
857+
for m in _methods(f, t, -1, world)
858+
m::Core.MethodMatch
859+
(mod === nothing || m.method.module mod) && push!(ms, m.method)
860+
end
861+
MethodList(ms, typeof(f).name.mt)
860862
end
863+
methods(@nospecialize(f), @nospecialize(t), mod::Module) = methods(f, t, (mod,))
861864

862865
methods(f::Core.Builtin) = MethodList(Method[], typeof(f).name.mt)
863866

base/refvalue.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ function unsafe_convert(P::Type{Ptr{T}}, b::RefValue{T}) where T
2222
# which also ensures this returns same pointer as the one rooted in the `RefValue` object.
2323
p = pointerref(Ptr{Ptr{Cvoid}}(pointer_from_objref(b)), 1, Core.sizeof(Ptr{Cvoid}))
2424
end
25-
return convert(P, p)
25+
return convert(P, p)::Ptr{T}
2626
end
2727
function unsafe_convert(P::Type{Ptr{Any}}, b::RefValue{Any})
28-
return convert(P, pointer_from_objref(b))
28+
return convert(P, pointer_from_objref(b))::Ptr{Any}
2929
end
30-
unsafe_convert(::Type{Ptr{Cvoid}}, b::RefValue{T}) where {T} = convert(Ptr{Cvoid}, unsafe_convert(Ptr{T}, b))
30+
unsafe_convert(::Type{Ptr{Cvoid}}, b::RefValue{T}) where {T} = convert(Ptr{Cvoid}, unsafe_convert(Ptr{T}, b))::Ptr{Cvoid}
3131

3232
getindex(b::RefValue) = b.x
3333
setindex!(b::RefValue, x) = (b.x = x; b)

base/regex.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -422,11 +422,11 @@ struct SubstitutionString{T<:AbstractString} <: AbstractString
422422
string::T
423423
end
424424

425-
ncodeunits(s::SubstitutionString) = ncodeunits(s.string)
426-
codeunit(s::SubstitutionString) = codeunit(s.string)
427-
codeunit(s::SubstitutionString, i::Integer) = codeunit(s.string, i)
428-
isvalid(s::SubstitutionString, i::Integer) = isvalid(s.string, i)
429-
iterate(s::SubstitutionString, i::Integer...) = iterate(s.string, i...)
425+
ncodeunits(s::SubstitutionString) = ncodeunits(s.string)::Int
426+
codeunit(s::SubstitutionString) = codeunit(s.string)::Type{<:Union{UInt8, UInt16, UInt32}}
427+
codeunit(s::SubstitutionString, i::Integer) = codeunit(s.string, i)::Union{UInt8, UInt16, UInt32}
428+
isvalid(s::SubstitutionString, i::Integer) = isvalid(s.string, i)::Bool
429+
iterate(s::SubstitutionString, i::Integer...) = iterate(s.string, i...)::Union{Nothing,Tuple{AbstractChar,Int}}
430430

431431
function show(io::IO, s::SubstitutionString)
432432
print(io, "s")

base/set.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ function unique!(f, A::AbstractVector; seen::Union{Nothing,Set}=nothing)
264264
return A
265265
end
266266

267-
i = firstindex(A)
267+
i = firstindex(A)::Int
268268
x = @inbounds A[i]
269269
y = f(x)
270270
if seen === nothing
@@ -291,7 +291,7 @@ function _unique!(f, A::AbstractVector, seen::Set, current::Integer, i::Integer)
291291
end
292292
i += 1
293293
end
294-
return resize!(A, current - firstindex(A) + 1)::typeof(A)
294+
return resize!(A, current - firstindex(A)::Int + 1)::typeof(A)
295295
end
296296

297297

base/shell.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const shell_special = "#{}()[]<>|&*?~;"
88
function rstrip_shell(s::AbstractString)
99
c_old = nothing
1010
for (i, c) in Iterators.reverse(pairs(s))
11+
i::Int; c::AbstractChar
1112
((c == '\\') && c_old == ' ') && return SubString(s, 1, i+1)
1213
isspace(c) || return SubString(s, 1, i)
1314
c_old = c
@@ -38,8 +39,8 @@ function shell_parse(str::AbstractString, interpolate::Bool=true;
3839
end
3940
end
4041
function consume_upto(s, i, j)
41-
update_arg(s[i:prevind(s, j)])
42-
something(peek(st), (lastindex(s)+1,'\0'))[1]
42+
update_arg(s[i:prevind(s, j)::Int])
43+
something(peek(st), (lastindex(s)::Int+1,'\0'))[1]
4344
end
4445
function append_arg()
4546
if isempty(arg); arg = Any["",]; end
@@ -48,6 +49,7 @@ function shell_parse(str::AbstractString, interpolate::Bool=true;
4849
end
4950

5051
for (j, c) in st
52+
j::Int; c::AbstractChar
5153
if !in_single_quotes && !in_double_quotes && isspace(c)
5254
i = consume_upto(s, i, j)
5355
append_arg()

base/show.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ function _show_default(io::IO, @nospecialize(x))
395395
show(io, inferencebarrier(t))
396396
print(io, '(')
397397
nf = nfields(x)
398-
nb = sizeof(x)
398+
nb = sizeof(x)::Int
399399
if nf != 0 || nb == 0
400400
if !show_circular(io, x)
401401
recur_io = IOContext(io, Pair{Symbol,Any}(:SHOWN_SET, x),

base/strings/basic.jl

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,10 @@ julia> sizeof("∀")
174174
3
175175
```
176176
"""
177-
sizeof(s::AbstractString) = ncodeunits(s) * sizeof(codeunit(s))
177+
sizeof(s::AbstractString) = ncodeunits(s)::Int * sizeof(codeunit(s)::Type{<:Union{UInt8,UInt16,UInt32}})
178178
firstindex(s::AbstractString) = 1
179-
lastindex(s::AbstractString) = thisind(s, ncodeunits(s))
180-
isempty(s::AbstractString) = iszero(ncodeunits(s))
179+
lastindex(s::AbstractString) = thisind(s, ncodeunits(s)::Int)
180+
isempty(s::AbstractString) = iszero(ncodeunits(s)::Int)
181181

182182
function getindex(s::AbstractString, i::Integer)
183183
@boundscheck checkbounds(s, i)
@@ -204,9 +204,9 @@ end
204204
## bounds checking ##
205205

206206
checkbounds(::Type{Bool}, s::AbstractString, i::Integer) =
207-
1 i ncodeunits(s)
207+
1 i ncodeunits(s)::Int
208208
checkbounds(::Type{Bool}, s::AbstractString, r::AbstractRange{<:Integer}) =
209-
isempty(r) || (1 minimum(r) && maximum(r) ncodeunits(s))
209+
isempty(r) || (1 minimum(r) && maximum(r) ncodeunits(s)::Int)
210210
checkbounds(::Type{Bool}, s::AbstractString, I::AbstractArray{<:Real}) =
211211
all(i -> checkbounds(Bool, s, i), I)
212212
checkbounds(::Type{Bool}, s::AbstractString, I::AbstractArray{<:Integer}) =
@@ -382,12 +382,12 @@ julia> length("jμΛIα")
382382
5
383383
```
384384
"""
385-
length(s::AbstractString) = @inbounds return length(s, 1, ncodeunits(s))
385+
length(s::AbstractString) = @inbounds return length(s, 1, ncodeunits(s)::Int)
386386

387387
function length(s::AbstractString, i::Int, j::Int)
388388
@boundscheck begin
389-
0 < i ncodeunits(s)+1 || throw(BoundsError(s, i))
390-
0  j < ncodeunits(s)+1 || throw(BoundsError(s, j))
389+
0 < i ncodeunits(s)::Int+1 || throw(BoundsError(s, i))
390+
0  j < ncodeunits(s)::Int+1 || throw(BoundsError(s, j))
391391
end
392392
n = 0
393393
for k = i:j
@@ -434,7 +434,7 @@ ERROR: BoundsError: attempt to access 2-codeunit String at index [-1]
434434
thisind(s::AbstractString, i::Integer) = thisind(s, Int(i))
435435

436436
function thisind(s::AbstractString, i::Int)
437-
z = ncodeunits(s) + 1
437+
z = ncodeunits(s)::Int + 1
438438
i == z && return i
439439
@boundscheck 0  i z || throw(BoundsError(s, i))
440440
@inbounds while 1 < i && !(isvalid(s, i)::Bool)
@@ -602,9 +602,9 @@ isascii(c::AbstractChar) = UInt32(c) < 0x80
602602
## string map, filter ##
603603

604604
function map(f, s::AbstractString)
605-
out = StringVector(max(4, sizeof(s)÷sizeof(codeunit(s))))
605+
out = StringVector(max(4, sizeof(s)::Int÷sizeof(codeunit(s)::Type{<:Union{UInt8,UInt16,UInt32}})))
606606
index = UInt(1)
607-
for c in s
607+
for c::AbstractChar in s
608608
c′ = f(c)
609609
isa(c′, AbstractChar) || throw(ArgumentError(
610610
"map(f, s::AbstractString) requires f to return AbstractChar; " *

base/strings/io.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -343,11 +343,11 @@ julia> escape_string(string('\\u2135','\\0','0')) # \\0 would be ambiguous
343343
"""
344344
function escape_string(io::IO, s::AbstractString, esc="")
345345
a = Iterators.Stateful(s)
346-
for c in a
346+
for c::AbstractChar in a
347347
if c in esc
348348
print(io, '\\', c)
349349
elseif isascii(c)
350-
c == '\0' ? print(io, escape_nul(peek(a))) :
350+
c == '\0' ? print(io, escape_nul(peek(a)::Union{AbstractChar,Nothing})) :
351351
c == '\e' ? print(io, "\\e") :
352352
c == '\\' ? print(io, "\\\\") :
353353
'\a' <= c <= '\r' ? print(io, '\\', "abtnvfr"[Int(c)-6]) :
@@ -356,10 +356,10 @@ function escape_string(io::IO, s::AbstractString, esc="")
356356
elseif !isoverlong(c) && !ismalformed(c)
357357
isprint(c) ? print(io, c) :
358358
c <= '\x7f' ? print(io, "\\x", string(UInt32(c), base = 16, pad = 2)) :
359-
c <= '\uffff' ? print(io, "\\u", string(UInt32(c), base = 16, pad = need_full_hex(peek(a)) ? 4 : 2)) :
360-
print(io, "\\U", string(UInt32(c), base = 16, pad = need_full_hex(peek(a)) ? 8 : 4))
359+
c <= '\uffff' ? print(io, "\\u", string(UInt32(c), base = 16, pad = need_full_hex(peek(a)::Union{AbstractChar,Nothing}) ? 4 : 2)) :
360+
print(io, "\\U", string(UInt32(c), base = 16, pad = need_full_hex(peek(a)::Union{AbstractChar,Nothing}) ? 8 : 4))
361361
else # malformed or overlong
362-
u = bswap(reinterpret(UInt32, c))
362+
u = bswap(reinterpret(UInt32, c)::UInt32)
363363
while true
364364
print(io, "\\x", string(u % UInt8, base = 16, pad = 2))
365365
(u >>= 8) == 0 && break

base/strings/search.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,14 @@ function _searchindex(s::Union{AbstractString,ByteArray},
144144
t::Union{AbstractString,AbstractChar,Int8,UInt8},
145145
i::Integer)
146146
if isempty(t)
147-
return 1 <= i <= nextind(s,lastindex(s)) ? i :
147+
return 1 <= i <= nextind(s,lastindex(s))::Int ? i :
148148
throw(BoundsError(s, i))
149149
end
150150
t1, trest = Iterators.peel(t)
151151
while true
152152
i = findnext(isequal(t1),s,i)
153153
if i === nothing return 0 end
154-
ii = nextind(s, i)
154+
ii = nextind(s, i)::Int
155155
a = Iterators.Stateful(trest)
156156
matched = all(splat(==), zip(SubString(s, ii), a))
157157
(isempty(a) && matched) && return i
@@ -351,21 +351,21 @@ function _rsearchindex(s::AbstractString,
351351
t::Union{AbstractString,AbstractChar,Int8,UInt8},
352352
i::Integer)
353353
if isempty(t)
354-
return 1 <= i <= nextind(s, lastindex(s)) ? i :
354+
return 1 <= i <= nextind(s, lastindex(s))::Int ? i :
355355
throw(BoundsError(s, i))
356356
end
357357
t1, trest = Iterators.peel(Iterators.reverse(t))
358358
while true
359359
i = findprev(isequal(t1), s, i)
360360
i === nothing && return 0
361-
ii = prevind(s, i)
361+
ii = prevind(s, i)::Int
362362
a = Iterators.Stateful(trest)
363363
b = Iterators.Stateful(Iterators.reverse(
364364
pairs(SubString(s, 1, ii))))
365365
matched = all(splat(==), zip(a, (x[2] for x in b)))
366366
if matched && isempty(a)
367367
isempty(b) && return firstindex(s)
368-
return nextind(s, popfirst!(b)[1])
368+
return nextind(s, popfirst!(b)[1])::Int
369369
end
370370
i = ii
371371
end

base/strings/substring.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ end
4444
SubString(s.string, s.offset+i, s.offset+j)
4545
end
4646

47-
SubString(s::AbstractString) = SubString(s, 1, lastindex(s))
48-
SubString{T}(s::T) where {T<:AbstractString} = SubString{T}(s, 1, lastindex(s))
47+
SubString(s::AbstractString) = SubString(s, 1, lastindex(s)::Int)
48+
SubString{T}(s::T) where {T<:AbstractString} = SubString{T}(s, 1, lastindex(s)::Int)
4949

5050
@propagate_inbounds view(s::AbstractString, r::AbstractUnitRange{<:Integer}) = SubString(s, r)
5151
@propagate_inbounds maybeview(s::AbstractString, r::AbstractUnitRange{<:Integer}) = view(s, r)
@@ -62,7 +62,7 @@ function String(s::SubString{String})
6262
end
6363

6464
ncodeunits(s::SubString) = s.ncodeunits
65-
codeunit(s::SubString) = codeunit(s.string)
65+
codeunit(s::SubString) = codeunit(s.string)::Type{<:Union{UInt8, UInt16, UInt32}}
6666
length(s::SubString) = length(s.string, s.offset+1, s.offset+s.ncodeunits)
6767

6868
function codeunit(s::SubString, i::Integer)
@@ -75,7 +75,7 @@ function iterate(s::SubString, i::Integer=firstindex(s))
7575
@boundscheck checkbounds(s, i)
7676
y = iterate(s.string, s.offset + i)
7777
y === nothing && return nothing
78-
c, i = y
78+
c, i = y::Tuple{AbstractChar,Int}
7979
return c, i - s.offset
8080
end
8181

@@ -87,7 +87,7 @@ end
8787
function isvalid(s::SubString, i::Integer)
8888
ib = true
8989
@boundscheck ib = checkbounds(Bool, s, i)
90-
@inbounds return ib && isvalid(s.string, s.offset + i)
90+
@inbounds return ib && isvalid(s.string, s.offset + i)::Bool
9191
end
9292

9393
byte_string_classify(s::SubString{String}) =

0 commit comments

Comments
 (0)