Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Backports release 1.0.6 #34011

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ own licenses:
- [LLVM](http://releases.llvm.org/6.0.0/LICENSE.TXT) [BSD-3, effectively]
- [UTF8PROC](https://github.com/JuliaStrings/utf8proc) [MIT]

The following components included in `stdlib` have their own separate licenses:

- stdlib/SuiteSparse/umfpack.jl (see [SUITESPARSE](http://suitesparse.com))
- stdlib/SuiteSparse/cholmod.jl (see [SUITESPARSE](http://suitesparse.com))

Julia's `stdlib` uses the following external libraries, which have their own licenses:

- [DSFMT](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/LICENSE.txt) [BSD-3]
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ endef
ifeq (,$(findstring $(OS),FreeBSD WINNT))
julia-base: $(build_libdir)/libgfortran*.$(SHLIB_EXT)*
$(build_libdir)/libgfortran*.$(SHLIB_EXT)*: | $(build_libdir) julia-deps
-$(CUSTOM_LD_LIBRARY_PATH) PATH=$(PATH):$(build_depsbindir) $(JULIAHOME)/contrib/fixup-libgfortran.sh --verbose $(build_libdir)
-$(CUSTOM_LD_LIBRARY_PATH) PATH="$(PATH):$(build_depsbindir)" $(JULIAHOME)/contrib/fixup-libgfortran.sh --verbose $(build_libdir)
JL_PRIVATE_LIBS-0 += libgfortran libgcc_s libquadmath
endif

Expand Down
9 changes: 7 additions & 2 deletions base/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,13 @@ of the `Broadcasted` object empty (populated with [`nothing`](@ref)).
end
return Broadcasted{Style}(bc.f, bc.args, axes)
end
instantiate(bc::Broadcasted{<:Union{AbstractArrayStyle{0}, Style{Tuple}}}) = bc

instantiate(bc::Broadcasted{<:AbstractArrayStyle{0}}) = bc
# Tuples don't need axes, but when they have axes (for .= assignment), we need to check them (#33020)
instantiate(bc::Broadcasted{Style{Tuple}, Nothing}) = bc
function instantiate(bc::Broadcasted{Style{Tuple}})
check_broadcast_axes(bc.axes, bc.args...)
return bc
end
## Flattening

"""
Expand Down
81 changes: 63 additions & 18 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ function fieldcount_noerror(@nospecialize t)
end


function try_compute_fieldidx(@nospecialize(typ), @nospecialize(field))
function try_compute_fieldidx(typ::DataType, @nospecialize(field))
if isa(field, Symbol)
field = fieldindex(typ, field, false)
field == 0 && return nothing
Expand Down Expand Up @@ -710,6 +710,7 @@ fieldtype_tfunc(@nospecialize(s0), @nospecialize(name), @nospecialize(inbounds))
fieldtype_tfunc(s0, name)

function fieldtype_nothrow(@nospecialize(s0), @nospecialize(name))
s0 === Bottom && return true # unreachable
if s0 === Any || s0 === Type || DataType ⊑ s0 || UnionAll ⊑ s0
# We have no idea
return false
Expand All @@ -721,14 +722,29 @@ function fieldtype_nothrow(@nospecialize(s0), @nospecialize(name))
return false
end

s = instanceof_tfunc(s0)[1]
u = unwrap_unionall(s)
return _fieldtype_nothrow(u, name)
su = unwrap_unionall(s0)
if isa(su, Union)
return fieldtype_nothrow(rewrap_unionall(su.a, s0), name) &&
fieldtype_nothrow(rewrap_unionall(su.b, s0), name)
end

s, exact = instanceof_tfunc(s0)
s === Bottom && return false # always
return _fieldtype_nothrow(s, exact, name)
end

function _fieldtype_nothrow(@nospecialize(u), name::Const)
function _fieldtype_nothrow(@nospecialize(s), exact::Bool, name::Const)
u = unwrap_unionall(s)
if isa(u, Union)
return _fieldtype_nothrow(u.a, name) && _fieldtype_nothrow(u.b, name)
a = _fieldtype_nothrow(u.a, exact, name)
b = _fieldtype_nothrow(u.b, exact, name)
return exact ? (a || b) : (a && b)
end
u isa DataType || return false
u.abstract && return false
if u.name === _NAMEDTUPLE_NAME && !isconcretetype(u)
# TODO: better approximate inference
return false
end
fld = name.val
if isa(fld, Symbol)
Expand All @@ -747,6 +763,9 @@ function _fieldtype_nothrow(@nospecialize(u), name::Const)
end

function fieldtype_tfunc(@nospecialize(s0), @nospecialize(name))
if s0 === Bottom
return Bottom
end
if s0 === Any || s0 === Type || DataType ⊑ s0 || UnionAll ⊑ s0
return Type
end
Expand All @@ -758,18 +777,28 @@ function fieldtype_tfunc(@nospecialize(s0), @nospecialize(name))
return Bottom
end

s = instanceof_tfunc(s0)[1]
u = unwrap_unionall(s)

if isa(u, Union)
return tmerge(rewrap(fieldtype_tfunc(Type{u.a}, name), s),
rewrap(fieldtype_tfunc(Type{u.b}, name), s))
su = unwrap_unionall(s0)
if isa(su, Union)
return tmerge(fieldtype_tfunc(rewrap(su.a, s0), name),
fieldtype_tfunc(rewrap(su.b, s0), name))
end

if !isa(u, DataType) || u.abstract
return Type
s, exact = instanceof_tfunc(s0)
s === Bottom && return Bottom
return _fieldtype_tfunc(s, exact, name)
end

function _fieldtype_tfunc(@nospecialize(s), exact::Bool, @nospecialize(name))
exact = exact && !has_free_typevars(s)
u = unwrap_unionall(s)
if isa(u, Union)
return tmerge(_fieldtype_tfunc(rewrap(u.a, s), exact, name),
_fieldtype_tfunc(rewrap(u.b, s), exact, name))
end
u isa DataType || return Type
u.abstract && return Type
if u.name === _NAMEDTUPLE_NAME && !isconcretetype(u)
# TODO: better approximate inference
return Type
end
ftypes = u.types
Expand All @@ -778,12 +807,25 @@ function fieldtype_tfunc(@nospecialize(s0), @nospecialize(name))
end

if !isa(name, Const)
name = widenconst(name)
if !(Int <: name || Symbol <: name)
return Bottom
end
t = Bottom
for i in 1:length(ftypes)
t = tmerge(t, fieldtype_tfunc(s0, Const(i)))
ft1 = unwrapva(ftypes[i])
exactft1 = exact || !has_free_typevars(ft1)
ft1 = rewrap_unionall(ft1, s)
if exactft1
if issingletontype(ft1)
ft1 = Const(ft1) # ft unique via type cache
else
ft1 = Type{ft1}
end
else
ft1 = Type{ft} where ft<:ft1
end
t = tmerge(t, ft1)
t === Any && break
end
return t
Expand All @@ -805,10 +847,13 @@ function fieldtype_tfunc(@nospecialize(s0), @nospecialize(name))
ft = ftypes[fld]
end

exact = (isa(s0, Const) || isType(s0)) && !has_free_typevars(s)
exactft = exact || !has_free_typevars(ft)
ft = rewrap_unionall(ft, s)
if exact
return Const(ft)
if exactft
if issingletontype(ft)
return Const(ft) # ft unique via type cache
end
return Type{ft}
end
return Type{<:ft}
end
Expand Down
2 changes: 1 addition & 1 deletion base/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ function lcm(a::T, b::T) where T<:Integer
if a == 0
return a
else
return checked_abs(a * div(b, gcd(b,a)))
return checked_abs(checked_mul(a, div(b, gcd(b,a))))
end
end

Expand Down
12 changes: 9 additions & 3 deletions base/reshapedarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ reshape(parent::AbstractArray, shp::Tuple{Union{Integer,OneTo}, Vararg{Union{Int
reshape(parent::AbstractArray, dims::Dims) = _reshape(parent, dims)

# Allow missing dimensions with Colon():
reshape(parent::AbstractVector, ::Colon) = parent
reshape(parent::AbstractArray, dims::Int...) = reshape(parent, dims)
reshape(parent::AbstractArray, dims::Union{Int,Colon}...) = reshape(parent, dims)
reshape(parent::AbstractArray, dims::Tuple{Vararg{Union{Int,Colon}}}) = _reshape(parent, _reshape_uncolon(parent, dims))
Expand Down Expand Up @@ -201,6 +202,8 @@ dataids(A::ReshapedArray) = dataids(A.parent)
d, r = divrem(ind, strds[1])
(_ind2sub_rs(front(ax), tail(strds), r)..., d + first(ax[end]))
end
offset_if_vec(i::Integer, axs::Tuple{<:AbstractUnitRange}) = i + first(axs[1]) - 1
offset_if_vec(i::Integer, axs::Tuple) = i

@inline function getindex(A::ReshapedArrayLF, index::Int)
@boundscheck checkbounds(A, index)
Expand All @@ -218,8 +221,9 @@ end
end

@inline function _unsafe_getindex(A::ReshapedArray{T,N}, indices::Vararg{Int,N}) where {T,N}
i = Base._sub2ind(size(A), indices...)
I = ind2sub_rs(axes(A.parent), A.mi, i)
axp = axes(A.parent)
i = offset_if_vec(Base._sub2ind(size(A), indices...), axp)
I = ind2sub_rs(axp, A.mi, i)
_unsafe_getindex_rs(parent(A), I)
end
@inline _unsafe_getindex_rs(A, i::Integer) = (@inbounds ret = A[i]; ret)
Expand All @@ -241,7 +245,9 @@ end
end

@inline function _unsafe_setindex!(A::ReshapedArray{T,N}, val, indices::Vararg{Int,N}) where {T,N}
@inbounds parent(A)[ind2sub_rs(axes(A.parent), A.mi, Base._sub2ind(size(A), indices...))...] = val
axp = axes(A.parent)
i = offset_if_vec(Base._sub2ind(size(A), indices...), axp)
@inbounds parent(A)[ind2sub_rs(axes(A.parent), A.mi, i)...] = val
val
end

Expand Down
14 changes: 13 additions & 1 deletion base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,20 @@ end
show(x)

Write an informative text representation of a value to the current output stream. New types
should overload `show(io, x)` where the first argument is a stream. The representation used
should overload `show(io::IO, x)` where the first argument is a stream. The representation used
by `show` generally includes Julia-specific formatting and type information.

[`repr`](@ref) returns the output of `show` as a string.

See also [`print`](@ref), which writes un-decorated representations.

# Examples
```jldoctest
julia> show("Hello World!")
"Hello World!"
julia> print("Hello World!")
Hello World!
```
"""
show(x) = show(stdout::IO, x)

Expand Down
17 changes: 15 additions & 2 deletions base/strings/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@
print([io::IO], xs...)

Write to `io` (or to the default output stream [`stdout`](@ref)
if `io` is not given) a canonical (un-decorated) text representation
of values `xs` if there is one, otherwise call [`show`](@ref).
if `io` is not given) a canonical (un-decorated) text representation.
The representation used by `print` includes minimal formatting and tries to
avoid Julia-specific details.

Printing `nothing` is not allowed and throws an error.

`print` falls back to calling `show`, so most types should just define
`show`. Define `print` if your type has a separate "plain" representation.
For example, `show` displays strings with quotes, and `print` displays strings
without quotes.

[`string`](@ref) returns the output of `print` as a string.

# Examples
```jldoctest
julia> print("Hello World!")
Expand Down Expand Up @@ -146,6 +152,12 @@ end

Create a string from any values, except `nothing`, using the [`print`](@ref) function.

`string` should usually not be defined directly. Instead, define a method
`print(io::IO, x::MyType)`. If `string(x)` for a certain type needs to be
highly efficient, then it may make sense to add a method to `string` and
define `print(io::IO, x::MyType) = print(io, string(x))` to ensure the
functions are consistent.

# Examples
```jldoctest
julia> string("a", 1, true)
Expand Down Expand Up @@ -179,6 +191,7 @@ end
repr(x; context=nothing)

Create a string from any value using the [`show`](@ref) function.
You should not add methods to `repr`; define a `show` method instead.

The optional keyword argument `context` can be set to an `IO` or [`IOContext`](@ref)
object whose attributes are used for the I/O stream passed to `show`.
Expand Down
5 changes: 4 additions & 1 deletion base/sysinfo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,9 @@ for executable permissions only (with `.exe` and `.com` extensions added on
Windows platforms); no searching of `PATH` is performed.
"""
function which(program_name::String)
if isempty(program_name)
return nothing
end
# Build a list of program names that we're going to try
program_names = String[]
base_pname = basename(program_name)
Expand Down Expand Up @@ -410,7 +413,7 @@ function which(program_name::String)
for pname in program_names
program_path = joinpath(path_dir, pname)
# If we find something that matches our name and we can execute
if isexecutable(program_path)
if isfile(program_path) && isexecutable(program_path)
return realpath(program_path)
end
end
Expand Down
11 changes: 7 additions & 4 deletions base/twiceprecision.jl
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ function (:)(start::T, step::T, stop::T) where T<:Union{Float16,Float32,Float64}
stop_n, stop_d = rat(stop)
if start_d != 0 && stop_d != 0 &&
T(start_n/start_d) == start && T(stop_n/stop_d) == stop
den = lcm(start_d, step_d) # use same denominator for start and step
den = lcm_unchecked(start_d, step_d) # use same denominator for start and step
m = maxintfloat(T, Int)
if den != 0 && abs(start*den) <= m && abs(step*den) <= m && # will round succeed?
rem(den, start_d) == 0 && rem(den, step_d) == 0 # check lcm overflow
Expand Down Expand Up @@ -429,7 +429,7 @@ function _range(a::T, st::T, ::Nothing, len::Integer) where T<:Union{Float16,Flo
step_n, step_d = rat(st)
if start_d != 0 && step_d != 0 &&
T(start_n/start_d) == a && T(step_n/step_d) == st
den = lcm(start_d, step_d)
den = lcm_unchecked(start_d, step_d)
m = maxintfloat(T, Int)
if abs(den*a) <= m && abs(den*st) <= m &&
rem(den, start_d) == 0 && rem(den, step_d) == 0
Expand Down Expand Up @@ -513,7 +513,7 @@ function _convertSRL(::Type{StepRangeLen{T,R,S}}, r::AbstractRange{U}) where {T,
step_n, step_d = rat(s)
if start_d != 0 && step_d != 0 &&
U(start_n/start_d) == f && U(step_n/step_d) == s
den = lcm(start_d, step_d)
den = lcm_unchecked(start_d, step_d)
m = maxintfloat(T, Int)
if den != 0 && abs(f*den) <= m && abs(s*den) <= m &&
rem(den, start_d) == 0 && rem(den, step_d) == 0
Expand Down Expand Up @@ -582,7 +582,7 @@ function _range(start::T, ::Nothing, stop::T, len::Integer) where {T<:IEEEFloat}
start_n, start_d = rat(start)
stop_n, stop_d = rat(stop)
if start_d != 0 && stop_d != 0
den = lcm(start_d, stop_d)
den = lcm_unchecked(start_d, stop_d)
m = maxintfloat(T, Int)
if den != 0 && abs(den*start) <= m && abs(den*stop) <= m
start_n = round(Int, den*start)
Expand Down Expand Up @@ -691,6 +691,9 @@ function rat(x)
return a, b
end

# This version of lcm does not check for overflows
lcm_unchecked(a::T, b::T) where T<:Integer = a * div(b, gcd(a, b))

narrow(::Type{T}) where {T<:AbstractFloat} = Float64
narrow(::Type{Float64}) = Float32
narrow(::Type{Float32}) = Float16
Expand Down
22 changes: 5 additions & 17 deletions base/weakkeydict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
WeakKeyDict([itr])

`WeakKeyDict()` constructs a hash table where the keys are weak
references to objects, and thus may be garbage collected even when
references to objects which may be garbage collected even when
referenced in a hash table.

See [`Dict`](@ref) for further help. Note, unlike [`Dict`](@ref),
Expand Down Expand Up @@ -111,24 +111,12 @@ getindex(wkh::WeakKeyDict{K}, key) where {K} = lock(() -> getindex(wkh.ht, key),
isempty(wkh::WeakKeyDict) = isempty(wkh.ht)
length(t::WeakKeyDict) = length(t.ht)

function iterate(t::WeakKeyDict{K,V}) where V where K
gc_token = Ref{Bool}(false) # no keys will be deleted via finalizers until this token is gc'd
finalizer(gc_token) do r
if r[]
r[] = false
unlock(t.lock)
end
end
s = lock(t.lock)
iterate(t, (gc_token,))
end
function iterate(t::WeakKeyDict{K,V}, state) where V where K
gc_token = first(state)
y = iterate(t.ht, tail(state)...)
function iterate(t::WeakKeyDict{K,V}, state...) where {K, V}
y = lock(() -> iterate(t.ht, state...), t)
y === nothing && return nothing
wkv, i = y
wkv, newstate = y
kv = Pair{K,V}(wkv[1].value::K, wkv[2])
return (kv, (gc_token, i))
return (kv, newstate)
end

filter!(f, d::WeakKeyDict) = filter_in_one_pass!(f, d)
Loading