Skip to content

Commit

Permalink
Merge branch 'master' into rationalize_irrational
Browse files Browse the repository at this point in the history
  • Loading branch information
nsajko authored Oct 31, 2024
2 parents 9fb836d + da74ef1 commit d97505c
Show file tree
Hide file tree
Showing 133 changed files with 2,817 additions and 1,371 deletions.
8 changes: 8 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ Standard library changes
`AnnotatedString` with various faces or other attributes applied ([#49586]).

#### Package Manager
* It is now possible to specify "sources" for packages in a `[sources]` section in Project.toml.
This can be used to add non-registered normal or test dependencies.
* Pkg now obeys `[compat]` bounds for `julia` and raises an error if the version of the running Julia binary is incompatible with the bounds in `Project.toml`.
Pkg has always obeyed this compat when working with Registry packages. This change affects mostly local packages
* `pkg> add` and `Pkg.add` will now add compat entries for new direct dependencies if the active environment is a
package (has a `name` and `uuid` entry).
* Dependencies can now be directly added as weak deps or extras via the `pkg> add --weak/extra Foo` or
`Pkg.add("Foo", target=:weakdeps/:extras)` forms.

#### LinearAlgebra
* `cbrt(::AbstractMatrix{<:Real})` is now defined and returns real-valued matrix cube roots of real-valued matrices ([#50661]).
Expand Down
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ New library features
the uniquing checking ([#53474])
* `RegexMatch` objects can now be used to construct `NamedTuple`s and `Dict`s ([#50988])
* `Lockable` is now exported ([#54595])
* `Base.require_one_based_indexing` and `Base.has_offset_axes` are now public ([#56196])
* New `ltruncate`, `rtruncate` and `ctruncate` functions for truncating strings to text width, accounting for char widths ([#55351])
* `isless` (and thus `cmp`, sorting, etc.) is now supported for zero-dimensional `AbstractArray`s ([#55772])

Standard library changes
------------------------
Expand Down Expand Up @@ -148,6 +150,8 @@ Standard library changes
Custom array types may specialize this function to return an appropriate result ([#55252]).
* The matrix multiplication `A * B` calls `matprod_dest(A, B, T::Type)` to generate the destination.
This function is now public ([#55537]).
* The function `haszero(T::Type)` is used to check if a type `T` has a unique zero element defined as `zero(T)`.
This is now public.

#### Logging

Expand Down Expand Up @@ -211,4 +215,6 @@ External dependencies
Tooling Improvements
--------------------

- A wall-time profiler is now available for users who need a sampling profiler that captures tasks regardless of their scheduling or running state. This type of profiler enables profiling of I/O-heavy tasks and helps detect areas of heavy contention in the system ([#55889]).

<!--- generated by NEWS-update.jl: -->
19 changes: 14 additions & 5 deletions base/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ function include(mod::Module, path::String)
end
include(path::String) = include(Base, path)

struct IncludeInto <: Function
m::Module
end
(this::IncludeInto)(fname::AbstractString) = include(this.m, fname)

# from now on, this is now a top-module for resolving syntax
const is_primary_base_module = ccall(:jl_module_parent, Ref{Module}, (Any,), Base) === Core.Main
ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Base, is_primary_base_module)
Expand Down Expand Up @@ -572,15 +577,20 @@ include("precompilation.jl")
for m in methods(include)
delete_method(m)
end
for m in methods(IncludeInto(Base))
delete_method(m)
end

# This method is here only to be overwritten during the test suite to test
# various sysimg related invalidation scenarios.
a_method_to_overwrite_in_test() = inferencebarrier(1)

# These functions are duplicated in client.jl/include(::String) for
# nicer stacktraces. Modifications here have to be backported there
include(mod::Module, _path::AbstractString) = _include(identity, mod, _path)
include(mapexpr::Function, mod::Module, _path::AbstractString) = _include(mapexpr, mod, _path)
@noinline include(mod::Module, _path::AbstractString) = _include(identity, mod, _path)
@noinline include(mapexpr::Function, mod::Module, _path::AbstractString) = _include(mapexpr, mod, _path)
(this::IncludeInto)(fname::AbstractString) = include(identity, this.m, fname)
(this::IncludeInto)(mapexpr::Function, fname::AbstractString) = include(mapexpr, this.m, fname)

# External libraries vendored into Base
Core.println("JuliaSyntax/src/JuliaSyntax.jl")
Expand Down Expand Up @@ -646,10 +656,9 @@ function __init__()
init_load_path()
init_active_project()
append!(empty!(_sysimage_modules), keys(loaded_modules))
empty!(explicit_loaded_modules)
empty!(loaded_precompiles) # If we load a packageimage when building the image this might not be empty
for (mod, key) in module_keys
push!(get!(Vector{Module}, loaded_precompiles, key), mod)
for mod in loaded_modules_order
push!(get!(Vector{Module}, loaded_precompiles, PkgId(mod)), mod)
end
if haskey(ENV, "JULIA_MAX_NUM_PRECOMPILE_FILES")
MAX_NUM_PRECOMPILE_FILES[] = parse(Int, ENV["JULIA_MAX_NUM_PRECOMPILE_FILES"])
Expand Down
9 changes: 9 additions & 0 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3044,6 +3044,15 @@ function cmp(A::AbstractVector, B::AbstractVector)
return cmp(length(A), length(B))
end

"""
isless(A::AbstractArray{<:Any,0}, B::AbstractArray{<:Any,0})
Return `true` when the only element of `A` is less than the only element of `B`.
"""
function isless(A::AbstractArray{<:Any,0}, B::AbstractArray{<:Any,0})
isless(only(A), only(B))
end

"""
isless(A::AbstractVector, B::AbstractVector)
Expand Down
8 changes: 6 additions & 2 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,13 @@ Nothing() = nothing
# This should always be inlined
getptls() = ccall(:jl_get_ptls_states, Ptr{Cvoid}, ())

include(m::Module, fname::String) = ccall(:jl_load_, Any, (Any, Any), m, fname)
include(m::Module, fname::String) = (@noinline; ccall(:jl_load_, Any, (Any, Any), m, fname))
eval(m::Module, @nospecialize(e)) = (@noinline; ccall(:jl_toplevel_eval_in, Any, (Any, Any), m, e))

eval(m::Module, @nospecialize(e)) = ccall(:jl_toplevel_eval_in, Any, (Any, Any), m, e)
struct EvalInto <: Function
m::Module
end
(this::EvalInto)(@nospecialize(e)) = eval(this.m, e)

mutable struct Box
contents::Any
Expand Down
2 changes: 1 addition & 1 deletion base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3648,7 +3648,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState, nextr
changes = StateUpdate(lhs, VarState(rt, false))
elseif isa(lhs, GlobalRef)
handle_global_assignment!(interp, frame, lhs, rt)
elseif !isa(lhs, SSAValue)
else
merge_effects!(interp, frame, EFFECTS_UNKNOWN)
end
end
Expand Down
13 changes: 5 additions & 8 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,6 @@ function analyze_method!(match::MethodMatch, argtypes::Vector{Any},
allow_typevars::Bool, invokesig::Union{Nothing,Vector{Any}}=nothing,
volatile_inf_result::Union{Nothing,VolatileInferenceResult}=nothing)
method = match.method
spec_types = match.spec_types

# Check that we have the correct number of arguments
na = Int(method.nargs)
Expand All @@ -954,6 +953,7 @@ function analyze_method!(match::MethodMatch, argtypes::Vector{Any},
if !match.fully_covers
# type-intersection was not able to give us a simple list of types, so
# ir_inline_unionsplit won't be able to deal with inlining this
spec_types = match.spec_types
if !(spec_types isa DataType && length(spec_types.parameters) == npassedargs &&
!isvarargtype(spec_types.parameters[end]))
return nothing
Expand Down Expand Up @@ -1428,28 +1428,26 @@ function handle_match!(cases::Vector{InliningCase},
match::MethodMatch, argtypes::Vector{Any}, @nospecialize(info::CallInfo), flag::UInt32,
state::InliningState;
allow_typevars::Bool, volatile_inf_result::Union{Nothing,VolatileInferenceResult})
spec_types = match.spec_types
# We may see duplicated dispatch signatures here when a signature gets widened
# during abstract interpretation: for the purpose of inlining, we can just skip
# processing this dispatch candidate (unless unmatched type parameters are present)
!allow_typevars && any(case::InliningCase->case.sig === spec_types, cases) && return true
!allow_typevars && any(case::InliningCase->case.sig === match.spec_types, cases) && return true
item = analyze_method!(match, argtypes, info, flag, state; allow_typevars, volatile_inf_result)
item === nothing && return false
push!(cases, InliningCase(spec_types, item))
push!(cases, InliningCase(match.spec_types, item))
return true
end

function handle_const_prop_result!(cases::Vector{InliningCase}, result::ConstPropResult,
match::MethodMatch, @nospecialize(info::CallInfo), flag::UInt32, state::InliningState;
allow_typevars::Bool)
mi = result.result.linfo
spec_types = match.spec_types
if !validate_sparams(mi.sparam_vals)
(allow_typevars && !may_have_fcalls(mi.def::Method)) || return false
end
item = resolve_todo(mi, result.result, info, flag, state)
item === nothing && return false
push!(cases, InliningCase(spec_types, item))
push!(cases, InliningCase(match.spec_types, item))
return true
end

Expand Down Expand Up @@ -1479,11 +1477,10 @@ end
function handle_semi_concrete_result!(cases::Vector{InliningCase}, result::SemiConcreteResult,
match::MethodMatch, @nospecialize(info::CallInfo), flag::UInt32, state::InliningState)
mi = result.mi
spec_types = match.spec_types
validate_sparams(mi.sparam_vals) || return false
item = semiconcrete_result_item(result, info, flag, state)
item === nothing && return false
push!(cases, InliningCase(spec_types, item))
push!(cases, InliningCase(match.spec_types, item))
return true
end

Expand Down
34 changes: 23 additions & 11 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -601,8 +601,16 @@ add_tfunc(svec, 0, INT_INF, @nospecs((𝕃::AbstractLattice, args...)->SimpleVec
return TypeVar
end
end
tv = TypeVar(nval, lb, ub)
return PartialTypeVar(tv, lb_certain, ub_certain)
lb_valid = lb isa Type || lb isa TypeVar
ub_valid = ub isa Type || ub isa TypeVar
if lb_valid && ub_valid
tv = TypeVar(nval, lb, ub)
return PartialTypeVar(tv, lb_certain, ub_certain)
elseif !lb_valid && lb_certain
return Union{}
elseif !ub_valid && ub_certain
return Union{}
end
end
return TypeVar
end
Expand Down Expand Up @@ -1339,13 +1347,15 @@ end
return getfield_tfunc(𝕃, o, f)
end
@nospecs function modifyfield!_tfunc(𝕃::AbstractLattice, o, f, op, v, order=Symbol)
T = _fieldtype_tfunc(𝕃, o, f, isconcretetype(o))
o′ = widenconst(o)
T = _fieldtype_tfunc(𝕃, o′, f, isconcretetype(o′))
T === Bottom && return Bottom
PT = Const(Pair)
return instanceof_tfunc(apply_type_tfunc(𝕃, PT, T, T), true)[1]
end
@nospecs function replacefield!_tfunc(𝕃::AbstractLattice, o, f, x, v, success_order=Symbol, failure_order=Symbol)
T = _fieldtype_tfunc(𝕃, o, f, isconcretetype(o))
o′ = widenconst(o)
T = _fieldtype_tfunc(𝕃, o′, f, isconcretetype(o′))
T === Bottom && return Bottom
PT = Const(ccall(:jl_apply_cmpswap_type, Any, (Any,), T) where T)
return instanceof_tfunc(apply_type_tfunc(𝕃, PT, T), true)[1]
Expand Down Expand Up @@ -2998,14 +3008,16 @@ function abstract_applicable(interp::AbstractInterpreter, argtypes::Vector{Any},
else
rt = Const(true) # has applicable matches
end
for i in 1:napplicable
match = applicable[i]::MethodMatch
edge = specialize_method(match)::MethodInstance
add_backedge!(sv, edge)
if rt !== Bool
for i in 1:napplicable
match = applicable[i]::MethodMatch
edge = specialize_method(match)
add_backedge!(sv, edge)
end
# also need an edge to the method table in case something gets
# added that did not intersect with any existing method
add_uncovered_edges!(sv, matches, atype)
end
# also need an edge to the method table in case something gets
# added that did not intersect with any existing method
add_uncovered_edges!(sv, matches, atype)
end
return Future(CallMeta(rt, Union{}, EFFECTS_TOTAL, NoCallInfo()))
end
Expand Down
9 changes: 7 additions & 2 deletions base/coreio.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

print(x) = print(stdout, x)
print(x1, x2) = print(stdout, x1, x2)
println(x) = print(stdout, x, "\n")
println(x1, x2) = print(stdout, x1, x2, "\n")

print(xs...) = print(stdout, xs...)
println(xs...) = println(stdout, xs...)
println(io::IO) = print(io, '\n')
println(xs...) = print(stdout, xs..., "\n") # fewer allocations than `println(stdout, xs...)`
println(io::IO) = print(io, "\n")

function show end
function repr end
Expand Down
10 changes: 9 additions & 1 deletion base/docs/basedocs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ kw"help", kw"Julia", kw"julia", kw""
available for direct use. Names can also be used via dot syntax (e.g. `Foo.foo` to access
the name `foo`), whether they are `export`ed or not.
See the [manual section about modules](@ref modules) for details.
!!! note
When two or more packages/modules export a name and that name does not refer to the
same thing in each of the packages, and the packages are loaded via `using` without
an explicit list of names, it is an error to reference that name without qualification.
It is thus recommended that code intended to be forward-compatible with future versions
of its dependencies and of Julia, e.g., code in released packages, list the names it
uses from each loaded package, e.g., `using Foo: Foo, f` rather than `using Foo`.
"""
kw"using"

Expand Down Expand Up @@ -2580,7 +2588,7 @@ cases.
See also [`setproperty!`](@ref Base.setproperty!) and [`getglobal`](@ref)
# Examples
```jldoctest; filter = r"Stacktrace:(\\n \\[[0-9]+\\].*)*"
```jldoctest; filter = r"Stacktrace:(\\n \\[[0-9]+\\].*\\n.*)*"
julia> module M; global a; end;
julia> M.a # same as `getglobal(M, :a)`
Expand Down
5 changes: 4 additions & 1 deletion base/errorshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,10 @@ function _simplify_include_frames(trace)
for i in length(trace):-1:1
frame::StackFrame, _ = trace[i]
mod = parentmodule(frame)
if first_ignored === nothing
if mod === Base && frame.func === :IncludeInto ||
mod === Core && frame.func === :EvalInto
kept_frames[i] = false
elseif first_ignored === nothing
if mod === Base && frame.func === :_include
# Hide include() machinery by default
first_ignored = i
Expand Down
47 changes: 47 additions & 0 deletions base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,53 @@ function isiterable(T)::Bool
return hasmethod(iterate, Tuple{T})
end

"""
@world(sym, world)
Resolve the binding `sym` in world `world`. See [`invoke_in_world`](@ref) for running
arbitrary code in fixed worlds. `world` may be `UnitRange`, in which case the macro
will error unless the binding is valid and has the same value across the entire world
range.
The `@world` macro is primarily used in the printing of bindings that are no longer
available in the current world.
## Example
```
julia> struct Foo; a::Int; end
Foo
julia> fold = Foo(1)
julia> Int(Base.get_world_counter())
26866
julia> struct Foo; a::Int; b::Int end
Foo
julia> fold
@world(Foo, 26866)(1)
```
!!! compat "Julia 1.12"
This functionality requires at least Julia 1.12.
"""
macro world(sym, world)
if isa(sym, Symbol)
return :($(_resolve_in_world)($(esc(world)), $(QuoteNode(GlobalRef(__module__, sym)))))
elseif isa(sym, GlobalRef)
return :($(_resolve_in_world)($(esc(world)), $(QuoteNode(sym))))
elseif isa(sym, Expr) && sym.head === :(.) &&
length(sym.args) == 2 && isa(sym.args[2], QuoteNode) && isa(sym.args[2].value, Symbol)
return :($(_resolve_in_world)($(esc(world)), $(GlobalRef)($(esc(sym.args[1])), $(sym.args[2]))))
else
error("`@world` requires a symbol or GlobalRef")
end
end

_resolve_in_world(world::Integer, gr::GlobalRef) =
invoke_in_world(UInt(world), Core.getglobal, gr.mod, gr.name)

# Special constprop heuristics for various binary opes
typename(typeof(function + end)).constprop_heuristic = Core.SAMETYPE_HEURISTIC
typename(typeof(function - end)).constprop_heuristic = Core.SAMETYPE_HEURISTIC
Expand Down
7 changes: 5 additions & 2 deletions base/file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ function _readdir(dir::AbstractString; return_objects::Bool=false, join::Bool=fa
end

"""
walkdir(dir; topdown=true, follow_symlinks=false, onerror=throw)
walkdir(dir = pwd(); topdown=true, follow_symlinks=false, onerror=throw)
Return an iterator that walks the directory tree of a directory.
Expand All @@ -1117,6 +1117,9 @@ resume where the last left off, like [`Iterators.Stateful`](@ref).
See also: [`readdir`](@ref).
!!! compat "Julia 1.12"
`pwd()` as the default directory was added in Julia 1.12.
# Examples
```julia
for (path, dirs, files) in walkdir(".")
Expand Down Expand Up @@ -1146,7 +1149,7 @@ julia> (path, dirs, files) = first(itr)
("my/test/dir", String[], String[])
```
"""
function walkdir(path; topdown=true, follow_symlinks=false, onerror=throw)
function walkdir(path = pwd(); topdown=true, follow_symlinks=false, onerror=throw)
function _walkdir(chnl, path)
tryf(f, p) = try
f(p)
Expand Down
Loading

0 comments on commit d97505c

Please sign in to comment.