julia> Base.return_types(String, Tuple{AbstractVector{UInt8}})
3-element Vector{Any}:
String
String
Any
julia> methods(String, Tuple{AbstractVector{UInt8}})
# 3 methods for type constructor:
[1] String(v::Vector{UInt8})
@ Base strings/string.jl:67
[2] String(s::Base.CodeUnits{UInt8, String})
@ Base strings/string.jl:107
[3] String(v::AbstractVector{UInt8})
@ Base strings/string.jl:66
So Base.return_types thinks that String(::AbstractVector{UInt8}) may not always be inferrable, and it blames this method in base/strings/string.jl, at line 66:
But I donβt understand how can that not always be perfectly inferrable? The copyto! return type is guaranteed to infer as Vector{UInt8}, and String(::Vector{UInt8}) also has perfect inference, according to Base.return_types:
julia> Base.return_types(length, Tuple{AbstractVector{UInt8}})
19-element Vector{Any}:
Int64
UInt8
Any
Any
Any
Any
Any
Int64
Int64
Integer
Integer
Int64
Integer
Any
Int64
Integer
Any
Union{}
Any
OK, I guess we could add some type assertions to some of those length methods. EDIT: actually, the first thing to do is add an ::Integer type assertion into the method above. EDIT2: that doesnβt help for some reason, so I guess itβll just be a ::String annotation.
As I explained here, Iβm not sure youβll get much support for this idea. Relying on world-splitting like this is generally considered a bad idea now, and attempts to fix it like this will just be an endless game of whack-a-mole.
More likely would just be that people support turning on max_methods=1 so that no world splitting occurs, and thus no code needs to be recompiled if someone adds a wonky method to length or string.