From d28a91733bac06f46140fe07010d9904a9b282e3 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Fri, 3 Jul 2020 17:42:29 -0500 Subject: [PATCH 1/2] Fix invalidations from loading OrderedCollections The major source of invalidations come from `print_status`. However, `TOML._print` calls itself, with apparently-noninferrable types, so we force runtime dispatch to sever the resulting self-backedges. --- ext/TOML/src/print.jl | 8 +++++--- src/Operations.jl | 10 +++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ext/TOML/src/print.jl b/ext/TOML/src/print.jl index e51f8ee7d8..d7f82a4b4a 100644 --- a/ext/TOML/src/print.jl +++ b/ext/TOML/src/print.jl @@ -87,8 +87,9 @@ function _print(io::IO, a::AbstractDict, printkey(io, ks) Base.print(io,"]\n") end - _print(io, value, ks, - indent = indent + header, first_block = header, sorted = sorted, by = by) + # Use runtime dispatch here since the type of value seems not to be enforced other than as AbstractDict + invoke(_print, Tuple{typeof(io), typeof(value), typeof(ks)}, + io, value, ks; indent = indent + header, first_block = header, sorted = sorted, by = by) pop!(ks) elseif is_array_of_tables(value) # print array of tables @@ -101,7 +102,8 @@ function _print(io::IO, a::AbstractDict, printkey(io, ks) Base.print(io,"]]\n") !isa(v, AbstractDict) && error("array should contain only tables") - _print(io, v, ks, indent = indent + 1, sorted = sorted, by = by) + invoke(_print, Tuple{typeof(io), typeof(v), typeof(ks)}, + io, v, ks; indent = indent + 1, sorted = sorted, by = by) end pop!(ks) end diff --git a/src/Operations.jl b/src/Operations.jl index 68fd1e350f..78198bf31d 100644 --- a/src/Operations.jl +++ b/src/Operations.jl @@ -1645,14 +1645,14 @@ function diff_array(old_ctx::Union{Context,Nothing}, new_ctx::Context; manifest= end # load deps new = manifest ? load_manifest_deps(new_ctx) : load_direct_deps(new_ctx) + T, S = Union{UUID,Nothing}, Union{PackageSpec,Nothing} if old_ctx === nothing - return [(pkg.uuid, nothing, pkg) for pkg in new] + return Tuple{T,S,S}[(pkg.uuid, nothing, pkg)::Tuple{T,S,S} for pkg in new] end old = manifest ? load_manifest_deps(old_ctx) : load_direct_deps(old_ctx) # merge old and new into single array - T, S = Union{UUID,Nothing}, Union{PackageSpec,Nothing} all_uuids = union(T[pkg.uuid for pkg in old], T[pkg.uuid for pkg in new]) - return Tuple{T,S,S}[(uuid, index_pkgs(old, uuid), index_pkgs(new, uuid)) for uuid in all_uuids] + return Tuple{T,S,S}[(uuid, index_pkgs(old, uuid), index_pkgs(new, uuid))::Tuple{T,S,S} for uuid in all_uuids] end function is_package_downloaded(ctx, pkg::PackageSpec) @@ -1676,12 +1676,12 @@ function print_status(ctx::Context, old_ctx::Union{Nothing,Context}, header::Sym (manifest ? "manifest" : "project") * ")", true) return nothing end - xs = !diff ? xs : [(id, old, new) for (id, old, new) in xs if old != new] + xs = !diff ? xs : eltype(xs)[(id, old, new) for (id, old, new) in xs if old != new] if isempty(xs) printpkgstyle(ctx, Symbol("No Changes"), "to $(pathrepr(manifest ? ctx.env.manifest_file : ctx.env.project_file))", true) return nothing end - xs = !filter ? xs : [(id, old, new) for (id, old, new) in xs if (id in uuids || something(new, old).name in names)] + xs = !filter ? xs : eltype(xs)[(id, old, new) for (id, old, new) in xs if (id in uuids || something(new, old).name in names)] if isempty(xs) printpkgstyle(ctx, Symbol("No Matches"), "in $(diff ? "diff for " : "")$(pathrepr(manifest ? ctx.env.manifest_file : ctx.env.project_file))", true) From 27dfcb40632886eee373941649ba2ddb79420eb6 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sat, 4 Jul 2020 06:55:20 -0500 Subject: [PATCH 2/2] Swtich to invokelatest --- ext/TOML/src/print.jl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ext/TOML/src/print.jl b/ext/TOML/src/print.jl index d7f82a4b4a..53d59b4878 100644 --- a/ext/TOML/src/print.jl +++ b/ext/TOML/src/print.jl @@ -88,8 +88,7 @@ function _print(io::IO, a::AbstractDict, Base.print(io,"]\n") end # Use runtime dispatch here since the type of value seems not to be enforced other than as AbstractDict - invoke(_print, Tuple{typeof(io), typeof(value), typeof(ks)}, - io, value, ks; indent = indent + header, first_block = header, sorted = sorted, by = by) + Base.invokelatest(_print, io, value, ks; indent = indent + header, first_block = header, sorted = sorted, by = by) pop!(ks) elseif is_array_of_tables(value) # print array of tables @@ -102,8 +101,7 @@ function _print(io::IO, a::AbstractDict, printkey(io, ks) Base.print(io,"]]\n") !isa(v, AbstractDict) && error("array should contain only tables") - invoke(_print, Tuple{typeof(io), typeof(v), typeof(ks)}, - io, v, ks; indent = indent + 1, sorted = sorted, by = by) + Base.invokelatest(_print, io, v, ks; indent = indent + 1, sorted = sorted, by = by) end pop!(ks) end