diff --git a/.buildkite-external-version b/.buildkite-external-version index ba2906d0666cf..9570137b1ef79 100644 --- a/.buildkite-external-version +++ b/.buildkite-external-version @@ -1 +1 @@ -main +release-julia-1.12 diff --git a/Compiler/src/Compiler.jl b/Compiler/src/Compiler.jl index 080cdc6f7ee0e..01f2dbe33b674 100644 --- a/Compiler/src/Compiler.jl +++ b/Compiler/src/Compiler.jl @@ -41,9 +41,8 @@ using Core: ABIOverride, Builtin, CodeInstance, IntrinsicFunction, MethodInstanc MethodTable, MethodCache, PartialOpaque, SimpleVector, TypeofVararg, _apply_iterate, apply_type, compilerbarrier, donotdelete, memoryref_isassigned, memoryrefget, memoryrefnew, memoryrefoffset, memoryrefset!, print, println, show, svec, - typename, unsafe_write, write + typename, unsafe_write, write, stdout, stderr -using Base using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospecializeinfer, PARTITION_KIND_GLOBAL, PARTITION_KIND_UNDEF_CONST, PARTITION_KIND_BACKDATED_CONST, PARTITION_KIND_DECLARED, PARTITION_FLAG_DEPWARN, @@ -64,7 +63,10 @@ using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospeciali partition_restriction, quoted, rename_unionall, rewrap_unionall, specialize_method, structdiff, tls_world_age, unconstrain_vararg_length, unionlen, uniontype_layout, uniontypes, unsafe_convert, unwrap_unionall, unwrapva, vect, widen_diagonal, - _uncompressed_ir, maybe_add_binding_backedge! + _uncompressed_ir, maybe_add_binding_backedge!, + devnull, devnull as stdin + +using Base using Base.Order import Base: ==, _topmod, append!, convert, copy, copy!, findall, first, get, get!, diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 3c4de73b4c36a..10cbca8c0c3d8 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -2488,7 +2488,7 @@ function abstract_eval_setglobal!(interp::AbstractInterpreter, sv::AbsIntState, (rt, exct) = global_assignment_rt_exct(interp, sv, saw_latestworld, gr, v) return CallMeta(rt, exct, Effects(setglobal!_effects, nothrow=exct===Bottom), GlobalAccessInfo(convert(Core.Binding, gr))) end - return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo()) + return CallMeta(Union{}, Union{TypeError, ErrorException}, EFFECTS_THROWS, NoCallInfo()) end βŠ‘ = partialorder(typeinf_lattice(interp)) if !(hasintersect(widenconst(M), Module) && hasintersect(widenconst(s), Symbol)) @@ -3444,9 +3444,13 @@ function refine_partial_type(@nospecialize t) return t end -abstract_eval_nonlinearized_foreigncall_name(interp::AbstractInterpreter, e, sstate::StatementState, sv::IRInterpretationState) = nothing +abstract_eval_nonlinearized_foreigncall_name( + ::AbstractInterpreter, @nospecialize(e), ::StatementState, ::IRInterpretationState + ) = nothing -function abstract_eval_nonlinearized_foreigncall_name(interp::AbstractInterpreter, e, sstate::StatementState, sv::AbsIntState) +function abstract_eval_nonlinearized_foreigncall_name( + interp::AbstractInterpreter, @nospecialize(e), sstate::StatementState, sv::InferenceState + ) if isexpr(e, :call) n = length(e.args) argtypes = Vector{Any}(undef, n) @@ -3728,7 +3732,7 @@ end function global_assignment_rt_exct(interp::AbstractInterpreter, sv::AbsIntState, saw_latestworld::Bool, g::GlobalRef, @nospecialize(newty)) if saw_latestworld - return Pair{Any,Any}(newty, ErrorException) + return Pair{Any,Any}(newty, Union{TypeError, ErrorException}) end newtyβ€² = RefValue{Any}(newty) (valid_worlds, ret) = scan_partitions(interp, g, sv.world) do interp::AbstractInterpreter, ::Core.Binding, partition::Core.BindingPartition @@ -3743,15 +3747,16 @@ function global_assignment_binding_rt_exct(interp::AbstractInterpreter, partitio if is_some_guard(kind) return Pair{Any,Any}(newty, ErrorException) elseif is_some_const_binding(kind) || is_some_imported(kind) - return Pair{Any,Any}(Bottom, ErrorException) + # N.B.: Backdating should not improve inference in an earlier world + return Pair{Any,Any}(kind == PARTITION_KIND_BACKDATED_CONST ? newty : Bottom, ErrorException) end ty = kind == PARTITION_KIND_DECLARED ? Any : partition_restriction(partition) wnewty = widenconst(newty) if !hasintersect(wnewty, ty) - return Pair{Any,Any}(Bottom, ErrorException) + return Pair{Any,Any}(Bottom, TypeError) elseif !(wnewty <: ty) retty = tmeet(typeinf_lattice(interp), newty, ty) - return Pair{Any,Any}(retty, ErrorException) + return Pair{Any,Any}(retty, TypeError) end return Pair{Any,Any}(newty, Bottom) end diff --git a/Compiler/src/opaque_closure.jl b/Compiler/src/opaque_closure.jl index d0a375c2a54b5..21f2640037893 100644 --- a/Compiler/src/opaque_closure.jl +++ b/Compiler/src/opaque_closure.jl @@ -48,6 +48,8 @@ function Core.OpaqueClosure(ir::IRCode, @nospecialize env...; end src.slotflags = fill(zero(UInt8), nargtypes) src.slottypes = copy(ir.argtypes) + src.min_world = ir.valid_worlds.min_world + src.max_world = ir.valid_worlds.max_world src.isva = isva src.nargs = UInt(nargtypes) src = ir_to_codeinf!(src, ir) diff --git a/Compiler/src/tfuncs.jl b/Compiler/src/tfuncs.jl index 33c866c401811..fcead89d0a151 100644 --- a/Compiler/src/tfuncs.jl +++ b/Compiler/src/tfuncs.jl @@ -586,15 +586,19 @@ add_tfunc(nfields, 1, 1, nfields_tfunc, 1) add_tfunc(Core._expr, 1, INT_INF, @nospecs((𝕃::AbstractLattice, args...)->Expr), 100) add_tfunc(svec, 0, INT_INF, @nospecs((𝕃::AbstractLattice, args...)->SimpleVector), 20) -@nospecs function _svec_len_tfunc(𝕃::AbstractLattice, s) +@nospecs function _svec_len_tfunc(::AbstractLattice, s) if isa(s, Const) && isa(s.val, SimpleVector) return Const(length(s.val)) end return Int end add_tfunc(Core._svec_len, 1, 1, _svec_len_tfunc, 1) +@nospecs function _svec_len_nothrow(𝕃::AbstractLattice, s) + βŠ‘ = partialorder(𝕃) + return s βŠ‘ SimpleVector +end -@nospecs function _svec_ref_tfunc(𝕃::AbstractLattice, s, i) +@nospecs function _svec_ref_tfunc(::AbstractLattice, s, i) if isa(s, Const) && isa(i, Const) s, i = s.val, i.val if isa(s, SimpleVector) && isa(i, Int) @@ -604,7 +608,7 @@ add_tfunc(Core._svec_len, 1, 1, _svec_len_tfunc, 1) return Any end add_tfunc(Core._svec_ref, 2, 2, _svec_ref_tfunc, 1) -@nospecs function typevar_tfunc(𝕃::AbstractLattice, n, lb_arg, ub_arg) +@nospecs function typevar_tfunc(::AbstractLattice, n, lb_arg, ub_arg) lb = Union{} ub = Any ub_certain = lb_certain = true @@ -2363,7 +2367,7 @@ function _builtin_nothrow(𝕃::AbstractLattice, @nospecialize(f::Builtin), argt return compilerbarrier_nothrow(argtypes[1], nothing) elseif f === Core._svec_len na == 1 || return false - return _svec_len_tfunc(𝕃, argtypes[1]) isa Const + return _svec_len_nothrow(𝕃, argtypes[1]) elseif f === Core._svec_ref na == 2 || return false return _svec_ref_tfunc(𝕃, argtypes[1], argtypes[2]) isa Const @@ -2974,6 +2978,13 @@ function intrinsic_exct(𝕃::AbstractLattice, f::IntrinsicFunction, argtypes::V return Union{} end + if f === Intrinsics.add_ptr || f === Intrinsics.sub_ptr + if !(argtypes[1] βŠ‘ Ptr && argtypes[2] βŠ‘ UInt) + return TypeError + end + return Union{} + end + # The remaining intrinsics are math/bits/comparison intrinsics. # All the non-floating point intrinsics work on primitive values of the same type. isshift = f === shl_int || f === lshr_int || f === ashr_int diff --git a/Compiler/test/effects.jl b/Compiler/test/effects.jl index 79d16602a8d92..e06d885fcefd7 100644 --- a/Compiler/test/effects.jl +++ b/Compiler/test/effects.jl @@ -1438,6 +1438,11 @@ let effects = Base.infer_effects(Core.Intrinsics.pointerset, Tuple{Vararg{Any}}) @test Compiler.is_consistent(effects) @test !Compiler.is_effect_free(effects) end +@test Compiler.intrinsic_nothrow(Core.Intrinsics.add_ptr, Any[Ptr{Int}, UInt]) +@test Compiler.intrinsic_nothrow(Core.Intrinsics.sub_ptr, Any[Ptr{Int}, UInt]) +@test !Compiler.intrinsic_nothrow(Core.Intrinsics.add_ptr, Any[UInt, UInt]) +@test !Compiler.intrinsic_nothrow(Core.Intrinsics.sub_ptr, Any[UInt, UInt]) +@test Compiler.is_nothrow(Base.infer_effects(+, Tuple{Ptr{UInt8}, UInt})) # effects modeling for atomic intrinsics # these functions especially need to be marked !effect_free since they imply synchronization for atomicfunc = Any[ @@ -1471,3 +1476,5 @@ let effects = Base.infer_effects((Core.SimpleVector,Int); optimize=false) do sve @test !Compiler.is_nothrow(effects) @test Compiler.is_terminates(effects) end + +@test Compiler.is_nothrow(Base.infer_effects(length, (Core.SimpleVector,))) diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index a4294e2e45f6b..6b1b964805149 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -6235,7 +6235,7 @@ g57292(xs::String...) = getfield(("abc",), 1, :not_atomic, xs...) global invalid_setglobal!_exct_modeling::Int @test Base.infer_exception_type((Float64,)) do x setglobal!(@__MODULE__, :invalid_setglobal!_exct_modeling, x) -end == ErrorException +end == TypeError # Issue #58257 - Hang in inference during BindingPartition resolution module A58257 diff --git a/Compiler/test/special_loading.jl b/Compiler/test/special_loading.jl index ba012446dc61f..6b7865e12f58e 100644 --- a/Compiler/test/special_loading.jl +++ b/Compiler/test/special_loading.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -mktempdir() do dir +include(joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "test", "tempdepot.jl")) +mkdepottempdir() do dir withenv("JULIA_DEPOT_PATH" => dir * (Sys.iswindows() ? ";" : ":"), "JULIA_LOAD_PATH" => nothing) do cd(joinpath(@__DIR__, "CompilerLoadingTest")) do @test success(pipeline(`$(Base.julia_cmd()[1]) --startup-file=no --project=. compiler_loading_test.jl`; stdout, stderr)) diff --git a/Compiler/test/validation.jl b/Compiler/test/validation.jl index f01ff85e4321c..766f887c05860 100644 --- a/Compiler/test/validation.jl +++ b/Compiler/test/validation.jl @@ -4,6 +4,15 @@ using Test, Core.IR include("setup_Compiler.jl") +@testset "stdio validation" begin + for s in (:stdout, :stderr, :print, :println, :write) + @test getglobal(Compiler, s) === getglobal(Core, s) + @test isconst(Compiler, s) + end + @test Compiler.stdin === devnull + @test isconst(Compiler, :stdin) +end + function f22938(a, b, x...) nothing nothing diff --git a/Makefile b/Makefile index d5742f2f4ab70..f58fda5ec8558 100644 --- a/Makefile +++ b/Makefile @@ -110,13 +110,7 @@ julia-src-release julia-src-debug : julia-src-% : julia-deps julia_flisp.boot.in julia-cli-release julia-cli-debug: julia-cli-% : julia-deps @$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT)/cli $* -julia-sysimg-ji : $(TOP_LEVEL_PKG_LINK_TARGETS) julia-stdlib julia-base julia-cli-$(JULIA_BUILD_MODE) julia-src-$(JULIA_BUILD_MODE) | $(build_private_libdir) - @$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) -f sysimage.mk sysimg-ji JULIA_EXECUTABLE='$(JULIA_EXECUTABLE)' - -julia-sysimg-bc : $(TOP_LEVEL_PKG_LINK_TARGETS) julia-stdlib julia-base julia-cli-$(JULIA_BUILD_MODE) julia-src-$(JULIA_BUILD_MODE) | $(build_private_libdir) - @$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) -f sysimage.mk sysimg-bc JULIA_EXECUTABLE='$(JULIA_EXECUTABLE)' - -julia-sysimg-release julia-sysimg-debug : julia-sysimg-% : julia-sysimg-ji julia-src-% +julia-sysimg-release julia-sysimg-debug : julia-sysimg-% : julia-src-% $(TOP_LEVEL_PKG_LINK_TARGETS) julia-stdlib julia-base julia-cli-% julia-src-% | $(build_private_libdir) @$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) -f sysimage.mk sysimg-$* julia-debug julia-release : julia-% : julia-sysimg-% julia-src-% julia-symlink julia-libccalltest \ diff --git a/base/array.jl b/base/array.jl index f134ad2bc9ea5..7fe5ff626f448 100644 --- a/base/array.jl +++ b/base/array.jl @@ -1053,14 +1053,14 @@ end # Specifically we are wasting ~10% of memory for small arrays # by not picking memory sizes that max out a GC pool function overallocation(maxsize) - maxsize < 8 && return 8; - # compute maxsize = maxsize + 4*maxsize^(7/8) + maxsize/8 + # compute maxsize = maxsize + 3*maxsize^(7/8) + maxsize/8 # for small n, we grow faster than O(n) # for large n, we grow at O(n/8) # and as we reach O(memory) for memory>>1MB, # this means we end by adding about 10% of memory each time + # most commonly, this will take steps of 0-3-9-34 or 1-4-16-66 or 2-8-33 exp2 = sizeof(maxsize) * 8 - Core.Intrinsics.ctlz_int(maxsize) - maxsize += (1 << div(exp2 * 7, 8)) * 4 + div(maxsize, 8) + maxsize += (1 << div(exp2 * 7, 8)) * 3 + div(maxsize, 8) return maxsize end diff --git a/base/binaryplatforms.jl b/base/binaryplatforms.jl index c4c65504be424..e211ac763fcad 100644 --- a/base/binaryplatforms.jl +++ b/base/binaryplatforms.jl @@ -1044,7 +1044,7 @@ function platforms_match(a::AbstractPlatform, b::AbstractPlatform) # Call the comparator, passing in which objects requested this comparison (one, the other, or both) # For some comparators this doesn't matter, but for non-symmetrical comparisons, it does. - if !(comparator(ak, bk, a_comp === comparator, b_comp === comparator)::Bool) + if !(@invokelatest(comparator(ak, bk, a_comp === comparator, b_comp === comparator))::Bool) return false end end diff --git a/base/boot.jl b/base/boot.jl index 32975e96af583..e1af7383fbb81 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -410,7 +410,7 @@ struct TypeError <: Exception # `context` optionally adds extra detail, e.g. the name of the type parameter # that got a bad value. func::Symbol - context::Union{AbstractString,Symbol} + context::Union{AbstractString,GlobalRef,Symbol} expected::Type got TypeError(func, context, @nospecialize(expected::Type), @nospecialize(got)) = diff --git a/base/div.jl b/base/div.jl index 3fec8d2f5cdf3..0ec852ff045c7 100644 --- a/base/div.jl +++ b/base/div.jl @@ -385,3 +385,9 @@ end # NOTE: C89 fmod() and x87 FPREM implicitly provide truncating float division, # so it is used here as the basis of float div(). div(x::T, y::T, r::RoundingMode) where {T<:AbstractFloat} = convert(T, round((x - rem(x, y, r)) / y)) + +# Vincent LefΓ¨vre: "The Euclidean Division Implemented with a Floating-Point Division and a Floor" +# https://inria.hal.science/inria-00070403 +# Theorem 1 implies that the following are exact if eps(x/y) <= 1 +div(x::Float32, y::Float32, r::RoundingMode) = Float32(round(Float64(x) / Float64(y), r)) +div(x::Float16, y::Float16, r::RoundingMode) = Float16(round(Float32(x) / Float32(y), r)) diff --git a/base/errorshow.jl b/base/errorshow.jl index e771597d7b1e0..d8d94d6f1fb94 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -91,6 +91,9 @@ function showerror(io::IO, ex::TypeError) end if ex.context == "" ctx = "in $(ex.func)" + elseif isa(ex.context, Core.GlobalRef) + gr = ex.context + ctx = "in $(ex.func) of global binding `$(gr.mod).$(gr.name)`" elseif ex.func === :var"keyword argument" ctx = "in keyword argument $(ex.context)" else @@ -259,7 +262,7 @@ function showerror(io::IO, ex::MethodError) is_arg_types = !isa(ex.args, Tuple) arg_types = is_arg_types ? ex.args : typesof(ex.args...) arg_types_param::SimpleVector = (unwrap_unionall(arg_types)::DataType).parameters - san_arg_types_param = Any[rewrap_unionall(a, arg_types) for a in arg_types_param] + san_arg_types_param = Any[rewrap_unionall(arg_types_param[i], arg_types) for i in 1:length(arg_types_param)] f = ex.f meth = methods_including_ambiguous(f, arg_types) if isa(meth, MethodList) && length(meth) > 1 @@ -399,10 +402,10 @@ function showerror_ambiguous(io::IO, meths, f, args::Type) sigfix = typeintersect(m.sig, sigfix) end if isa(unwrap_unionall(sigfix), DataType) && sigfix <: Tuple - let sigfix=sigfix - if all(m->morespecific(sigfix, m.sig), meths) + let sigfix=Core.Box(sigfix) + if all(m->morespecific(sigfix.contents, m.sig), meths) print(io, "\nPossible fix, define\n ") - show_tuple_as_call(io, :function, sigfix) + show_tuple_as_call(io, :function, sigfix.contents) else print(io, "To resolve the ambiguity, try making one of the methods more specific, or ") print(io, "adding a new method more specific than any of the existing applicable methods.") @@ -487,10 +490,10 @@ function show_method_candidates(io::IO, ex::MethodError, kwargs=[]) # If isvarargtype then it checks whether the rest of the input arguments matches # the varargtype if Base.isvarargtype(sig[i]) - sigstr = (unwrapva(unwrap_unionall(sig[i])), "...") + sigstr = Core.svec(unwrapva(unwrap_unionall(sig[i])), "...") j = length(t_i) else - sigstr = (sig[i],) + sigstr = Core.svec(sig[i],) j = i end # Checks if the type of arg 1:i of the input intersects with the current method @@ -536,9 +539,9 @@ function show_method_candidates(io::IO, ex::MethodError, kwargs=[]) for (k, sigtype) in enumerate(sig[length(t_i)+1:end]) sigtype = isvarargtype(sigtype) ? unwrap_unionall(sigtype) : sigtype if Base.isvarargtype(sigtype) - sigstr = (unwrapva(sigtype::Core.TypeofVararg), "...") + sigstr = Core.svec(unwrapva(sigtype::Core.TypeofVararg), "...") else - sigstr = (sigtype,) + sigstr = Core.svec(sigtype,) end if !((min(length(t_i), length(sig)) == 0) && k==1) print(iob, ", ") diff --git a/base/essentials.jl b/base/essentials.jl index 412629411e36a..66400d88fd1ab 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -1009,6 +1009,10 @@ struct Colon <: Function end const (:) = Colon() +function show(io::IO, ::Colon) + show_type_name(io, Colon.name) + print(io, "()") +end """ Val(c) diff --git a/base/experimental.jl b/base/experimental.jl index efaf4bd33a820..8500d8c3ea91a 100644 --- a/base/experimental.jl +++ b/base/experimental.jl @@ -315,6 +315,7 @@ the handler for that type. This interface is experimental and subject to change or removal without notice. """ function show_error_hints(io, ex, args...) + @nospecialize hinters = get(_hint_handlers, typeof(ex), nothing) isnothing(hinters) && return for handler in hinters diff --git a/base/fastmath.jl b/base/fastmath.jl index f2f60519b99ac..ed686fb92bf34 100644 --- a/base/fastmath.jl +++ b/base/fastmath.jl @@ -297,7 +297,7 @@ exp10_fast(x::Union{Float32,Float64}) = Base.Math.exp10_fast(x) # builtins -function pow_fast(x::Float64, y::Integer) +@inline function pow_fast(x::Float64, y::Integer) z = y % Int32 z == y ? pow_fast(x, z) : x^y end diff --git a/base/file.jl b/base/file.jl index 66e8114aba4ba..ce9bc76256fd3 100644 --- a/base/file.jl +++ b/base/file.jl @@ -253,9 +253,9 @@ function mkpath(path::AbstractString; mode::Integer = 0o777) return path end -# Files that were requested to be deleted but can't be by the current process -# i.e. loaded DLLs on Windows -delayed_delete_dir() = joinpath(tempdir(), "julia_delayed_deletes") +# Files that were requested to be deleted but can't be by the current process, +# i.e. loaded DLLs on Windows, are listed in the directory below +delayed_delete_ref() = joinpath(tempdir(), "julia_delayed_deletes_ref") """ rm(path::AbstractString; force::Bool=false, recursive::Bool=false) @@ -288,13 +288,7 @@ function rm(path::AbstractString; force::Bool=false, recursive::Bool=false, allo force && err.code==Base.UV_ENOENT && return @static if Sys.iswindows() if allow_delayed_delete && err.code==Base.UV_EACCES && endswith(path, ".dll") - # Loaded DLLs cannot be deleted on Windows, even with posix delete mode - # but they can be moved. So move out to allow the dir to be deleted. - # Pkg.gc() cleans up this dir when possible - dir = mkpath(delayed_delete_dir()) - temp_path = tempname(dir, cleanup = false, suffix = string("_", basename(path))) - @debug "Could not delete DLL most likely because it is loaded, moving to tempdir" path temp_path - mv(path, temp_path) + delayed_delete_dll(path) return end end @@ -330,6 +324,22 @@ function rm(path::AbstractString; force::Bool=false, recursive::Bool=false, allo end +# Loaded DLLs cannot be deleted on Windows, even with posix delete mode but they can be renamed. +# delayed_delete_dll(path) does so temporarily, until later cleanup by Pkg.gc(). +function delayed_delete_dll(path) + # in-use DLL must be kept on the same drive + temp_path = tempname(abspath(dirname(path)); cleanup=false, suffix=string("_", basename(path))) + @debug "Could not delete DLL most likely because it is loaded, moving to a temporary path" path temp_path + mkpath(delayed_delete_ref()) + io = last(mktemp(delayed_delete_ref(); cleanup=false)) + try + print(io, temp_path) # record the temporary path for Pkg.gc() + finally + close(io) + end + rename(path, temp_path) # do not call mv which could recursively call rm(path) +end + # The following use Unix command line facilities function checkfor_mv_cp_cptree(src::AbstractString, dst::AbstractString, txt::AbstractString; force::Bool=false) @@ -678,8 +688,35 @@ end # deprecated internal function used by some packages temp_cleanup_purge(; force=false) = force ? temp_cleanup_purge_all() : @lock TEMP_CLEANUP_LOCK temp_cleanup_purge_prelocked(false) +function temp_cleanup_postprocess(cleanup_dirs) + if !isempty(cleanup_dirs) + rmcmd = """ + cleanuplist = readlines(stdin) # This loop won't start running until stdin is closed, which is supposed to be sequenced after the process exits + sleep(1) # Wait for the operating system to hopefully be ready, since the OS implementation is probably incorrect, given the history of buggy work-arounds like this that have existed for ages in dotNet and libuv + for path in cleanuplist + try + rm(path, force=true, recursive=true) + catch ex + @warn "Failed to clean up temporary path \$(repr(path))\n\$ex" _group=:file + end + end + """ + cmd = Cmd(Base.cmd_gen(((Base.julia_cmd(),), ("--startup-file=no",), ("-e",), (rmcmd,))); ignorestatus = true, detach = true) + pw = Base.PipeEndpoint() + run(cmd, pw, devnull, stderr; wait=false) + join(pw, cleanup_dirs, "\n") + Base.dup(Base._fd(pw)) # intentionally leak a reference, until the process exits + close(pw) + end +end + +function temp_cleanup_atexit() + temp_cleanup_purge_all() + @lock TEMP_CLEANUP_LOCK temp_cleanup_postprocess(keys(TEMP_CLEANUP)) +end + function __postinit__() - Base.atexit(temp_cleanup_purge_all) + Base.atexit(temp_cleanup_atexit) end const temp_prefix = "jl_" diff --git a/base/intfuncs.jl b/base/intfuncs.jl index 3f26d2597f9d9..d660c6d0a8ecc 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -148,6 +148,8 @@ gcd(a::Rational) = checked_abs(a.num) // a.den lcm(a::Union{Integer,Rational}) = gcd(a) gcd(a::Unsigned, b::Signed) = gcd(promote(a, abs(b))...) gcd(a::Signed, b::Unsigned) = gcd(promote(abs(a), b)...) +lcm(a::Unsigned, b::Signed) = lcm(promote(a, abs(b))...) +lcm(a::Signed, b::Unsigned) = lcm(promote(abs(a), b)...) gcd(a::Real, b::Real) = gcd(promote(a,b)...) lcm(a::Real, b::Real) = lcm(promote(a,b)...) gcd(a::Real, b::Real, c::Real...) = gcd(a, gcd(b, c...)) @@ -252,6 +254,16 @@ function gcdx(a::Real, b::Real, cs::Real...) dβ€², x, ys... = gcdx(d, cs...) return dβ€², i*x, j*x, ys... end +function gcdx(a::Signed, b::Unsigned) + R = promote_type(typeof(a), typeof(b)) + _a = a % signed(R) # handle the case a == typemin(typeof(a)) if R != typeof(a) + d, u, v = gcdx(promote(abs(_a), b)...) + d, flipsign(u, a), v +end +function gcdx(a::Unsigned, b::Signed) + d, v, u = gcdx(b, a) + d, u, v +end # multiplicative inverse of n mod m, error if none @@ -477,18 +489,20 @@ julia> powermod(5, 3, 19) function powermod(x::Integer, p::Integer, m::T) where T<:Integer p == 0 && return mod(one(m),m) # When the concrete type of p is signed and has the lowest value, - # `p != 0 && p == -p` is equivalent to `p == typemin(typeof(p))` for 2's complement representation. + # `p < 0 && p == -p` is equivalent to `p == typemin(typeof(p))` for 2's complement representation. # but will work for integer types like `BigInt` that don't have `typemin` defined # It needs special handling otherwise will cause overflow problem. - if p == -p - imod = invmod(x, m) - rhalf = powermod(imod, -(pΓ·2), m) - r::T = mod(widemul(rhalf, rhalf), m) - isodd(p) && (r = mod(widemul(r, imod), m)) - #else odd - return r - elseif p < 0 - return powermod(invmod(x, m), -p, m) + if p < 0 + if p == -p + imod = invmod(x, m) + rhalf = powermod(imod, -(pΓ·2), m) + r::T = mod(widemul(rhalf, rhalf), m) + isodd(p) && (r = mod(widemul(r, imod), m)) + #else odd + return r + else + return powermod(invmod(x, m), -p, m) + end end (m == 1 || m == -1) && return zero(m) b = oftype(m,mod(x,m)) # this also checks for divide by zero diff --git a/base/iobuffer.jl b/base/iobuffer.jl index ca2757201aae8..fee699287705b 100644 --- a/base/iobuffer.jl +++ b/base/iobuffer.jl @@ -604,7 +604,8 @@ end end # The fast path here usually checks there is already room, then does nothing. # When append is true, new data is added after io.size, not io.ptr - existing_space = min(lastindex(io.data), io.maxsize + get_offset(io)) - (io.append ? io.size : io.ptr - 1) + start_offset = io.append ? io.size : io.ptr - 1 + existing_space = min(lastindex(io.data) - start_offset, io.maxsize - (start_offset - get_offset(io))) if existing_space < nshort % Int # Outline this function to make it more likely that ensureroom inlines itself return ensureroom_slowpath(io, nshort, existing_space) @@ -824,12 +825,13 @@ function unsafe_write(to::GenericIOBuffer, p::Ptr{UInt8}, nb::UInt) append = to.append ptr = append ? size+1 : to.ptr data = to.data - to_write = min(nb, (min(Int(length(data))::Int, to.maxsize + get_offset(to)) - ptr + 1) % UInt) % Int + start_offset = ptr - 1 + to_write = max(0, min(nb, (min(Int(length(data))::Int - start_offset, to.maxsize - (start_offset - get_offset(to)))) % UInt) % Int) # Dispatch based on the type of data, to possibly allow using memcpy _unsafe_write(data, p, ptr, to_write % UInt) # Update to.size only if the ptr has advanced to higher than # the previous size. Otherwise, we just overwrote existing data - to.size = max(size, ptr + to_write - 1) + to.size = max(size, start_offset + to_write) # If to.append, we only update size, not ptr. if !append to.ptr = ptr + to_write @@ -867,7 +869,7 @@ end ptr = (to.append ? to.size+1 : to.ptr) # We have just ensured there is room for 1 byte, EXCEPT if we were to exceed # maxsize. So, we just need to check that here. - if ptr > to.maxsize + get_offset(to) + if ptr - get_offset(to) > to.maxsize return 0 else to.data[ptr] = a diff --git a/base/iterators.jl b/base/iterators.jl index f7ae8138f6856..47e365f5c7a86 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -16,7 +16,7 @@ using .Base: (:), |, +, -, *, !==, !, ==, !=, <=, <, >, >=, =>, missing, any, _counttuple, eachindex, ntuple, zero, prod, reduce, in, firstindex, lastindex, tail, fieldtypes, min, max, minimum, zero, oneunit, promote, promote_shape, LazyString, - afoldl + afoldl, @default_eltype using Core using Core: @doc @@ -1140,6 +1140,8 @@ end next === nothing && return nothing restnext = _piterate(rest...) restnext === nothing && return nothing + VS = @default_eltype(iter1) + next = Pair{VS, typeof(next[2])}(next[1], next[2]) return (next, restnext...) end @inline function iterate(P::ProductIterator) @@ -1152,8 +1154,8 @@ end @inline _piterate1(::Tuple{}, ::Tuple{}) = nothing @inline function _piterate1(iters, states) iter1 = first(iters) - next = iterate(iter1, first(states)[2]) - restnext = tail(states) + state1, restnext... = states + next = iterate(iter1, state1[2]) if next === nothing isdone(iter1) === true && return nothing restnext = _piterate1(tail(iters), restnext) @@ -1161,6 +1163,7 @@ end next = iterate(iter1) next === nothing && return nothing end + next = Pair{fieldtype(typeof(state1), 1), typeof(next[2])}(next[1], next[2]) return (next, restnext...) end @inline function iterate(P::ProductIterator, states) diff --git a/base/loading.jl b/base/loading.jl index c69f28cdc5a02..428b106aa08ee 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -2622,12 +2622,11 @@ function __require_prelocked(pkg::PkgId, env) if JLOptions().use_compiled_modules == 1 if !generating_output(#=incremental=#false) project = active_project() - if !generating_output() && !parallel_precompile_attempted && !disable_parallel_precompile && @isdefined(Precompilation) && project !== nothing && - isfile(project) && project_file_manifest_path(project) !== nothing + if !generating_output() && !parallel_precompile_attempted && !disable_parallel_precompile && @isdefined(Precompilation) parallel_precompile_attempted = true unlock(require_lock) try - Precompilation.precompilepkgs([pkg.name]; _from_loading=true, ignore_loaded=false) + Precompilation.precompilepkgs([pkg]; _from_loading=true, ignore_loaded=false) finally lock(require_lock) end diff --git a/base/logging/ConsoleLogger.jl b/base/logging/ConsoleLogger.jl index 8766d0ae56331..b6dc01f4f326c 100644 --- a/base/logging/ConsoleLogger.jl +++ b/base/logging/ConsoleLogger.jl @@ -124,8 +124,8 @@ function handle_message(logger::ConsoleLogger, level::LogLevel, message, _module # split into lines. This is specialised to improve type inference, # and reduce the risk of resulting method invalidations. message = string(message) - msglines = if Base._isannotated(message) && !isempty(Base.annotations(message)) - message = Base.AnnotatedString(String(message), Base.annotations(message)) + msglines = if Base._isannotated(message) && !isempty(Base.annotations(message)::Vector{Base.RegionAnnotation}) + message = Base.AnnotatedString(String(message)::String, Base.annotations(message)::Vector{Base.RegionAnnotation}) @NamedTuple{indent::Int, msg::Union{SubString{Base.AnnotatedString{String}}, SubString{String}}}[ (indent=0, msg=l) for l in split(chomp(message), '\n')] else diff --git a/base/mpfr.jl b/base/mpfr.jl index 2175fb56cc526..cd73506c9e96f 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -391,12 +391,18 @@ BigFloat(x::Union{Float16,Float32}, r::MPFRRoundingMode=rounding_raw(BigFloat); BigFloat(Float64(x), r; precision=precision) function BigFloat(x::Rational, r::MPFRRoundingMode=rounding_raw(BigFloat); precision::Integer=_precision_with_base_2(BigFloat)) + r_den = _opposite_round(r) setprecision(BigFloat, precision) do setrounding_raw(BigFloat, r) do - BigFloat(numerator(x))::BigFloat / BigFloat(denominator(x))::BigFloat + BigFloat(numerator(x))::BigFloat / BigFloat(denominator(x), r_den)::BigFloat end end end +function _opposite_round(r::MPFRRoundingMode) + r == MPFRRoundUp && return MPFRRoundDown + r == MPFRRoundDown && return MPFRRoundUp + return r +end function tryparse(::Type{BigFloat}, s::AbstractString; base::Integer=0, precision::Integer=_precision_with_base_2(BigFloat), rounding::MPFRRoundingMode=rounding_raw(BigFloat)) !isempty(s) && isspace(s[end]) && return tryparse(BigFloat, rstrip(s), base = base) diff --git a/base/precompilation.jl b/base/precompilation.jl index e737faa210c79..45634d877115f 100644 --- a/base/precompilation.jl +++ b/base/precompilation.jl @@ -26,9 +26,24 @@ struct ExplicitEnv #local_prefs::Union{Nothing, Dict{String, Any}} end -function ExplicitEnv(envpath::String=Base.active_project()) - if !isfile(envpath) - error("expected a project file at $(repr(envpath))") +ExplicitEnv() = ExplicitEnv(Base.active_project()) +function ExplicitEnv(::Nothing, envpath::String="") + ExplicitEnv(envpath, + Dict{String, UUID}(), # project_deps + Dict{String, UUID}(), # project_weakdeps + Dict{String, UUID}(), # project_extras + Dict{String, Vector{UUID}}(), # project_extensions + Dict{UUID, Vector{UUID}}(), # deps + Dict{UUID, Vector{UUID}}(), # weakdeps + Dict{UUID, Dict{String, Vector{UUID}}}(), # extensions + Dict{UUID, String}(), # names + Dict{UUID, Union{SHA1, String, Nothing, Missing}}()) +end +function ExplicitEnv(envpath::String) + # Handle missing project file by creating an empty environment + if !isfile(envpath) || project_file_manifest_path(envpath) === nothing + envpath = abspath(envpath) + return ExplicitEnv(nothing, envpath) end envpath = abspath(envpath) project_d = parsed_toml(envpath) @@ -456,7 +471,7 @@ function collect_all_deps(direct_deps, dep, alldeps=Set{Base.PkgId}()) end -function precompilepkgs(pkgs::Vector{String}=String[]; +function precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}}=String[]; internal_call::Bool=false, strict::Bool = false, warn_loaded::Bool = true, @@ -468,13 +483,14 @@ function precompilepkgs(pkgs::Vector{String}=String[]; fancyprint::Bool = can_fancyprint(io) && !timing, manifest::Bool=false, ignore_loaded::Bool=true) + @debug "precompilepkgs called with" pkgs internal_call strict warn_loaded timing _from_loading configs fancyprint manifest ignore_loaded # monomorphize this to avoid latency problems _precompilepkgs(pkgs, internal_call, strict, warn_loaded, timing, _from_loading, configs isa Vector{Config} ? configs : [configs], IOContext{IO}(io), fancyprint, manifest, ignore_loaded) end -function _precompilepkgs(pkgs::Vector{String}, +function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}}, internal_call::Bool, strict::Bool, warn_loaded::Bool, @@ -486,6 +502,23 @@ function _precompilepkgs(pkgs::Vector{String}, manifest::Bool, ignore_loaded::Bool) requested_pkgs = copy(pkgs) # for understanding user intent + pkg_names = pkgs isa Vector{String} ? copy(pkgs) : String[pkg.name for pkg in pkgs] + if pkgs isa Vector{PkgId} + requested_pkgids = copy(pkgs) + else + requested_pkgids = PkgId[] + for name in pkgs + pkgid = Base.identify_package(name) + if pkgid === nothing + if _from_loading + return # leave it up to loading to handle this + else + throw(PkgPrecompileError("Unknown package: $name")) + end + end + push!(requested_pkgids, pkgid) + end + end time_start = time_ns() @@ -518,9 +551,12 @@ function _precompilepkgs(pkgs::Vector{String}, # inverse map of `parent_to_ext` above (ext β†’ parent) ext_to_parent = Dict{Base.PkgId, Base.PkgId}() - function describe_pkg(pkg::PkgId, is_project_dep::Bool, flags::Cmd, cacheflags::Base.CacheFlags) + function describe_pkg(pkg::PkgId, is_project_dep::Bool, is_serial_dep::Bool, flags::Cmd, cacheflags::Base.CacheFlags) name = full_name(ext_to_parent, pkg) name = is_project_dep ? name : color_string(name, :light_black) + if is_serial_dep + name *= color_string(" (serial)", :light_black) + end if nconfigs > 1 && !isempty(flags) config_str = join(flags, " ") name *= color_string(" `$config_str`", :light_black) @@ -630,15 +666,27 @@ function _precompilepkgs(pkgs::Vector{String}, end @debug "precompile: extensions collected" + serial_deps = Base.PkgId[] # packages that are being precompiled in serial + + if _from_loading + # if called from loading precompilation it may be a package from another environment stack + # where we don't have access to the dep graph, so just add as a single package and do serial + # precompilation of its deps within the job. + for pkgid in requested_pkgids # In case loading asks for multiple packages + pkgid === nothing && continue + if !haskey(direct_deps, pkgid) + @debug "precompile: package `$(pkgid)` is outside of the environment, so adding as single package serial job" + direct_deps[pkgid] = Base.PkgId[] # no deps, do them in serial in the job + push!(project_deps, pkgid) # add to project_deps so it doesn't show up in gray + push!(serial_deps, pkgid) + end + end + end + # return early if no deps if isempty(direct_deps) if isempty(pkgs) return - elseif _from_loading - # if called from loading precompilation it may be a package from another environment stack so - # don't error and allow serial precompilation to try - # TODO: actually handle packages from other envs in the stack - return else error("No direct dependencies outside of the sysimage found matching $(pkgs)") end @@ -672,6 +720,7 @@ function _precompilepkgs(pkgs::Vector{String}, circular_deps = Base.PkgId[] for pkg in keys(direct_deps) @assert isempty(stack) + pkg in serial_deps && continue # skip serial deps as we don't have their dependency graph if scan_pkg!(stack, could_be_cycle, cycles, pkg, direct_deps) push!(circular_deps, pkg) for pkg_config in keys(was_processed) @@ -685,18 +734,31 @@ function _precompilepkgs(pkgs::Vector{String}, end @debug "precompile: circular dep check done" + # If you have a workspace and want to precompile all projects in it, look through all packages in the manifest + # instead of collecting from a project i.e. not filter out packages that are in the current project. + # i.e. Pkg sets manifest to true for workspace precompile requests + # TODO: rename `manifest`? if !manifest - if isempty(pkgs) - pkgs = [pkg.name for pkg in project_deps] + if isempty(pkg_names) + pkg_names = [pkg.name for pkg in project_deps] end keep = Set{Base.PkgId}() for dep in direct_deps dep_pkgid = first(dep) - if dep_pkgid.name in pkgs + if dep_pkgid.name in pkg_names push!(keep, dep_pkgid) collect_all_deps(direct_deps, dep_pkgid, keep) end end + # Also keep packages that were explicitly requested as PkgIds (for extensions) + if pkgs isa Vector{PkgId} + for requested_pkgid in requested_pkgids + if haskey(direct_deps, requested_pkgid) + push!(keep, requested_pkgid) + collect_all_deps(direct_deps, requested_pkgid, keep) + end + end + end for ext in keys(ext_to_parent) if issubset(collect_all_deps(direct_deps, ext), keep) # if all extension deps are kept push!(keep, ext) @@ -846,7 +908,7 @@ function _precompilepkgs(pkgs::Vector{String}, dep, config = pkg_config loaded = warn_loaded && haskey(Base.loaded_modules, dep) flags, cacheflags = config - name = describe_pkg(dep, dep in project_deps, flags, cacheflags) + name = describe_pkg(dep, dep in project_deps, dep in serial_deps, flags, cacheflags) line = if pkg_config in precomperr_deps string(color_string(" ? ", Base.warn_color()), name) elseif haskey(failed_deps, pkg_config) @@ -904,7 +966,8 @@ function _precompilepkgs(pkgs::Vector{String}, for (pkg, deps) in direct_deps cachepaths = get!(() -> Base.find_all_in_cache_path(pkg), cachepath_cache, pkg) sourcepath = Base.locate_package(pkg) - single_requested_pkg = length(requested_pkgs) == 1 && only(requested_pkgs) == pkg.name + single_requested_pkg = length(requested_pkgs) == 1 && + (pkg in requested_pkgids || pkg.name in pkg_names) for config in configs pkg_config = (pkg, config) if sourcepath === nothing @@ -929,12 +992,13 @@ function _precompilepkgs(pkgs::Vector{String}, if !circular && is_stale Base.acquire(parallel_limiter) is_project_dep = pkg in project_deps + is_serial_dep = pkg in serial_deps # std monitoring std_pipe = Base.link_pipe!(Pipe(); reader_supports_async=true, writer_supports_async=true) t_monitor = @async monitor_std(pkg_config, std_pipe; single_requested_pkg) - name = describe_pkg(pkg, is_project_dep, flags, cacheflags) + name = describe_pkg(pkg, is_project_dep, is_serial_dep, flags, cacheflags) @lock print_lock begin if !fancyprint && isempty(pkg_queue) printpkgstyle(io, :Precompiling, something(target[], "packages...")) @@ -1030,7 +1094,7 @@ function _precompilepkgs(pkgs::Vector{String}, str = sprint(context=io) do iostr if !quick_exit if fancyprint # replace the progress bar - what = isempty(requested_pkgs) ? "packages finished." : "$(join(requested_pkgs, ", ", " and ")) finished." + what = isempty(requested_pkgids) ? "packages finished." : "$(join((p.name for p in requested_pkgids), ", ", " and ")) finished." printpkgstyle(iostr, :Precompiling, what) end plural = length(configs) > 1 ? "dependency configurations" : ndeps == 1 ? "dependency" : "dependencies" diff --git a/base/stream.jl b/base/stream.jl index 6103d4ff1bb31..836fe8391302e 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -617,7 +617,8 @@ end function alloc_request(buffer::IOBuffer, recommended_size::UInt) ensureroom(buffer, recommended_size) ptr = buffer.append ? buffer.size + 1 : buffer.ptr - nb = min(length(buffer.data), buffer.maxsize + get_offset(buffer)) - ptr + 1 + start_offset = ptr - 1 + nb = max(0, min(length(buffer.data) - start_offset, buffer.maxsize - (start_offset - get_offset(buffer)))) return (Ptr{Cvoid}(pointer(buffer.data, ptr)), nb) end diff --git a/base/threadingconstructs.jl b/base/threadingconstructs.jl index b83f47ef7c8cd..bb45219c60a88 100644 --- a/base/threadingconstructs.jl +++ b/base/threadingconstructs.jl @@ -287,8 +287,14 @@ A macro to execute a `for` loop in parallel. The iteration space is distributed coarse-grained tasks. This policy can be specified by the `schedule` argument. The execution of the loop waits for the evaluation of all iterations. +Tasks spawned by `@threads` are scheduled on the `:default` threadpool. This means that +`@threads` will not use threads from the `:interactive` threadpool, even if called from +the main thread or from a task in the interactive pool. The `:default` threadpool is +intended for compute-intensive parallel workloads. + See also: [`@spawn`](@ref Threads.@spawn) and `pmap` in [`Distributed`](@ref man-distributed). +For more information on threadpools, see the chapter on [threadpools](@ref man-threadpools). # Extended help diff --git a/contrib/juliac/juliac-trim-base.jl b/contrib/juliac/juliac-trim-base.jl index 244a643a1a76f..6300633eef8fe 100644 --- a/contrib/juliac/juliac-trim-base.jl +++ b/contrib/juliac/juliac-trim-base.jl @@ -77,7 +77,6 @@ end print(io, T.var.name) end end - show_type_name(io::IO, tn::Core.TypeName) = print(io, tn.name) mapreduce(f::F, op::F2, A::AbstractArrayOrBroadcasted; dims=:, init=_InitialValue()) where {F, F2} = _mapreduce_dim(f, op, init, A, dims) diff --git a/deps/blastrampoline.version b/deps/blastrampoline.version index bb711cfcd67ec..4f9dc0aff0741 100644 --- a/deps/blastrampoline.version +++ b/deps/blastrampoline.version @@ -4,6 +4,6 @@ BLASTRAMPOLINE_JLL_NAME := libblastrampoline ## source build -BLASTRAMPOLINE_VER := 5.13.1 -BLASTRAMPOLINE_BRANCH=v5.13.1 -BLASTRAMPOLINE_SHA1=f26278e83ddc9035ae7695da597f1a5b26a4c62b +BLASTRAMPOLINE_VER := 5.15.0 +BLASTRAMPOLINE_BRANCH=v5.15.0 +BLASTRAMPOLINE_SHA1=072b5f67895bec0b92f8c83194567c1c48e9833d diff --git a/deps/checksums/Pkg-69926e385c878253d62e2588a19b252277196ebf.tar.gz/md5 b/deps/checksums/Pkg-69926e385c878253d62e2588a19b252277196ebf.tar.gz/md5 deleted file mode 100644 index faee08623f288..0000000000000 --- a/deps/checksums/Pkg-69926e385c878253d62e2588a19b252277196ebf.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -6e3a44c3870f135953b325a155fecd65 diff --git a/deps/checksums/Pkg-69926e385c878253d62e2588a19b252277196ebf.tar.gz/sha512 b/deps/checksums/Pkg-69926e385c878253d62e2588a19b252277196ebf.tar.gz/sha512 deleted file mode 100644 index e09a59d4feb83..0000000000000 --- a/deps/checksums/Pkg-69926e385c878253d62e2588a19b252277196ebf.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -565bdb1a4e8bda374d08a49b2ba70130762ca06004cc50d07ca58ca9a3741195977f563bc990bd627735b6464162a15a7bfb08570e812abf2f22151713de2210 diff --git a/deps/checksums/Pkg-f571edda902c848382517503665fea6aa275ceb9.tar.gz/md5 b/deps/checksums/Pkg-f571edda902c848382517503665fea6aa275ceb9.tar.gz/md5 new file mode 100644 index 0000000000000..480f2f77c5cb8 --- /dev/null +++ b/deps/checksums/Pkg-f571edda902c848382517503665fea6aa275ceb9.tar.gz/md5 @@ -0,0 +1 @@ +1f7f4710e3216abc3109024c41051ae8 diff --git a/deps/checksums/Pkg-f571edda902c848382517503665fea6aa275ceb9.tar.gz/sha512 b/deps/checksums/Pkg-f571edda902c848382517503665fea6aa275ceb9.tar.gz/sha512 new file mode 100644 index 0000000000000..5c3356eb58bc0 --- /dev/null +++ b/deps/checksums/Pkg-f571edda902c848382517503665fea6aa275ceb9.tar.gz/sha512 @@ -0,0 +1 @@ +47286eb6d32836b34524833e0461dabc2e25fd917f2cf552242c6807da1cb2b637c60a2e3b40e457bc5296ae932ba4432ec2c5647dc1861407031f74bdb674fc diff --git a/deps/checksums/blastrampoline b/deps/checksums/blastrampoline index eef1653cf353a..d4c42a32024f9 100644 --- a/deps/checksums/blastrampoline +++ b/deps/checksums/blastrampoline @@ -1,38 +1,38 @@ -blastrampoline-f26278e83ddc9035ae7695da597f1a5b26a4c62b.tar.gz/md5/855b7723a6e9eb8885876eb675d48329 -blastrampoline-f26278e83ddc9035ae7695da597f1a5b26a4c62b.tar.gz/sha512/29cbd060c8f5eb17ef486d0a10ee4b221eeceec3a2ab0f9f98f60880f3d19a2247d93ac0dc0d32ec568ef876acd30f6c0642aaf704757580c2e17884e425607f -libblastrampoline.v5.13.1+1.aarch64-apple-darwin.tar.gz/md5/d8dc0f092f86b379b2fb9da97382be70 -libblastrampoline.v5.13.1+1.aarch64-apple-darwin.tar.gz/sha512/d9fc0439565afaabe53f56f64c20aeddb846c991dafeafdef6c2369bd7a359c1a6b49cdf8d63eaae2730a336509854b5c306e630eb520445712efc4e41c0263e -libblastrampoline.v5.13.1+1.aarch64-linux-gnu.tar.gz/md5/c181e51a6ca4cde0da3d036d561e24dc -libblastrampoline.v5.13.1+1.aarch64-linux-gnu.tar.gz/sha512/fe4a86bb4c94ef86c2307adad528bb58d0508a33c194c64190fffe7902f5b915592567d9e0cc35414633c5ab9067def2fa20cf669a2f4309265744180a5ec51a -libblastrampoline.v5.13.1+1.aarch64-linux-musl.tar.gz/md5/6f9eb8d73a0e61f3a2b97dba7105086e -libblastrampoline.v5.13.1+1.aarch64-linux-musl.tar.gz/sha512/9c3db080155729a91b5dd47df91d3852539aefc331d4dc51167fccaf3b01e601b36911ec259c53e211fe192c108e839a1f14b837009fa4f7d88ed82d658f80ff -libblastrampoline.v5.13.1+1.aarch64-unknown-freebsd.tar.gz/md5/68f65db9da9938929d510eea3540335b -libblastrampoline.v5.13.1+1.aarch64-unknown-freebsd.tar.gz/sha512/2fc7b375a751f3bb201504e0417828602fe014a2c8626137779c09ca7264ac6d39d44db0d1d32e0dc506284f56b49e23791922b0cc1237021473fb505fbf06bd -libblastrampoline.v5.13.1+1.armv6l-linux-gnueabihf.tar.gz/md5/a377fa4e5751fbeb3c42f319cb6341de -libblastrampoline.v5.13.1+1.armv6l-linux-gnueabihf.tar.gz/sha512/9ddb1e2f4daab45d65b66dafc00df6ca7f788cb919cd6699c4aa0deca3e99a86d9ced10c3741610a6e480093d483e8a02c1d9165f91a7179632c1e2ae1abcfb7 -libblastrampoline.v5.13.1+1.armv6l-linux-musleabihf.tar.gz/md5/42c841baa05f80f17ea1b1d4f3405bef -libblastrampoline.v5.13.1+1.armv6l-linux-musleabihf.tar.gz/sha512/0c3ed42bd48f8f1ee9b1dc18faa7afa6e2fb27cffc59b9a420e29b5e6cdf8fb3bde36b82f3086075f8f7f329614aeb91ca5f173b1683e30e9530076f341ea2e0 -libblastrampoline.v5.13.1+1.armv7l-linux-gnueabihf.tar.gz/md5/61e515ec1223c99705175a26e6fbaf87 -libblastrampoline.v5.13.1+1.armv7l-linux-gnueabihf.tar.gz/sha512/92260dcc563ece74719f21921a7cb51266884ed01b50c97fa997b4a98737e900ec9eaa8012d2c4c67ab479c4080bd1cf2708612eaaaddbba28e4f9147f3708ea -libblastrampoline.v5.13.1+1.armv7l-linux-musleabihf.tar.gz/md5/d45816d705dd46572d85105567bc060e -libblastrampoline.v5.13.1+1.armv7l-linux-musleabihf.tar.gz/sha512/45cba07050b818cd85c67acdfc29515e1fe416eb4e0c219171f2c0c026f7412903c3a9367d48258259a16e89f36c1e8f9fa054e455759720f1c6c5e8e27be476 -libblastrampoline.v5.13.1+1.i686-linux-gnu.tar.gz/md5/c8d3fd5f314353133934396361857c92 -libblastrampoline.v5.13.1+1.i686-linux-gnu.tar.gz/sha512/a949b3c0655ad9d6f8d53fd8a3f0b4ab504046e49a373039defc94e832b7faf90c77520f3912c4d6db8b0829951d85b4fc2a4021b3d8bb2c399d1ad04ce77ab0 -libblastrampoline.v5.13.1+1.i686-linux-musl.tar.gz/md5/a7bbd2233366d180ce8aa61fd3568c11 -libblastrampoline.v5.13.1+1.i686-linux-musl.tar.gz/sha512/e78cbef5b3bcfa93a86e14eebf0d704a94ac7b1f5c7030706d1f4a960de888c42e3daddb65395c7102e08dfd444efbfb40273e58a5f1de199d44ad55fd3ae658 -libblastrampoline.v5.13.1+1.i686-w64-mingw32.tar.gz/md5/35bf0e9d253d3bbd188c1feba5635e1d -libblastrampoline.v5.13.1+1.i686-w64-mingw32.tar.gz/sha512/6b28e83265b6bd7337ccf7784c74f0490fcf5089bb9c21e2333dace8801f94f09b46ef683d2bd4f2c885b64a26ec4e8755bab21a6e81098e287c15de27d66293 -libblastrampoline.v5.13.1+1.powerpc64le-linux-gnu.tar.gz/md5/8be947c20f7d35ec22247f9a11ccce43 -libblastrampoline.v5.13.1+1.powerpc64le-linux-gnu.tar.gz/sha512/56f4246f96d2f49b03f5e5f3b996660a48d50b3784f89df7cd1dc52bab6efea0c120a65015040041a51d18fc6f361f89486f77317d771fbf588a1ba7565d77a2 -libblastrampoline.v5.13.1+1.riscv64-linux-gnu.tar.gz/md5/85e1f70a3235097158b4884a58a58154 -libblastrampoline.v5.13.1+1.riscv64-linux-gnu.tar.gz/sha512/11f1f5c2a409dbdab11d6bc968610b5700e9b0cb95094e348fe43ddca5586eda47bda1c382fb1f4b5a15aa741a6fc2b31f58f9b08bfe46631b5471e864bc009b -libblastrampoline.v5.13.1+1.x86_64-apple-darwin.tar.gz/md5/c6756ca8b6778ce2a4a440f63355c32e -libblastrampoline.v5.13.1+1.x86_64-apple-darwin.tar.gz/sha512/895d9bba75a9a0861809dca48b3dae7b5ffc5d866a518729ffd52f70fa1742a41a4b8b4e03bb354cba12d9ad11a33f3f112fa69a30ab3f945a9dede0d59d92b3 -libblastrampoline.v5.13.1+1.x86_64-linux-gnu.tar.gz/md5/1326a406aa98b6045f7459d7fb237894 -libblastrampoline.v5.13.1+1.x86_64-linux-gnu.tar.gz/sha512/4965baa1de5532425ea57b8100e369cf44b55963340cd144c0359f845560f27a1bea1597e4c72ec541917f71aaff8a4863f47d01a095c2e761a68212bfb08d1e -libblastrampoline.v5.13.1+1.x86_64-linux-musl.tar.gz/md5/5103983b7fecc7b87f495cd3b6c4d7a5 -libblastrampoline.v5.13.1+1.x86_64-linux-musl.tar.gz/sha512/f3243d84a0a0a191abad9e3850c37be78892eb5905b63b47bfb3e5a4148e0dae672ee72d311c5c764ad0fffe57d39c10dfd2086466efd76b5030118941d36a00 -libblastrampoline.v5.13.1+1.x86_64-unknown-freebsd.tar.gz/md5/a001ecd07b5178ce724a4f78996dc43e -libblastrampoline.v5.13.1+1.x86_64-unknown-freebsd.tar.gz/sha512/508866d54a9a49df2ef7eaa5d807173016c6dfaec59c4c89d5b37cd3faa7384302d2d4d39aca1975d79a948414657b7ec048a3ebdf6bf5c938037aa89303013a -libblastrampoline.v5.13.1+1.x86_64-w64-mingw32.tar.gz/md5/b7c51c8e1a11accc5c5097042da646d9 -libblastrampoline.v5.13.1+1.x86_64-w64-mingw32.tar.gz/sha512/24bc32f0dabc886898ca0e5fd2b3d7250fc67f7bd962ec2aae8c946f405826967a8b8623e524bf22c201bc7e6c55d16c4a5fb2a2250cbbefaf73e383fc080aba +blastrampoline-072b5f67895bec0b92f8c83194567c1c48e9833d.tar.gz/md5/aa445967f00e19fef56c7072c72a6832 +blastrampoline-072b5f67895bec0b92f8c83194567c1c48e9833d.tar.gz/sha512/3185a39b553c9cb9f6171755462f52f1d164ec3d7ad83274cb4557e6cf5d6cef3bd7447f85c27ebcb3b1c76da0a547f978099bd554688bc769dd8ded654a2ad2 +libblastrampoline.v5.15.0+0.aarch64-apple-darwin.tar.gz/md5/d816e41ff36472e67d9d815f8db5b75d +libblastrampoline.v5.15.0+0.aarch64-apple-darwin.tar.gz/sha512/b4c844f6f7f4d917629fb27dcaabb70f46f362b2fc0b4686df56c39e46251328ee323d01e09609988ebfa76d123eac033641fae14f4a48bfbe4b20b77ef745a9 +libblastrampoline.v5.15.0+0.aarch64-linux-gnu.tar.gz/md5/375e826ab5bdaf34b71c61eafc9deac8 +libblastrampoline.v5.15.0+0.aarch64-linux-gnu.tar.gz/sha512/2f8503aea3454136800f51fd3edf3b26efd1bab194d33fc9a302b00cff00b237462bd2a9409016656ac8e9904244004f4725d3388f29da4512b962f018af0609 +libblastrampoline.v5.15.0+0.aarch64-linux-musl.tar.gz/md5/f1c90626a26885bac905ad6ed9c26b46 +libblastrampoline.v5.15.0+0.aarch64-linux-musl.tar.gz/sha512/0cd900176f4b5e628b54fdfb4f9504fb6b352f92b97a1b3cb102343c94ffddb37b564a5d682d36631af3b03f6b4a49ad7e33f473f8450d95f74e3f986f39b780 +libblastrampoline.v5.15.0+0.aarch64-unknown-freebsd.tar.gz/md5/b9025566d8ba21fa10f55065bd9e3795 +libblastrampoline.v5.15.0+0.aarch64-unknown-freebsd.tar.gz/sha512/97ef1dd8116c4fc89cfa35d8f8674885e3b425d30cd45ab727ae98cf5f9b2b481352217bf2a01e6d3e0f5a95700c1771c15db4dcd73312c6d3286895c04c6f6b +libblastrampoline.v5.15.0+0.armv6l-linux-gnueabihf.tar.gz/md5/24e043853904f395436db5045add7e2c +libblastrampoline.v5.15.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/8948720cc3cf46ec0c7489ea90e8defd24eaebaaf0c9a98a0de13bdfffdd732311f1e1608078573a30e3170ad543eb0caf31a500255827482af526957bccacbb +libblastrampoline.v5.15.0+0.armv6l-linux-musleabihf.tar.gz/md5/3cbbb1c09d1731e9dd29dd9350110aae +libblastrampoline.v5.15.0+0.armv6l-linux-musleabihf.tar.gz/sha512/f1806cb4a1b59a78027291ca01481f2d6acf74340c3bc9534af93c3874aa6774dd4c6b5cf7b1bf98b028602d74b9301b0250fad9d2c2e0e02188c604f63e1559 +libblastrampoline.v5.15.0+0.armv7l-linux-gnueabihf.tar.gz/md5/da36360de121353b213c488158c264ed +libblastrampoline.v5.15.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/25883ac30da9a14816e295545a7f8135c20adc3e2e3ab7b374a8796bcfef31b57ab1bc8f4788aef53e2f02d2b795ee89181f143b30132a8af531f019a0219a72 +libblastrampoline.v5.15.0+0.armv7l-linux-musleabihf.tar.gz/md5/7062e23f7549d790cb2c6ff5ef96aff6 +libblastrampoline.v5.15.0+0.armv7l-linux-musleabihf.tar.gz/sha512/06f3da585d720801c840ded52cb29b25364e892b1c1b895ee49a37bde721063757da0f7da4336c9dd518b6269f3c47b2b109d6d37d0a578d805fffe814c239f1 +libblastrampoline.v5.15.0+0.i686-linux-gnu.tar.gz/md5/fe7d22677ec883261429c0201210e35c +libblastrampoline.v5.15.0+0.i686-linux-gnu.tar.gz/sha512/b99713ae9a00bffdca3001a1a8a84b99e1b3194a755d1a52eb7a73cd8d0571adfb8746b182cb62b3a3e8f7584ae49ece89d503af032b0485b3e6e832bd17de83 +libblastrampoline.v5.15.0+0.i686-linux-musl.tar.gz/md5/3a54aba695352019a507a44d49d4b73a +libblastrampoline.v5.15.0+0.i686-linux-musl.tar.gz/sha512/9a3baeb75551ec14b58eb370730a50bd0023aa63610d47e492d08dd4d54ff8afca4b8c9b34501ba5eaf2dab02922b88cfeb6ea9383b58783337999eb966f2f0e +libblastrampoline.v5.15.0+0.i686-w64-mingw32.tar.gz/md5/f8424745959e7bce3a804ccee41b30bf +libblastrampoline.v5.15.0+0.i686-w64-mingw32.tar.gz/sha512/1b0e877098e666a0ffa7d057f60a1063d710d598ee8a53094815237d98119f5101c4e643fce7190ce22ce3787249920ab7dc6ff2dc1e3088cd95779b19e17bf7 +libblastrampoline.v5.15.0+0.powerpc64le-linux-gnu.tar.gz/md5/927bb0e1a4b5e3ceb225bd8c0f75ec77 +libblastrampoline.v5.15.0+0.powerpc64le-linux-gnu.tar.gz/sha512/a414a84fb45d2666dfd72cd9d6e013481e95c8d6d7cae40939bef779c14fe50d0a8473ddeb7d6060fcc8c4531cd34bd06ff6bbc7a44a6b106b8d0e2c8d62bdbd +libblastrampoline.v5.15.0+0.riscv64-linux-gnu.tar.gz/md5/3369a45ed2b52482ca2a83ddb515e08b +libblastrampoline.v5.15.0+0.riscv64-linux-gnu.tar.gz/sha512/68ceb3dea1ebb1689892f05b6c7ab5a088b5249cab5a70bba8164d6290b74634deaa9aa3cfa5c84de836313ac0569542280a48623f95b3744746b2f8984c1d37 +libblastrampoline.v5.15.0+0.x86_64-apple-darwin.tar.gz/md5/07e63e6ef01f2bde3f80b724170991fb +libblastrampoline.v5.15.0+0.x86_64-apple-darwin.tar.gz/sha512/361689ede0771148e353a4b911fef76839754ddf8f735a60d597b8c523569e206b5daede3885e3ec1302e9e4ca5488b6ea203bd3ed384ccd607934d813b27ba7 +libblastrampoline.v5.15.0+0.x86_64-linux-gnu.tar.gz/md5/e7bcbd90bb3f7d4f197269b3f64cfc4c +libblastrampoline.v5.15.0+0.x86_64-linux-gnu.tar.gz/sha512/5a55c9b10460bf9472c18fc381cf941d10443b9a089c7e774b4e9456c11a100dd61788c9c5139f77504f0b0bce7e4567b1e002386c402695c968632280b4d316 +libblastrampoline.v5.15.0+0.x86_64-linux-musl.tar.gz/md5/bb8bacb2748137adfb0aa83834bc72d0 +libblastrampoline.v5.15.0+0.x86_64-linux-musl.tar.gz/sha512/5d683868e377d2aee34fb2699f8c3733714d2c7cf0ac7ddb1d35a78460015d784b9e00f8d30e8bc6ee570a47de6baaa7f7efd90790588cc2953cd19897c56a92 +libblastrampoline.v5.15.0+0.x86_64-unknown-freebsd.tar.gz/md5/60e6833b6e7656db680032c0d1b5d5b7 +libblastrampoline.v5.15.0+0.x86_64-unknown-freebsd.tar.gz/sha512/ca155fcc0b66889fe608291738e5e4c8506d28c42e03a948e4e56d441949be1d1dcbd201ba0f2536c862da3d8fdf7c7ee77a9b0b715dc1b9893767510ff0ffb9 +libblastrampoline.v5.15.0+0.x86_64-w64-mingw32.tar.gz/md5/950ec7ca747e8f13cfb7bd1967af5db6 +libblastrampoline.v5.15.0+0.x86_64-w64-mingw32.tar.gz/sha512/6dbcde726cf3b1e2ecc91913b3ff954881706381fcd97907173fd8c21aff6708a9f6998f510356c7f284f826ee67264509831752399efe7163a4baaeb071c3c8 diff --git a/doc/src/manual/code-loading.md b/doc/src/manual/code-loading.md index 24e64b0ca068e..9b17518d32882 100644 --- a/doc/src/manual/code-loading.md +++ b/doc/src/manual/code-loading.md @@ -42,6 +42,9 @@ These environment each serve a different purpose: * Package directories provide **convenience** when a full carefully-tracked project environment is unnecessary. They are useful when you want to put a set of packages somewhere and be able to directly use them, without needing to create a project environment for them. * Stacked environments allow for **adding** tools to the primary environment. You can push an environment of development tools onto the end of the stack to make them available from the REPL and scripts, but not from inside packages. +!!! note + When loading a package from another environment in the stack other than the active environment the package is loaded in the context of the active environment. This means that the package will be loaded as if it were imported in the active environment, which may affect how its dependencies versions are resolved. When such a package is precompiling it will be marked as a `(serial)` precompile job, which means that its dependencies will be precompiled in series within the same job, which will likely be slower. + At a high-level, each environment conceptually defines three maps: roots, graph and paths. When resolving the meaning of `import X`, the roots and graph maps are used to determine the identity of `X`, while the paths map is used to locate the source code of `X`. The specific roles of the three maps are: - **roots:** `name::Symbol` ⟢ `uuid::UUID` diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index c0a0bd2d14460..6009bd435534c 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -1083,7 +1083,6 @@ static FunctionInfo getFunctionWeight(const Function &F) } struct ModuleInfo { - Triple triple; size_t globals; size_t funcs; size_t bbs; @@ -1094,7 +1093,6 @@ struct ModuleInfo { ModuleInfo compute_module_info(Module &M) { ModuleInfo info; - info.triple = Triple(M.getTargetTriple()); info.globals = 0; info.funcs = 0; info.bbs = 0; @@ -1895,12 +1893,6 @@ static unsigned compute_image_thread_count(const ModuleInfo &info) { #endif if (jl_is_timing_passes) // LLVM isn't thread safe when timing the passes https://github.com/llvm/llvm-project/issues/44417 return 1; - // COFF has limits on external symbols (even hidden) up to 65536. We reserve the last few - // for any of our other symbols that we insert during compilation. - if (info.triple.isOSBinFormatCOFF() && info.globals > 64000) { - LLVM_DEBUG(dbgs() << "COFF is restricted to a single thread for large images\n"); - return 1; - } // This is not overridable because empty modules do occasionally appear, but they'll be very small and thus exit early to // known easy behavior. Plus they really don't warrant multiple threads if (info.weight < 1000) { diff --git a/src/codegen.cpp b/src/codegen.cpp index 3189171e9b30a..8f0644c0cff7f 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3251,8 +3251,7 @@ static jl_cgval_t emit_globalop(jl_codectx_t &ctx, jl_module_t *mod, jl_sym_t *s if (ty != nullptr) { const std::string fname = issetglobal ? "setglobal!" : isreplaceglobal ? "replaceglobal!" : isswapglobal ? "swapglobal!" : ismodifyglobal ? "modifyglobal!" : "setglobalonce!"; if (!ismodifyglobal) { - // TODO: use typeassert in jl_check_binding_assign_value too - emit_typecheck(ctx, rval, ty, "typeassert"); + emit_typecheck(ctx, rval, ty, fname.c_str()); rval = update_julia_type(ctx, rval, ty); if (rval.typ == jl_bottom_type) return jl_cgval_t(); diff --git a/src/datatype.c b/src/datatype.c index 5c771ed2a003a..4cf2c6d780bbd 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -1981,11 +1981,11 @@ jl_value_t *swap_nth_field(jl_datatype_t *st, jl_value_t *v, size_t i, jl_value_ } } -inline jl_value_t *modify_value(jl_value_t *ty, _Atomic(jl_value_t*) *p, jl_value_t *parent, jl_value_t *op, jl_value_t *rhs, int isatomic, jl_module_t *mod, jl_sym_t *name) +inline jl_value_t *modify_value(jl_value_t *ty, _Atomic(jl_value_t*) *p, jl_value_t *parent, jl_value_t *op, jl_value_t *rhs, int isatomic, jl_binding_t *b, jl_module_t *mod, jl_sym_t *name) { jl_value_t *r = isatomic ? jl_atomic_load(p) : jl_atomic_load_relaxed(p); if (__unlikely(r == NULL)) { - if (mod && name) + if (b) jl_undefined_var_error(name, (jl_value_t*)mod); jl_throw(jl_undefref_exception); } @@ -1996,11 +1996,10 @@ inline jl_value_t *modify_value(jl_value_t *ty, _Atomic(jl_value_t*) *p, jl_valu args[1] = rhs; jl_value_t *y = jl_apply_generic(op, args, 2); args[1] = y; - if (!jl_isa(y, ty)) { - if (mod && name) - jl_errorf("cannot assign an incompatible value to the global %s.%s.", jl_symbol_name(mod->name), jl_symbol_name(name)); + if (b) + jl_check_binding_assign_value(b, mod, name, y, "modifyglobal!"); + else if (!jl_isa(y, ty)) jl_type_error(jl_is_genericmemory(parent) ? "memoryrefmodify!" : "modifyfield!", ty, y); - } if (isatomic ? jl_atomic_cmpswap(p, &r, y) : jl_atomic_cmpswap_release(p, &r, y)) { jl_gc_wb(parent, y); break; @@ -2114,7 +2113,7 @@ jl_value_t *modify_nth_field(jl_datatype_t *st, jl_value_t *v, size_t i, jl_valu jl_value_t *ty = jl_field_type_concrete(st, i); char *p = (char*)v + offs; if (jl_field_isptr(st, i)) { - return modify_value(ty, (_Atomic(jl_value_t*)*)p, v, op, rhs, isatomic, NULL, NULL); + return modify_value(ty, (_Atomic(jl_value_t*)*)p, v, op, rhs, isatomic, NULL, NULL, NULL); } else { uint8_t *psel = jl_is_uniontype(ty) ? (uint8_t*)&p[jl_field_size(st, i) - 1] : NULL; diff --git a/src/genericmemory.c b/src/genericmemory.c index e35ed5e5ac5b3..32adc1add3d06 100644 --- a/src/genericmemory.c +++ b/src/genericmemory.c @@ -543,7 +543,7 @@ JL_DLLEXPORT jl_value_t *jl_memoryrefmodify(jl_genericmemoryref_t m, jl_value_t char *data = (char*)m.ptr_or_offset; if (layout->flags.arrayelem_isboxed) { assert(data - (char*)m.mem->ptr < sizeof(jl_value_t*) * m.mem->length); - return modify_value(eltype, (_Atomic(jl_value_t*)*)data, owner, op, rhs, isatomic, NULL, NULL); + return modify_value(eltype, (_Atomic(jl_value_t*)*)data, owner, op, rhs, isatomic, NULL, NULL, NULL); } size_t fsz = layout->size; uint8_t *psel = NULL; diff --git a/src/gf.c b/src/gf.c index b13830c1e1ba9..47db5474701ac 100644 --- a/src/gf.c +++ b/src/gf.c @@ -3683,7 +3683,7 @@ JL_DLLEXPORT jl_value_t *jl_normalize_to_compilable_sig(jl_tupletype_t *ti, jl_s jl_method_instance_t *jl_normalize_to_compilable_mi(jl_method_instance_t *mi JL_PROPAGATES_ROOT) { jl_method_t *def = mi->def.method; - if (!jl_is_method(def) || !jl_is_datatype(mi->specTypes)) + if (!jl_is_method(def) || !jl_is_datatype(mi->specTypes) || def->is_for_opaque_closure) return mi; jl_value_t *compilationsig = jl_normalize_to_compilable_sig((jl_datatype_t*)mi->specTypes, mi->sparam_vals, def, 1); if (compilationsig == jl_nothing || jl_egal(compilationsig, mi->specTypes)) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index e9ba0bb251082..aad8105b34308 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -1895,7 +1895,7 @@ ,(expand-update-operator op op= (car e) rhs T)))) (else (if (and (pair? lhs) (eq? op= '=) - (not (memq (car lhs) '(|.| tuple vcat ncat typed_hcat typed_vcat typed_ncat)))) + (not (memq (car lhs) '(|.| globalref tuple vcat ncat typed_hcat typed_vcat typed_ncat)))) (error (string "invalid assignment location \"" (deparse lhs) "\""))) (expand-update-operator- op op= lhs rhs declT)))) @@ -5032,6 +5032,7 @@ f(x) = yt(x) (check-top-level e) (let ((val (make-ssavalue))) (emit `(= ,val ,e)) + (emit `(latestworld)) (if tail (emit-return tail val)) val)) diff --git a/src/julia.h b/src/julia.h index e8322119299a3..7cda8fd456f74 100644 --- a/src/julia.h +++ b/src/julia.h @@ -2121,7 +2121,7 @@ JL_DLLEXPORT jl_value_t *jl_get_module_binding_or_nothing(jl_module_t *m, jl_sym // get binding for reading JL_DLLEXPORT jl_binding_t *jl_get_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var); -JL_DLLEXPORT jl_value_t *jl_module_globalref(jl_module_t *m, jl_sym_t *var); +JL_DLLEXPORT jl_value_t *jl_module_globalref(jl_module_t *m, jl_sym_t *var) JL_GLOBALLY_ROOTED; JL_DLLEXPORT jl_value_t *jl_get_binding_type(jl_module_t *m, jl_sym_t *var); // get binding for assignment JL_DLLEXPORT void jl_check_binding_currently_writable(jl_binding_t *b, jl_module_t *m, jl_sym_t *s); @@ -2197,6 +2197,10 @@ JL_DLLEXPORT void JL_NORETURN jl_type_error_rt(const char *fname, const char *context, jl_value_t *ty JL_MAYBE_UNROOTED, jl_value_t *got JL_MAYBE_UNROOTED); +JL_DLLEXPORT void JL_NORETURN jl_type_error_global(const char *fname, + jl_module_t *mod, jl_sym_t *sym, + jl_value_t *ty JL_MAYBE_UNROOTED, + jl_value_t *got JL_MAYBE_UNROOTED); JL_DLLEXPORT void JL_NORETURN jl_undefined_var_error(jl_sym_t *var, jl_value_t *scope JL_MAYBE_UNROOTED); JL_DLLEXPORT void JL_NORETURN jl_has_no_field_error(jl_datatype_t *t, jl_sym_t *var); JL_DLLEXPORT void JL_NORETURN jl_argument_error(char *str); diff --git a/src/julia_internal.h b/src/julia_internal.h index 9473f6be4b898..c9e1b0e204df6 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -851,7 +851,7 @@ int set_nth_fieldonce(jl_datatype_t *st, jl_value_t *v, size_t i, jl_value_t *rh jl_value_t *swap_bits(jl_value_t *ty, char *v, uint8_t *psel, jl_value_t *parent, jl_value_t *rhs, enum atomic_kind isatomic); jl_value_t *replace_value(jl_value_t *ty, _Atomic(jl_value_t*) *p, jl_value_t *parent, jl_value_t *expected, jl_value_t *rhs, int isatomic, jl_module_t *mod, jl_sym_t *name); jl_value_t *replace_bits(jl_value_t *ty, char *p, uint8_t *psel, jl_value_t *parent, jl_value_t *expected, jl_value_t *rhs, enum atomic_kind isatomic); -jl_value_t *modify_value(jl_value_t *ty, _Atomic(jl_value_t*) *p, jl_value_t *parent, jl_value_t *op, jl_value_t *rhs, int isatomic, jl_module_t *mod, jl_sym_t *name); +jl_value_t *modify_value(jl_value_t *ty, _Atomic(jl_value_t*) *p, jl_value_t *parent, jl_value_t *op, jl_value_t *rhs, int isatomic, jl_binding_t *b, jl_module_t *mod, jl_sym_t *name); jl_value_t *modify_bits(jl_value_t *ty, char *p, uint8_t *psel, jl_value_t *parent, jl_value_t *op, jl_value_t *rhs, enum atomic_kind isatomic); int setonce_bits(jl_datatype_t *rty, char *p, jl_value_t *owner, jl_value_t *rhs, enum atomic_kind isatomic); jl_expr_t *jl_exprn(jl_sym_t *head, size_t n); @@ -865,6 +865,7 @@ JL_DLLEXPORT int jl_datatype_isinlinealloc(jl_datatype_t *ty, int pointerfree); int jl_type_equality_is_identity(jl_value_t *t1, jl_value_t *t2) JL_NOTSAFEPOINT; JL_DLLEXPORT void jl_eval_const_decl(jl_module_t *m, jl_value_t *arg, jl_value_t *val); +jl_value_t *jl_check_binding_assign_value(jl_binding_t *b JL_PROPAGATES_ROOT, jl_module_t *mod, jl_sym_t *var, jl_value_t *rhs JL_MAYBE_UNROOTED, const char *msg); void jl_binding_set_type(jl_binding_t *b, jl_module_t *mod, jl_sym_t *sym, jl_value_t *ty); void jl_eval_global_expr(jl_module_t *m, jl_expr_t *ex, int set_type); JL_DLLEXPORT void jl_declare_global(jl_module_t *m, jl_value_t *arg, jl_value_t *set_type, int strong); @@ -1500,6 +1501,7 @@ JL_DLLEXPORT void jl_raise_debugger(void) JL_NOTSAFEPOINT; JL_DLLEXPORT void jl_gdblookup(void* ip) JL_NOTSAFEPOINT; void jl_print_native_codeloc(uintptr_t ip) JL_NOTSAFEPOINT; void jl_print_bt_entry_codeloc(jl_bt_element_t *bt_data) JL_NOTSAFEPOINT; +JL_DLLEXPORT void jl_print_task_backtraces(int show_done) JL_NOTSAFEPOINT; #ifdef _OS_WINDOWS_ JL_DLLEXPORT void jl_refresh_dbg_module_list(void); #endif diff --git a/src/module.c b/src/module.c index b5d3e785bc96c..60d2652ddfaaa 100644 --- a/src/module.c +++ b/src/module.c @@ -1877,7 +1877,7 @@ void jl_binding_deprecation_warning(jl_binding_t *b) // For a generally writable binding (checked using jl_check_binding_currently_writable in this world age), check whether // we can actually write the value `rhs` to it. -jl_value_t *jl_check_binding_assign_value(jl_binding_t *b JL_PROPAGATES_ROOT, jl_module_t *mod, jl_sym_t *var, jl_value_t *rhs JL_MAYBE_UNROOTED) +jl_value_t *jl_check_binding_assign_value(jl_binding_t *b JL_PROPAGATES_ROOT, jl_module_t *mod, jl_sym_t *var, jl_value_t *rhs JL_MAYBE_UNROOTED, const char *msg) { JL_GC_PUSH1(&rhs); // callee-rooted jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age); @@ -1885,10 +1885,8 @@ jl_value_t *jl_check_binding_assign_value(jl_binding_t *b JL_PROPAGATES_ROOT, jl assert(kind == PARTITION_KIND_DECLARED || kind == PARTITION_KIND_GLOBAL); jl_value_t *old_ty = kind == PARTITION_KIND_DECLARED ? (jl_value_t*)jl_any_type : bpart->restriction; JL_GC_PROMISE_ROOTED(old_ty); - if (old_ty != (jl_value_t*)jl_any_type && jl_typeof(rhs) != old_ty) { - if (!jl_isa(rhs, old_ty)) - jl_errorf("cannot assign an incompatible value to the global %s.%s.", - jl_symbol_name(mod->name), jl_symbol_name(var)); + if (old_ty != (jl_value_t*)jl_any_type && jl_typeof(rhs) != old_ty && !jl_isa(rhs, old_ty)) { + jl_type_error_global(msg, mod, var, old_ty, rhs); } JL_GC_POP(); return old_ty; @@ -1896,7 +1894,7 @@ jl_value_t *jl_check_binding_assign_value(jl_binding_t *b JL_PROPAGATES_ROOT, jl JL_DLLEXPORT void jl_checked_assignment(jl_binding_t *b, jl_module_t *mod, jl_sym_t *var, jl_value_t *rhs) { - if (jl_check_binding_assign_value(b, mod, var, rhs) != NULL) { + if (jl_check_binding_assign_value(b, mod, var, rhs, "setglobal!") != NULL) { jl_atomic_store_release(&b->value, rhs); jl_gc_wb(b, rhs); } @@ -1904,7 +1902,7 @@ JL_DLLEXPORT void jl_checked_assignment(jl_binding_t *b, jl_module_t *mod, jl_sy JL_DLLEXPORT jl_value_t *jl_checked_swap(jl_binding_t *b, jl_module_t *mod, jl_sym_t *var, jl_value_t *rhs) { - jl_check_binding_assign_value(b, mod, var, rhs); + jl_check_binding_assign_value(b, mod, var, rhs, "swapglobal!"); jl_value_t *old = jl_atomic_exchange(&b->value, rhs); jl_gc_wb(b, rhs); if (__unlikely(old == NULL)) @@ -1914,7 +1912,7 @@ JL_DLLEXPORT jl_value_t *jl_checked_swap(jl_binding_t *b, jl_module_t *mod, jl_s JL_DLLEXPORT jl_value_t *jl_checked_replace(jl_binding_t *b, jl_module_t *mod, jl_sym_t *var, jl_value_t *expected, jl_value_t *rhs) { - jl_value_t *ty = jl_check_binding_assign_value(b, mod, var, rhs); + jl_value_t *ty = jl_check_binding_assign_value(b, mod, var, rhs, "replaceglobal!"); return replace_value(ty, &b->value, (jl_value_t*)b, expected, rhs, 1, mod, var); } @@ -1928,12 +1926,12 @@ JL_DLLEXPORT jl_value_t *jl_checked_modify(jl_binding_t *b, jl_module_t *mod, jl jl_symbol_name(mod->name), jl_symbol_name(var)); jl_value_t *ty = bpart->restriction; JL_GC_PROMISE_ROOTED(ty); - return modify_value(ty, &b->value, (jl_value_t*)b, op, rhs, 1, mod, var); + return modify_value(ty, &b->value, (jl_value_t*)b, op, rhs, 1, b, mod, var); } JL_DLLEXPORT jl_value_t *jl_checked_assignonce(jl_binding_t *b, jl_module_t *mod, jl_sym_t *var, jl_value_t *rhs ) { - jl_check_binding_assign_value(b, mod, var, rhs); + jl_check_binding_assign_value(b, mod, var, rhs, "setglobalonce!"); jl_value_t *old = NULL; if (jl_atomic_cmpswap(&b->value, &old, rhs)) jl_gc_wb(b, rhs); diff --git a/src/rtutils.c b/src/rtutils.c index 2976e56b4195d..6d4a375017bf2 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -121,6 +121,16 @@ JL_DLLEXPORT void JL_NORETURN jl_type_error_rt(const char *fname, const char *co jl_throw(ex); } +JL_DLLEXPORT void JL_NORETURN jl_type_error_global(const char *fname, jl_module_t *mod, jl_sym_t *sym, + jl_value_t *expected JL_MAYBE_UNROOTED, + jl_value_t *got JL_MAYBE_UNROOTED) +{ + jl_value_t *gr = jl_module_globalref(mod, sym); + jl_value_t *ex = jl_new_struct(jl_typeerror_type, jl_symbol(fname), gr, expected, got); + jl_throw(ex); +} + + // with function name or description only JL_DLLEXPORT void JL_NORETURN jl_type_error(const char *fname, jl_value_t *expected JL_MAYBE_UNROOTED, diff --git a/src/signal-handling.c b/src/signal-handling.c index 6e19028ca7940..b03f0c1a430cd 100644 --- a/src/signal-handling.c +++ b/src/signal-handling.c @@ -636,6 +636,9 @@ void jl_critical_error(int sig, int si_code, bt_context_t *context, jl_task_t *c jl_safe_printf("\n[%d] signal %d (%d): %s\n", getpid(), sig, si_code, strsignal(sig)); else jl_safe_printf("\n[%d] signal %d: %s\n", getpid(), sig, strsignal(sig)); + if (sig == SIGQUIT) { + jl_print_task_backtraces(0); + } } jl_safe_printf("in expression starting at %s:%d\n", jl_filename, jl_lineno); if (context && ct) { diff --git a/src/stackwalk.c b/src/stackwalk.c index 1f3c8d690c8ce..50566b46ff45a 100644 --- a/src/stackwalk.c +++ b/src/stackwalk.c @@ -1383,11 +1383,19 @@ JL_DLLEXPORT void jlbacktrace(void) JL_NOTSAFEPOINT // Print backtrace for specified task to jl_safe_printf stderr JL_DLLEXPORT void jlbacktracet(jl_task_t *t) JL_NOTSAFEPOINT { - jl_task_t *ct = jl_current_task; - jl_ptls_t ptls = ct->ptls; - ptls->bt_size = 0; - jl_bt_element_t *bt_data = ptls->bt_data; - jl_record_backtrace_result_t r = jl_record_backtrace(t, bt_data, JL_MAX_BT_SIZE, 0); + jl_bt_element_t *bt_data; + jl_task_t *ct = jl_get_current_task(); + size_t max_bt_size; + if (ct && ct->ptls != NULL) { + jl_ptls_t ptls = ct->ptls; + ptls->bt_size = 0; + bt_data = ptls->bt_data; + max_bt_size = JL_MAX_BT_SIZE; + } else { + max_bt_size = 1024; //8kb of stack should be safe + bt_data = (jl_bt_element_t *)alloca(max_bt_size * sizeof(jl_bt_element_t)); + } + jl_record_backtrace_result_t r = jl_record_backtrace(t, bt_data, max_bt_size, 0); size_t bt_size = r.bt_size; size_t i; for (i = 0; i < bt_size; i += jl_bt_entry_size(bt_data + i)) { diff --git a/stdlib/InteractiveUtils/src/codeview.jl b/stdlib/InteractiveUtils/src/codeview.jl index 1aa83a19285ff..a93a00dd4f0a6 100644 --- a/stdlib/InteractiveUtils/src/codeview.jl +++ b/stdlib/InteractiveUtils/src/codeview.jl @@ -176,7 +176,8 @@ function code_warntype(io::IO, @nospecialize(f), @nospecialize(tt=Base.default_t end nothing end -code_warntype(args...; kwargs...) = (@nospecialize; code_warntype(stdout, args...; kwargs...)) +code_warntype(f; kwargs...) = (@nospecialize; code_warntype(stdout, f; kwargs...)) +code_warntype(f, argtypes; kwargs...) = (@nospecialize; code_warntype(stdout, f, argtypes; kwargs...)) using Base: CodegenParams diff --git a/stdlib/Mmap/src/Mmap.jl b/stdlib/Mmap/src/Mmap.jl index c527123d51bb8..fb6bb72026588 100644 --- a/stdlib/Mmap/src/Mmap.jl +++ b/stdlib/Mmap/src/Mmap.jl @@ -199,7 +199,7 @@ function mmap(io::IO, overflow && throw(ArgumentError("requested size prod($((len, dims...))) too large, would overflow typeof(size(T)) == $(typeof(len))")) end len >= 0 || throw(ArgumentError("requested size must be β‰₯ 0, got $len")) - len == 0 && return Array{T}(undef, ntuple(x->0,Val(N))) + len == 0 && return Array{T}(undef, dims) len < typemax(Int) - PAGESIZE || throw(ArgumentError("requested size must be < $(typemax(Int)-PAGESIZE), got $len")) offset >= 0 || throw(ArgumentError("requested offset must be β‰₯ 0, got $offset")) diff --git a/stdlib/Mmap/test/runtests.jl b/stdlib/Mmap/test/runtests.jl index 0c34c49d400a7..d129c0ee94295 100644 --- a/stdlib/Mmap/test/runtests.jl +++ b/stdlib/Mmap/test/runtests.jl @@ -11,12 +11,13 @@ GC.gc(); GC.gc() GC.gc(); GC.gc() @test mmap(file, Array{UInt8,3}, (1,1,11)) == reshape(t,(1,1,11)) GC.gc(); GC.gc() -@test mmap(file, Array{UInt8,3}, (11,0,1)) == Array{UInt8}(undef, (0,0,0)) +@test size(mmap(file, Array{UInt8,3}, (11,0,1))) == (11,0,1) @test mmap(file, Vector{UInt8}, (11,)) == t GC.gc(); GC.gc() @test mmap(file, Array{UInt8,2}, (1,11)) == t' GC.gc(); GC.gc() -@test mmap(file, Array{UInt8,2}, (0,12)) == Array{UInt8}(undef, (0,0)) +@test size(mmap(file, Array{UInt8,2}, (0,12))) == (0,12) +@test size(mmap(file, Matrix{Float32}, (10,0))) == (10,0) m = mmap(file, Array{UInt8,3}, (1,2,1)) @test m == reshape(b"He",(1,2,1)) finalize(m); m=nothing; GC.gc() diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 865c71e8767ac..7f2e0b664dcc1 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = release-1.12 -PKG_SHA1 = 69926e385c878253d62e2588a19b252277196ebf +PKG_SHA1 = f571edda902c848382517503665fea6aa275ceb9 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/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index b0abb6e78f997..f82068c372b3b 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -1845,25 +1845,10 @@ function repl_eval_counter(hp) end function out_transform(@nospecialize(x), n::Ref{Int}) - return Expr(:toplevel, get_usings!([], x)..., quote - let __temp_val_a72df459 = $x - $capture_result($n, __temp_val_a72df459) - __temp_val_a72df459 - end - end) -end - -function get_usings!(usings, ex) - ex isa Expr || return usings - # get all `using` and `import` statements which are at the top level - for (i, arg) in enumerate(ex.args) - if Base.isexpr(arg, :toplevel) - get_usings!(usings, arg) - elseif Base.isexpr(arg, [:using, :import]) - push!(usings, popat!(ex.args, i)) - end - end - return usings + return Expr(:block, # avoid line numbers or scope that would leak into the output and change the meaning of x + :(local __temp_val_a72df459 = $x), + Expr(:call, capture_result, n, :__temp_val_a72df459), + :__temp_val_a72df459) end function create_global_out!(mod) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 03b4b4fec98f1..8c39231153fcc 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -698,6 +698,15 @@ code_typed(CC.typeinf, (REPLInterpreter, CC.InferenceState)) MAX_METHOD_COMPLETIONS::Int = 40 function _complete_methods(ex_org::Expr, context_module::Module, shift::Bool) isempty(ex_org.args) && return 2, nothing, [], Set{Symbol}() + # Desugar do block call into call with lambda + if ex_org.head === :do && length(ex_org.args) >= 2 + ex_call = ex_org.args[1] + ex_args = [x for x in ex_call.args if !(x isa Expr && x.head === :parameters)] + ex_params = findfirst(x -> x isa Expr && x.head === :parameters, ex_call.args) + new_args = [ex_args[1], ex_org.args[end], ex_args[2:end]...] + ex_params !== nothing && push!(new_args, ex_call.args[ex_params]) + ex_org = Expr(:call, new_args...) + end funct = repl_eval_ex(ex_org.args[1], context_module) funct === nothing && return 2, nothing, [], Set{Symbol}() funct = CC.widenconst(funct) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index 5e0a30abb4137..52153a12f606f 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -640,7 +640,7 @@ function _repl(x, brief::Bool=true, mod::Module=Main, internal_accesses::Union{N docs = esc(:(@doc $x)) docs = if isfield(x) quote - if isa($(esc(x.args[1])), DataType) + if $(esc(x.args[1])) isa Type fielddoc($(esc(x.args[1])), $(esc(x.args[2]))) else $docs @@ -684,6 +684,7 @@ function fielddoc(binding::Binding, field::Symbol) end # As with the additional `doc` methods, this converts an object to a `Binding` first. +fielddoc(obj::UnionAll, field::Symbol) = fielddoc(Base.unwrap_unionall(obj), field) fielddoc(object, field::Symbol) = fielddoc(aliasof(object, typeof(object)), field) diff --git a/stdlib/REPL/test/docview.jl b/stdlib/REPL/test/docview.jl index 8c92d9b3b1d95..0ac6f88d12ed6 100644 --- a/stdlib/REPL/test/docview.jl +++ b/stdlib/REPL/test/docview.jl @@ -111,6 +111,24 @@ end @test endswith(get_help_standard("Int.not_a_field"), "`$Int` has no fields.\n") end +@testset "Parametric struct field help (#59524)" begin + "NonParametricStruct docstring" + struct NonParametricStruct + "field_x docstring" + field_x::Float64 + end + + "ParametricStruct docstring" + struct ParametricStruct{T<:Real} + "field_y docstring" + field_y::T + end + + @test occursin("field_x docstring", get_help_standard("NonParametricStruct.field_x")) + @test occursin("field_y docstring", get_help_standard("ParametricStruct.field_y")) + @test endswith(get_help_standard("ParametricStruct.not_a_field"), "ParametricStruct` has field `field_y`.\n") +end + module InternalWarningsTests module A diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index 62cb6bbed8cb0..0ca3788d2b460 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -32,7 +32,7 @@ function kill_timer(delay) # **DON'T COPY ME.** # The correct way to handle timeouts is to close the handle: # e.g. `close(stdout_read); close(stdin_write)` - test_task.queue === nothing || Base.list_deletefirst!(test_task.queue::IntrusiveLinkedList{Task}, test_task) + test_task.queue === nothing || Base.list_deletefirst!(test_task.queue::Base.IntrusiveLinkedList{Task}, test_task) schedule(test_task, "hard kill repl test"; error=true) print(stderr, "WARNING: attempting hard kill of repl test after exceeding timeout\n") end diff --git a/stdlib/REPL/test/replcompletions.jl b/stdlib/REPL/test/replcompletions.jl index b3b141425e1a4..736f6fb405a41 100644 --- a/stdlib/REPL/test/replcompletions.jl +++ b/stdlib/REPL/test/replcompletions.jl @@ -139,6 +139,7 @@ let ex = kwtest4(a::SubString; x23, _something) = pass kwtest5(a::Int, b, x...; somekwarg, somekotherkwarg) = pass kwtest5(a::Char, b; xyz) = pass + kwtest6(f::Function, arg1; somekwarg) = pass const named = (; len2=3) const fmsoebelkv = (; len2=3) @@ -198,6 +199,8 @@ test_scomplete(s) = map_completion_text(@inferred(shell_completions(s, lastinde test_complete_pos(s) = map_completion_text(@inferred(completions(replace(s, '|' => ""), findfirst('|', s)-1))) test_complete_context(s, m=@__MODULE__; shift::Bool=true) = map_completion_text(@inferred(completions(s,lastindex(s), m, shift))) +test_complete_context_pos(s, m=@__MODULE__; shift::Bool=true) = + map_completion_text(@inferred(completions(replace(s, '|' => ""), findfirst('|', s)-1, m, shift))) test_complete_foo(s; shift::Bool=true) = test_complete_context(s, Main.CompletionFoo; shift) test_complete_noshift(s) = map_completion_text(@inferred(completions(s, lastindex(s), Main, false))) @@ -2720,3 +2723,10 @@ let s = "foo58296(findfi" @test "findfirst" in c @test r == 10:15 end + +# #58833 - Autocompletion of keyword arguments with do-blocks is broken +let s = "kwtest6(123; som|) do x; x + 3 end" + c, r = test_complete_context_pos(s, Main.CompletionFoo) + @test "somekwarg=" in c + @test r == 14:16 +end diff --git a/stdlib/libblastrampoline_jll/Project.toml b/stdlib/libblastrampoline_jll/Project.toml index 08e75ea061293..1356d2d6f27af 100644 --- a/stdlib/libblastrampoline_jll/Project.toml +++ b/stdlib/libblastrampoline_jll/Project.toml @@ -1,6 +1,6 @@ name = "libblastrampoline_jll" uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.13.1+1" +version = "5.15.0+0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/sysimage.mk b/sysimage.mk index 5faffc6b76990..310dbde37580a 100644 --- a/sysimage.mk +++ b/sysimage.mk @@ -7,7 +7,7 @@ include $(JULIAHOME)/stdlib/stdlib.mk default: sysimg-$(JULIA_BUILD_MODE) # contains either "debug" or "release" all: sysimg-release sysimg-debug basecompiler-ji: $(build_private_libdir)/basecompiler.ji -sysimg-ji: $(build_private_libdir)/sys.ji +sysimg-ji: $(build_private_libdir)/sysbase.ji sysimg-bc: $(build_private_libdir)/sys-bc.a sysimg-release: $(build_private_libdir)/sys.$(SHLIB_EXT) sysimg-debug: $(build_private_libdir)/sys-debug.$(SHLIB_EXT) @@ -69,28 +69,45 @@ RELDATADIR := $(call rel_path,$(JULIAHOME)/base,$(build_datarootdir))/ # <-- mak $(build_private_libdir)/basecompiler.ji: $(COMPILER_SRCS) @$(call PRINT_JULIA, cd $(JULIAHOME)/base && \ - JULIA_NUM_THREADS=1 $(call spawn,$(JULIA_EXECUTABLE)) -C "$(JULIA_CPU_TARGET)" $(HEAPLIM) --output-ji $(call cygpath_w,$@).tmp \ - --startup-file=no --warn-overwrite=yes --depwarn=error -g$(BOOTSTRAP_DEBUG_LEVEL) -O1 Base_compiler.jl --buildroot $(RELBUILDROOT) --dataroot $(RELDATADIR)) - @mv $@.tmp $@ - -$(build_private_libdir)/basecompiler-o.a $(build_private_libdir)/basecompiler-bc.a: $(build_private_libdir)/basecompiler-%.a : $(COMPILER_SRCS) - @$(call PRINT_JULIA, cd $(JULIAHOME)/base && \ - JULIA_NUM_THREADS=1 $(call spawn,$(JULIA_EXECUTABLE)) -C "$(JULIA_CPU_TARGET)" $(HEAPLIM) --output-$* $(call cygpath_w,$@).tmp \ + JULIA_NUM_THREADS=1 $(call spawn,$(JULIA_EXECUTABLE)) $(HEAPLIM) --output-ji $(call cygpath_w,$@).tmp \ --startup-file=no --warn-overwrite=yes -g$(BOOTSTRAP_DEBUG_LEVEL) -O1 Base_compiler.jl --buildroot $(RELBUILDROOT) --dataroot $(RELDATADIR)) @mv $@.tmp $@ -$(build_private_libdir)/sys.ji: $(build_private_libdir)/basecompiler.$(SHLIB_EXT) $(JULIAHOME)/VERSION $(BASE_SRCS) $(STDLIB_SRCS) - @$(call PRINT_JULIA, cd $(JULIAHOME)/base && \ - if ! JULIA_BINDIR=$(call cygpath_w,$(build_bindir)) WINEPATH="$(call cygpath_w,$(build_bindir));$$WINEPATH" \ - JULIA_NUM_THREADS=1 $(call spawn, $(JULIA_EXECUTABLE)) -g1 -O1 -C "$(JULIA_CPU_TARGET)" $(HEAPLIM) --output-ji $(call cygpath_w,$@).tmp $(JULIA_SYSIMG_BUILD_FLAGS) \ - --startup-file=no --warn-overwrite=yes --depwarn=error --sysimage $(call cygpath_w,$<) sysimg.jl --buildroot $(RELBUILDROOT) --dataroot $(RELDATADIR); then \ - echo '*** This error might be fixed by running `make clean`. If the error persists$(COMMA) try `make cleanall`. ***'; \ +define base_builder +$$(build_private_libdir)/basecompiler$1-o.a $$(build_private_libdir)/basecompiler$1-bc.a : $$(build_private_libdir)/basecompiler$1-%.a : $(COMPILER_SRCS) + @$$(call PRINT_JULIA, cd $$(JULIAHOME)/base && \ + WINEPATH="$$(call cygpath_w,$$(build_bindir));$$$$WINEPATH" \ + JULIA_NUM_THREADS=1 \ + $$(call spawn, $3) $2 -C "$$(JULIA_CPU_TARGET)" $$(HEAPLIM) --output-$$* $$(call cygpath_w,$$@).tmp \ + --startup-file=no --warn-overwrite=yes -g$$(BOOTSTRAP_DEBUG_LEVEL) Base_compiler.jl --buildroot $$(RELBUILDROOT) --dataroot $$(RELDATADIR)) + @mv $$@.tmp $$@ +$$(build_private_libdir)/sysbase$1.ji: $$(build_private_libdir)/basecompiler$1.$$(SHLIB_EXT) $$(JULIAHOME)/VERSION $$(BASE_SRCS) $$(STDLIB_SRCS) + @$$(call PRINT_JULIA, cd $$(JULIAHOME)/base && \ + if ! JULIA_BINDIR=$$(call cygpath_w,$$(build_bindir)) \ + WINEPATH="$$(call cygpath_w,$$(build_bindir));$$$$WINEPATH" \ + JULIA_NUM_THREADS=1 \ + $$(call spawn, $$(JULIA_EXECUTABLE)) -g1 $2 -C "$$(JULIA_CPU_TARGET)" $$(HEAPLIM) --output-ji $$(call cygpath_w,$$@).tmp $$(JULIA_SYSIMG_BUILD_FLAGS) \ + --startup-file=no --warn-overwrite=yes --sysimage $$(call cygpath_w,$$<) sysimg.jl --buildroot $$(RELBUILDROOT) --dataroot $$(RELDATADIR); then \ + echo '*** This error might be fixed by running `make clean`. If the error persists$$(COMMA) try `make cleanall`. ***'; \ false; \ fi ) - @mv $@.tmp $@ + @mv $$@.tmp $$@ +.SECONDARY: $$(build_private_libdir)/basecompiler$1-o.a $$(build_private_libdir)/basecompiler$1-bc.a $$(build_private_libdir)/sysbase$1.ji # request Make to keep these files around +endef define sysimg_builder -$$(build_private_libdir)/sys$1-o.a $$(build_private_libdir)/sys$1-bc.a : $$(build_private_libdir)/sys$1-%.a : $$(build_private_libdir)/sys.ji $$(JULIAHOME)/contrib/generate_precompile.jl +$$(build_private_libdir)/sysbase$1-o.a $$(build_private_libdir)/sysbase$1-bc.a : $$(build_private_libdir)/sysbase$1-%.a : $$(build_private_libdir)/basecompiler$1.$$(SHLIB_EXT) $$(JULIAHOME)/VERSION $$(BASE_SRCS) $$(STDLIB_SRCS) + @$$(call PRINT_JULIA, cd $$(JULIAHOME)/base && \ + if ! JULIA_BINDIR=$$(call cygpath_w,$$(build_bindir)) \ + WINEPATH="$$(call cygpath_w,$$(build_bindir));$$$$WINEPATH" \ + JULIA_NUM_THREADS=1 \ + $$(call spawn, $$(JULIA_EXECUTABLE)) -g1 $2 -C "$$(JULIA_CPU_TARGET)" $$(HEAPLIM) --output-$$* $$(call cygpath_w,$$@).tmp $$(JULIA_SYSIMG_BUILD_FLAGS) \ + --startup-file=no --warn-overwrite=yes --sysimage $$(call cygpath_w,$$<) sysimg.jl --buildroot $$(RELBUILDROOT) --dataroot $$(RELDATADIR); then \ + echo '*** This error might be fixed by running `make clean`. If the error persists$$(COMMA) try `make cleanall`. ***'; \ + false; \ + fi ) + @mv $$@.tmp $$@ +$$(build_private_libdir)/sys$1-o.a $$(build_private_libdir)/sys$1-bc.a : $$(build_private_libdir)/sys$1-%.a : $$(build_private_libdir)/sysbase$1.$$(SHLIB_EXT) $$(JULIAHOME)/contrib/generate_precompile.jl @$$(call PRINT_JULIA, cd $$(JULIAHOME)/base && \ if ! JULIA_BINDIR=$$(call cygpath_w,$(build_bindir)) \ WINEPATH="$$(call cygpath_w,$$(build_bindir));$$$$WINEPATH" \ @@ -105,6 +122,9 @@ $$(build_private_libdir)/sys$1-o.a $$(build_private_libdir)/sys$1-bc.a : $$(buil fi ) @mv $$@.tmp $$@ .SECONDARY: $$(build_private_libdir)/sys$1-o.a $(build_private_libdir)/sys$1-bc.a # request Make to keep these files around +.SECONDARY: $$(build_private_libdir)/sysbase$1-o.a $(build_private_libdir)/sysbase$1-bc.a # request Make to keep these files around endef +$(eval $(call base_builder,,-O1,$(JULIA_EXECUTABLE_release))) +$(eval $(call base_builder,-debug,-O0,$(JULIA_EXECUTABLE_debug))) $(eval $(call sysimg_builder,,-O3,$(JULIA_EXECUTABLE_release))) $(eval $(call sysimg_builder,-debug,-O0,$(JULIA_EXECUTABLE_debug))) diff --git a/test/arrayops.jl b/test/arrayops.jl index 836bbb1daec9a..d511988dd7a80 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -519,6 +519,12 @@ end v = empty!(collect(1:100)) pushfirst!(v, 1) @test length(v.ref.mem) == 100 + + # test that insert! at position 1 doesn't allocate for empty arrays with capacity (issue #58640) + v = empty!(Vector{Int}(undef, 5)) + insert!(v, 1, 10) + @test v == [10] + @test length(v.ref.mem) == 5 end @testset "popat!(::Vector, i, [default])" begin diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index 09cb4c1d6bf9a..75e338ea5d518 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -60,6 +60,32 @@ let @test format_filename("%a%%b") == "a%b" end +if Sys.isunix() + @testset "SIGQUIT prints task backtraces" begin + script = """ + mutable struct RLimit + cur::Int64 + max::Int64 + end + const RLIMIT_CORE = 4 # from /usr/include/sys/resource.h + ccall(:setrlimit, Cint, (Cint, Ref{RLimit}), RLIMIT_CORE, Ref(RLimit(0, 0))) + write(stdout, "r") + wait() + """ + exename = `$(Base.julia_cmd()) --startup-file=no --color=no` + errp = PipeBuffer() + # disable coredumps for this process + p = open(pipeline(`$exename -e $script`, stderr=errp), "r") + @test read(p, UInt8) == UInt8('r') + Base.kill(p, Base.SIGQUIT) + wait(p) + err_s = readchomp(errp) + @test Base.process_signaled(p) && p.termsignal == Base.SIGQUIT + @test occursin("==== Thread ", err_s) + @test occursin("==== Done", err_s) + end +end + @testset "julia_cmd" begin julia_basic = Base.julia_cmd() function get_julia_cmd(arg) diff --git a/test/compileall.jl b/test/compileall.jl index 1987bda7f04df..726cadbba68c8 100644 --- a/test/compileall.jl +++ b/test/compileall.jl @@ -2,8 +2,10 @@ # We make it a separate test target here, so that it can run in parallel # with the rest of the tests. +include("tempdepot.jl") + function precompile_test_harness(@nospecialize(f)) - load_path = mktempdir() + load_path = mkdepottempdir() try pushfirst!(LOAD_PATH, load_path) pushfirst!(DEPOT_PATH, load_path) diff --git a/test/core.jl b/test/core.jl index 5c4ba7c9722b2..d18f7fe8136b6 100644 --- a/test/core.jl +++ b/test/core.jl @@ -9,6 +9,8 @@ const Bottom = Union{} # For curmod_* include("testenv.jl") +include("tempdepot.jl") + ## tests that `const` field declarations # sanity tests that our built-in types are marked correctly for const fields @@ -6830,9 +6832,6 @@ Base._growat!(A, 4, 1) Base._growat!(A, 2, 3) @test getindex(A, 1) === 0x01 @test getindex(A, 2) === missing -@test getindex(A, 3) === missing -@test getindex(A, 4) === missing -@test getindex(A, 5) === missing @test getindex(A, 6) === 0x03 @test getindex(A, 7) === missing @test getindex(A, 8) === missing @@ -8134,7 +8133,10 @@ end setglobal!(m, :x, 2, :release) @test m.x === 2 @test_throws ConcurrencyViolationError setglobal!(m, :x, 3, :not_atomic) - @test_throws ErrorException setglobal!(m, :x, 4., :release) + @test_throws TypeError setglobal!(m, :x, 4., :release) + + f_set_bad_type(m) = setglobal!(m, :x, 4., :release) + @test_throws TypeError f_set_bad_type(m) m.x = 1 @test m.x === 1 @@ -8422,7 +8424,7 @@ end # precompilation let load_path = mktempdir() - depot_path = mktempdir() + depot_path = mkdepottempdir() try pushfirst!(LOAD_PATH, load_path) pushfirst!(DEPOT_PATH, depot_path) @@ -8464,11 +8466,6 @@ let load_path = mktempdir() filter!((β‰ )(load_path), LOAD_PATH) filter!((β‰ )(depot_path), DEPOT_PATH) rm(load_path, recursive=true, force=true) - try - rm(depot_path, force=true, recursive=true) - catch err - @show err - end end end diff --git a/test/embedding/embedding-test.jl b/test/embedding/embedding-test.jl index 34ef9a796ba56..0744cac679698 100644 --- a/test/embedding/embedding-test.jl +++ b/test/embedding/embedding-test.jl @@ -32,5 +32,5 @@ end @test lines[9] == "called bar" @test lines[10] == "calling new bar" @test lines[11] == " From worker 2:\tTaking over the world..." - @test readline(err) == "exception caught from C" + @test "exception caught from C" in readlines(err) end diff --git a/test/intfuncs.jl b/test/intfuncs.jl index adcfee2a050dd..dc800a3a00b08 100644 --- a/test/intfuncs.jl +++ b/test/intfuncs.jl @@ -216,6 +216,35 @@ end x, y = Int8(-12), UInt(100) d, u, v = gcdx(x, y) @test x*u + y*v == d + +end + +# issue #58025 +@testset "Mixed signed/unsigned types" begin + cases = [ # adapted from https://github.com/JuliaLang/julia/pull/59487#issuecomment-3258209203 + (UInt16(100), Int8(-101)), + (Int8(-50), UInt16(75)), + (UInt32(12), Int16(-18)), + (Int64(-24), UInt8(36)), + (UInt8(15), Int16(-25)), + (Int32(-42), UInt64(56)), + (UInt128(1000), Int32(-1500)), + (UInt64(0), Int32(-5)), + (Int16(-7), UInt8(0)), + (Int8(-14), UInt8(13)), + ] + for (a, b) in cases + g1 = gcd(a, b) + g2, s, t = gcdx(a, b) + @test g1 === g2 + @test s*a + t*b == g2 + @test g2 >= 0 + @test lcm(a, b) === convert(typeof(g1), lcm(widen(a), widen(b))) + end + + @test gcdx(Int16(-32768), Int8(-128)) === (Int16(128), Int16(0), Int16(-1)) + @test gcdx(Int8(-128), UInt16(256)) === (0x0080, 0xffff, 0x0000) + @test_broken gcd(Int8(-128), UInt16(256)) === 0x0080 end @testset "gcd/lcm/gcdx for custom types" begin @@ -323,6 +352,9 @@ end @test powermod(2, big(3), -5) == -2 @inferred powermod(2, -2, -5) @inferred powermod(big(2), -2, UInt(5)) + + @test powermod(-3, 0x80, 7) === 2 + @test powermod(0x03, 0x80, 0x07) === 0x02 end @testset "nextpow/prevpow" begin diff --git a/test/loading.jl b/test/loading.jl index d12cd2769ef1d..49db010ce1adc 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -34,6 +34,7 @@ end @test @nested_LINE_expansion2() == ((@__LINE__() - 5, @__LINE__() - 9), @__LINE__()) original_depot_path = copy(Base.DEPOT_PATH) +include("tempdepot.jl") include("precompile_utils.jl") loaded_files = String[] @@ -226,7 +227,6 @@ end end end - ## functional testing of package identification, location & loading ## saved_load_path = copy(LOAD_PATH) @@ -236,8 +236,9 @@ watcher_counter = Ref(0) push!(Base.active_project_callbacks, () -> watcher_counter[] += 1) push!(Base.active_project_callbacks, () -> error("broken")) +const testdefaultdepot = mkdepottempdir() push!(empty!(LOAD_PATH), joinpath(@__DIR__, "project")) -append!(empty!(DEPOT_PATH), [mktempdir(), joinpath(@__DIR__, "depot")]) +append!(empty!(DEPOT_PATH), [testdefaultdepot, joinpath(@__DIR__, "depot")]) @test watcher_counter[] == 0 @test_logs (:error, r"active project callback .* failed") Base.set_active_project(nothing) @test watcher_counter[] == 1 @@ -461,7 +462,7 @@ function make_env(flat, root, roots, graph, paths, dummies) ) end -const depots = [mktempdir() for _ = 1:3] +const depots = [mkdepottempdir() for _ = 1:3] const envs = Dict{String,Any}() append!(empty!(DEPOT_PATH), depots) @@ -755,13 +756,6 @@ end for env in keys(envs) rm(env, force=true, recursive=true) end -for depot in depots - try - rm(depot, force=true, recursive=true) - catch err - @show err - end -end append!(empty!(LOAD_PATH), saved_load_path) append!(empty!(DEPOT_PATH), saved_depot_path) @@ -1043,9 +1037,10 @@ end _pkgversion == pkgversion(parent) || error("unexpected extension \$ext version: \$_pkgversion") end """ - depot_path = mktempdir() - try - proj = joinpath(@__DIR__, "project", "Extensions", "HasDepWithExtensions.jl") + depot_path = mkdepottempdir() + proj = joinpath(@__DIR__, "project", "Extensions", "HasDepWithExtensions.jl") + + begin function gen_extension_cmd(compile, distr=false) load_distr = distr ? "using Distributed; addprocs(1)" : "" @@ -1155,7 +1150,7 @@ end # Extension-to-extension dependencies - mktempdir() do depot # Parallel pre-compilation + mkdepottempdir() do depot # Parallel pre-compilation code = """ Base.disable_parallel_precompile = false using ExtToExtDependency @@ -1171,7 +1166,7 @@ end ) @test occursin("Hello ext-to-ext!", String(read(cmd))) end - mktempdir() do depot # Serial pre-compilation + mkdepottempdir() do depot # Serial pre-compilation code = """ Base.disable_parallel_precompile = true using ExtToExtDependency @@ -1188,7 +1183,7 @@ end @test occursin("Hello ext-to-ext!", String(read(cmd))) end - mktempdir() do depot # Parallel pre-compilation + mkdepottempdir() do depot # Parallel pre-compilation code = """ Base.disable_parallel_precompile = false using CrossPackageExtToExtDependency @@ -1204,7 +1199,7 @@ end ) @test occursin("Hello x-package ext-to-ext!", String(read(cmd))) end - mktempdir() do depot # Serial pre-compilation + mkdepottempdir() do depot # Serial pre-compilation code = """ Base.disable_parallel_precompile = true using CrossPackageExtToExtDependency @@ -1224,7 +1219,7 @@ end # Extensions for "parent" dependencies # (i.e. an `ExtAB` where A depends on / loads B, but B provides the extension) - mktempdir() do depot # Parallel pre-compilation + mkdepottempdir() do depot # Parallel pre-compilation code = """ Base.disable_parallel_precompile = false using Parent @@ -1239,7 +1234,7 @@ end ) @test occursin("Hello parent!", String(read(cmd))) end - mktempdir() do depot # Serial pre-compilation + mkdepottempdir() do depot # Serial pre-compilation code = """ Base.disable_parallel_precompile = true using Parent @@ -1254,13 +1249,6 @@ end ) @test occursin("Hello parent!", String(read(cmd))) end - - finally - try - rm(depot_path, force=true, recursive=true) - catch err - @show err - end end end @@ -1361,7 +1349,7 @@ end end @testset "relocatable upgrades #51989" begin - mktempdir() do depot + mkdepottempdir() do depot # realpath is needed because Pkg is used for one of the precompile paths below, and Pkg calls realpath on the # project path so the cache file slug will be different if the tempdir is given as a symlink # (which it often is on MacOS) which would break the test. @@ -1435,7 +1423,7 @@ end end @testset "code coverage disabled during precompilation" begin - mktempdir() do depot + mkdepottempdir() do depot cov_test_dir = joinpath(@__DIR__, "project", "deps", "CovTest.jl") cov_cache_dir = joinpath(depot, "compiled", "v$(VERSION.major).$(VERSION.minor)", "CovTest") function rm_cov_files() @@ -1479,7 +1467,7 @@ end end @testset "command-line flags" begin - mktempdir() do depot_path mktempdir() do dir + mkdepottempdir() do depot_path mktempdir() do dir # generate a Parent.jl and Child.jl package, with Parent depending on Child open(joinpath(dir, "Child.jl"), "w") do io println(io, """ @@ -1495,7 +1483,7 @@ end # helper function to load a package and return the output function load_package(name, args=``) - code = "using $name" + code = "Base.disable_parallel_precompile = true; using $name" cmd = addenv(`$(Base.julia_cmd()) -e $code $args`, "JULIA_LOAD_PATH" => dir, "JULIA_DEPOT_PATH" => depot_path, @@ -1562,7 +1550,7 @@ end end @testset "including non-existent file throws proper error #52462" begin - mktempdir() do depot + mkdepottempdir() do depot project_path = joinpath(depot, "project") mkpath(project_path) @@ -1704,7 +1692,7 @@ end end @testset "require_stdlib loading duplication" begin - depot_path = mktempdir() + depot_path = mkdepottempdir() oldBase64 = nothing try push!(empty!(DEPOT_PATH), depot_path) @@ -1728,6 +1716,5 @@ end finally oldBase64 === nothing || Base.register_root_module(oldBase64) copy!(DEPOT_PATH, original_depot_path) - rm(depot_path, force=true, recursive=true) end end diff --git a/test/math.jl b/test/math.jl index 9a8b3a16d8fb3..6ea0ce25f9a73 100644 --- a/test/math.jl +++ b/test/math.jl @@ -390,6 +390,15 @@ end @test isnan(exp(reinterpret(Float64, 0x7ffbb14880000000))) end +@testset "issue #57463" begin + for T in (Int16, Int32, Int64, Int128) + @test iszero(1.1^typemin(T)) + @test iszero(0.9^typemax(T)) + @test isinf(1.1^typemax(T)) + @test isinf(0.9^typemin(T)) + end +end + @testset "test abstractarray trig functions" begin TAA = rand(2,2) TAA = (TAA + TAA')/2. diff --git a/test/mpfr.jl b/test/mpfr.jl index 3bb8768b280d5..627d49935795d 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -35,6 +35,9 @@ import Base.MPFR @test typeof(BigFloat(1//1)) == BigFloat @test typeof(BigFloat(one(Rational{BigInt}))) == BigFloat + rat = 1 // (big(2)^300 + 1) + @test BigFloat(rat, RoundDown) < rat < BigFloat(rat, RoundUp) + @test BigFloat(-rat, RoundUp) < -rat < BigFloat(-rat, RoundDown) # BigFloat constructor respects global precision when not specified let prec = precision(BigFloat) < 16 ? 256 : precision(BigFloat) Γ· 2 diff --git a/test/numbers.jl b/test/numbers.jl index dc4f2cb613d77..0d8a8b1d867c0 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -1739,6 +1739,27 @@ end @test cld(-1.1, 0.1) == div(-1.1, 0.1, RoundUp) == ceil(big(-1.1)/big(0.1)) == -11.0 @test fld(-1.1, 0.1) == div(-1.1, 0.1, RoundDown) == floor(big(-1.1)/big(0.1)) == -12.0 end + @testset "issue #49450" begin + @test div(514, Float16(0.75)) === Float16(685) + @test fld(514, Float16(0.75)) === Float16(685) + @test cld(515, Float16(0.75)) === Float16(687) + + @test cld(1, Float16(0.000999)) === Float16(1001) + @test cld(2, Float16(0.001999)) === Float16(1001) + @test cld(3, Float16(0.002934)) === Float16(1023) + @test cld(4, Float16(0.003998)) === Float16(1001) + @test fld(5, Float16(0.004925)) === Float16(1015) + + @test div(4_194_307, Float32(0.75)) === Float32(5_592_409) + @test fld(4_194_307, Float32(0.75)) === Float32(5_592_409) + @test cld(4_194_308, Float32(0.75)) === Float32(5_592_411) + + @test fld(5, Float32(6.556511e-7)) === Float32(7_626_007) + @test fld(10, Float32(1.3113022e-6)) === Float32(7_626_007) + @test fld(11, Float32(1.4305115e-6)) === Float32(7_689_557) + @test cld(16, Float32(2.8014183e-6)) === Float32(5_711_393) + @test cld(17, Float32(2.2053719e-6)) === Float32(7_708_451) + end end @testset "return types" begin for T in (Int8,Int16,Int32,Int64,Int128, UInt8,UInt16,UInt32,UInt64,UInt128) diff --git a/test/opaque_closure.jl b/test/opaque_closure.jl index 0dc2ed95b8872..2de5193ec4f35 100644 --- a/test/opaque_closure.jl +++ b/test/opaque_closure.jl @@ -297,6 +297,20 @@ let src = code_typed((Int,Int)) do x, y... @test oc(1,2) === (1,(2,)) @test_throws MethodError oc(1,2,3) end + + # with manually constructed IRCode, without round-trip to CodeInfo + f59222(xs...) = length(xs) + ir = Base.code_ircode_by_type(Tuple{typeof(f59222), Symbol, Symbol})[1][1] + ir.argtypes[1] = Tuple{} + let oc = OpaqueClosure(ir; isva=true) + @test oc(:a, :b) == 2 + end + ir = Base.code_ircode_by_type(Tuple{typeof(f59222), Symbol, Vararg{Symbol}})[1][1] + ir.argtypes[1] = Tuple{} + let oc = OpaqueClosure(ir; isva=true) + @test oc(:a) == 1 + @test oc(:a, :b, :c) == 3 + end end # Check for correct handling in case of broken return type. diff --git a/test/precompile.jl b/test/precompile.jl index 13af539eed2ab..b83d675862ce5 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -4,6 +4,7 @@ using Test, Distributed, Random, Logging, Libdl using REPL # testing the doc lookup function should be outside of the scope of this file, but is currently tested here include("precompile_utils.jl") +include("tempdepot.jl") Foo_module = :Foo4b3a94a1a081a8cb foo_incl_dep = :foo4b3a94a1a081a8cb @@ -686,16 +687,15 @@ precompile_test_harness(false) do dir error("break me") end """) - @test_warn r"LoadError: break me\nStacktrace:\n[ ]*\[1\] [\e01m\[]*error" try - Base.require(Main, :FooBar2) - error("the \"break me\" test failed") - catch exc - isa(exc, ErrorException) || rethrow() - # The LoadError shouldn't be surfaced but is printed to stderr, hence the `@test_warn` capture tests - occursin("LoadError: break me", exc.msg) && rethrow() - # The actual error that is thrown - occursin("Failed to precompile FooBar2", exc.msg) || rethrow() - end + try + Base.require(Main, :FooBar2) + error("the \"break me\" test failed") + catch exc + isa(exc, Base.Precompilation.PkgPrecompileError) || rethrow() + occursin("Failed to precompile FooBar2", exc.msg) || rethrow() + # The LoadError is printed to stderr in the precompilepkgs worker and captured in the PkgPrecompileError msg + occursin("LoadError: break me", exc.msg) || rethrow() + end # Test that trying to eval into closed modules during precompilation is an error FooBar3_file = joinpath(dir, "FooBar3.jl") @@ -707,11 +707,12 @@ precompile_test_harness(false) do dir $code end """) - @test_warn "Evaluation into the closed module `Base` breaks incremental compilation" try - Base.require(Main, :FooBar3) - catch exc - isa(exc, ErrorException) || rethrow() - end + try + Base.require(Main, :FooBar3) + catch exc + isa(exc, Base.Precompilation.PkgPrecompileError) || rethrow() + occursin("Evaluation into the closed module `Base` breaks incremental compilation", exc.msg) || rethrow() + end end # Test transitive dependency for #21266 @@ -1524,11 +1525,11 @@ end test_workers = addprocs(1) push!(test_workers, myid()) save_cwd = pwd() - temp_path = mktempdir() + temp_path = mkdepottempdir() try cd(temp_path) load_path = mktempdir(temp_path) - load_cache_path = mktempdir(temp_path) + load_cache_path = mkdepottempdir(temp_path) ModuleA = :Issue19960A ModuleB = :Issue19960B @@ -1576,11 +1577,6 @@ end end finally cd(save_cwd) - try - rm(temp_path, recursive=true) - catch err - @show err - end pop!(test_workers) # remove myid rmprocs(test_workers) end @@ -2496,6 +2492,46 @@ precompile_test_harness("Package top-level load itself") do load_path end end +precompile_test_harness("Package precompilation works without manifest") do load_path + pkg_dir = joinpath(load_path, "TestPkgNoManifest") + mkpath(pkg_dir) + + # Create Project.toml with stdlib dependencies + write(joinpath(pkg_dir, "Project.toml"), """ + name = "TestPkgNoManifest" + uuid = "f47a8e44-5f82-4c5c-9076-4b4e8b7e8e8e" + version = "0.1.0" + + [deps] + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + """) + + # Create src directory and main module file + src_dir = joinpath(pkg_dir, "src") + mkpath(src_dir) + write(joinpath(src_dir, "TestPkgNoManifest.jl"), """ + module TestPkgNoManifest + end + """) + + old_active_project = Base.active_project() + try + # Activate the new package environment + Base.set_active_project(joinpath(pkg_dir, "Project.toml")) + + # Ensure there's no manifest file (this is the key to the test) + manifest_path = joinpath(pkg_dir, "Manifest.toml") + isfile(manifest_path) && rm(manifest_path) + + # This should work without errors - precompiling a package with no manifest + @eval using TestPkgNoManifest + finally + # Restore original load path and active project + Base.set_active_project(old_active_project) + end +end + # Verify that inference / caching was not performed for any macros in the sysimage let m = only(methods(Base.var"@big_str")) @test m.specializations === Core.svec() || !isdefined(m.specializations, :cache) diff --git a/test/precompile_utils.jl b/test/precompile_utils.jl index 55eba353f2ada..c9a7c98d262e0 100644 --- a/test/precompile_utils.jl +++ b/test/precompile_utils.jl @@ -1,28 +1,18 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +include("tempdepot.jl") + function precompile_test_harness(@nospecialize(f), testset::String) @testset "$testset" precompile_test_harness(f, true) end function precompile_test_harness(@nospecialize(f), separate::Bool=true) - load_path = mktempdir() - load_cache_path = separate ? mktempdir() : load_path + load_path = mkdepottempdir() + load_cache_path = separate ? mkdepottempdir() : load_path try pushfirst!(LOAD_PATH, load_path) pushfirst!(DEPOT_PATH, load_cache_path) f(load_path) finally - try - rm(load_path, force=true, recursive=true) - catch err - @show err - end - if separate - try - rm(load_cache_path, force=true, recursive=true) - catch err - @show err - end - end filter!((β‰ )(load_path), LOAD_PATH) separate && filter!((β‰ )(load_cache_path), DEPOT_PATH) end diff --git a/test/relocatedepot.jl b/test/relocatedepot.jl index 2ef6dec90dbc1..e8758365e3ff4 100644 --- a/test/relocatedepot.jl +++ b/test/relocatedepot.jl @@ -4,6 +4,7 @@ using Test include("testenv.jl") +include("tempdepot.jl") function test_harness(@nospecialize(fn); empty_load_path=true, empty_depot_path=true) @@ -32,7 +33,7 @@ if !test_relocated_depot # insert @depot only once for first match test_harness() do - mktempdir() do dir + mkdepottempdir() do dir pushfirst!(DEPOT_PATH, dir) if Sys.iswindows() # dirs start with a drive letter instead of a path separator @@ -46,7 +47,7 @@ if !test_relocated_depot # 55340 empty!(DEPOT_PATH) - mktempdir() do dir + mkdepottempdir() do dir jlrc = joinpath(dir, "julia-rc2") jl = joinpath(dir, "julia") mkdir(jl) @@ -61,7 +62,7 @@ if !test_relocated_depot # deal with and without trailing path separators test_harness() do - mktempdir() do dir + mkdepottempdir() do dir pushfirst!(DEPOT_PATH, dir) path = joinpath(dir, "foo") if isdirpath(DEPOT_PATH[1]) @@ -176,7 +177,7 @@ if !test_relocated_depot # add them as include_dependency()s to a new pkg Foo, which will be precompiled into depot3. # After loading the include_dependency()s of Foo should refer to depot1 depot2 each. test_harness() do - mktempdir() do depot1 + mkdepottempdir() do depot1 # precompile Example in depot1 example1_root = joinpath(depot1, "Example1") mkpath(joinpath(example1_root, "src")) @@ -196,7 +197,7 @@ if !test_relocated_depot end pushfirst!(LOAD_PATH, depot1); pushfirst!(DEPOT_PATH, depot1) pkg = Base.identify_package("Example1"); Base.require(pkg) - mktempdir() do depot2 + mkdepottempdir() do depot2 # precompile Example in depot2 example2_root = joinpath(depot2, "Example2") mkpath(joinpath(example2_root, "src")) @@ -216,7 +217,7 @@ if !test_relocated_depot end pushfirst!(LOAD_PATH, depot2); pushfirst!(DEPOT_PATH, depot2) pkg = Base.identify_package("Example2"); Base.require(pkg) - mktempdir() do depot3 + mkdepottempdir() do depot3 # precompile Foo in depot3 open(joinpath(depot3, "Module52161.jl"), write=true) do io println(io, """ diff --git a/test/syntax.jl b/test/syntax.jl index be01279b82359..833ecf232ed44 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -2529,6 +2529,15 @@ end @test ncalls_in_lowered(:((.+)(a, b .- (.^)(c, 2))), GlobalRef(Base, :BroadcastFunction)) == 0 end +module M59008 # dotop with global LHS in macro +using Test +global a = 1 +macro counter() + :(a += 1) +end +@test @counter() === 2 === a +end + # issue #37656 @test :(if true 'a' else 1 end) == Expr(:if, true, quote 'a' end, quote 1 end) diff --git a/test/tempdepot.jl b/test/tempdepot.jl new file mode 100755 index 0000000000000..18fad0cf15346 --- /dev/null +++ b/test/tempdepot.jl @@ -0,0 +1,43 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +# This includes the `mkdepottempdir` and `rmdepot` functions, used to +# respectively create and remove temporary depots to use in tests. +# `mktempdir` and `rm` cannot be used because, on Windows, the DLLs generated by +# precompilation in the depots cannot be removed by the program that uses them. +# This file can be included multiple times in the same module if necessary, +# which can happen with unisolated test runs. + +if Sys.iswindows() && !@isdefined(DEPOTS_TOREMOVE) + const DEPOTS_TOREMOVE = String[] + atexit(() -> Base.Filesystem.temp_cleanup_postprocess(DEPOTS_TOREMOVE)) +end + +function rmdepot(depot) + try + @static if Sys.iswindows() # on Windows, delay the rm + push!(DEPOTS_TOREMOVE, depot) + else # on the other systems, do it immediately + rm(depot, force=true, recursive=true) + end + catch err + @show err + end +end + +function mkdepottempdir(f::Function, parent=tempdir(); prefix="jltestdepot_") + tmpdir = mktempdir(parent; prefix, cleanup=false) + try + f(tmpdir) + finally + rmdepot(tmpdir) + end +end +function mkdepottempdir(parent=tempdir(); prefix="jltestdepot_", cleanup=true) + @static if Sys.iswindows() + tmpdir = mktempdir(parent; prefix, cleanup=false) + cleanup && push!(DEPOTS_TOREMOVE, tmpdir) + tmpdir + else + mktempdir(parent; prefix, cleanup) + end +end diff --git a/test/trimming/trimmability.jl b/test/trimming/trimmability.jl index acba8244534ef..403f4f6c3a798 100644 --- a/test/trimming/trimmability.jl +++ b/test/trimming/trimmability.jl @@ -50,5 +50,7 @@ function @main(args::Vector{String})::Cint catch end + Base.donotdelete(reshape([1,2,3],:,1,1)) + return 0 end diff --git a/test/worlds.jl b/test/worlds.jl index 4a2836164e2c6..2bd1bcab353c6 100644 --- a/test/worlds.jl +++ b/test/worlds.jl @@ -589,3 +589,21 @@ module C57316; import ..X57316.Y57316 as Z, .Z.Y57316 as W; end @test !isdefined(B57316, :X57316) @test !isdefined(C57316, :X57316) @test !isdefined(C57316, :Y57316) + +# issue #59429 - world age semantics with toplevel in macros +module M59429 +using Test +macro new_enum(T::Symbol, args...) + esc(quote + @enum $T $(args...) + function Base.hash(x::$T, h::UInt) + rand(UInt) + end + end) +end + +@new_enum Foo59429 bar59429 baz59429 + +# Test that the hash function works without world age issues +@test hash(bar59429, UInt(0)) isa UInt +end