diff --git a/Makefile b/Makefile index b9fb05e56f4c1..c5271e62420e0 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ $(BUILDROOT)/doc/_build/html/en/index.html: $(shell find $(BUILDROOT)/base $(BUI julia-symlink: julia-cli-$(JULIA_BUILD_MODE) ifeq ($(OS),WINNT) - @echo '@"%~dp0\'"$$(echo $(call rel_path,$(BUILDROOT),$(JULIA_EXECUTABLE)) | tr / '\\')"\" '%*' > $(BUILDROOT)/julia.bat + echo '@"%~dp0/'"$$(echo '$(call rel_path,$(BUILDROOT),$(JULIA_EXECUTABLE))')"'" %*' | tr / '\\' > $(BUILDROOT)/julia.bat chmod a+x $(BUILDROOT)/julia.bat else ifndef JULIA_VAGRANT_BUILD diff --git a/base/Base.jl b/base/Base.jl index 2f78da71ca42c..c55ddf35aebfb 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -244,9 +244,6 @@ include("weakkeydict.jl") include("logging.jl") using .CoreLogging -# BinaryPlatforms, used by Artifacts -include("binaryplatforms.jl") - # functions defined in Random function rand end function randn end @@ -298,6 +295,9 @@ using .Order include("sort.jl") using .Sort +# BinaryPlatforms, used by Artifacts. Needs `Sort`. +include("binaryplatforms.jl") + # Fast math include("fastmath.jl") using .FastMath diff --git a/base/abstractdict.jl b/base/abstractdict.jl index cfd964759bcce..baef62235696d 100644 --- a/base/abstractdict.jl +++ b/base/abstractdict.jl @@ -155,7 +155,10 @@ empty(a::AbstractDict) = empty(a, keytype(a), valtype(a)) empty(a::AbstractDict, ::Type{V}) where {V} = empty(a, keytype(a), V) # Note: this is the form which makes sense for `Vector`. copy(a::AbstractDict) = merge!(empty(a), a) -copy!(dst::AbstractDict, src::AbstractDict) = merge!(empty!(dst), src) +function copy!(dst::AbstractDict, src::AbstractDict) + dst === src && return dst + merge!(empty!(dst), src) +end """ merge!(d::AbstractDict, others::AbstractDict...) diff --git a/base/abstractset.jl b/base/abstractset.jl index a082e789a3ba9..effc10ef5782b 100644 --- a/base/abstractset.jl +++ b/base/abstractset.jl @@ -3,7 +3,10 @@ eltype(::Type{<:AbstractSet{T}}) where {T} = @isdefined(T) ? T : Any sizehint!(s::AbstractSet, n) = nothing -copy!(dst::AbstractSet, src::AbstractSet) = union!(empty!(dst), src) +function copy!(dst::AbstractSet, src::AbstractSet) + dst === src && return dst + union!(empty!(dst), src) +end ## set operations (union, intersection, symmetric difference) diff --git a/base/asyncmap.jl b/base/asyncmap.jl index 976ce6c7b85ca..740e5e62879c7 100644 --- a/base/asyncmap.jl +++ b/base/asyncmap.jl @@ -15,7 +15,7 @@ up to 100 tasks will be used for concurrent mapping. `ntasks` can also be specified as a zero-arg function. In this case, the number of tasks to run in parallel is checked before processing every element and a new -task started if the value of `ntasks_func` is less than the current number +task started if the value of `ntasks_func` is greater than the current number of tasks. If `batch_size` is specified, the collection is processed in batch mode. `f` must diff --git a/base/binaryplatforms.jl b/base/binaryplatforms.jl index e93494fac0f7e..99ad4b98c9c85 100644 --- a/base/binaryplatforms.jl +++ b/base/binaryplatforms.jl @@ -608,7 +608,8 @@ const arch_march_isa_mapping = let "armv8_0" => get_set("aarch64", "armv8.0-a"), "armv8_1" => get_set("aarch64", "armv8.1-a"), "armv8_2_crypto" => get_set("aarch64", "armv8.2-a+crypto"), - "armv8_4_crypto_sve" => get_set("aarch64", "armv8.4-a+crypto+sve"), + "a64fx" => get_set("aarch64", "a64fx"), + "apple_m1" => get_set("aarch64", "apple_m1"), ], "powerpc64le" => [ "power8" => get_set("powerpc64le", "power8"), diff --git a/base/cmd.jl b/base/cmd.jl index 809bc0f3c0a57..6cd2027875024 100644 --- a/base/cmd.jl +++ b/base/cmd.jl @@ -230,7 +230,7 @@ byteenv(env::Union{AbstractVector{Pair{T,V}}, Tuple{Vararg{Pair{T,V}}}}) where { String[cstr(k*"="*string(v)) for (k,v) in env] """ - setenv(command::Cmd, env; dir="") + setenv(command::Cmd, env; dir) Set environment variables to use when running the given `command`. `env` is either a dictionary mapping strings to strings, an array of strings of the form `"var=val"`, or @@ -239,11 +239,22 @@ existing environment, create `env` through `copy(ENV)` and then setting `env["va as desired, or use `addenv`. The `dir` keyword argument can be used to specify a working directory for the command. +`dir` defaults to the currently set `dir` for `command` (which is the current working +directory if not specified already). """ -setenv(cmd::Cmd, env; dir="") = Cmd(cmd; env=byteenv(env), dir=dir) -setenv(cmd::Cmd, env::Pair{<:AbstractString}...; dir="") = +setenv(cmd::Cmd, env; dir=cmd.dir) = Cmd(cmd; env=byteenv(env), dir=dir) +setenv(cmd::Cmd, env::Pair{<:AbstractString}...; dir=cmd.dir) = setenv(cmd, env; dir=dir) -setenv(cmd::Cmd; dir="") = Cmd(cmd; dir=dir) +setenv(cmd::Cmd; dir=cmd.dir) = Cmd(cmd; dir=dir) + +# split environment entry string into before and after first `=` (key and value) +function splitenv(e::String) + i = findnext('=', e, 2) + if i === nothing + throw(ArgumentError("malformed environment entry")) + end + e[1:prevind(e, i)], e[nextind(e, i):end] +end """ addenv(command::Cmd, env...; inherit::Bool = true) @@ -262,7 +273,7 @@ function addenv(cmd::Cmd, env::Dict; inherit::Bool = true) merge!(new_env, ENV) end else - for (k, v) in split.(cmd.env, "=") + for (k, v) in splitenv.(cmd.env) new_env[string(k)::String] = string(v)::String end end @@ -277,7 +288,7 @@ function addenv(cmd::Cmd, pairs::Pair{<:AbstractString}...; inherit::Bool = true end function addenv(cmd::Cmd, env::Vector{<:AbstractString}; inherit::Bool = true) - return addenv(cmd, Dict(k => v for (k, v) in split.(env, "=")); inherit) + return addenv(cmd, Dict(k => v for (k, v) in splitenv.(env)); inherit) end (&)(left::AbstractCmd, right::AbstractCmd) = AndCmds(left, right) diff --git a/base/cpuid.jl b/base/cpuid.jl index b1fb82cf86dae..48930d8064ba9 100644 --- a/base/cpuid.jl +++ b/base/cpuid.jl @@ -56,9 +56,10 @@ const ISAs_by_family = Dict( "aarch64" => [ # Implicit in all sets, because always required: fp, asimd "armv8.0-a" => ISA(Set{UInt32}()), - "armv8.1-a" => ISA(Set((JL_AArch64_lse, JL_AArch64_crc, JL_AArch64_rdm))), - "armv8.2-a+crypto" => ISA(Set((JL_AArch64_lse, JL_AArch64_crc, JL_AArch64_rdm, JL_AArch64_aes, JL_AArch64_sha2))), - "armv8.4-a+crypto+sve" => ISA(Set((JL_AArch64_lse, JL_AArch64_crc, JL_AArch64_rdm, JL_AArch64_fp16fml, JL_AArch64_aes, JL_AArch64_sha2, JL_AArch64_dotprod, JL_AArch64_sve))), + "armv8.1-a" => ISA(Set((JL_AArch64_v8_1a, JL_AArch64_lse, JL_AArch64_crc, JL_AArch64_rdm))), + "armv8.2-a+crypto" => ISA(Set((JL_AArch64_v8_2a, JL_AArch64_lse, JL_AArch64_crc, JL_AArch64_rdm, JL_AArch64_aes, JL_AArch64_sha2))), + "a64fx" => ISA(Set((JL_AArch64_v8_2a, JL_AArch64_lse, JL_AArch64_crc, JL_AArch64_rdm, JL_AArch64_sha2, JL_AArch64_ccpp, JL_AArch64_complxnum, JL_AArch64_fullfp16, JL_AArch64_sve))), + "apple_m1" => ISA(Set((JL_AArch64_v8_5a, JL_AArch64_lse, JL_AArch64_crc, JL_AArch64_rdm, JL_AArch64_aes, JL_AArch64_sha2, JL_AArch64_sha3, JL_AArch64_ccpp, JL_AArch64_complxnum, JL_AArch64_fp16fml, JL_AArch64_fullfp16, JL_AArch64_dotprod, JL_AArch64_rcpc, JL_AArch64_altnzcv))), ], "powerpc64le" => [ # We have no way to test powerpc64le features yet, so we're only going to declare the lowest ISA: @@ -88,14 +89,27 @@ function normalize_arch(arch::String) return arch end +let + # Collect all relevant features for the current architecture, if any. + FEATURES = UInt32[] + arch = normalize_arch(String(Sys.ARCH)) + if arch in keys(ISAs_by_family) + for isa in ISAs_by_family[arch] + unique!(append!(FEATURES, last(isa).features)) + end + end + + # Use `@eval` to inline the list of features. + @eval function cpu_isa() + return ISA(Set{UInt32}(feat for feat in $(FEATURES) if test_cpu_feature(feat))) + end +end + """ cpu_isa() Return the [`ISA`](@ref) (instruction set architecture) of the current CPU. """ -function cpu_isa() - all_features = last(last(get(ISAs_by_family, normalize_arch(String(Sys.ARCH)), "" => [ISA(Set{UInt32}())]))).features - return ISA(Set{UInt32}(feat for feat in all_features if test_cpu_feature(feat))) -end +cpu_isa end # module CPUID diff --git a/base/expr.jl b/base/expr.jl index a7aa74edef22e..ed06da44a1701 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -422,6 +422,7 @@ macro generated(f) if isa(f, Expr) && (f.head === :function || is_short_function_def(f)) body = f.args[2] lno = body.args[1] + tmp = gensym("tmp") return Expr(:escape, Expr(f.head, f.args[1], Expr(:block, @@ -429,8 +430,8 @@ macro generated(f) Expr(:if, Expr(:generated), # https://github.com/JuliaLang/julia/issues/25678 Expr(:block, - :(local tmp = $body), - :(if tmp isa Core.CodeInfo; return tmp; else tmp; end)), + :(local $tmp = $body), + :(if $tmp isa $(GlobalRef(Core, :CodeInfo)); return $tmp; else $tmp; end)), Expr(:block, Expr(:meta, :generated_only), Expr(:return, nothing)))))) diff --git a/base/io.jl b/base/io.jl index a00d871f9c59c..ca6f6a9ffd6bd 100644 --- a/base/io.jl +++ b/base/io.jl @@ -20,7 +20,7 @@ struct SystemError <: Exception extrainfo SystemError(p::AbstractString, e::Integer, extrainfo) = new(p, e, extrainfo) SystemError(p::AbstractString, e::Integer) = new(p, e, nothing) - SystemError(p::AbstractString) = new(p, Libc.errno()) + SystemError(p::AbstractString) = new(p, Libc.errno(), nothing) end lock(::IO) = nothing diff --git a/base/loading.jl b/base/loading.jl index e15e07221640d..ce01a969f2fb2 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -1571,7 +1571,8 @@ function srctext_files(f::IO, srctextpos::Int64) end # Test to see if this UUID is mentioned in this `Project.toml`; either as -# the top-level UUID (e.g. that of the project itself) or as a dependency. +# the top-level UUID (e.g. that of the project itself), as a dependency, +# or as a extra for Preferences. function get_uuid_name(project::Dict{String, Any}, uuid::UUID) uuid_p = get(project, "uuid", nothing)::Union{Nothing, String} name = get(project, "name", nothing)::Union{Nothing, String} @@ -1586,6 +1587,16 @@ function get_uuid_name(project::Dict{String, Any}, uuid::UUID) end end end + for subkey in ("deps", "extras") + subsection = get(project, subkey, nothing)::Union{Nothing, Dict{String, Any}} + if subsection !== nothing + for (k, v) in subsection + if uuid == UUID(v::String) + return k + end + end + end + end return nothing end diff --git a/base/process.jl b/base/process.jl index 0c7db8a405d20..43e9a44ec338e 100644 --- a/base/process.jl +++ b/base/process.jl @@ -389,13 +389,26 @@ Returns the value returned by `f`. """ function open(f::Function, cmds::AbstractCmd, args...; kwargs...) P = open(cmds, args...; kwargs...) + function waitkill(P::Process) + close(P) + # 0.1 seconds after we hope it dies (from closing stdio), + # we kill the process with SIGTERM (15) + local t = Timer(0.1) do t + process_running(P) && kill(P) + end + wait(P) + close(t) + end ret = try f(P) catch - kill(P) + waitkill(P) rethrow() - finally - close(P.in) + end + close(P.in) + if !eof(P.out) + waitkill(P) + throw(_UVError("open(do)", UV_EPIPE)) end success(P) || pipeline_error(P) return ret diff --git a/base/sort.jl b/base/sort.jl index a5d899feb6955..20e601e412812 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -651,6 +651,8 @@ end defalg(v::AbstractArray) = DEFAULT_STABLE defalg(v::AbstractArray{<:Union{Number, Missing}}) = DEFAULT_UNSTABLE +defalg(v::AbstractArray{Missing}) = DEFAULT_UNSTABLE +defalg(v::AbstractArray{Union{}}) = DEFAULT_UNSTABLE function sort!(v::AbstractVector, alg::Algorithm, order::Ordering) inds = axes(v,1) diff --git a/base/util.jl b/base/util.jl index 9abdb39da03c3..b42ad0e219b98 100644 --- a/base/util.jl +++ b/base/util.jl @@ -571,6 +571,9 @@ function runtests(tests = ["all"]; ncores::Int = ceil(Int, Sys.CPU_THREADS::Int seed !== nothing && push!(tests, "--seed=0x$(string(seed % UInt128, base=16))") # cast to UInt128 to avoid a minus sign ENV2 = copy(ENV) ENV2["JULIA_CPU_THREADS"] = "$ncores" + delete!(ENV2, "JULIA_LOAD_PATH") + delete!(ENV2, "JULIA_PROJECT") + ENV2["JULIA_DEPOT_PATH"] = mktempdir(; cleanup = true) try run(setenv(`$(julia_cmd()) $(joinpath(Sys.BINDIR::String, Base.DATAROOTDIR, "julia", "test", "runtests.jl")) $tests`, ENV2)) diff --git a/contrib/generate_precompile.jl b/contrib/generate_precompile.jl index 28be1a992efda..81f594cc91add 100644 --- a/contrib/generate_precompile.jl +++ b/contrib/generate_precompile.jl @@ -178,6 +178,11 @@ if Test !== nothing """ end +const JULIA_PROMPT = "julia> " +const PKG_PROMPT = "pkg> " +const SHELL_PROMPT = "shell> " +const HELP_PROMPT = "help?> " + function generate_precompile_statements() start_time = time_ns() debug_output = devnull # or stdout @@ -261,7 +266,7 @@ function generate_precompile_statements() end end # wait for the definitive prompt before start writing to the TTY - readuntil(output_copy, "julia>") + readuntil(output_copy, JULIA_PROMPT) sleep(0.1) readavailable(output_copy) # Input our script @@ -279,9 +284,16 @@ function generate_precompile_statements() write(ptm, l, "\n") readuntil(output_copy, "\n") # wait for the next prompt-like to appear - # NOTE: this is rather inaccurate because the Pkg REPL mode is a special flower readuntil(output_copy, "\n") - readuntil(output_copy, "> ") + strbuf = "" + while true + strbuf *= String(readavailable(output_copy)) + occursin(JULIA_PROMPT, strbuf) && break + occursin(PKG_PROMPT, strbuf) && break + occursin(SHELL_PROMPT, strbuf) && break + occursin(HELP_PROMPT, strbuf) && break + sleep(0.1) + end end println() end @@ -344,6 +356,7 @@ generate_precompile_statements() # As a last step in system image generation, # remove some references to build time environment for a more reproducible build. +Base.Filesystem.temp_cleanup_purge(force=true) @eval Base PROGRAM_FILE = "" @eval Sys begin BINDIR = "" diff --git a/contrib/new-stdlib.sh b/contrib/new-stdlib.sh index 323dc11271da6..15f82cffb1c46 100755 --- a/contrib/new-stdlib.sh +++ b/contrib/new-stdlib.sh @@ -50,14 +50,14 @@ UNAME=$(echo "$NAME" | tr [a-z] [A-Z]) sed -e "/^STDLIBS_EXT =/,/^\$/s!^\$!\\ STDLIBS_EXT += $NAME\\ -${UNAME}_GIT_URL := git://github.com/$USER/$NAME.jl.git\\ -${UNAME}_TAR_URL = https://api.github.com/repos/$USER/$NAME.jl/tarball/\$1\\ !" "$ROOT/Makefile" >"$ROOT/Makefile.tmp" mv "$ROOT/Makefile.tmp" "$ROOT/Makefile" cat >"$ROOT/$NAME.version" < { unmap_page((void*)block.wr_ptr, block.total); } else { - protect_page((void*)block.wr_ptr, block.total, Prot::RO); + protect_page((void*)block.wr_ptr, block.total, Prot::NO); block.state = SplitPtrBlock::WRInit; } } diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index cc7993390e0ee..4f6aa1dd8d9b1 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -131,6 +131,8 @@ static void create_PRUNTIME_FUNCTION(uint8_t *Code, size_t Size, StringRef fnnam tbl->BeginAddress = (DWORD)(Code - Section); tbl->EndAddress = (DWORD)(Code - Section + Size); tbl->UnwindData = (DWORD)(UnwindData - Section); + assert(Code >= Section && Code + Size <= Section + Allocated); + assert(UnwindData >= Section && UnwindData <= Section + Allocated); #else // defined(_CPU_X86_64_) Section += (uintptr_t)Code; mod_size = Size; @@ -321,24 +323,18 @@ class JuliaJITEventListener: public JITEventListener uint8_t *catchjmp = NULL; for (const object::SymbolRef &sym_iter : debugObj.symbols()) { StringRef sName = cantFail(sym_iter.getName()); - uint8_t **pAddr = NULL; - if (sName.equals("__UnwindData")) { - pAddr = &UnwindData; - } - else if (sName.equals("__catchjmp")) { - pAddr = &catchjmp; - } - if (pAddr) { + if (sName.equals("__UnwindData") || sName.equals("__catchjmp")) { uint64_t Addr = cantFail(sym_iter.getAddress()); auto Section = cantFail(sym_iter.getSection()); assert(Section != EndSection && Section->isText()); uint64_t SectionAddr = Section->getAddress(); #if JL_LLVM_VERSION >= 100000 - sName = cantFail(Section->getName()); + StringRef secName = cantFail(Section->getName()); #else - Section->getName(sName); + StringRef secName; + Section->getName(secName); #endif - uint64_t SectionLoadAddr = getLoadAddress(sName); + uint64_t SectionLoadAddr = getLoadAddress(secName); assert(SectionLoadAddr); if (SectionAddrCheck) // assert that all of the Sections are at the same location assert(SectionAddrCheck == SectionAddr && @@ -350,7 +346,12 @@ class JuliaJITEventListener: public JITEventListener SectionWriteCheck = (uintptr_t)lookupWriteAddressFor(memmgr, (void*)SectionLoadAddr); Addr += SectionWriteCheck - SectionLoadAddr; - *pAddr = (uint8_t*)Addr; + if (sName.equals("__UnwindData")) { + UnwindData = (uint8_t*)Addr; + } + else if (sName.equals("__catchjmp")) { + catchjmp = (uint8_t*)Addr; + } } } assert(catchjmp); @@ -373,6 +374,7 @@ class JuliaJITEventListener: public JITEventListener UnwindData[6] = 1; // first instruction UnwindData[7] = 0x50; // push RBP *(DWORD*)&UnwindData[8] = (DWORD)(catchjmp - (uint8_t*)SectionWriteCheck); // relative location of catchjmp + UnwindData -= SectionWriteCheck - SectionLoadCheck; #endif // defined(_OS_X86_64_) #endif // defined(_OS_WINDOWS_) @@ -1106,6 +1108,14 @@ bool jl_dylib_DI_for_fptr(size_t pointer, object::SectionRef *Section, int64_t * struct link_map *extra_info; dladdr_success = dladdr1((void*)pointer, &dlinfo, (void**)&extra_info, RTLD_DL_LINKMAP) != 0; #else +#ifdef _OS_DARWIN_ + // On macOS 12, dladdr(-1, …) succeeds and returns the main executable image, + // despite there never actually being an image there. This is not what we want, + // as we use -1 as a known-invalid value e.g. in the test suite. + if (pointer == ~(size_t)0) { + return false; + } +#endif dladdr_success = dladdr((void*)pointer, &dlinfo) != 0; #endif if (!dladdr_success || !dlinfo.dli_fname) @@ -1152,6 +1162,7 @@ static int jl_getDylibFunctionInfo(jl_frame_t **frames, size_t pointer, int skip static IMAGEHLP_LINE64 frame_info_line; DWORD dwDisplacement = 0; JL_LOCK_NOGC(&jl_in_stackwalk); + jl_refresh_dbg_module_list(); DWORD64 dwAddress = pointer; frame_info_line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); if (SymGetLineFromAddr64(GetCurrentProcess(), dwAddress, &dwDisplacement, &frame_info_line)) { diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 48b175680c535..0cc74a54894af 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -120,6 +120,10 @@ ;; inside ref only replace within the first argument (list* 'ref (replace-beginend (cadr ex) a n tuples last) (cddr ex))) + ;; TODO: this probably should not be allowed since keyword args aren't + ;; positional, but in this context we have just used their positions anyway + ((eq? (car ex) 'kw) + (list 'kw (cadr ex) (replace-beginend (caddr ex) a n tuples last))) (else (cons (car ex) (map (lambda (x) (replace-beginend x a n tuples last)) @@ -130,31 +134,33 @@ ;; returns (values index-list stmts) where stmts are statements that need ;; to execute first. (define (process-indices a i) - (let loop ((lst i) - (n 1) - (stmts '()) - (tuples '()) - (ret '())) - (if (null? lst) - (values (reverse ret) (reverse stmts)) - (let ((idx (car lst)) - (last (null? (cdr lst)))) - (if (and (pair? idx) (eq? (car idx) '...)) - (if (symbol-like? (cadr idx)) - (loop (cdr lst) (+ n 1) - stmts - (cons (cadr idx) tuples) - (cons `(... ,(replace-beginend (cadr idx) a n tuples last)) - ret)) - (let ((g (make-ssavalue))) - (loop (cdr lst) (+ n 1) - (cons `(= ,g ,(replace-beginend (cadr idx) a n tuples last)) - stmts) - (cons g tuples) - (cons `(... ,g) ret)))) - (loop (cdr lst) (+ n 1) - stmts tuples - (cons (replace-beginend idx a n tuples last) ret))))))) + (let ((has-va? (any vararg? i))) + (let loop ((lst i) + (n 1) + (stmts '()) + (tuples '()) + (ret '())) + (if (null? lst) + (values (reverse ret) (reverse stmts)) + (let* ((idx0 (car lst)) + (idx (if (vararg? idx0) (cadr idx0) idx0)) + (last (null? (cdr lst))) + (replaced (replace-beginend idx a n tuples last)) + (val (if (kwarg? replaced) (caddr replaced) replaced)) + (idx (if (or (not has-va?) (simple-atom? val)) + val (make-ssavalue)))) + (loop (cdr lst) (+ n 1) + (if (eq? idx val) + stmts + (cons `(= ,idx ,val) + stmts)) + (if (vararg? idx0) (cons idx tuples) tuples) + (cons (if (vararg? idx0) + `(... ,idx) + (if (eq? val replaced) + idx + (list 'kw (cadr replaced) idx))) + ret))))))) ;; GF method does not need to keep decl expressions on lambda args ;; except for rest arg diff --git a/src/llvm-multiversioning.cpp b/src/llvm-multiversioning.cpp index 68081eb53d3a5..3fcd241c14088 100644 --- a/src/llvm-multiversioning.cpp +++ b/src/llvm-multiversioning.cpp @@ -992,7 +992,7 @@ void CloneCtx::emit_metadata() idxs.push_back(baseidx); for (uint32_t j = 0; j < nfvars; j++) { auto base_f = grp->base_func(fvars[j]); - if (shared_relocs.count(j)) { + if (shared_relocs.count(j) || tgt->relocs.count(j)) { count++; idxs.push_back(jl_sysimg_tag_mask | j); auto f = map_get(*tgt->vmap, base_f, base_f); @@ -1000,7 +1000,7 @@ void CloneCtx::emit_metadata() } else if (auto f = map_get(*tgt->vmap, base_f)) { count++; - idxs.push_back(tgt->relocs.count(j) ? (jl_sysimg_tag_mask | j) : j); + idxs.push_back(j); offsets.push_back(get_ptrdiff32(cast(f), fbase)); } } diff --git a/src/llvm-remove-addrspaces.cpp b/src/llvm-remove-addrspaces.cpp index de5633b905762..258e96f717603 100644 --- a/src/llvm-remove-addrspaces.cpp +++ b/src/llvm-remove-addrspaces.cpp @@ -112,10 +112,9 @@ class AddrspaceRemoveTypeRemapper : public ValueMapTypeRemapper { } private: - static DenseMap MappedTypes; + DenseMap MappedTypes; }; -DenseMap AddrspaceRemoveTypeRemapper::MappedTypes; class AddrspaceRemoveValueMaterializer : public ValueMaterializer { ValueToValueMapTy &VM; diff --git a/src/macroexpand.scm b/src/macroexpand.scm index f1302e57cc4c8..8a42b26fa79a1 100644 --- a/src/macroexpand.scm +++ b/src/macroexpand.scm @@ -271,9 +271,7 @@ (define (other x) (resolve-expansion-vars-with-new-env x env m parent-scope inarg)) (case (car e) ((where) `(where ,(recur (cadr e)) ,@(map other (cddr e)))) - ((|::|) (if (length= e 2) - `(|::| ,(other (cadr e))) - `(|::| ,(recur (cadr e)) ,(other (caddr e))))) + ((|::|) `(|::| ,(recur (cadr e)) ,(other (caddr e)))) ((call) `(call ,(other (cadr e)) ,@(map (lambda (x) (resolve-expansion-vars-with-new-env x env m parent-scope #t)) @@ -457,14 +455,16 @@ ;; decl-var that also identifies f in f()=... (define (decl-var* e) - (cond ((not (pair? e)) e) - ((eq? (car e) 'escape) '()) - ((eq? (car e) 'call) (decl-var* (cadr e))) - ((eq? (car e) '=) (decl-var* (cadr e))) - ((eq? (car e) 'curly) (decl-var* (cadr e))) - ((eq? (car e) '|::|) (decl-var* (cadr e))) - ((eq? (car e) 'where) (decl-var* (cadr e))) - (else (decl-var e)))) + (if (pair? e) + (case (car e) + ((escape) '()) + ((call) (decl-var* (cadr e))) + ((=) (decl-var* (cadr e))) + ((curly) (decl-var* (cadr e))) + ((|::|) (if (length= e 2) '() (decl-var* (cadr e)))) + ((where) (decl-var* (cadr e))) + (else (decl-var e))) + e)) (define (decl-vars* e) (if (and (pair? e) (eq? (car e) 'tuple)) diff --git a/src/module.c b/src/module.c index 15624373d921f..e3b333bd142a5 100644 --- a/src/module.c +++ b/src/module.c @@ -485,7 +485,7 @@ static void module_import_(jl_module_t *to, jl_module_t *from, jl_sym_t *s, jl_s } } else { - jl_binding_t *nb = new_binding(s); + jl_binding_t *nb = new_binding(b->name); nb->owner = b->owner; nb->imported = (explici!=0); nb->deprecated = b->deprecated; diff --git a/src/support/win32_ucontext.c b/src/support/win32_ucontext.c index df50eb209341e..c67bcdf642e4d 100644 --- a/src/support/win32_ucontext.c +++ b/src/support/win32_ucontext.c @@ -73,7 +73,7 @@ void jl_makecontext(win32_ucontext_t *ucp, void (*func)(void)) jmpbuf->Rip = (unsigned long long)func; jmpbuf->Rsp = (unsigned long long)stack_top; jmpbuf->Rbp = 0; - jmpbuf->Frame = 0; // SEH frame + jmpbuf->Frame = ~(uint64_t)0; // SEH frame #elif defined(_CPU_X86_) jmpbuf->Eip = (unsigned long)func; jmpbuf->Esp = (unsigned long)stack_top; diff --git a/stdlib/ArgTools.version b/stdlib/ArgTools.version index c9026ce76af7b..69f6363d87089 100644 --- a/stdlib/ArgTools.version +++ b/stdlib/ArgTools.version @@ -1,2 +1,4 @@ ARGTOOLS_BRANCH = master ARGTOOLS_SHA1 = fa878696ff2ae4ba7ca9942bf9544556c0d86ce4 +ARGTOOLS_GIT_URL := https://github.com/JuliaIO/ArgTools.jl.git +ARGTOOLS_TAR_URL = https://api.github.com/repos/JuliaIO/ArgTools.jl/tarball/$1 diff --git a/stdlib/Dates/src/io.jl b/stdlib/Dates/src/io.jl index 721e36deef7a8..f6fa4e8311f4f 100644 --- a/stdlib/Dates/src/io.jl +++ b/stdlib/Dates/src/io.jl @@ -150,7 +150,7 @@ struct Decimal3 end len = ii - i if len > 3 ms, r = divrem(ms0, Int64(10) ^ (len - 3)) - r == 0 || throw(InexactError(:convert, Decimal3, ms0)) + r == 0 || return nothing else ms = ms0 * Int64(10) ^ (3 - len) end @@ -332,6 +332,23 @@ const CONVERSION_TRANSLATIONS = IdDict{Type, Any}( Time => (Hour, Minute, Second, Millisecond, Microsecond, Nanosecond, AMPM), ) +# The `DateFormat(format, locale)` method just below consumes the following Regex. +# Constructing this Regex is fairly expensive; doing so in the method itself can +# consume half or better of `DateFormat(format, locale)`'s runtime. So instead we +# construct and cache it outside the method body. Note, however, that when +# `keys(CONVERSION_SPECIFIERS)` changes, the cached Regex must be updated accordingly; +# hence the mutability (Ref-ness) of the cache, the helper method with which to populate +# the cache, the cache of the hash of `keys(CONVERSION_SPECIFIERS)` (to facilitate checking +# for changes), and the lock (to maintain consistency of these objects across threads when +# threads simultaneously modify `CONVERSION_SPECIFIERS` and construct `DateFormat`s). +function compute_dateformat_regex(conversion_specifiers) + letters = String(collect(keys(conversion_specifiers))) + return Regex("(? DateFormat @@ -378,8 +395,20 @@ function DateFormat(f::AbstractString, locale::DateLocale=ENGLISH) prev = () prev_offset = 1 - letters = String(collect(keys(CONVERSION_SPECIFIERS))) - for m in eachmatch(Regex("(? s"\1") if !isempty(prev) diff --git a/stdlib/Dates/test/io.jl b/stdlib/Dates/test/io.jl index d82dac88276cb..04d2bd99364e2 100644 --- a/stdlib/Dates/test/io.jl +++ b/stdlib/Dates/test/io.jl @@ -456,13 +456,17 @@ end # Issue #21504 @test tryparse(Dates.Date, "0-1000") === nothing +# Issue #44003 +@test tryparse(Dates.Date, "2017", Dates.DateFormat(".s")) === nothing + @testset "parse milliseconds, Issue #22100" begin @test Dates.DateTime("2017-Mar-17 00:00:00.0000", "y-u-d H:M:S.s") == Dates.DateTime(2017, 3, 17) @test Dates.parse_components(".1", Dates.DateFormat(".s")) == [Dates.Millisecond(100)] @test Dates.parse_components(".12", Dates.DateFormat(".s")) == [Dates.Millisecond(120)] @test Dates.parse_components(".123", Dates.DateFormat(".s")) == [Dates.Millisecond(123)] @test Dates.parse_components(".1230", Dates.DateFormat(".s")) == [Dates.Millisecond(123)] - @test_throws InexactError Dates.parse_components(".1234", Dates.DateFormat(".s")) + # Issue #44003 + @test_throws ArgumentError Dates.parse_components(".1234", Dates.DateFormat(".s")) # Ensure that no overflow occurs when using Int32 literals: Int32(10)^10 @test Dates.parse_components("." * rpad(999, 10, '0'), Dates.DateFormat(".s")) == [Dates.Millisecond(999)] diff --git a/stdlib/Downloads.version b/stdlib/Downloads.version index cf98e7d23214d..9c9c4f085a045 100644 --- a/stdlib/Downloads.version +++ b/stdlib/Downloads.version @@ -1,2 +1,4 @@ DOWNLOADS_BRANCH = release-1.4 DOWNLOADS_SHA1 = b07b4cf3b20b77faa7efbe29c0adfa8b4b7ee8d8 +DOWNLOADS_GIT_URL := https://github.com/JuliaLang/Downloads.jl.git +DOWNLOADS_TAR_URL = https://api.github.com/repos/JuliaLang/Downloads.jl/tarball/$1 diff --git a/stdlib/LibCURL.version b/stdlib/LibCURL.version index aa3dc34719df9..c3bc8cb29f30c 100644 --- a/stdlib/LibCURL.version +++ b/stdlib/LibCURL.version @@ -1,2 +1,4 @@ LIBCURL_BRANCH = master LIBCURL_SHA1 = 8310487053915d5c995513f569ad85ba65c3544f +LIBCURL_GIT_URL := https://github.com/JuliaWeb/LibCURL.jl.git +LIBCURL_TAR_URL = https://api.github.com/repos/JuliaWeb/LibCURL.jl/tarball/$1 diff --git a/stdlib/LinearAlgebra/src/triangular.jl b/stdlib/LinearAlgebra/src/triangular.jl index 7e9decef21b29..52612f0d3fbd2 100644 --- a/stdlib/LinearAlgebra/src/triangular.jl +++ b/stdlib/LinearAlgebra/src/triangular.jl @@ -1486,7 +1486,7 @@ end function ldiv!(xA::Union{UpperTriangular,UnitUpperTriangular}, B::UpperTriangular) return UpperTriangular(ldiv!(xA, triu!(B.data))) end -function ldiv!(xA::Union{LowerTriangular,UnitLowerTriangular}, B::UpperTriangular) +function ldiv!(xA::Union{LowerTriangular,UnitLowerTriangular}, B::LowerTriangular) return LowerTriangular(ldiv!(xA, tril!(B.data))) end diff --git a/stdlib/LinearAlgebra/test/triangular.jl b/stdlib/LinearAlgebra/test/triangular.jl index 81b1f986460ba..4b253fa9d4f2f 100644 --- a/stdlib/LinearAlgebra/test/triangular.jl +++ b/stdlib/LinearAlgebra/test/triangular.jl @@ -376,7 +376,8 @@ for elty1 in (Float32, Float64, BigFloat, ComplexF32, ComplexF64, Complex{BigFlo @test_throws DimensionMismatch A2' * offsizeA @test_throws DimensionMismatch A2 * offsizeA if (uplo1 == uplo2 && elty1 == elty2 != Int && t1 != UnitLowerTriangular && t1 != UnitUpperTriangular) - @test rdiv!(copy(A1), copy(A2)) ≈ A1/A2 ≈ Matrix(A1)/Matrix(A2) + @test rdiv!(copy(A1), copy(A2))::t1 ≈ A1/A2 ≈ Matrix(A1)/Matrix(A2) + @test ldiv!(copy(A2), copy(A1))::t1 ≈ A2\A1 ≈ Matrix(A2)\Matrix(A1) end if (uplo1 != uplo2 && elty1 == elty2 != Int && t2 != UnitLowerTriangular && t2 != UnitUpperTriangular) @test lmul!(adjoint(copy(A1)), copy(A2)) ≈ A1'*A2 ≈ Matrix(A1)'*Matrix(A2) diff --git a/stdlib/Makefile b/stdlib/Makefile index 490d67a13e936..cf006cefb367f 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -45,20 +45,6 @@ STDLIBS = Artifacts Base64 CRC32c Dates DelimitedFiles Distributed FileWatching $(JLL_NAMES) STDLIBS_EXT = Pkg Statistics LibCURL Downloads ArgTools Tar NetworkOptions -PKG_GIT_URL := git://github.com/JuliaLang/Pkg.jl.git -PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 -STATISTICS_GIT_URL := git://github.com/JuliaLang/Statistics.jl.git -STATISTICS_TAR_URL = https://api.github.com/repos/JuliaLang/Statistics.jl/tarball/$1 -LIBCURL_GIT_URL := git://github.com/JuliaWeb/LibCURL.jl.git -LIBCURL_TAR_URL = https://api.github.com/repos/JuliaWeb/LibCURL.jl/tarball/$1 -DOWNLOADS_GIT_URL := git://github.com/JuliaLang/Downloads.jl.git -DOWNLOADS_TAR_URL = https://api.github.com/repos/JuliaLang/Downloads.jl/tarball/$1 -ARGTOOLS_GIT_URL := git://github.com/JuliaIO/ArgTools.jl.git -ARGTOOLS_TAR_URL = https://api.github.com/repos/JuliaIO/ArgTools.jl/tarball/$1 -TAR_GIT_URL := git://github.com/JuliaIO/Tar.jl.git -TAR_TAR_URL = https://api.github.com/repos/JuliaIO/Tar.jl/tarball/$1 -NETWORKOPTIONS_GIT_URL := git://github.com/JuliaLang/NetworkOptions.jl.git -NETWORKOPTIONS_TAR_URL = https://api.github.com/repos/JuliaLang/NetworkOptions.jl/tarball/$1 $(foreach module, $(STDLIBS_EXT), $(eval $(call stdlib-external,$(module),$(shell echo $(module) | tr a-z A-Z)))) diff --git a/stdlib/NetworkOptions.version b/stdlib/NetworkOptions.version index b8e8b3d371c38..5fc9d5de0db9f 100644 --- a/stdlib/NetworkOptions.version +++ b/stdlib/NetworkOptions.version @@ -1,2 +1,4 @@ NETWORKOPTIONS_BRANCH = master NETWORKOPTIONS_SHA1 = a251de1e1c8ce4edc351d0f05233ba7fe7d2c27a +NETWORKOPTIONS_GIT_URL := https://github.com/JuliaLang/NetworkOptions.jl.git +NETWORKOPTIONS_TAR_URL = https://api.github.com/repos/JuliaLang/NetworkOptions.jl/tarball/$1 diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 9c86baca41097..9a4b56c59ef4a 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,2 +1,4 @@ PKG_BRANCH = release-1.6 -PKG_SHA1 = 3d41ca188d72e1dc1862e780f31153d629d6a3dd +PKG_SHA1 = 30a31381d06d845999314d39005ee8457bd08924 +PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git +PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 diff --git a/stdlib/Sockets/src/Sockets.jl b/stdlib/Sockets/src/Sockets.jl index 99dab5e61e01e..1e5b90cdda390 100644 --- a/stdlib/Sockets/src/Sockets.jl +++ b/stdlib/Sockets/src/Sockets.jl @@ -806,6 +806,7 @@ socket is connected to. Valid only for connected TCP sockets. getpeername(sock::TCPSocket) = _sockname(sock, false) function _sockname(sock, self=true) + sock.status == StatusInit || check_open(sock) rport = Ref{Cushort}(0) raddress = zeros(UInt8, 16) rfamily = Ref{Cuint}(0) diff --git a/stdlib/SparseArrays/src/sparsematrix.jl b/stdlib/SparseArrays/src/sparsematrix.jl index db2a06361642f..e7da7377bc631 100644 --- a/stdlib/SparseArrays/src/sparsematrix.jl +++ b/stdlib/SparseArrays/src/sparsematrix.jl @@ -2787,6 +2787,7 @@ end # Nonscalar A[I,J] = B: Convert B to a SparseMatrixCSC of the appropriate shape first _to_same_csc(::AbstractSparseMatrixCSC{Tv, Ti}, V::AbstractMatrix, I...) where {Tv,Ti} = convert(SparseMatrixCSC{Tv,Ti}, V) +_to_same_csc(::AbstractSparseMatrixCSC{Tv, Ti}, V::AbstractMatrix, i::Integer, J) where {Tv,Ti} = convert(SparseMatrixCSC{Tv,Ti}, reshape(V, (1, length(J)))) _to_same_csc(::AbstractSparseMatrixCSC{Tv, Ti}, V::AbstractVector, I...) where {Tv,Ti} = convert(SparseMatrixCSC{Tv,Ti}, reshape(V, map(length, I))) setindex!(A::AbstractSparseMatrixCSC{Tv}, B::AbstractVecOrMat, I::Integer, J::Integer) where {Tv} = _setindex_scalar!(A, B, I, J) @@ -2795,12 +2796,20 @@ function setindex!(A::AbstractSparseMatrixCSC{Tv,Ti}, V::AbstractVecOrMat, Ix::U require_one_based_indexing(A, V, Ix, Jx) (I, J) = Base.ensure_indexable(to_indices(A, (Ix, Jx))) checkbounds(A, I, J) - Base.setindex_shape_check(V, length(I), length(J)) + nJ = length(J) + Base.setindex_shape_check(V, length(I), nJ) B = _to_same_csc(A, V, I, J) + m, n = size(A) + if (!isempty(I) && (I[1] < 1 || I[end] > m)) || (!isempty(J) && (J[1] < 1 || J[end] > n)) + throw(BoundsError(A, (I, J))) + end + if isempty(I) || isempty(J) + return A + end + issortedI = issorted(I) issortedJ = issorted(J) - if !issortedI && !issortedJ pI = sortperm(I); @inbounds I = I[pI] pJ = sortperm(J); @inbounds J = J[pJ] @@ -2813,20 +2822,6 @@ function setindex!(A::AbstractSparseMatrixCSC{Tv,Ti}, V::AbstractVecOrMat, Ix::U B = B[:, pJ] end - m, n = size(A) - mB, nB = size(B) - - if (!isempty(I) && (I[1] < 1 || I[end] > m)) || (!isempty(J) && (J[1] < 1 || J[end] > n)) - throw(BoundsError(A, (I, J))) - end - - if isempty(I) || isempty(J) - return A - end - - nI = length(I) - nJ = length(J) - colptrA = getcolptr(A); rowvalA = rowvals(A); nzvalA = nonzeros(A) colptrB = getcolptr(B); rowvalB = rowvals(B); nzvalB = nonzeros(B) @@ -2840,7 +2835,6 @@ function setindex!(A::AbstractSparseMatrixCSC{Tv,Ti}, V::AbstractVecOrMat, Ix::U resize!(nzvalA, nnzS) colB = 1 - asgn_col = J[colB] I_asgn = falses(m) fill!(view(I_asgn, I), true) diff --git a/stdlib/Statistics.version b/stdlib/Statistics.version index 50d261cc008b0..a0815d3274a63 100644 --- a/stdlib/Statistics.version +++ b/stdlib/Statistics.version @@ -1,2 +1,4 @@ STATISTICS_BRANCH = master STATISTICS_SHA1 = 4b3ef9aaa79350510ca0be395458f66051c2f92d +STATISTICS_GIT_URL := https://github.com/JuliaLang/Statistics.jl.git +STATISTICS_TAR_URL = https://api.github.com/repos/JuliaLang/Statistics.jl/tarball/$1 diff --git a/stdlib/Tar.version b/stdlib/Tar.version index fcaae523b87bd..cab36df8a31bd 100644 --- a/stdlib/Tar.version +++ b/stdlib/Tar.version @@ -1,2 +1,4 @@ TAR_BRANCH = release-1.9 TAR_SHA1 = 2c86131a240bf06b9d4fa4bd813d66ea4bb1d7ae +TAR_GIT_URL := https://github.com/JuliaIO/Tar.jl.git +TAR_TAR_URL = https://api.github.com/repos/JuliaIO/Tar.jl/tarball/$1 diff --git a/test/Makefile b/test/Makefile index 9ca65ffa9d7c7..2541cd3048634 100644 --- a/test/Makefile +++ b/test/Makefile @@ -7,7 +7,7 @@ STDLIBDIR := $(build_datarootdir)/julia/stdlib/$(VERSDIR) # TODO: this Makefile ignores BUILDDIR, except for computing JULIA_EXECUTABLE TESTGROUPS = unicode strings compiler -TESTS = all stdlib $(TESTGROUPS) \ +TESTS = all default stdlib $(TESTGROUPS) \ $(patsubst $(STDLIBDIR)/%/,%,$(dir $(wildcard $(STDLIBDIR)/*/.))) \ $(filter-out runtests testdefs, \ $(patsubst $(SRCDIR)/%.jl,%,$(wildcard $(SRCDIR)/*.jl))) \ @@ -19,7 +19,7 @@ EMBEDDING_ARGS := "JULIA=$(JULIA_EXECUTABLE)" "BIN=$(SRCDIR)/embedding" "CC=$(CC GCEXT_ARGS := "JULIA=$(JULIA_EXECUTABLE)" "BIN=$(SRCDIR)/gcext" "CC=$(CC)" -default: all +default: $(TESTS): @cd $(SRCDIR) && \ diff --git a/test/arrayops.jl b/test/arrayops.jl index 05a46cf5cf8e1..e22f073f00ada 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -2876,3 +2876,18 @@ end @test [fill(1); fill(2, (2,1,1))] == reshape([1; 2; 2], (3, 1, 1)) @test_throws DimensionMismatch [fill(1); rand(2, 2, 2)] end + +@testset "Allow assignment of singleton array to sparse array #43644" begin + K = spzeros(3,3) + b = zeros(3,3) + b[3,:] = [1,2,3] + K[3,1:3] += [1.0 2.0 3.0]' + @test K == b + K[3:3,1:3] += zeros(1, 3) + @test K == b + K[3,1:3] += zeros(3) + @test K == b + K[3,:] += zeros(3,1) + @test K == b + @test_throws DimensionMismatch K[3,1:2] += [1.0 2.0 3.0]' +end diff --git a/test/choosetests.jl b/test/choosetests.jl index 40c4cfcd54eb1..f67b45cfff3f4 100644 --- a/test/choosetests.jl +++ b/test/choosetests.jl @@ -93,7 +93,7 @@ function choosetests(choices = []) --seed= : set the initial seed for all testgroups (parsed as a UInt128) --skip ... : skip test or collection tagged with TESTS: - Can be special tokens, such as "all", "unicode", "stdlib", the names of stdlib modules, or the names of any file in the TESTNAMES array (defaults to "all"). + Can be special tokens, such as "all", "unicode", "stdlib", the names of stdlib modules, or the names of any file in the testnames array (defaults to "all"). Or prefix a name with `-` (such as `-core`) to skip a particular test. """) @@ -109,9 +109,13 @@ function choosetests(choices = []) unhandled = copy(skip_tests) - if tests == ["all"] || isempty(tests) - tests = testnames + requested_all = "all" in tests + requested_default = "default" in tests + if isempty(tests) || requested_all || requested_default + append!(tests, testnames) end + filter!(x -> x != "all", tests) + filter!(x -> x != "default", tests) function filtertests!(tests, name, files=[name]) flt = x -> (x != name && !(x in files)) @@ -124,7 +128,7 @@ function choosetests(choices = []) end end - explicit_pkg3 = "Pkg" in tests + explicit_pkg = "Pkg" in tests explicit_libgit2 = "LibGit2/online" in tests filtertests!(tests, "unicode", ["unicode/utf8"]) @@ -187,8 +191,9 @@ function choosetests(choices = []) end filter!(x -> (x != "stdlib" && !(x in STDLIBS)) , tests) append!(tests, new_tests) - explicit_pkg3 || filter!(x -> x != "Pkg", tests) - explicit_libgit2 || filter!(x -> x != "LibGit2/online", tests) + + requested_all || explicit_pkg || filter!(x -> x != "Pkg", tests) + requested_all || explicit_libgit2 || filter!(x -> x != "LibGit2/online", tests) # Filter out tests from the test groups in the stdlibs filter!(!in(tests), unhandled) diff --git a/test/core.jl b/test/core.jl index 69261e30504a8..3424cdbdb418c 100644 --- a/test/core.jl +++ b/test/core.jl @@ -1441,6 +1441,12 @@ let @test invoke(i2169, Tuple{Array}, Int8[1]) === Int8(-128) end +# issue #44227 +struct F{T} end +F{Int32}(; y=1) = 1 +F{Int64}(; y=1) = invoke(F{Int32}, Tuple{}; y) +@test F{Int64}() === 1 + # issue #2365 mutable struct B2365{T} v::Union{T, Nothing} diff --git a/test/dict.jl b/test/dict.jl index 5b1ac446e3215..10454ffd5d90a 100644 --- a/test/dict.jl +++ b/test/dict.jl @@ -1146,6 +1146,8 @@ end @test s === copy!(s, Base.ImmutableDict(a[])) == Dict(a[]) end end + s2 = copy(s) + @test copy!(s, s) == s2 end @testset "map!(f, values(dict))" begin diff --git a/test/error.jl b/test/error.jl index bb97a0e66ed0b..6d7e77564085d 100644 --- a/test/error.jl +++ b/test/error.jl @@ -81,3 +81,8 @@ end # non-Functions @test retry(Float64)(1) === 1.0 end + +@testset "SystemError initialization" begin + e = SystemError("fail") + @test e.extrainfo === nothing +end diff --git a/test/loading.jl b/test/loading.jl index 293a2e3d1d957..02dfb617fe35f 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -189,6 +189,42 @@ end end end +# extras +@testset "extras" begin + mktempdir() do dir + project_file = joinpath(dir, "Project.toml") + touch(project_file) # dummy_uuid calls realpath + # various UUIDs to work with + proj_uuid = dummy_uuid(project_file) + root_uuid = uuid4() + this_uuid = uuid4() + + old_load_path = copy(LOAD_PATH) + try + copy!(LOAD_PATH, [project_file]) + write(project_file, """ + name = "Root" + uuid = "$root_uuid" + [extras] + This = "$this_uuid" + """) + # look up various packages by name + root = Base.identify_package("Root") + this = Base.identify_package("This") + that = Base.identify_package("That") + + @test root.uuid == root_uuid + @test this == nothing + @test that == nothing + + @test Base.get_uuid_name(project_file, this_uuid) == "This" + finally + copy!(LOAD_PATH, old_load_path) + end + end +end + + ## functional testing of package identification, location & loading ## saved_load_path = copy(LOAD_PATH) diff --git a/test/sets.jl b/test/sets.jl index 82f2a3b0aab6f..5cb55051e2ab4 100644 --- a/test/sets.jl +++ b/test/sets.jl @@ -146,6 +146,9 @@ end @test s === copy!(s, BitSet(a)) == S(a) end end + s = Set([1, 2]) + s2 = copy(s) + @test copy!(s, s) == s2 end @testset "sizehint, empty" begin diff --git a/test/spawn.jl b/test/spawn.jl index 4f826b05df93d..74ae54af72bc1 100644 --- a/test/spawn.jl +++ b/test/spawn.jl @@ -733,6 +733,31 @@ end cmd2 = addenv(cmd, "FOO" => "foo2", "BAR" => "bar"; inherit=true) @test strip(String(read(cmd2))) == "foo2 bar" end + + @test addenv(``, ["a=b=c"], inherit=false).env == ["a=b=c"] + cmd = addenv(``, "a"=>"b=c", inherit=false) + @test cmd.env == ["a=b=c"] + cmd = addenv(cmd, "b"=>"b") + @test issetequal(cmd.env, ["b=b", "a=b=c"]) +end + +@testset "setenv with dir (with tests for #42131)" begin + dir1 = joinpath(pwd(), "dir1") + dir2 = joinpath(pwd(), "dir2") + cmd = Cmd(`julia`; dir=dir1) + @test cmd.dir == dir1 + @test Cmd(cmd).dir == dir1 + @test Cmd(cmd; dir=dir2).dir == dir2 + @test Cmd(cmd; dir="").dir == "" + @test setenv(cmd).dir == dir1 + @test setenv(cmd; dir=dir2).dir == dir2 + @test setenv(cmd; dir="").dir == "" + @test setenv(cmd, "FOO"=>"foo").dir == dir1 + @test setenv(cmd, "FOO"=>"foo"; dir=dir2).dir == dir2 + @test setenv(cmd, "FOO"=>"foo"; dir="").dir == "" + @test setenv(cmd, Dict("FOO"=>"foo")).dir == dir1 + @test setenv(cmd, Dict("FOO"=>"foo"); dir=dir2).dir == dir2 + @test setenv(cmd, Dict("FOO"=>"foo"); dir="").dir == "" end diff --git a/test/syntax.jl b/test/syntax.jl index 6823ac47ee6b7..f6ba616167f9b 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -1193,6 +1193,25 @@ end @test [(0,0)... 1] == [0 0 1] @test Float32[(0,0)... 1] == Float32[0 0 1] +# issue #43960, evaluation order of splatting in `ref` +let a = [], b = [4,3,2,1] + f() = (push!(a, 1); 2) + g() = (push!(a, 2); ()) + @test b[f(), g()...] == 3 + @test a == [1,2] +end + +# issue #44239 +struct KWGetindex end +Base.getindex(::KWGetindex, args...; kws...) = (args, NamedTuple(kws)) +let A = KWGetindex(), a = [], b = [4,3,2,1] + f() = (push!(a, 1); 2) + g() = (push!(a, 2); ()) + @test A[f(), g()..., k = f()] === ((2,), (k = 2,)) + @test a == [1, 2, 1] + @test A[var"end"=1] === ((), (var"end" = 1,)) +end + @testset "raw_str macro" begin @test raw"$" == "\$" @test raw"\n" == "\\n" @@ -2465,6 +2484,7 @@ end end module Mod2 +import ..Mod.x as x_from_mod const y = 2 end @@ -2505,6 +2525,11 @@ import .Mod.@mac as @m @test_throws ErrorException eval(:(import .Mod.func as @notmacro)) @test_throws ErrorException eval(:(using .Mod: @mac as notmacro)) @test_throws ErrorException eval(:(using .Mod: func as @notmacro)) + +import .Mod2.x_from_mod + +@test @isdefined(x_from_mod) +@test x_from_mod == Mod.x end import .TestImportAs.Mod2 as M2 @@ -2709,6 +2734,21 @@ end @eval f39705(x) = $(Expr(:||)) && x @test f39705(1) === false +# issue 25678: module of name `Core` +# https://github.com/JuliaLang/julia/pull/40778/files#r784416018 +@test @eval Module() begin + Core = 1 + @generated f() = 1 + f() == 1 +end + +# issue 25678: argument of name `tmp` +# https://github.com/JuliaLang/julia/pull/43823#discussion_r785365312 +@test @eval Module() begin + @generated f(tmp) = tmp + f(1) === Int +end + # issue 42220 macro m42220() return quote @@ -2744,3 +2784,7 @@ end @generated g25678(x) = return :x @test g25678(7) === 7 + +let ex = :(const $(esc(:x)) = 1; (::typeof(2))() = $(esc(:x))) + @test macroexpand(Main, Expr(:var"hygienic-scope", ex, Main)).args[3].args[1] == :((::$(GlobalRef(Main, :typeof))(2))()) +end