Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion base/docs/Docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ function metadata(__source__, __module__, expr, ismodule)
if isa(eachex, Symbol) || isexpr(eachex, :(::))
# a field declaration
if last_docstr !== nothing
push!(fields, P(namify(eachex), last_docstr))
push!(fields, P(namify(eachex)::Symbol, last_docstr))
last_docstr = nothing
end
elseif isexpr(eachex, :function) || isexpr(eachex, :(=))
Expand Down
66 changes: 49 additions & 17 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,16 @@ struct LoadingCache
located::Dict{Tuple{PkgId, Union{String, Nothing}}, Union{Tuple{PkgLoadSpec, String}, Nothing}}
end
const LOADING_CACHE = Ref{Union{LoadingCache, Nothing}}(nothing) # n.b.: all access to and through this are protected by require_lock
LoadingCache() = LoadingCache(load_path(), Dict(), Dict(), Dict(), Set(), Dict(), Dict(), Dict())
LoadingCache() = LoadingCache(
load_path(),
Dict{String, UUID}(),
Dict{String, Union{Bool, String}}(),
Dict{String, Union{Nothing, String}}(),
Set{String}(),
Dict{Tuple{PkgId, String}, Union{Nothing, Tuple{PkgId, String}}}(),
Dict{String, Union{Nothing, Tuple{PkgId, String}}}(),
Dict{Tuple{PkgId, Union{String, Nothing}}, Union{Tuple{PkgLoadSpec, String}, Nothing}}()
)


struct TOMLCache{Dates}
Expand Down Expand Up @@ -343,25 +352,22 @@ Same as [`Base.identify_package`](@ref) except that the path to the environment
is also returned, except when the identity is not identified.
"""
identify_package_env(where::Module, name::String) = identify_package_env(PkgId(where), name)
function identify_package_env(where::Union{PkgId, Nothing}, name::String)
function identify_package_env(where::PkgId, name::String)
# Special cases
if where !== nothing
if where.name === name
# Project tries to load itself
return (where, nothing)
elseif where.uuid === nothing
# Project without Project.toml - treat as toplevel load
where = nothing
end
if where.name === name
# Project tries to load itself
return (where, nothing)
elseif where.uuid === nothing
# Project without Project.toml - treat as toplevel load
return identify_package_env(nothing, name)
end

# Check if we have a cached answer for this
assert_havelock(require_lock)
cache = LOADING_CACHE[]
cache_key = where === nothing ? name : (where, name)
cache_key = (where, name)
if cache !== nothing
env_cache = where === nothing ? cache.identified : cache.identified_where
pkg_env = get(env_cache, cache_key, missing)
pkg_env = get(cache.identified_where, cache_key, missing)
pkg_env === missing || return pkg_env
end

Expand All @@ -372,14 +378,14 @@ function identify_package_env(where::Union{PkgId, Nothing}, name::String)
pkgid = environment_deps_get(env, where, name)
# If we didn't find `where` at all, keep looking through the environment stack
pkgid === nothing && continue
if pkgid.uuid !== nothing || where === nothing
pkg_env = pkgid, env
if pkgid.uuid !== nothing
pkg_env = (pkgid, env)
end
# If we don't have pkgid.uuid, still break here - this is a sentinel that indicates
# that we've found `where` but it did not have the required dependency. We terminate the search.
break
end
if pkg_env === nothing && where !== nothing && is_stdlib(where)
if pkg_env === nothing && is_stdlib(where)
# if not found it could be that manifests are from a different julia version/commit
# where stdlib dependencies have changed, so look up deps based on the stdlib Project.toml
# as a fallback
Expand All @@ -388,7 +394,33 @@ function identify_package_env(where::Union{PkgId, Nothing}, name::String)

# Cache the result
if cache !== nothing
env_cache[cache_key] = pkg_env
cache.identified_where[cache_key] = pkg_env
end
return pkg_env
end
function identify_package_env(where::Nothing, name::String)
# Check if we have a cached answer for this
assert_havelock(require_lock)
cache = LOADING_CACHE[]
if cache !== nothing
pkg_env = get(cache.identified, name, missing)
pkg_env === missing || return pkg_env
end

# Main part: Search through all environments in the load path to see if we have
# a matching entry.
pkg_env = nothing
for env in load_path()
pkgid = environment_deps_get(env, nothing, name)
# If we didn't find `where` at all, keep looking through the environment stack
pkgid === nothing && continue
pkg_env = (pkgid, env)
break
end

# Cache the result
if cache !== nothing
cache.identified[name] = pkg_env
end
return pkg_env
end
Expand Down
42 changes: 25 additions & 17 deletions base/precompilation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -568,15 +568,15 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
_from_loading::Bool,
configs::Vector{Config},
io::IOContext{IO},
fancyprint::Bool,
fancyprint::Bool,
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)
requested_pkgids = copy(pkgs)
else
requested_pkgids = PkgId[]
requested_pkgids = PkgId[]
for name in pkgs
pkgid = Base.identify_package(name)
if pkgid === nothing
Expand All @@ -586,9 +586,10 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
throw(PkgPrecompileError("Unknown package: $name"))
end
end
push!(requested_pkgids, pkgid)
push!(requested_pkgids, pkgid)
end
end
requested_pkgids = requested_pkgids′

time_start = time_ns()

Expand All @@ -605,17 +606,20 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
# suppress precompilation progress messages when precompiling for loading packages, except during interactive sessions
# or when specified by logging heuristics that explicitly require it
# since the complicated IO implemented here can have somewhat disastrous consequences when happening in the background (e.g. #59599)
logio = io
logcalls = nothing
logio = io
logcalls = nothing
if _from_loading
if isinteractive()
logcalls = CoreLogging.Info # sync with Base.compilecache
logcalls = CoreLogging.Info # sync with Base.compilecache
else
logio = IOContext{IO}(devnull)
fancyprint = false
logcalls = CoreLogging.Debug # sync with Base.compilecache
logio = IOContext{IO}(devnull)
fancyprint = false
logcalls = CoreLogging.Debug # sync with Base.compilecache
end
end
fancyprint = fancyprint′
logio = logio′
logcalls = logcalls′

nconfigs = length(configs)
hascolor = get(logio, :color, false)::Bool
Expand Down Expand Up @@ -992,7 +996,7 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
for pkg_config in pkg_queue_show
dep, config = pkg_config
loaded = warn_loaded && haskey(Base.loaded_modules, dep)
flags, cacheflags = config
local flags, cacheflags = config
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)
Expand Down Expand Up @@ -1077,7 +1081,7 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
notify(was_processed[pkg_config])
continue
end
flags, cacheflags = config
local flags, cacheflags = config
task = @async begin
try
loaded = warn_loaded && haskey(Base.loaded_modules, pkg)
Expand Down Expand Up @@ -1118,17 +1122,21 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
end
# for extensions, any extension that can trigger it needs to be accounted for here (even stdlibs, which are excluded from direct_deps)
loadable_exts = haskey(ext_to_parent, pkg) ? filter((dep)->haskey(ext_to_parent, dep), triggers[pkg]) : nothing
if !isempty(deps)

flags_ =if !isempty(deps)
# if deps is empty, either it doesn't have any (so compiled-modules is
# irrelevant) or we couldn't compute them (so we actually should attempt
# serial compile, as the dependencies are not in the parallel list)
flags = `$flags --compiled-modules=strict`
`$flags --compiled-modules=strict`
else
flags
end

if _from_loading && pkg in requested_pkgids
# loading already took the cachefile_lock and printed logmsg for its explicit requests
t = @elapsed ret = begin
Base.compilecache(pkg, sourcespec, std_pipe, std_pipe, !ignore_loaded;
flags, cacheflags, loadable_exts)
flags=flags_, cacheflags, loadable_exts)
end
else
# allows processes to wait if another process is precompiling a given package to
Expand All @@ -1138,7 +1146,7 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
if interrupted_or_done[]
return ErrorException("canceled")
end
cachepaths = Base.find_all_in_cache_path(pkg)
local cachepaths = Base.find_all_in_cache_path(pkg)
local freshpath = Base.compilecache_freshest_path(pkg; ignore_loaded, stale_cache, cachepath_cache, cachepaths, sourcespec, flags=cacheflags)
local is_stale = freshpath === nothing
if !is_stale
Expand All @@ -1149,7 +1157,7 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
@debug "Precompiling $(repr("text/plain", pkg))"
end
Base.compilecache(pkg, sourcespec, std_pipe, std_pipe, !ignore_loaded;
flags, cacheflags, loadable_exts)
flags=flags_, cacheflags, loadable_exts)
end
end
if ret isa Exception
Expand Down
2 changes: 1 addition & 1 deletion base/shell.jl
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ function shell_split(s::AbstractString)
parsed = shell_parse(s, false)[1]
args = String[]
for arg in parsed
push!(args, string(arg...))
push!(args, string(arg...)::String)
end
args
end
Expand Down
38 changes: 25 additions & 13 deletions base/strings/annotated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ function annotatedstring(xs...)
size = filesize(s.io)
if x isa AnnotatedString
for annot in x.annotations
push!(annotations, setindex(annot, annot.region .+ size, :region))
push!(annotations, @inline(setindex(annot, annot.region .+ size, :region)))
end
print(s, x.string)
elseif x isa SubString{<:AnnotatedString}
Expand All @@ -259,7 +259,7 @@ function annotatedstring(xs...)
if start <= x.offset + x.ncodeunits && stop > x.offset
rstart = size + max(0, start - x.offset - 1) + 1
rstop = size + min(stop, x.offset + x.ncodeunits) - x.offset
push!(annotations, setindex(annot, rstart:rstop, :region))
push!(annotations, @inline(setindex(annot, rstart:rstop, :region)))
end
end
print(s, SubString(x.string.string, x.offset, x.ncodeunits, Val(:noshift)))
Expand Down Expand Up @@ -293,12 +293,12 @@ function repeat(str::AnnotatedString, r::Integer)
elseif allequal(a -> a.region, str.annotations) && first(str.annotations).region == fullregion
newfullregion = firstindex(unannot):lastindex(unannot)
for annot in str.annotations
push!(annotations, setindex(annot, newfullregion, :region))
push!(annotations, @inline(setindex(annot, newfullregion, :region)))
end
else
for offset in 0:len:(r-1)*len
for annot in str.annotations
push!(annotations, setindex(annot, annot.region .+ offset, :region))
push!(annotations, @inline(setindex(annot, annot.region .+ offset, :region)))
end
end
end
Expand All @@ -318,10 +318,10 @@ function reverse(s::AnnotatedString)
lastind = lastindex(s)
AnnotatedString(
reverse(s.string),
[setindex(annot,
[@inline(setindex(annot,
UnitRange(1 + lastind - last(annot.region),
1 + lastind - first(annot.region)),
:region)
:region))
for annot in s.annotations])
end

Expand Down Expand Up @@ -389,16 +389,28 @@ See also: [`annotate!`](@ref).
annotations(s::AnnotatedString) = s.annotations

function annotations(s::SubString{<:AnnotatedString})
RegionAnnotation[
setindex(ann, first(ann.region)-s.offset:last(ann.region)-s.offset, :region)
for ann in annotations(s.string, s.offset+1:s.offset+s.ncodeunits)]
substr_range = s.offset+1:s.offset+s.ncodeunits
result = RegionAnnotation[]
for ann in annotations(s.string, substr_range)
# Shift the region to be relative to the substring start
shifted_region = first(ann.region)-s.offset:last(ann.region)-s.offset
# @inline setindex makes :region const knowable (#60365)
push!(result, @inline(setindex(ann, shifted_region, :region)))
end
return result
end

function annotations(s::AnnotatedString, pos::UnitRange{<:Integer})
# TODO optimise
RegionAnnotation[
setindex(ann, max(first(pos), first(ann.region)):min(last(pos), last(ann.region)), :region)
for ann in s.annotations if !isempty(intersect(pos, ann.region))]
result = RegionAnnotation[]
for ann in s.annotations
if !isempty(intersect(pos, ann.region))
clamped_region = max(first(pos), first(ann.region)):min(last(pos), last(ann.region))
# @inline setindex makes :region const knowable (#60365)
push!(result, @inline(setindex(ann, clamped_region, :region)))
end
end
return result
end

annotations(s::AnnotatedString, pos::Integer) = annotations(s, pos:pos)
Expand Down Expand Up @@ -455,7 +467,7 @@ function annotated_chartransform(f::Function, str::AnnotatedString, state=nothin
start, stop = first(annot.region), last(annot.region)
start_offset = last(offsets[findlast(<=(start) ∘ first, offsets)::Int])
stop_offset = last(offsets[findlast(<=(stop) ∘ first, offsets)::Int])
push!(annots, setindex(annot, (start + start_offset):(stop + stop_offset), :region))
push!(annots, @inline(setindex(annot, (start + start_offset):(stop + stop_offset), :region)))
end
AnnotatedString(takestring!(outstr), annots)
end
Expand Down
12 changes: 6 additions & 6 deletions base/strings/annotated_io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function write(dest::AnnotatedIOBuffer, src::AnnotatedIOBuffer)
srcpos = position(src)
nb = write(dest.io, src.io)
isappending || _clear_annotations_in_region!(dest.annotations, destpos:destpos+nb)
srcannots = [setindex(annot, max(1 + srcpos, first(annot.region)):last(annot.region), :region)
srcannots = [@inline(setindex(annot, max(1 + srcpos, first(annot.region)):last(annot.region), :region))
for annot in src.annotations if first(annot.region) >= srcpos]
_insert_annotations!(dest, srcannots, destpos - srcpos)
nb
Expand Down Expand Up @@ -81,7 +81,7 @@ function read(io::AnnotatedIOBuffer, ::Type{AnnotatedString{T}}) where {T <: Abs
if (start = position(io)) == 0
AnnotatedString(read(io.io, T), copy(io.annotations))
else
annots = [setindex(annot, UnitRange{Int}(max(1, first(annot.region) - start), last(annot.region)-start), :region)
annots = [@inline(setindex(annot, UnitRange{Int}(max(1, first(annot.region) - start), last(annot.region)-start), :region))
for annot in io.annotations if last(annot.region) > start]
AnnotatedString(read(io.io, T), annots)
end
Expand All @@ -101,7 +101,7 @@ read(io::AnnotatedIOBuffer, ::Type{AnnotatedChar}) = read(io, AnnotatedChar{Char
function truncate(io::AnnotatedIOBuffer, size::Integer)
truncate(io.io, size)
filter!(ann -> first(ann.region) <= size, io.annotations)
map!(ann -> setindex(ann, first(ann.region):min(size, last(ann.region)), :region),
map!(ann -> @inline(setindex(ann, first(ann.region):min(size, last(ann.region)), :region)),
io.annotations, io.annotations)
io
end
Expand All @@ -125,17 +125,17 @@ function _clear_annotations_in_region!(annotations::Vector{RegionAnnotation}, sp
# Test for partial overlap
if first(region) <= first(span) <= last(region) || first(region) <= last(span) <= last(region)
annotations[i] =
setindex(annot,
@inline(setindex(annot,
if first(region) < first(span)
first(region):first(span)-1
else
last(span)+1:last(region)
end,
:region)
:region))
# If `span` fits exactly within `region`, then we've only copied over
# the beginning overhang, but also need to conserve the end overhang.
if first(region) < first(span) && last(span) < last(region)
push!(extras, (i, setindex(annot, last(span)+1:last(region), :region)))
push!(extras, (i, @inline(setindex(annot, last(span)+1:last(region), :region))))
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion base/terminfo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ struct TermInfo
aliases::Dict{Symbol, Symbol}
end

TermInfo() = TermInfo([], Dict(), Dict(), Dict(), nothing, Dict())
TermInfo() = TermInfo(String[], Dict{Symbol, Bool}(), Dict{Symbol, Int}(), Dict{Symbol, String}(), nothing, Dict{Symbol, Symbol}())

function read(data::IO, ::Type{TermInfoRaw})
# Parse according to `term(5)`
Expand Down