diff --git a/base/Enums.jl b/base/Enums.jl index 87f99e7114789..40bc9a63315dc 100644 --- a/base/Enums.jl +++ b/base/Enums.jl @@ -7,6 +7,11 @@ export Enum, @enum function basetype end +""" + Enum{T<:Integer} + +The abstract supertype of all enumerated types defined with [`@enum`](@ref). +""" abstract type Enum{T<:Integer} end (::Type{T})(x::Enum{T2}) where {T<:Integer,T2<:Integer} = T(bitcast(T2, x))::T diff --git a/base/arrayshow.jl b/base/arrayshow.jl index 9b1b7197f7f41..13d153b336b0f 100644 --- a/base/arrayshow.jl +++ b/base/arrayshow.jl @@ -434,10 +434,11 @@ function show_vector(io::IO, v, opn='[', cls=']') io = IOContext(io, :typeinfo => eltype(v), :compact => get(io, :compact, true)) limited = get(io, :limit, false) if limited && length(v) > 20 - inds = axes1(v) - show_delim_array(io, v, opn, ",", "", false, inds[1], inds[1]+9) + axs1 = axes1(v) + f, l = first(axs1), last(axs1) + show_delim_array(io, v, opn, ",", "", false, f, f+9) print(io, " … ") - show_delim_array(io, v, "", ",", cls, false, inds[end-9], inds[end]) + show_delim_array(io, v, "", ",", cls, false, l-9, l) else show_delim_array(io, v, opn, ",", cls, false) end diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index b01ad3a271fca..4801b21cb3f01 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -910,7 +910,7 @@ function abstract_eval(@nospecialize(e), vtypes::VarTable, sv::InferenceState) isconst = false end end - if isconst + if isconst && fieldcount(t) == length(e.args) - 1 t = Const(ccall(:jl_new_structv, Any, (Any, Ptr{Cvoid}, UInt32), t, args, length(args))) end end diff --git a/base/deepcopy.jl b/base/deepcopy.jl index 7ed68bbf2b6ac..5bf1311a13603 100644 --- a/base/deepcopy.jl +++ b/base/deepcopy.jl @@ -27,7 +27,7 @@ updated as appropriate before returning. """ deepcopy(x) = deepcopy_internal(x, IdDict())::typeof(x) -deepcopy_internal(x::Union{Symbol,Core.MethodInstance,Method,GlobalRef,DataType,Union,Task}, +deepcopy_internal(x::Union{Symbol,Core.MethodInstance,Method,GlobalRef,DataType,Union,UnionAll,Task}, stackdict::IdDict) = x deepcopy_internal(x::Tuple, stackdict::IdDict) = ntuple(i->deepcopy_internal(x[i], stackdict), length(x)) diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index 34859af709659..e58f0f51913fb 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -129,10 +129,13 @@ kw"primitive type" """ macro -`macro` defines a method to include generated code in the final body of a program. A -macro maps a tuple of arguments to a returned expression, and the resulting expression -is compiled directly rather than requiring a runtime `eval` call. Macro arguments may -include expressions, literal values, and symbols. For example: +`macro` defines a method for inserting generated code into a program. +A macro maps a sequence of argument expressions to a returned expression, and the +resulting expression is substituted directly into the program at the point where +the macro is invoked. +Macros are a way to run generated code without calling `eval`, since the generated +code instead simply becomes part of the surrounding program. +Macro arguments may include expressions, literal values, and symbols. # Examples ```jldoctest @@ -197,6 +200,91 @@ julia> z """ kw"global" +""" + = + +`=` is the assignment operator. +* For variable `a` and expression `b`, `a = b` makes `a` refer to the value of `b`. +* For functions `f(x)`, `f(x) = x` defines a new function constant `f`, or adds a new method to `f` if `f` is already defined; this usage is equivalent to `function f(x); x; end`. +* `a[i] = v` calls [`setindex!`](@ref)`(a,v,i)`. +* `a.b = c` calls [`setproperty!`](@ref)`(a,:b,c)`. +* Inside a function call, `f(a=b)` passes `b` as the value of keyword argument `a`. +* Inside parentheses with commas, `(a=1,)` constructs a [`NamedTuple`](@ref). + +# Examples +Assigning `a` to `b` does not create a copy of `b`; instead use [`copy`](@ref) or [`deepcopy`](@ref). + +```jldoctest +julia> b = [1]; a = b; b[1] = 2; a +1-element Array{Int64,1}: + 2 + +julia> b = [1]; a = copy(b); b[1] = 2; a +1-element Array{Int64,1}: + 1 + +``` +Collections passed to functions are also not copied. Functions can modify (mutate) the contents of the objects their arguments refer to. (The names of functions which do this are conventionally suffixed with '!'.) +```jldoctest +julia> function f!(x); x[:] .+= 1; end +f! (generic function with 1 method) + +julia> a = [1]; f!(a); a +1-element Array{Int64,1}: + 2 + +``` +Assignment can operate on multiple variables in parallel, taking values from an iterable: +```jldoctest +julia> a, b = 4, 5 +(4, 5) + +julia> a, b = 1:3 +1:3 + +julia> a, b +(1, 2) + +``` +Assignment can operate on multiple variables in series, and will return the value of the right-hand-most expression: +```jldoctest +julia> a = [1]; b = [2]; c = [3]; a = b = c +1-element Array{Int64,1} + 3 + +julia> b[1] = 2; a, b, c +([2], [2], [2]) + +``` +Assignment at out-of-bounds indices does not grow a collection. If the collection is a [`Vector`](@ref) it can instead be grown with [`push!`](@ref) or [`append!`](@ref). +```jldoctest +julia> a = [1, 1]; a[3] = 2 +ERROR: BoundsError: attempt to access 2-element Array{Int64,1} at index [3] +[...] + +julia> push!(a, 2, 3) +4-element Array{Int64,1}: + 1 + 1 + 2 + 3 + +``` +Assigning `[]` does not eliminate elements from a collection; instead use `filter!`. +```jldoctest +julia> a = collect(1:3); a[a .<= 1] = [] +ERROR: DimensionMismatch("tried to assign 0 elements to 1 destinations") +[...] + +julia> filter!(x -> x > 1, a) # in-place & thus more efficient than a = a[a .> 1] +2-element Array{Int64,1}: + 2 + 3 + +``` +""" +kw"=" + """ let @@ -237,6 +325,34 @@ For other purposes, `:( ... )` and `quote .. end` blocks are treated identically """ kw"quote" +""" + Expr(head::Symbol, args...) + +A type representing compound expressions in parsed julia code (ASTs). +Each expression consists of a `head` Symbol identifying which kind of +expression it is (e.g. a call, for loop, conditional statement, etc.), +and subexpressions (e.g. the arguments of a call). +The subexpressions are stored in a `Vector{Any}` field called `args`. + +See the manual chapter on [Metaprogramming](@ref) and the developer +documentation [Julia ASTs](@ref). + +# Examples +```jldoctest +julia> Expr(:call, :+, 1, 2) +:(1 + 2) + +julia> dump(:(a ? b : c)) +Expr + head: Symbol if + args: Array{Any}((3,)) + 1: Symbol a + 2: Symbol b + 3: Symbol c +``` +""" +Expr + """ ' @@ -314,7 +430,9 @@ kw"function" """ return -`return` can be used in function bodies to exit early and return a given value, e.g. +`return x` causes the enclosing function to exit early, passing the given value `x` +back to its caller. `return` by itself with no value is equivalent to `return nothing` +(see [`nothing`](@ref)). ```julia function compare(a, b) @@ -340,12 +458,15 @@ function test2(xs) end end ``` -In the first example, the return breaks out of its enclosing function as soon as it hits +In the first example, the return breaks out of `test1` as soon as it hits an even number, so `test1([5,6,7])` returns `12`. You might expect the second example to behave the same way, but in fact the `return` there only breaks out of the *inner* function (inside the `do` block) and gives a value back to `map`. `test2([5,6,7])` then returns `[5,12,7]`. + +When used in a top-level expression (i.e. outside any function), `return` causes +the entire current top-level expression to terminate early. """ kw"return" @@ -376,7 +497,7 @@ kw"if", kw"elseif", kw"else" """ for -`for` loops repeatedly evaluate the body of the loop by +`for` loops repeatedly evaluate a block of statements while iterating over a sequence of values. # Examples @@ -394,8 +515,8 @@ kw"for" """ while -`while` loops repeatedly evaluate a conditional expression, and continues evaluating the -body of the while loop so long as the expression remains `true`. If the condition +`while` loops repeatedly evaluate a conditional expression, and continue evaluating the +body of the while loop as long as the expression remains true. If the condition expression is false when the while loop is first reached, the body is never evaluated. # Examples @@ -442,19 +563,23 @@ kw"end" """ try/catch -A `try`/`catch` statement allows for `Exception`s to be tested for. For example, a -customized square root function can be written to automatically call either the real or -complex square root method on demand using `Exception`s: +A `try`/`catch` statement allows intercepting errors (exceptions) thrown +by [`throw`](@ref) so that program execution can continue. +For example, the following code attempts to write a file, but warns the user +and proceeds instead of terminating execution if the file cannot be written: ```julia -f(x) = try - sqrt(x) +try + open("/danger", "w") do f + println(f, "Hello") + end catch - sqrt(complex(x, 0)) + @warn "Could not write file." end ``` -`try`/`catch` statements also allow the `Exception` to be saved in a variable, e.g. `catch y`. +The syntax `catch e` (where `e` is any variable) assigns the thrown +exception object to the given variable within the `catch` block. The power of the `try`/`catch` construct lies in the ability to unwind a deeply nested computation immediately to a much higher level in the stack of calling functions. @@ -530,7 +655,9 @@ kw"continue" """ do -Create an anonymous function. For example: +Create an anonymous function and pass it as the first argument to +a function call. +For example: ```julia map(1:10) do x @@ -811,7 +938,7 @@ nothing """ Core.TypeofBottom -The singleton type containing only the value `Union{}`. +The singleton type containing only the value `Union{}` (which represents the empty type). """ Core.TypeofBottom @@ -1215,7 +1342,7 @@ Unsigned """ Bool <: Integer -Boolean type. +Boolean type, containing the values `true` and `false`. """ Bool @@ -1248,10 +1375,41 @@ for bit in (8, 16, 32, 64, 128) end end +""" + Symbol + +The type of object used to represent identifiers in parsed julia code (ASTs). +Also often used as a name or label to identify an entity (e.g. as a dictionary key). +`Symbol`s can be entered using the `:` quote operator: +```jldoctest +julia> :name +:name + +julia> typeof(:name) +Symbol + +julia> x = 42 +42 + +julia> eval(:x) +42 +``` +`Symbol`s can also be constructed from strings or other values by calling the +constructor `Symbol(x...)`. + +`Symbol`s are immutable and should be compared using `===`. +The implementation re-uses the same object for all `Symbol`s with the same name, +so comparison tends to be efficient (it can just compare pointers). + +Unlike strings, `Symbol`s are "atomic" or "scalar" entities that do not support +iteration over characters. +""" +Symbol + """ Symbol(x...) -> Symbol -Create a `Symbol` by concatenating the string representations of the arguments together. +Create a [`Symbol`](@ref) by concatenating the string representations of the arguments together. # Examples ```jldoctest @@ -1262,7 +1420,7 @@ julia> Symbol("day", 4) :day4 ``` """ -Symbol +Symbol(x...) """ tuple(xs...) @@ -1351,9 +1509,11 @@ typeof isdefined(object, s::Symbol) isdefined(object, index::Int) -Tests whether an assignable location is defined. The arguments can be a module and a symbol +Tests whether a global variable or object field is defined. The arguments can be a module and a symbol or a composite object and field name (as a symbol) or index. +To test whether an array element is defined, use [`isassigned`](@ref) instead. + # Examples ```jldoctest julia> isdefined(Base, :sum) diff --git a/base/floatfuncs.jl b/base/floatfuncs.jl index 22118c5c62f25..9c90137e0d4fc 100644 --- a/base/floatfuncs.jl +++ b/base/floatfuncs.jl @@ -231,7 +231,8 @@ the square root of [`eps`](@ref) of the type of `x` or `y`, whichever is bigger This corresponds to requiring equality of about half of the significand digits. Otherwise, e.g. for integer arguments or if an `atol > 0` is supplied, `rtol` defaults to zero. -`x` and `y` may also be arrays of numbers, in which case `norm` defaults to `vecnorm` but +`x` and `y` may also be arrays of numbers, in which case `norm` defaults to the usual +`norm` function in LinearAlgebra, but may be changed by passing a `norm::Function` keyword argument. (For numbers, `norm` is the same thing as `abs`.) When `x` and `y` are arrays, if `norm(x-y)` is not finite (i.e. `±Inf` or `NaN`), the comparison falls back to checking whether all elements of `x` and `y` are diff --git a/base/iostream.jl b/base/iostream.jl index dbacbd888bc14..bbb13632747ab 100644 --- a/base/iostream.jl +++ b/base/iostream.jl @@ -4,6 +4,12 @@ const sizeof_ios_t = Int(ccall(:jl_sizeof_ios_t, Cint, ())) +""" + IOStream + +A buffered IO stream wrapping an OS file descriptor. +Mostly used to represent files returned by [`open`](@ref). +""" mutable struct IOStream <: IO handle::Ptr{Cvoid} ios::Array{UInt8,1} diff --git a/base/iterators.jl b/base/iterators.jl index b329a6c6f9eff..83a0a3c49e5ac 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -115,7 +115,7 @@ and `x` is the `i`th value from the given iterator. It's useful when you need not only the values `x` over which you are iterating, but also the number of iterations so far. Note that `i` may not be valid for indexing `iter`; it's also possible that `x != iter[i]`, if `iter` -has indices that do not start at 1. See the `enumerate(IndexLinear(), +has indices that do not start at 1. See the `pairs(IndexLinear(), iter)` method if you want to ensure that `i` is an index. # Examples @@ -1089,10 +1089,9 @@ end @inline peek(s::Stateful, sentinel=nothing) = s.nextvalstate !== nothing ? s.nextvalstate[1] : sentinel @inline iterate(s::Stateful, state=nothing) = s.nextvalstate === nothing ? nothing : (popfirst!(s), nothing) -IteratorSize(::Type{Stateful{VS,T}} where VS) where {T} = - isa(IteratorSize(T), SizeUnknown) ? SizeUnknown() : HasLength() +IteratorSize(::Type{Stateful{T,VS}}) where {T,VS} = IteratorSize(T) isa HasShape ? HasLength() : IteratorSize(T) eltype(::Type{Stateful{T, VS}} where VS) where {T} = eltype(T) -IteratorEltype(::Type{Stateful{VS,T}} where VS) where {T} = IteratorEltype(T) +IteratorEltype(::Type{Stateful{T,VS}}) where {T,VS} = IteratorEltype(T) length(s::Stateful) = length(s.itr) - s.taken end diff --git a/base/mpfr.jl b/base/mpfr.jl index aaf3e9783bf62..64d8bd8f5dbe3 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -74,7 +74,7 @@ function convert(::Type{RoundingMode}, r::MPFRRoundingMode) elseif r == MPFRRoundFromZero return RoundFromZero else - throw(ArgumentError("invalid MPFR rounding mode code: $c")) + throw(ArgumentError("invalid MPFR rounding mode code: $r")) end end diff --git a/base/parse.jl b/base/parse.jl index b21d85f7faf99..a652e1f7387ab 100644 --- a/base/parse.jl +++ b/base/parse.jl @@ -319,7 +319,7 @@ function tryparse_internal(::Type{Complex{T}}, s::Union{String,SubString{String} end if i₊ == 0 # purely real or imaginary value - if iᵢ > 0 # purely imaginary + if iᵢ > i && !(iᵢ == i+1 && s[i] in ('+','-')) # purely imaginary (not "±inf") x = tryparse_internal(T, s, i, iᵢ-1, raise) x === nothing && return nothing return Complex{T}(zero(x),x) diff --git a/base/reinterpretarray.jl b/base/reinterpretarray.jl index 8d7a175d8252d..d910b13d3551c 100644 --- a/base/reinterpretarray.jl +++ b/base/reinterpretarray.jl @@ -68,6 +68,7 @@ IndexStyle(a::ReinterpretArray) = IndexStyle(a.parent) parent(a::ReinterpretArray) = a.parent dataids(a::ReinterpretArray) = dataids(a.parent) +unaliascopy(a::ReinterpretArray{T}) where {T} = reinterpret(T, unaliascopy(a.parent)) function size(a::ReinterpretArray{T,N,S} where {N}) where {T,S} psize = size(a.parent) diff --git a/base/strings/io.jl b/base/strings/io.jl index 7453845211148..757c3888d00be 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -440,7 +440,24 @@ function unescape_string(io, s::AbstractString) end unescape_string(s::AbstractString) = sprint(unescape_string, s, sizehint=lastindex(s)) +""" + @b_str + +Create an immutable byte (`UInt8`) vector using string syntax. +# Examples +```jldoctest +julia> v = b"12\\x01\\x02" +4-element Base.CodeUnits{UInt8,String}: + 0x31 + 0x32 + 0x01 + 0x02 + +julia> v[2] +0x32 +``` +""" macro b_str(s) v = codeunits(unescape_string(s)) QuoteNode(v) diff --git a/base/strings/search.jl b/base/strings/search.jl index cb819b3007177..8b62b34bc2d07 100644 --- a/base/strings/search.jl +++ b/base/strings/search.jl @@ -259,7 +259,7 @@ findnext(t::AbstractString, s::AbstractString, i::Integer) = _search(s, t, i) findlast(pattern::AbstractString, string::AbstractString) Find the last occurrence of `pattern` in `string`. Equivalent to -[`findlast(pattern, string, lastindex(s))`](@ref). +[`findprev(pattern, string, lastindex(string))`](@ref). # Examples ```jldoctest diff --git a/base/strings/util.jl b/base/strings/util.jl index 270e23dfeca61..d247ceb117da1 100644 --- a/base/strings/util.jl +++ b/base/strings/util.jl @@ -96,6 +96,9 @@ julia> chop(a, head = 5, tail = 5) ``` """ function chop(s::AbstractString; head::Integer = 0, tail::Integer = 1) + if isempty(s) + return SubString(s) + end SubString(s, nextind(s, firstindex(s), head), prevind(s, lastindex(s), tail)) end diff --git a/base/sysimg.jl b/base/sysimg.jl index 8e0dd138b9cea..d3c2f1e7a833c 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -186,7 +186,32 @@ include("abstractarraymath.jl") include("arraymath.jl") # define MIME"foo/bar" early so that we can overload 3-arg show +""" + MIME + +A type representing a standard internet data format. "MIME" stands for +"Multipurpose Internet Mail Extensions", since the standard was originally +used to describe multimedia attachments to email messages. + +A `MIME` object can be passed as the second argument to [`show`](@ref) to +request output in that format. + +# Examples +```jldoctest +julia> show(stdout, MIME("text/plain"), "hi") +"hi" +``` +""" struct MIME{mime} end + +""" + @MIME_str + +A convenience macro for writing [`MIME`](@ref) types, typically used when +adding methods to `show`. +For example the syntax `show(io::IO, ::MIME"text/html", x::MyType) = ...` +could be used to define how to write an HTML representation of `MyType`. +""" macro MIME_str(s) :(MIME{$(Expr(:quote, Symbol(s)))}) end diff --git a/deps/Versions.make b/deps/Versions.make index ff62882f1bc11..b4f226a09f80d 100644 --- a/deps/Versions.make +++ b/deps/Versions.make @@ -7,7 +7,7 @@ SUITESPARSE_VER = 4.4.5 UNWIND_VER = 1.1-julia2 OSXUNWIND_VER = 0.0.5 GMP_VER = 6.1.2 -MPFR_VER = 4.0.1 +MPFR_VER = 4.0.2 PATCHELF_VER = 0.9 MBEDTLS_VER = 2.6.0 CURL_VER = 7.56.0 @@ -15,4 +15,4 @@ CURL_VER = 7.56.0 # Specify the version of the Mozilla CA Certificate Store to obtain. # The versions of cacert.pem are identified by the date (YYYY-MM-DD) of their changes. # See https://curl.haxx.se/docs/caextract.html for more details. -MOZILLA_CACERT_VERSION := 2018-10-17 +MOZILLA_CACERT_VERSION := 2019-01-23 diff --git a/deps/checksums/Pkg-40cbbe224d4a491503279dfc5b9aefe15412f007.tar.gz/md5 b/deps/checksums/Pkg-40cbbe224d4a491503279dfc5b9aefe15412f007.tar.gz/md5 new file mode 100644 index 0000000000000..af3a19a984099 --- /dev/null +++ b/deps/checksums/Pkg-40cbbe224d4a491503279dfc5b9aefe15412f007.tar.gz/md5 @@ -0,0 +1 @@ +50634db6a61a7d03bb4a7121a17096e8 diff --git a/deps/checksums/Pkg-40cbbe224d4a491503279dfc5b9aefe15412f007.tar.gz/sha512 b/deps/checksums/Pkg-40cbbe224d4a491503279dfc5b9aefe15412f007.tar.gz/sha512 new file mode 100644 index 0000000000000..e60ffff22b26a --- /dev/null +++ b/deps/checksums/Pkg-40cbbe224d4a491503279dfc5b9aefe15412f007.tar.gz/sha512 @@ -0,0 +1 @@ +b7804e281fa18701c9394de8b8a7e351aa7b668158b3125ac8b398a825f0b29f54269f839450c09204a73a607b890eb72edcf20139b1269ed2628129c68e70e8 diff --git a/deps/checksums/Pkg-853b3f1fd9895db32b402d89e9dee153b66b2316.tar.gz/md5 b/deps/checksums/Pkg-853b3f1fd9895db32b402d89e9dee153b66b2316.tar.gz/md5 deleted file mode 100644 index aa9fda894b7d1..0000000000000 --- a/deps/checksums/Pkg-853b3f1fd9895db32b402d89e9dee153b66b2316.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -b51ae77c52564bcb0e7033b3fdcffba1 diff --git a/deps/checksums/Pkg-853b3f1fd9895db32b402d89e9dee153b66b2316.tar.gz/sha512 b/deps/checksums/Pkg-853b3f1fd9895db32b402d89e9dee153b66b2316.tar.gz/sha512 deleted file mode 100644 index fbe7fcfb9ddf9..0000000000000 --- a/deps/checksums/Pkg-853b3f1fd9895db32b402d89e9dee153b66b2316.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -f81ef6ec68b190d18a28562c4d2507b393b5f9d09d900fa682ab876564908c7700c282343e568fed66703ddc9a12ab0a425f70e5fe705002b2da6397274b30f8 diff --git a/deps/checksums/cacert-2019-01-23.pem/md5 b/deps/checksums/cacert-2019-01-23.pem/md5 new file mode 100644 index 0000000000000..24c61558beb49 --- /dev/null +++ b/deps/checksums/cacert-2019-01-23.pem/md5 @@ -0,0 +1 @@ +fccbe6cec7a76e3351ad32e305184787 diff --git a/deps/checksums/cacert-2019-01-23.pem/sha512 b/deps/checksums/cacert-2019-01-23.pem/sha512 new file mode 100644 index 0000000000000..94305a88a3b68 --- /dev/null +++ b/deps/checksums/cacert-2019-01-23.pem/sha512 @@ -0,0 +1 @@ +01faebab60b49a30736e0c88b713999f48c99b425889f7df9bbb80eb91367a6f26f20befdf8ac72b8d77659b143b7b37f91ad7dac5fde37c1d621fc663003687 diff --git a/deps/checksums/libssh2-02ecf17a6d5f9837699e8fb3aad0c804caa67eeb.tar.gz/md5 b/deps/checksums/libssh2-02ecf17a6d5f9837699e8fb3aad0c804caa67eeb.tar.gz/md5 new file mode 100644 index 0000000000000..7091746b1815f --- /dev/null +++ b/deps/checksums/libssh2-02ecf17a6d5f9837699e8fb3aad0c804caa67eeb.tar.gz/md5 @@ -0,0 +1 @@ +bcf01c3fa49a1684edc2d637ad7e03d6 diff --git a/deps/checksums/libssh2-02ecf17a6d5f9837699e8fb3aad0c804caa67eeb.tar.gz/sha512 b/deps/checksums/libssh2-02ecf17a6d5f9837699e8fb3aad0c804caa67eeb.tar.gz/sha512 new file mode 100644 index 0000000000000..2d6d2980fa7f2 --- /dev/null +++ b/deps/checksums/libssh2-02ecf17a6d5f9837699e8fb3aad0c804caa67eeb.tar.gz/sha512 @@ -0,0 +1 @@ +ae4c798ae5c13ad1574646896665ccd1f7d91e64573a23662ce7016b00109c1c351013856c25bf12284d9c3996ca3b828506825e50fcb059969adc02a96c06f8 diff --git a/deps/checksums/libssh2-30e9c1347e3b8baa2951db612f05e6d87fc8e2f2.tar.gz/md5 b/deps/checksums/libssh2-30e9c1347e3b8baa2951db612f05e6d87fc8e2f2.tar.gz/md5 deleted file mode 100644 index a2fc72b9885cc..0000000000000 --- a/deps/checksums/libssh2-30e9c1347e3b8baa2951db612f05e6d87fc8e2f2.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -d251ef0efecff323b6f570cc737d3411 diff --git a/deps/checksums/libssh2-30e9c1347e3b8baa2951db612f05e6d87fc8e2f2.tar.gz/sha512 b/deps/checksums/libssh2-30e9c1347e3b8baa2951db612f05e6d87fc8e2f2.tar.gz/sha512 deleted file mode 100644 index 1db563c8be7bb..0000000000000 --- a/deps/checksums/libssh2-30e9c1347e3b8baa2951db612f05e6d87fc8e2f2.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -ae7535cf8f70e7c837e80365cd9ee7c4040d45e952871a3e5c8f1b71bd8eb2d96babb07fa4c5d66a83bb45960728ef8dbba30ab9a6387a68cf815a84cdae8795 diff --git a/deps/checksums/mpfr-4.0.1.tar.bz2/md5 b/deps/checksums/mpfr-4.0.1.tar.bz2/md5 deleted file mode 100644 index 0033858e5788e..0000000000000 --- a/deps/checksums/mpfr-4.0.1.tar.bz2/md5 +++ /dev/null @@ -1 +0,0 @@ -8c21d8ac7460493b2b9f3ef3cc610454 diff --git a/deps/checksums/mpfr-4.0.1.tar.bz2/sha512 b/deps/checksums/mpfr-4.0.1.tar.bz2/sha512 deleted file mode 100644 index 42c78a8b089dd..0000000000000 --- a/deps/checksums/mpfr-4.0.1.tar.bz2/sha512 +++ /dev/null @@ -1 +0,0 @@ -c1674fc0a5edcde188bdf7d6d14063cfb4f1259b9eaf39d0081f7176e9921ca0af1b12b7aba1a9560d9f2d5f37329d22bc7b82f13421d91d83114b439bc60dcc diff --git a/deps/checksums/mpfr-4.0.2.tar.bz2/md5 b/deps/checksums/mpfr-4.0.2.tar.bz2/md5 new file mode 100644 index 0000000000000..8639e86c33058 --- /dev/null +++ b/deps/checksums/mpfr-4.0.2.tar.bz2/md5 @@ -0,0 +1 @@ +6d8a8bb46fe09ff44e21cdbf84f5cdac diff --git a/deps/checksums/mpfr-4.0.2.tar.bz2/sha512 b/deps/checksums/mpfr-4.0.2.tar.bz2/sha512 new file mode 100644 index 0000000000000..d073360a775c8 --- /dev/null +++ b/deps/checksums/mpfr-4.0.2.tar.bz2/sha512 @@ -0,0 +1 @@ +18bb3a87123d02b7537bc298d41bdbb33e58b8c196cc4040578e3b470e86c6c89e1bd8ab8b3919d106fe5b86922ef8999dc1aba7c521ee90a69f690be288a30d diff --git a/deps/gmp.mk b/deps/gmp.mk index 347d20df65ee3..698d2d07c6a48 100644 --- a/deps/gmp.mk +++ b/deps/gmp.mk @@ -21,7 +21,13 @@ $(SRCCACHE)/gmp-$(GMP_VER)/build-patched: $(SRCCACHE)/gmp-$(GMP_VER)/source-extr cd $(dir $@) && patch < $(SRCDIR)/patches/gmp-exception.patch echo 1 > $@ -$(BUILDDIR)/gmp-$(GMP_VER)/build-configured: $(SRCCACHE)/gmp-$(GMP_VER)/source-extracted $(SRCCACHE)/gmp-$(GMP_VER)/build-patched +$(SRCCACHE)/gmp-$(GMP_VER)/gmp-config-ldflags.patch-applied: | $(SRCCACHE)/gmp-$(GMP_VER)/build-patched + cd $(dir $@) && patch -p1 < $(SRCDIR)/patches/gmp-config-ldflags.patch + echo 1 > $@ + +$(BUILDDIR)/gmp-$(GMP_VER)/build-configured: $(SRCCACHE)/gmp-$(GMP_VER)/gmp-config-ldflags.patch-applied + +$(BUILDDIR)/gmp-$(GMP_VER)/build-configured: $(SRCCACHE)/gmp-$(GMP_VER)/source-extracted mkdir -p $(dir $@) cd $(dir $@) && \ $(dir $<)/configure $(CONFIGURE_COMMON) F77= --enable-shared --disable-static $(GMP_CONFIGURE_OPTS) diff --git a/deps/libssh2.version b/deps/libssh2.version index dadad22483c2a..fe1ecb3080028 100644 --- a/deps/libssh2.version +++ b/deps/libssh2.version @@ -1,2 +1,2 @@ -LIBSSH2_BRANCH=libssh2-1.8.0 -LIBSSH2_SHA1=30e9c1347e3b8baa2951db612f05e6d87fc8e2f2 +LIBSSH2_BRANCH=libssh2-1.8.2 +LIBSSH2_SHA1=02ecf17a6d5f9837699e8fb3aad0c804caa67eeb diff --git a/deps/llvm.mk b/deps/llvm.mk index c516b577f6269..ed3342f397bfd 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -66,7 +66,7 @@ LLVM_CXXFLAGS += $(CXXFLAGS) LLVM_CPPFLAGS += $(CPPFLAGS) LLVM_LDFLAGS += $(LDFLAGS) LLVM_CMAKE += -DLLVM_TARGETS_TO_BUILD:STRING="$(LLVM_TARGETS)" -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="$(LLVM_EXPERIMENTAL_TARGETS)" -DCMAKE_BUILD_TYPE="$(LLVM_CMAKE_BUILDTYPE)" -LLVM_CMAKE += -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_LIBXML2=OFF +LLVM_CMAKE += -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_HOST_TRIPLE="$(or $(XC_HOST),$(BUILD_MACHINE))" ifeq ($(USE_POLLY_ACC),1) LLVM_CMAKE += -DPOLLY_ENABLE_GPGPU_CODEGEN=ON endif diff --git a/deps/patches/gmp-config-ldflags.patch b/deps/patches/gmp-config-ldflags.patch new file mode 100644 index 0000000000000..fb89fa66b8da5 --- /dev/null +++ b/deps/patches/gmp-config-ldflags.patch @@ -0,0 +1,381 @@ +--- gmp-6.1.2/configure 2019-03-25 17:58:41.928471374 -0400 ++++ gmp-6.1.2-LDFLAGS/configure 2019-03-26 13:08:07.756316866 -0400 +@@ -5880,7 +5880,7 @@ if test "$gmp_prog_cc_works" = yes; then + int main () { return 0; } + EOF + echo "Test compile: " >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -5934,7 +5934,7 @@ void *f() { return g(); } + int main () { return 0; } + EOF + echo "Test compile: function pointer return" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -5990,7 +5990,7 @@ int cmov () { return (n >= 0 ? n : 0); } + int main () { return 0; } + EOF + echo "Test compile: cmov instruction" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6047,7 +6047,7 @@ unsigned long gcc303 () { return (unsign + int main () { return 0; } + EOF + echo "Test compile: double -> ulong conversion" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6102,7 +6102,7 @@ unsigned long fneg () { return -fneg_dat + int main () { return 0; } + EOF + echo "Test compile: double negation" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6158,7 +6158,7 @@ float ftod () { return (float) ftod_data + int main () { return 0; } + EOF + echo "Test compile: double -> float conversion" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6243,7 +6243,7 @@ param_init () + int main () { return 0; } + EOF + echo "Test compile: gnupro alpha ev6 char spilling" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6294,7 +6294,7 @@ if test "$gmp_prog_cc_works" = yes; then + int k; int foo () { __builtin_alloca (k); } + EOF + echo "Test compile: __builtin_alloca availability" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6340,7 +6340,7 @@ int foo () + int main () { return 0; } + EOF + echo "Test compile: alloca array" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6418,7 +6418,7 @@ int f () + int main () { return 0; } + EOF + echo "Test compile: abs int -> double conversion" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6483,7 +6483,7 @@ int dummy; + int main () { return 0; } + EOF + echo "Test compile: long long reliability test 1" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6544,7 +6544,7 @@ int dummy; + int main () { return 0; } + EOF + echo "Test compile: long long reliability test 2" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6605,7 +6605,7 @@ int dummy; + int main () { return 0; } + EOF + echo "Test compile: freebsd hacked gcc" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6704,7 +6704,7 @@ main () + + EOF + echo "Test compile: mpn_lshift_com optimization" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6813,7 +6813,7 @@ main () + + EOF + echo "Test compile: mpn_lshift_com optimization 2" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7325,7 +7325,7 @@ _main: + xorl %eax, %eax + ret + EOF +- gmp_compile="$cc $cflags $cppflags conftest.s -o conftest >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.s -o conftest >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7390,7 +7390,7 @@ $as_echo_n "checking compiler $cc $cflag + cat >conftest.c <&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7498,7 +7498,7 @@ if test "$gmp_prog_cc_works" = yes; then + int main () { return 0; } + EOF + echo "Test compile: " >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7552,7 +7552,7 @@ void *f() { return g(); } + int main () { return 0; } + EOF + echo "Test compile: function pointer return" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7608,7 +7608,7 @@ int cmov () { return (n >= 0 ? n : 0); } + int main () { return 0; } + EOF + echo "Test compile: cmov instruction" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7665,7 +7665,7 @@ unsigned long gcc303 () { return (unsign + int main () { return 0; } + EOF + echo "Test compile: double -> ulong conversion" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7720,7 +7720,7 @@ unsigned long fneg () { return -fneg_dat + int main () { return 0; } + EOF + echo "Test compile: double negation" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7776,7 +7776,7 @@ float ftod () { return (float) ftod_data + int main () { return 0; } + EOF + echo "Test compile: double -> float conversion" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7861,7 +7861,7 @@ param_init () + int main () { return 0; } + EOF + echo "Test compile: gnupro alpha ev6 char spilling" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7912,7 +7912,7 @@ if test "$gmp_prog_cc_works" = yes; then + int k; int foo () { __builtin_alloca (k); } + EOF + echo "Test compile: __builtin_alloca availability" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7958,7 +7958,7 @@ int foo () + int main () { return 0; } + EOF + echo "Test compile: alloca array" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -8036,7 +8036,7 @@ int f () + int main () { return 0; } + EOF + echo "Test compile: abs int -> double conversion" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -8101,7 +8101,7 @@ int dummy; + int main () { return 0; } + EOF + echo "Test compile: long long reliability test 1" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -8162,7 +8162,7 @@ int dummy; + int main () { return 0; } + EOF + echo "Test compile: long long reliability test 2" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -8223,7 +8223,7 @@ int dummy; + int main () { return 0; } + EOF + echo "Test compile: freebsd hacked gcc" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -8322,7 +8322,7 @@ main () + + EOF + echo "Test compile: mpn_lshift_com optimization" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -8431,7 +8431,7 @@ main () + + EOF + echo "Test compile: mpn_lshift_com optimization 2" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -9987,7 +9987,7 @@ main () + return 0; + } + EOF +-gmp_compile="$CC_FOR_BUILD conftest.c" ++gmp_compile="$CC_FOR_BUILD $LDFLAGS conftest.c" + cc_for_build_works=no + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 +@@ -10019,7 +10019,7 @@ main () + return 0; + } + EOF +-gmp_compile="$HOST_CC conftest.c" ++gmp_compile="$HOST_CC $LDFLAGS conftest.c" + cc_for_build_works=no + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 +@@ -10052,7 +10052,7 @@ main () + return 0; + } + EOF +-gmp_compile="$i conftest.c" ++gmp_compile="$i $LDFLAGS conftest.c" + cc_for_build_works=no + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 +@@ -10132,7 +10132,7 @@ main () + } + EOF + for i in .exe ,ff8 ""; do +- gmp_compile="$CC_FOR_BUILD conftest.c -o conftest$i" ++ gmp_compile="$CC_FOR_BUILD $LDFLAGS conftest.c -o conftest$i" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -10168,7 +10168,7 @@ main (int argc, char **argv) + return 0; + } + EOF +-gmp_compile="$CC_FOR_BUILD conftest.c" ++gmp_compile="$CC_FOR_BUILD $LDFLAGS conftest.c" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -10210,7 +10210,7 @@ foo () + return log (d); + } + EOF +-gmp_compile="$CC_FOR_BUILD conftest.c -lm" ++gmp_compile="$CC_FOR_BUILD $LDFLAGS conftest.c -lm" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -10543,7 +10543,7 @@ if test "$gmp_prog_cxx_works" = yes; the + int main (void) { return 0; } + EOF + echo "Test compile: " >&5 +- gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS conftest.cc >&5" ++ gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS $LDFLAGS conftest.cc >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_cxxcompile\""; } >&5 + (eval $gmp_cxxcompile) 2>&5 + ac_status=$? +@@ -10583,7 +10583,7 @@ using namespace foo; + int main (void) { return 0; } + EOF + echo "Test compile: namespace" >&5 +- gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS conftest.cc >&5" ++ gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS $LDFLAGS conftest.cc >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_cxxcompile\""; } >&5 + (eval $gmp_cxxcompile) 2>&5 + ac_status=$? +@@ -10629,7 +10629,7 @@ void someoutput (void) { std::cout << 12 + int main (void) { return 0; } + EOF + echo "Test compile: std iostream" >&5 +- gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS conftest.cc >&5" ++ gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS $LDFLAGS conftest.cc >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_cxxcompile\""; } >&5 + (eval $gmp_cxxcompile) 2>&5 + ac_status=$? +@@ -27095,7 +27095,7 @@ for tmp_underscore in "" "_"; do + ${tmp_gsym_prefix}main$gmp_cv_asm_label_suffix + addl $ ${tmp_underscore}_GLOBAL_OFFSET_TABLE_, %ebx + EOF +- gmp_compile="$CCAS $CFLAGS $CPPFLAGS $lt_prog_compiler_pic conftest.s >&5 && $CC $CFLAGS $CPPFLAGS $lt_prog_compiler_pic conftest.$OBJEXT >&5" ++ gmp_compile="$CCAS $CFLAGS $CPPFLAGS $lt_prog_compiler_pic conftest.s >&5 && $CC $CFLAGS $CPPFLAGS $LDFLAGS $lt_prog_compiler_pic conftest.$OBJEXT >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? + diff --git a/doc/src/devdocs/subarrays.md b/doc/src/devdocs/subarrays.md index 6b91083b1d094..c86fdb07b76d5 100644 --- a/doc/src/devdocs/subarrays.md +++ b/doc/src/devdocs/subarrays.md @@ -3,34 +3,9 @@ Julia's `SubArray` type is a container encoding a "view" of a parent [`AbstractArray`](@ref). This page documents some of the design principles and implementation of `SubArray`s. -## Indexing: cartesian vs. linear indexing - -Broadly speaking, there are two main ways to access data in an array. The first, often called -cartesian indexing, uses `N` indices for an `N` -dimensional `AbstractArray`. For example, a -matrix `A` (2-dimensional) can be indexed in cartesian style as `A[i,j]`. The second indexing -method, referred to as linear indexing, uses a single index even for higher-dimensional objects. - For example, if `A = reshape(1:12, 3, 4)`, then the expression `A[5]` returns the value 5. Julia -allows you to combine these styles of indexing: for example, a 3d array `A3` can be indexed as -`A3[i,j]`, in which case `i` is interpreted as a cartesian index for the first dimension, and -`j` is a linear index over dimensions 2 and 3. - -For `Array`s, linear indexing appeals to the underlying storage format: an array is laid out as -a contiguous block of memory, and hence the linear index is just the offset (+1) of the corresponding -entry relative to the beginning of the array. However, this is not true for many other `AbstractArray` -types: examples include [`SparseMatrixCSC`](@ref) from the `SparseArrays` standard library -module, arrays that require some kind of -computation (such as interpolation), and the type under discussion here, `SubArray`. -For these types, the underlying information is more naturally described in terms of -cartesian indices. - -The `getindex` and `setindex!` functions for `AbstractArray` types may include automatic conversion -between indexing types. For explicit conversion, [`CartesianIndices`](@ref) can be used. - -While converting from a cartesian index to a linear index is fast (it's just multiplication and -addition), converting from a linear index to a cartesian index is very slow: it relies on the -`div` operation, which is one of the slowest low-level operations you can perform with a CPU. - For this reason, any code that deals with `AbstractArray` types is best designed in terms of -cartesian, rather than linear, indexing. +One of the major design goals is to ensure high performance for views of both [`IndexLinear`](@ref) and +[`IndexCartesian`](@ref) arrays. Furthermore, views of `IndexLinear` arrays should themselves be +`IndexLinear` to the extent that it is possible. ## Index replacement diff --git a/doc/src/devdocs/sysimg.md b/doc/src/devdocs/sysimg.md index 6c1227841ec62..41d5ea7777fbc 100644 --- a/doc/src/devdocs/sysimg.md +++ b/doc/src/devdocs/sysimg.md @@ -80,7 +80,7 @@ Additionally, a few special features are supported to control the function cloni 3. `opt_size` - This cause the function for the targe to be optimize for size when there isn't a significant + This causes the function for the target to be optimized for size when there isn't a significant runtime performance impact. This corresponds to `-Os` GCC and Clang option. 4. `min_size` diff --git a/doc/src/manual/arrays.md b/doc/src/manual/arrays.md index 4667fb4fd6e05..5ce8e46e9e845 100644 --- a/doc/src/manual/arrays.md +++ b/doc/src/manual/arrays.md @@ -397,17 +397,6 @@ julia> x[1, [2 3; 4 1]] 13 1 ``` -Empty ranges of the form `n:n-1` are sometimes used to indicate the inter-index location between -`n-1` and `n`. For example, the [`searchsorted`](@ref) function uses this convention to indicate -the insertion point of a value not found in a sorted array: - -```jldoctest -julia> a = [1,2,5,6,7]; - -julia> searchsorted(a, 4) -3:2 -``` - ## Assignment The general syntax for assigning values in an n-dimensional array `A` is: @@ -648,6 +637,119 @@ julia> x[mask] 16 ``` +### Number of indices + +#### Cartesian indexing + +The ordinary way to index into an `N`-dimensional array is to use exactly `N` indices; each +index selects the position(s) in its particular dimension. For example, in the three-dimensional +array `A = rand(4, 3, 2)`, `A[2, 3, 1]` will select the number in the second row of the third +column in the first "page" of the array. This is often referred to as _cartesian indexing_. + +#### Linear indexing + +When exactly one index `i` is provided, that index no longer represents a location in a +particular dimension of the array. Instead, it selects the `i`th element using the +column-major iteration order that linearly spans the entire array. This is known as _linear +indexing_. It essentially treats the array as though it had been reshaped into a +one-dimensional vector with [`vec`](@ref). + +```jldoctest linindexing +julia> A = [2 6; 4 7; 3 1] +3×2 Array{Int64,2}: + 2 6 + 4 7 + 3 1 + +julia> A[5] +7 + +julia> vec(A)[5] +7 +``` + +A linear index into the array `A` can be converted to a `CartesianIndex` for cartesian +indexing with `CartesianIndices(A)[i]` (see [`CartesianIndices`](@ref)), and a set of +`N` cartesian indices can be converted to a linear index with +`LinearIndices(A)[i_1, i_2, ..., i_N]` (see [`LinearIndices`](@ref)). + +```jldoctest linindexing +julia> CartesianIndices(A)[5] +CartesianIndex(2, 2) + +julia> LinearIndices(A)[2, 2] +5 +``` + +It's important to note that there's a very large assymmetry in the performance +of these conversions. Converting a linear index to a set of cartesian indices +requires dividing and taking the remainder, whereas going the other way is just +multiplies and adds. In modern processors, integer division can be 10-50 times +slower than multiplication. While some arrays — like [`Array`](@ref) itself — +are implemented using a linear chunk of memory and directly use a linear index +in their implementations, other arrays — like [`Diagonal`](@ref) — need the +full set of cartesian indices to do their lookup (see [`IndexStyle`](@ref) to +introspect which is which). As such, when iterating over an entire array, it's +much better to iterate over [`eachindex(A)`](@ref) instead of `1:length(A)`. +Not only will the former be much faster in cases where `A` is `IndexCartesian`, +but it will also support OffsetArrays, too. + +#### Omitted and extra indices + +In addition to linear indexing, an `N`-dimensional array may be indexed with +fewer or more than `N` indices in certain situations. + +Indices may be omitted if the trailing dimensions that are not indexed into are +all length one. In other words, trailing indices can be omitted only if there +is only one possible value that those omitted indices could be for an in-bounds +indexing expression. For example, a four-dimensional array with size `(3, 4, 2, +1)` may be indexed with only three indices as the dimension that gets skipped +(the fourth dimension) has length one. Note that linear indexing takes +precedence over this rule. + +```jldoctest +julia> A = reshape(1:24, 3, 4, 2, 1) +3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64: +[:, :, 1, 1] = + 1 4 7 10 + 2 5 8 11 + 3 6 9 12 + +[:, :, 2, 1] = + 13 16 19 22 + 14 17 20 23 + 15 18 21 24 + +julia> A[1, 3, 2] # Omits the fourth dimension (length 1) +19 + +julia> A[1, 3] # Attempts to omit dimensions 3 & 4 (lengths 2 and 1) +ERROR: BoundsError: attempt to access 3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64 at index [1, 3] + +julia> A[19] # Linear indexing +19 +``` + +When omitting _all_ indices with `A[]`, this semantic provides a simple idiom +to retrieve the only element in an array and simultaneously ensure that there +was only one element. + +Similarly, more than `N` indices may be provided if all the indices beyond the +dimensionality of the array are `1` (or more generally are the first and only +element of `axes(A, d)` where `d` is that particular dimension number). This +allows vectors to be indexed like one-column matrices, for example: + +```jldoctest +julia> A = [8,6,7] +3-element Array{Int64,1}: + 8 + 6 + 7 + +julia> A[2,1] +6 +``` + ## Iteration The recommended ways to iterate over a whole array are diff --git a/doc/src/manual/parallel-computing.md b/doc/src/manual/parallel-computing.md index e0071085f2bc5..7c2a3f31ba431 100644 --- a/doc/src/manual/parallel-computing.md +++ b/doc/src/manual/parallel-computing.md @@ -1088,7 +1088,7 @@ julia> for p in workers() # start tasks on the workers to process requests in pa julia> @elapsed while n > 0 # print out results job_id, exec_time, where = take!(results) println("$job_id finished in $(round(exec_time; digits=2)) seconds on worker $where") - n = n - 1 + global n = n - 1 end 1 finished in 0.18 seconds on worker 4 2 finished in 0.26 seconds on worker 5 diff --git a/doc/src/manual/types.md b/doc/src/manual/types.md index c219f3768a40d..5e2b20903c78a 100644 --- a/doc/src/manual/types.md +++ b/doc/src/manual/types.md @@ -938,7 +938,7 @@ julia> NamedTuple{(:a, :b)}((1,"")) If field types are specified, the arguments are converted. Otherwise the types of the arguments are used directly. -#### [Singleton Types](@id man-singleton-types) +### [Singleton Types](@id man-singleton-types) There is a special kind of abstract parametric type that must be mentioned here: singleton types. For each type, `T`, the "singleton type" `Type{T}` is an abstract type whose only instance is diff --git a/doc/src/manual/variables-and-scoping.md b/doc/src/manual/variables-and-scoping.md index eae8c87bb8318..d15f4a50fa66f 100644 --- a/doc/src/manual/variables-and-scoping.md +++ b/doc/src/manual/variables-and-scoping.md @@ -26,7 +26,7 @@ comprehensions, broadcast-fusing | local | global or local Notably missing from this table are [begin blocks](@ref man-compound-expressions) and [if blocks](@ref man-conditional-evaluation) -which do *not* introduce new scope blocks. +which do *not* introduce new scopes. Both types of scopes follow somewhat different rules which will be explained below. Julia uses [lexical scoping](https://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_scoping_vs._dynamic_scoping), @@ -97,15 +97,12 @@ A new local scope is introduced by most code blocks (see above [table](@ref man-scope-table) for a complete list). A local scope inherits all the variables from a parent local scope, both for reading and writing. -Additionally, the local scope inherits all global variables that are assigned -in its parent global scope block (if it is surrounded by a global `if` or `begin` scope). Unlike global scopes, local scopes are not namespaces, thus variables in an inner scope cannot be retrieved from the parent scope through some sort of qualified access. The following rules and examples pertain to local scopes. -A newly introduced variable in a local scope does not -back-propagate to its parent scope. +A newly introduced variable in a local scope cannot be referenced by a parent scope. For example, here the ``z`` is not introduced into the top-level scope: ```jldoctest @@ -121,18 +118,30 @@ ERROR: UndefVarError: z not defined In this and all following examples it is assumed that their top-level is a global scope with a clean workspace, for instance a newly started REPL. -Inside a local scope a variable can be forced to be a new local variable using the [`local`](@ref) keyword: +Inner local scopes can, however, update variables in their parent scopes: ```jldoctest -julia> x = 0; +julia> for i = 1:1 + z = i + for j = 1:1 + z = 0 + end + println(z) + end +0 +``` -julia> for i = 1:10 - local x # this is also the default +Inside a local scope a variable can be forced to be a new local variable using the [`local`](@ref) keyword: + +```jldoctest +julia> for i = 1:1 x = i + 1 + for j = 1:1 + local x = 0 + end + println(x) end - -julia> x -0 +2 ``` Inside a local scope a global variable can be assigned to by using the keyword [`global`](@ref): @@ -163,9 +172,6 @@ julia> z The `local` and `global` keywords can also be applied to destructuring assignments, e.g. `local x, y = 1, 2`. In this case the keyword affects all listed variables. -Local scopes are introduced by most block keywords, -with notable exceptions of `begin` and `if`. - In a local scope, all variables are inherited from its parent global scope block unless: @@ -194,8 +200,8 @@ An explicit `global` is needed to assign to a global variable: !!! sidebar "Avoiding globals" Avoiding changing the value of global variables is considered by many to be a programming best-practice. - One reason for this is that remotely changing the state of global variables in other - modules should be done with care as it makes the local behavior of the program hard to reason about. + Changing the value of a global variable can cause "action at a distance", + making the behavior of a program harder to reason about. This is why the scope blocks that introduce local scope require the `global` keyword to declare the intent to modify a global variable. @@ -233,9 +239,9 @@ julia> x, y # verify that global x and y are unchanged (1, 2) ``` -The reason to allow *modifying local* variables of parent scopes in +The reason to allow modifying local variables of parent scopes in nested functions is to allow constructing [`closures`](https://en.wikipedia.org/wiki/Closure_%28computer_programming%29) -which have a private state, for instance the `state` variable in the +which have private state, for instance the `state` variable in the following example: ```jldoctest diff --git a/src/disasm.cpp b/src/disasm.cpp index 418643d56874c..27ba5b8aa093a 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -747,24 +747,23 @@ static void jl_dump_asm_internal( { // GC safe // Get the host information - std::string TripleName = sys::getDefaultTargetTriple(); - Triple TheTriple(Triple::normalize(TripleName)); + Triple TheTriple(sys::getProcessTriple()); const auto &target = jl_get_llvm_disasm_target(); const auto &cpu = target.first; const auto &features = target.second; std::string err; - const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, err); + const Target *TheTarget = TargetRegistry::lookupTarget(TheTriple.str(), err); // Set up required helpers and streamer std::unique_ptr Streamer; SourceMgr SrcMgr; - std::unique_ptr MAI(TheTarget->createMCAsmInfo(*TheTarget->createMCRegInfo(TripleName),TripleName)); + std::unique_ptr MAI(TheTarget->createMCAsmInfo(*TheTarget->createMCRegInfo(TheTriple.str()), TheTriple.str())); assert(MAI && "Unable to create target asm info!"); - std::unique_ptr MRI(TheTarget->createMCRegInfo(TripleName)); + std::unique_ptr MRI(TheTarget->createMCRegInfo(TheTriple.str())); assert(MRI && "Unable to create target register info!"); std::unique_ptr MOFI(new MCObjectFileInfo()); @@ -773,16 +772,15 @@ static void jl_dump_asm_internal( // Set up Subtarget and Disassembler std::unique_ptr - STI(TheTarget->createMCSubtargetInfo(TripleName, cpu, features)); + STI(TheTarget->createMCSubtargetInfo(TheTriple.str(), cpu, features)); std::unique_ptr DisAsm(TheTarget->createMCDisassembler(*STI, Ctx)); if (!DisAsm) { - jl_printf(JL_STDERR, "ERROR: no disassembler for target %s\n", - TripleName.c_str()); + rstream << "ERROR: no disassembler for target " << TheTriple.str(); return; } unsigned OutputAsmVariant = 0; // ATT or Intel-style assembly - if (strcmp(asm_variant, "intel")==0) { + if (strcmp(asm_variant, "intel") == 0) { OutputAsmVariant = 1; } bool ShowEncoding = false; diff --git a/src/dump.c b/src/dump.c index d29ae8565bdde..9f379e3f0e439 100644 --- a/src/dump.c +++ b/src/dump.c @@ -257,7 +257,7 @@ static int type_parameter_recursively_external(jl_value_t *p0) JL_NOTSAFEPOINT return 0; if (module_in_worklist(p->name->module)) return 0; - if (p->name->wrapper != (jl_value_t*)p0) { + if (jl_unwrap_unionall(p->name->wrapper) != (jl_value_t*)p) { if (!type_recursively_external(p)) return 0; } @@ -745,7 +745,7 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li else if (jl_is_unionall(v)) { write_uint8(s->s, TAG_UNIONALL); jl_datatype_t *d = (jl_datatype_t*)jl_unwrap_unionall(v); - if (jl_is_datatype(d) && d->name->wrapper == v && + if (jl_is_datatype(d) && jl_unwrap_unionall(d->name->wrapper) == (jl_value_t*)d && !module_in_worklist(d->name->module)) { write_uint8(s->s, 1); jl_serialize_value(s, d->name->module); diff --git a/src/gf.c b/src/gf.c index 78e9bfa40e758..05007a1035a27 100644 --- a/src/gf.c +++ b/src/gf.c @@ -35,28 +35,6 @@ JL_DLLEXPORT size_t jl_get_tls_world_age(void) return jl_get_ptls_states()->world_age; } -JL_DLLEXPORT jl_value_t *jl_invoke(jl_method_instance_t *meth, jl_value_t **args, uint32_t nargs) -{ - jl_callptr_t fptr = meth->invoke; - if (fptr != jl_fptr_trampoline) { - return fptr(meth, args, nargs); - } - else { - // if this hasn't been inferred (compiled) yet, - // inferring it might not be able to handle the world range - // so we just do a generic apply here - // because that might actually be faster - // since it can go through the unrolled caches for this world - // and if inference is successful, this meth would get updated anyways, - // and we'll get the fast path here next time - - // TODO: if `meth` came from an `invoke` call, we should make sure - // meth->def is called instead of doing normal dispatch. - - return jl_apply(args, nargs); - } -} - /// ----- Handling for Julia callbacks ----- /// JL_DLLEXPORT int8_t jl_is_in_pure_context(void) @@ -2235,6 +2213,8 @@ JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_value_t *types JL_PROPAGATES_ROO return (jl_value_t*)entry; } +jl_value_t *jl_gf_invoke_by_method(jl_method_t *method, jl_value_t **args, size_t nargs); + // invoke() // this does method dispatch with a set of types to match other than the // types of the actual arguments. this means it sometimes does NOT call the @@ -2247,13 +2227,10 @@ JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_value_t *types JL_PROPAGATES_ROO jl_value_t *jl_gf_invoke(jl_value_t *types0, jl_value_t **args, size_t nargs) { size_t world = jl_get_ptls_states()->world_age; - jl_svec_t *tpenv = jl_emptysvec; - jl_tupletype_t *tt = NULL; jl_value_t *types = NULL; - JL_GC_PUSH3(&types, &tpenv, &tt); + JL_GC_PUSH1(&types); jl_value_t *gf = args[0]; types = jl_argtype_with_function(gf, types0); - jl_methtable_t *mt = jl_gf_mtable(gf); jl_typemap_entry_t *entry = (jl_typemap_entry_t*)jl_gf_invoke_lookup(types, world); if ((jl_value_t*)entry == jl_nothing) { @@ -2263,10 +2240,19 @@ jl_value_t *jl_gf_invoke(jl_value_t *types0, jl_value_t **args, size_t nargs) // now we have found the matching definition. // next look for or create a specialization of this definition. + JL_GC_POP(); + return jl_gf_invoke_by_method(entry->func.method, args, nargs); +} - jl_method_t *method = entry->func.method; +jl_value_t *jl_gf_invoke_by_method(jl_method_t *method, jl_value_t **args, size_t nargs) +{ + size_t world = jl_get_ptls_states()->world_age; jl_method_instance_t *mfunc = NULL; jl_typemap_entry_t *tm = NULL; + jl_methtable_t *mt = jl_gf_mtable(args[0]); + jl_svec_t *tpenv = jl_emptysvec; + jl_tupletype_t *tt = NULL; + JL_GC_PUSH2(&tpenv, &tt); if (method->invokes != NULL) tm = jl_typemap_assoc_exact(method->invokes, args, nargs, jl_cachearg_offset(mt), world); if (tm) { @@ -2283,7 +2269,7 @@ jl_value_t *jl_gf_invoke(jl_value_t *types0, jl_value_t **args, size_t nargs) if (method->invokes == NULL) method->invokes = jl_nothing; - mfunc = cache_method(mt, &method->invokes, entry->func.value, tt, method, world, tpenv, 1); + mfunc = cache_method(mt, &method->invokes, (jl_value_t*)method, tt, method, world, tpenv, 1); JL_UNLOCK(&method->writelock); } JL_GC_POP(); @@ -2339,6 +2325,33 @@ JL_DLLEXPORT jl_value_t *jl_get_invoke_lambda(jl_methtable_t *mt, return (jl_value_t*)mfunc; } +JL_DLLEXPORT jl_value_t *jl_invoke(jl_method_instance_t *meth, jl_value_t **args, uint32_t nargs) +{ + jl_callptr_t fptr = meth->invoke; + if (fptr != jl_fptr_trampoline) { + return fptr(meth, args, nargs); + } + else { + // if this hasn't been inferred (compiled) yet, + // inferring it might not be able to handle the world range + // so we just do a generic apply here + // because that might actually be faster + // since it can go through the unrolled caches for this world + // and if inference is successful, this meth would get updated anyways, + // and we'll get the fast path here next time + + jl_method_instance_t *mfunc = jl_lookup_generic_(args, nargs, + jl_int32hash_fast(jl_return_address()), + jl_get_ptls_states()->world_age); + // check whether `jl_apply_generic` would call the right method + if (mfunc->def.method == meth->def.method) + return mfunc->invoke(mfunc, args, nargs); + + // no; came from an `invoke` call + return jl_gf_invoke_by_method(meth->def.method, args, nargs); + } +} + // Return value is rooted globally jl_function_t *jl_new_generic_function_with_supertype(jl_sym_t *name, jl_module_t *module, jl_datatype_t *st, int iskw) { diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 22c8acf4d28e0..766312ba45987 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -396,6 +396,8 @@ (vararg (let ((l (if (null? pargl) '() (last pargl)))) (if (or (vararg? l) (varargexpr? l)) (list l) '()))) + ;; positional args with vararg + (pargl-all pargl) ;; positional args without vararg (pargl (if (null? vararg) pargl (butlast pargl))) ;; positional args with everything required; for use by the core function @@ -424,13 +426,7 @@ (filter nospecialize-meta? kargl))) ;; body statements (stmts (cdr body)) - (positional-sparams - (filter (lambda (s) - (let ((name (car s))) - (or (expr-contains-eq name (cons 'list pargl)) - (and (pair? vararg) (expr-contains-eq name (car vararg))) - (not (expr-contains-eq name (cons 'list kargl)))))) - sparams)) + (positional-sparams (filter-sparams (cons 'list pargl-all) sparams)) (keyword-sparams (filter (lambda (s) (not (any (lambda (p) (eq? (car p) (car s))) @@ -462,7 +458,7 @@ ;; call with no keyword args ,(method-def-expr- - name positional-sparams (append pargl vararg) + name positional-sparams pargl-all `(block ,@(without-generated prologue) ,(let (;; call mangled(vals..., [rest_kw,] pargs..., [vararg]...) @@ -478,9 +474,7 @@ ;; call with unsorted keyword args. this sorts and re-dispatches. ,(method-def-expr- - name - ;; remove sparams that don't occur, to avoid printing the warning twice - (filter-sparams (cons 'list argl) positional-sparams) + name positional-sparams `((|::| ;; if there are optional positional args, we need to be able to reference the function name ,(if (any kwarg? pargl) (gensy) UNUSED) @@ -3048,7 +3042,9 @@ f(x) = yt(x) (kill)) (cdr e))) (else - (mark-used e) + (if (eq? (car e) '=) + (visit (caddr e)) + (mark-used e)) (if (and (or (eq? (car e) '=) (and (eq? (car e) 'method) (length> e 2))) (has? unused (cadr e))) diff --git a/src/support/strtod.c b/src/support/strtod.c index 047d404d90cda..225f2dbd4c933 100644 --- a/src/support/strtod.c +++ b/src/support/strtod.c @@ -118,9 +118,16 @@ JL_DLLEXPORT double jl_strtod_c(const char *nptr, char **endptr) decimal_point_pos = NULL; + p = nptr; + + /* parse leading spaces */ + while (isspace((unsigned char)*p)) { + p++; + } + /* Parse infinities and nans */ - val = parse_inf_or_nan(nptr, endptr); - if (*endptr != nptr) + val = parse_inf_or_nan(p, endptr); + if (*endptr != p) return val; /* Set errno to zero, so that we can distinguish zero results @@ -130,12 +137,6 @@ JL_DLLEXPORT double jl_strtod_c(const char *nptr, char **endptr) /* We process the optional sign manually, then pass the remainder to the system strtod. This ensures that the result of an underflow has the correct sign. */ - p = nptr; - - /* parse leading spaces */ - while (isspace((unsigned char)*p)) { - p++; - } /* Process leading sign, if present */ if (*p == '-') { diff --git a/stdlib/Distributed/src/macros.jl b/stdlib/Distributed/src/macros.jl index 15faadb3c31fa..4285073ec90a3 100644 --- a/stdlib/Distributed/src/macros.jl +++ b/stdlib/Distributed/src/macros.jl @@ -135,24 +135,17 @@ end extract_imports!(imports, x) = imports function extract_imports!(imports, ex::Expr) if Meta.isexpr(ex, (:import, :using)) - m = ex.args[1] - if isa(m, Expr) && m.head === :(:) - push!(imports, m.args[1].args[1]) - else - for a in ex.args - push!(imports, a.args[1]) - end - end + push!(imports, ex) elseif Meta.isexpr(ex, :let) extract_imports!(imports, ex.args[2]) elseif Meta.isexpr(ex, (:toplevel, :block)) - for i in eachindex(ex.args) - extract_imports!(imports, ex.args[i]) + for arg in ex.args + extract_imports!(imports, arg) end end return imports end -extract_imports(x) = extract_imports!(Symbol[], x) +extract_imports(x) = extract_imports!(Any[], x) """ @everywhere [procs()] expr @@ -183,7 +176,7 @@ macro everywhere(ex) end macro everywhere(procs, ex) - imps = [Expr(:import, m) for m in extract_imports(ex)] + imps = extract_imports(ex) return quote $(isempty(imps) ? nothing : Expr(:toplevel, imps...)) # run imports locally first let ex = $(Expr(:quote, ex)), procs = $(esc(procs)) diff --git a/stdlib/Distributed/test/distributed_exec.jl b/stdlib/Distributed/test/distributed_exec.jl index b82d66e685af9..77341e41dcd25 100644 --- a/stdlib/Distributed/test/distributed_exec.jl +++ b/stdlib/Distributed/test/distributed_exec.jl @@ -8,7 +8,7 @@ import Distributed: launch, manage include(joinpath(Sys.BINDIR, "..", "share", "julia", "test", "testenv.jl")) @test Distributed.extract_imports(:(begin; import Foo, Bar; let; using Baz; end; end)) == - [:Foo, :Bar, :Baz] + Any[:(import Foo, Bar), :(using Baz)] # Test a few "remote" invocations when no workers are present @test remote(myid)() == 1 diff --git a/stdlib/LibGit2/src/LibGit2.jl b/stdlib/LibGit2/src/LibGit2.jl index b54e9cbb298ee..3e864ff2220c4 100644 --- a/stdlib/LibGit2/src/LibGit2.jl +++ b/stdlib/LibGit2/src/LibGit2.jl @@ -1003,7 +1003,7 @@ function set_ssl_cert_locations(cert_loc) cert_dir = isdir(cert_loc) ? cert_loc : Cstring(C_NULL) cert_file == C_NULL && cert_dir == C_NULL && return @check ccall((:git_libgit2_opts, :libgit2), Cint, - (Cint, Cstring, Cstring), + (Cint, Cstring...), Cint(Consts.SET_SSL_CERT_LOCATIONS), cert_file, cert_dir) end diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index b73279abb2878..2589172dfb84b 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -172,7 +172,7 @@ end function rmul!(A::AbstractMatrix, D::Diagonal) @assert !has_offset_axes(A) - A .= A .* transpose(D.diag) + A .= A .* permutedims(D.diag) return A end @@ -260,20 +260,20 @@ lmul!(A::Diagonal, B::Diagonal) = Diagonal(B.diag .= A.diag .* B.diag) function lmul!(adjA::Adjoint{<:Any,<:Diagonal}, B::AbstractMatrix) A = adjA.parent - return lmul!(conj(A.diag), B) + return lmul!(adjoint(A), B) end function lmul!(transA::Transpose{<:Any,<:Diagonal}, B::AbstractMatrix) A = transA.parent - return lmul!(A.diag, B) + return lmul!(transpose(A), B) end function rmul!(A::AbstractMatrix, adjB::Adjoint{<:Any,<:Diagonal}) B = adjB.parent - return rmul!(A, conj(B.diag)) + return rmul!(A, adjoint(B)) end function rmul!(A::AbstractMatrix, transB::Transpose{<:Any,<:Diagonal}) B = transB.parent - return rmul!(A, B.diag) + return rmul!(A, transpose(B)) end # Get ambiguous method if try to unify AbstractVector/AbstractMatrix here using AbstractVecOrMat @@ -552,10 +552,9 @@ end *(x::Adjoint{<:Any,<:AbstractVector}, D::Diagonal) = Adjoint(map((t,s) -> t'*s, D.diag, parent(x))) *(x::Adjoint{<:Any,<:AbstractVector}, D::Diagonal, y::AbstractVector) = mapreduce(t -> t[1]*t[2]*t[3], +, zip(x, D.diag, y)) -*(x::Transpose{<:Any,<:AbstractVector}, D::Diagonal) = Transpose(map(*, D.diag, parent(x))) +*(x::Transpose{<:Any,<:AbstractVector}, D::Diagonal) = Transpose(map((t,s) -> transpose(t)*s, D.diag, parent(x))) *(x::Transpose{<:Any,<:AbstractVector}, D::Diagonal, y::AbstractVector) = mapreduce(t -> t[1]*t[2]*t[3], +, zip(x, D.diag, y)) -# TODO: these methods will yield row matrices, rather than adjoint/transpose vectors function cholesky!(A::Diagonal, ::Val{false} = Val(false); check::Bool = true) info = 0 diff --git a/stdlib/LinearAlgebra/test/diagonal.jl b/stdlib/LinearAlgebra/test/diagonal.jl index 2f7f2a698a61f..9e6169f930ae6 100644 --- a/stdlib/LinearAlgebra/test/diagonal.jl +++ b/stdlib/LinearAlgebra/test/diagonal.jl @@ -461,10 +461,20 @@ end fullBB = copyto!(Matrix{Matrix{T}}(undef, 2, 2), BB) for (transform1, transform2) in ((identity, identity), (identity, adjoint ), (adjoint, identity ), (adjoint, adjoint ), - (identity, transpose), (transpose, identity ), (transpose, transpose) ) + (identity, transpose), (transpose, identity ), (transpose, transpose), + (identity, Adjoint ), (Adjoint, identity ), (Adjoint, Adjoint ), + (identity, Transpose), (Transpose, identity ), (Transpose, Transpose)) @test *(transform1(D), transform2(B))::typeof(D) ≈ *(transform1(Matrix(D)), transform2(Matrix(B))) atol=2 * eps() @test *(transform1(DD), transform2(BB))::typeof(DD) == *(transform1(fullDD), transform2(fullBB)) end + M = randn(T, 5, 5) + MM = [randn(T, 2, 2) for _ in 1:2, _ in 1:2] + for transform in (identity, adjoint, transpose, Adjoint, Transpose) + @test lmul!(transform(D), copy(M)) == *(transform(Matrix(D)), M) + @test rmul!(copy(M), transform(D)) == *(M, transform(Matrix(D))) + @test lmul!(transform(DD), copy(MM)) == *(transform(fullDD), MM) + @test rmul!(copy(MM), transform(DD)) == *(MM, transform(fullDD)) + end end end @@ -474,10 +484,16 @@ end end @testset "Multiplication with Adjoint and Transpose vectors (#26863)" begin - x = rand(5) - D = Diagonal(rand(5)) - @test x'*D*x == (x'*D)*x == (x'*Array(D))*x - @test Transpose(x)*D*x == (Transpose(x)*D)*x == (Transpose(x)*Array(D))*x + x = collect(1:2) + xt = transpose(x) + A = reshape([[1 2; 3 4], zeros(Int,2,2), zeros(Int, 2, 2), [5 6; 7 8]], 2, 2) + D = Diagonal(A) + @test x'*D == x'*A == copy(x')*D == copy(x')*A + @test xt*D == xt*A == copy(xt)*D == copy(xt)*A + y = [x, x] + yt = transpose(y) + @test y'*D*y == (y'*D)*y == (y'*A)*y + @test yt*D*y == (yt*D)*y == (yt*A)*y end @testset "Triangular division by Diagonal #27989" begin diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index bbc925802f99e..6d98077f7d03a 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,2 +1,2 @@ PKG_BRANCH = master -PKG_SHA1 = 853b3f1fd9895db32b402d89e9dee153b66b2316 +PKG_SHA1 = 40cbbe224d4a491503279dfc5b9aefe15412f007 diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index d9a9136074d8d..571d50c2130fe 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -353,7 +353,7 @@ get_value(sym, fn) = (sym, true) function get_value_getfield(ex::Expr, fn) # Example :((top(getfield))(Base,:max)) val, found = get_value_getfield(ex.args[2],fn) #Look up Base in Main and returns the module - found || return (nothing, false) + (found && length(ex.args) >= 3) || return (nothing, false) return get_value_getfield(ex.args[3], val) #Look up max in Base and returns the function if found. end get_value_getfield(sym, fn) = get_value(sym, fn) @@ -407,7 +407,7 @@ function try_get_type(sym::Expr, fn::Module) elseif sym.head === :ref # some simple cases of `expand` return try_get_type(Expr(:call, GlobalRef(Base, :getindex), sym.args...), fn) - elseif sym.head === :. + elseif sym.head === :. && sym.args[2] isa QuoteNode # second check catches broadcasting return try_get_type(Expr(:call, GlobalRef(Core, :getfield), sym.args...), fn) end return (Any, false) @@ -432,10 +432,21 @@ function complete_methods(ex_org::Expr, context_module=Main)::Vector{Completion} args_ex = Any[] func, found = get_value(ex_org.args[1], context_module) !found && return Completion[] - for ex in ex_org.args[2:end] - val, found = get_type(ex, context_module) - push!(args_ex, val) + + funargs = ex_org.args[2:end] + # handle broadcasting, but only handle number of arguments instead of + # argument types + if ex_org.head === :. && ex_org.args[2] isa Expr + for _ in ex_org.args[2].args + push!(args_ex, Any) + end + else + for ex in funargs + val, found = get_type(ex, context_module) + push!(args_ex, val) + end end + out = Completion[] t_in = Tuple{Core.Typeof(func), args_ex...} # Input types na = length(args_ex)+1 @@ -610,12 +621,16 @@ function completions(string, pos, context_module=Main)::Completions # Make sure that only bslash_completions is working on strings inc_tag==:string && return String[], 0:-1, false - if inc_tag == :other && should_method_complete(partial) frange, method_name_end = find_start_brace(partial) ex = Meta.parse(partial[frange] * ")", raise=false, depwarn=false) - if isa(ex, Expr) && ex.head==:call - return complete_methods(ex, context_module), first(frange):method_name_end, false + + if isa(ex, Expr) + if ex.head==:call + return complete_methods(ex, context_module), first(frange):method_name_end, false + elseif ex.head==:. && ex.args[2] isa Expr && ex.args[2].head==:tuple + return complete_methods(ex, context_module), first(frange):(method_name_end - 1), false + end end elseif inc_tag == :comment return Completion[], 0:-1, false diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index c569bf91876c1..664a3c11fefc5 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -21,13 +21,13 @@ helpmode(line::AbstractString) = helpmode(stdout, line) function _helpmode(io::IO, line::AbstractString) line = strip(line) + x = Meta.parse(line, raise = false, depwarn = false) expr = - if haskey(keywords, Symbol(line)) + if haskey(keywords, Symbol(line)) || isexpr(x, :error) || isexpr(x, :invalid) # Docs for keywords must be treated separately since trying to parse a single # keyword such as `function` would throw a parse error due to the missing `end`. Symbol(line) else - x = Meta.parse(line, raise = false, depwarn = false) # Retrieving docs for macros requires us to make a distinction between the text # `@macroname` and `@macroname()`. These both parse the same, but are used by # the docsystem to return different results. The first returns all documentation diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index f3011415085e6..9aa34b68b54de 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -972,6 +972,12 @@ for (line, expr) in Pair[ @test Base.eval(REPL._helpmode(buf, line)) isa Union{Markdown.MD,Nothing} end +# PR 30754, Issues #22013, #24871, #26933, #29282, #29361, #30348 +for line in ["′", "abstract", "type", "|=", ".="] + @test occursin("No documentation found.", + sprint(show, Base.eval(REPL._helpmode(IOBuffer(), line))::Union{Markdown.MD,Nothing})) +end + # PR #27562 fake_repl() do stdin_write, stdout_read, repl repltask = @async begin diff --git a/stdlib/REPL/test/replcompletions.jl b/stdlib/REPL/test/replcompletions.jl index 15bcc527c6953..eb19f8d60097b 100644 --- a/stdlib/REPL/test/replcompletions.jl +++ b/stdlib/REPL/test/replcompletions.jl @@ -960,6 +960,16 @@ let s = "type_test.xx.y" @test s[r] == "y" end +let s = ":(function foo(::Int) end).args[1].args[2]." + c, r = test_complete_context(s) + @test c == Any[] +end + +let s = "log(log.(x)," + c, r = test_complete_context(s) + @test !isempty(c) +end + let s = "Base.return_types(getin" c, r = test_complete_context(s) @test "getindex" in c @@ -981,6 +991,14 @@ let s = "test(1,1, " @test s[r] == "test" end +let s = "test.(1,1, " + c, r, res = test_complete_context(s) + @test !res + @test length(c) == 4 + @test r == 1:4 + @test s[r] == "test" +end + let s = "prevind(\"θ\",1," c, r, res = test_complete_context(s) @test c[1] == string(first(methods(prevind, Tuple{String, Int}))) diff --git a/stdlib/SHA/test/runtests.jl b/stdlib/SHA/test/runtests.jl index 63a333bdf779d..ce0d2b68fdbac 100644 --- a/stdlib/SHA/test/runtests.jl +++ b/stdlib/SHA/test/runtests.jl @@ -9,7 +9,8 @@ const VERBOSE = false lorem = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." so_many_as_array = repeat([0x61], 1000000) so_many_as_tuple = ntuple((i) -> 0x61, 1000000) -file = ".sha" # Subject to change +tempdir = mktempdir() +file = joinpath(tempdir, ".sha") fIO = open(file, "w") write(fIO, '\0') close(fIO) @@ -274,16 +275,24 @@ end # test error if eltype of input is not UInt8 for f in sha_funcs global nerrors + data = UInt32[0x23467, 0x324775] try - f(UInt32[0x23467, 0x324775]) - warn("Non-UInt8 Arrays should fail") - nerrors += 1 - catch + f(data) + catch ex + if ex isa MethodError && + ex.f === f && + ex.args === (data,) + continue + end + rethrow() end + warn("Non-UInt8 Arrays should fail") + nerrors += 1 end # Clean up the I/O mess rm(file) +rm(tempdir) if nerrors == 0 VERBOSE && println("ALL OK") diff --git a/stdlib/SparseArrays/src/sparsematrix.jl b/stdlib/SparseArrays/src/sparsematrix.jl index 1ce5b41ce5356..712c251b340e5 100644 --- a/stdlib/SparseArrays/src/sparsematrix.jl +++ b/stdlib/SparseArrays/src/sparsematrix.jl @@ -9,7 +9,9 @@ SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrix{Tv,Ti} Matrix type for storing sparse matrices in the -[Compressed Sparse Column](@ref man-csc) format. +[Compressed Sparse Column](@ref man-csc) format. The standard way +of constructing SparseMatrixCSC is through the [`sparse`](@ref) function. +See also [`spzeros`](@ref), [`spdiagm`](@ref) and [`sprand`](@ref). """ struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrix{Tv,Ti} m::Int # Number of rows @@ -1564,12 +1566,22 @@ sparse(s::UniformScaling, dims::Dims{2}) = SparseMatrixCSC(s, dims) sparse(s::UniformScaling, m::Integer, n::Integer) = sparse(s, Dims((m, n))) # TODO: More appropriate location? -conj!(A::SparseMatrixCSC) = (@inbounds broadcast!(conj, A.nzval, A.nzval); A) -(-)(A::SparseMatrixCSC) = SparseMatrixCSC(A.m, A.n, copy(A.colptr), copy(A.rowval), map(-, A.nzval)) +function conj!(A::SparseMatrixCSC) + map!(conj, nzvalview(A), nzvalview(A)) + return A +end +function (-)(A::SparseMatrixCSC) + nzval = similar(A.nzval) + map!(-, view(nzval, 1:nnz(A)), nzvalview(A)) + return SparseMatrixCSC(A.m, A.n, copy(A.colptr), copy(A.rowval), nzval) +end # the rest of real, conj, imag are handled correctly via AbstractArray methods -conj(A::SparseMatrixCSC{<:Complex}) = - SparseMatrixCSC(A.m, A.n, copy(A.colptr), copy(A.rowval), conj(A.nzval)) +function conj(A::SparseMatrixCSC{<:Complex}) + nzval = similar(A.nzval) + map!(conj, view(nzval, 1:nnz(A)), nzvalview(A)) + return SparseMatrixCSC(A.m, A.n, copy(A.colptr), copy(A.rowval), nzval) +end imag(A::SparseMatrixCSC{Tv,Ti}) where {Tv<:Real,Ti} = spzeros(Tv, Ti, A.m, A.n) ## Binary arithmetic and boolean operators diff --git a/stdlib/SparseArrays/src/sparsevector.jl b/stdlib/SparseArrays/src/sparsevector.jl index ce9fbbc35e947..445fe542fbcc3 100644 --- a/stdlib/SparseArrays/src/sparsevector.jl +++ b/stdlib/SparseArrays/src/sparsevector.jl @@ -689,6 +689,8 @@ function getindex(A::SparseMatrixCSC{Tv,Ti}, I::AbstractVector) where {Tv,Ti} SparseVector(n, rowvalB, nzvalB) end +Base.copy(a::SubArray{<:Any,<:Any,<:Union{SparseVector, SparseMatrixCSC}}) = a.parent[a.indices...] + function findall(x::SparseVector) return findall(identity, x) end diff --git a/stdlib/SparseArrays/test/sparse.jl b/stdlib/SparseArrays/test/sparse.jl index c46ab90c349b7..569e95862428d 100644 --- a/stdlib/SparseArrays/test/sparse.jl +++ b/stdlib/SparseArrays/test/sparse.jl @@ -2364,4 +2364,16 @@ end @test one(A) isa SparseMatrixCSC{Int} end +@testset "unary operations on matrices where length(nzval)>nnz" begin + # this should create a sparse matrix with length(nzval)>nnz + A = SparseMatrixCSC(Complex{BigInt}[1+im 2+2im]')'[1:1, 2:2] + # ...ensure it does! If necessary, the test needs to be updated to use + # another mechanism to create a suitable A. + @assert length(A.nzval) > nnz(A) + @test -A == fill(-2-2im, 1, 1) + @test conj(A) == fill(2-2im, 1, 1) + conj!(A) + @test A == fill(2-2im, 1, 1) +end + end # module diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index b89c4feb3a437..a06f1b19601de 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -1832,6 +1832,15 @@ function g15276() end @test g15276() isa Vector{Int} +function inbounds_30563() + local y + @inbounds for i in 1:10 + y = (m->2i)(0) + end + return y +end +@test Base.return_types(inbounds_30563, ()) == Any[Int] + # issue #27316 - inference shouldn't hang on these f27316(::Vector) = nothing f27316(::Any) = f27316(Any[][1]), f27316(Any[][1]) diff --git a/test/copy.jl b/test/copy.jl index 74650d28d42d4..9b7dd82bdf03a 100644 --- a/test/copy.jl +++ b/test/copy.jl @@ -84,6 +84,9 @@ end @test c[1] === c[2] end +# issue #30911 +@test deepcopy(Array{Int,N} where N) == Array{Int,N} where N + # issue #14027 struct Nullable14027{T} hasvalue::Bool diff --git a/test/core.jl b/test/core.jl index d9f3af8635377..0e1ba76c0baf2 100644 --- a/test/core.jl +++ b/test/core.jl @@ -2435,6 +2435,20 @@ const T24460 = Tuple{T,T} where T g24460() = invoke(f24460, T24460, 1, 2) @test @inferred(g24460()) === 2.0 +# issue #30679 +@noinline function f30679(::DataType) + b = IOBuffer() + write(b, 0x00) + 2 +end +@noinline function f30679(t::Type{Int}) + x = invoke(f30679, Tuple{DataType}, t) + b = IOBuffer() + write(b, 0x00) + return x + 40 +end +@test f30679(Int) == 42 + call_lambda1() = (()->x)(1) call_lambda2() = ((x)->x)() call_lambda3() = ((x)->x)(1,2) diff --git a/test/iterators.jl b/test/iterators.jl index 86b2cd1d2969d..25a2df2ce8021 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -623,3 +623,26 @@ end @test @inferred(first(z)) == (1, "a", 1.0, 1, "a", 1.0, 1, "a", 1.0) @test @inferred(first(Iterators.drop(z, 1))) == (2, "b", 2.0, 2, "a", 1.2, 1, "c", 1.0) end + +@testset "Stateful fix #30643" begin + @test Base.IteratorSize(1:10) isa Base.HasShape + a = Iterators.Stateful(1:10) + @test Base.IteratorSize(a) isa Base.HasLength + @test length(a) == 10 + @test length(collect(a)) == 10 + @test length(a) == 0 + b = Iterators.Stateful(Iterators.take(1:10,3)) + @test Base.IteratorSize(b) isa Base.HasLength + @test length(b) == 3 + @test length(collect(b)) == 3 + @test length(b) == 0 + c = Iterators.Stateful(Iterators.countfrom(1)) + @test Base.IteratorSize(c) isa Base.IsInfinite + @test length(Iterators.take(c,3)) == 3 + @test length(collect(Iterators.take(c,3))) == 3 + d = Iterators.Stateful(Iterators.filter(isodd,1:10)) + @test Base.IteratorSize(d) isa Base.SizeUnknown + @test length(collect(Iterators.take(d,3))) == 3 + @test length(collect(d)) == 2 + @test length(collect(d)) == 0 +end diff --git a/test/keywordargs.jl b/test/keywordargs.jl index 51c6c60e83772..eacacdc2ea248 100644 --- a/test/keywordargs.jl +++ b/test/keywordargs.jl @@ -117,6 +117,17 @@ end @test kwf7(1.5;k=2.5) === Float64 @test_throws MethodError kwf7(1.5) @test_throws TypeError kwf7(1.5; k=2) + + # issue #30792 + g30792(a::C; b=R(1)) where {R <: Real, C <: Union{R, Complex{R}}} = R + @test g30792(1.0) === Float64 + @test g30792(1.0im) === Float64 + @test g30792(1.0im, b=1) === Float64 + @test_throws MethodError g30792("") + f30792(a::C; b::R=R(1)) where {R <: Real, C <: Union{R, Complex{R}}} = R + @test f30792(2im) === Int + @test f30792(2im, b=3) === Int + @test_throws TypeError f30792(2im, b=3.0) end # try to confuse it with quoted symbol kwf8(x::MIME{:T};k::T=0) where {T} = 0 diff --git a/test/offsetarray.jl b/test/offsetarray.jl index 112a3b423e767..8490a3134d5af 100644 --- a/test/offsetarray.jl +++ b/test/offsetarray.jl @@ -203,6 +203,8 @@ cmp_showf(Base.print_matrix, io, OffsetArray(rand(10^3,5), (10,-9))) # column cmp_showf(Base.print_matrix, io, OffsetArray(rand(5,10^3), (10,-9))) # rows fit cmp_showf(Base.print_matrix, io, OffsetArray(rand(10^3,10^3), (10,-9))) # neither fits cmp_showf(Base.print_matrix, io, OffsetArray(reshape(range(-0.212121212121, stop=2/11, length=3*29), 3, 29), (-2, -15)); options=(:displaysize=>(53,210),)) +cmp_showf(show, io, OffsetArray(collect(1:100), (100,))) # issue #31641 + targets1 = ["0-dimensional $OAs_name.OffsetArray{Float64,0,Array{Float64,0}}:\n1.0", "$OAs_name.OffsetArray{Float64,1,Array{Float64,1}} with indices 2:2:\n 1.0", "$OAs_name.OffsetArray{Float64,2,Array{Float64,2}} with indices 2:2×3:3:\n 1.0", diff --git a/test/parse.jl b/test/parse.jl index 45e13a95b7f90..1d3e064823cf4 100644 --- a/test/parse.jl +++ b/test/parse.jl @@ -278,8 +278,8 @@ end # parsing complex numbers (#22250) @testset "complex parsing" begin - for r in (1,0,-1), i in (1,0,-1), sign in ('-','+'), Im in ("i","j","im") - for s1 in (""," "), s2 in (""," "), s3 in (""," "), s4 in (""," ") + for sign in ('-','+'), Im in ("i","j","im"), s1 in (""," "), s2 in (""," "), s3 in (""," "), s4 in (""," ") + for r in (1,0,-1), i in (1,0,-1), n = Complex(r, sign == '+' ? i : -i) s = string(s1, r, s2, sign, s3, i, Im, s4) @test n === parse(Complex{Int}, s) @@ -293,6 +293,13 @@ end @test n*parse(T,"1e-3") == parse(Complex{T}, string(s1, r, "e-3", s2, sign, s3, i, "e-3", Im, s4)) end end + for r in (-1.0,-1e-9,Inf,-Inf,NaN), i in (-1.0,-1e-9,Inf,NaN) + n = Complex(r, sign == '+' ? i : -i) + s = lowercase(string(s1, r, s2, sign, s3, i, Im, s4)) + @test n === parse(ComplexF64, s) + @test Complex(r) === parse(ComplexF64, string(s1, r, s2)) + @test Complex(0,i) === parse(ComplexF64, string(s3, i, Im, s4)) + end end @test parse(Complex{Float16}, "3.3+4i") === Complex{Float16}(3.3+4im) @test parse(Complex{Int}, SubString("xxxxxx1+2imxxxx", 7, 10)) === 1+2im @@ -338,3 +345,10 @@ end # Ensure dotting binary doesn't break dotting unary @test Meta.parse(".~[1,2]") == Expr(:call, :.~, Expr(:vect, 1, 2)) end + +@testset "inf and nan parsing" begin + for (v,vs) in ((NaN,"nan"), (Inf,"inf"), (Inf,"infinity")), sbefore in ("", " "), safter in ("", " "), sign in (+, -), case in (lowercase, uppercase) + s = case(string(sbefore, sign, vs, safter)) + @test isequal(parse(Float64, s), sign(v)) + end +end diff --git a/test/precompile.jl b/test/precompile.jl index e9ccf795bde00..b275c6aa439e8 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -744,5 +744,27 @@ let end end +# issue #29936 +let + load_path = mktempdir() + load_cache_path = mktempdir() + try + write(joinpath(load_path, "Foo29936.jl"), + """ + module Foo29936 + const global m = Val{nothing}() + const global h = Val{:hey}() + wab = [("a", m), ("b", h),] + end + """) + pushfirst!(LOAD_PATH, load_path) + pushfirst!(DEPOT_PATH, load_cache_path) + @eval using Foo29936 + @test [("Plan", Foo29936.m), ("Plan", Foo29936.h),] isa Vector{Tuple{String,Val}} + finally + rm(load_path, recursive=true) + rm(load_cache_path, recursive=true) + end +end end # !withenv diff --git a/test/reinterpretarray.jl b/test/reinterpretarray.jl index 70899c8b6ee53..d712a8ffa3b47 100644 --- a/test/reinterpretarray.jl +++ b/test/reinterpretarray.jl @@ -161,6 +161,16 @@ let a = [0.1 0.2; 0.3 0.4], at = reshape([(i,i+1) for i = 1:2:8], 2, 2) @test r == OffsetArray(reshape(1:8, 2, 2, 2), (0, offsetvt...)) end +@testset "potentially aliased copies" begin + buffer = UInt8[1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0] + mid = length(buffer) ÷ 2 + x1 = reinterpret(Int64, @view buffer[1:mid]) + x2 = reinterpret(Int64, @view buffer[mid+1:end]) + x1 .= x2 + @test x1 == x2 == [2] + @test x1[] === x2[] === Int64(2) +end + # Test 0-dimensional Arrays A = zeros(UInt32) B = reinterpret(Int32,A) diff --git a/test/strings/util.jl b/test/strings/util.jl index 17d1f9355006c..20de96ee9ce87 100644 --- a/test/strings/util.jl +++ b/test/strings/util.jl @@ -301,6 +301,7 @@ end @test chomp("foo\r\n") == "foo" @test chomp("fo∀\r\n") == "fo∀" @test chomp("fo∀") == "fo∀" + @test chop("") == "" @test chop("fooε") == "foo" @test chop("foεo") == "foε" @test chop("∃∃∃∃") == "∃∃∃"