Skip to content

Commit 6f7331c

Browse files
authored
Backports for 1.12.0-beta4 (#58369)
2 parents 87870a9 + 59ad720 commit 6f7331c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+1033
-477
lines changed

Compiler/src/abstractinterpretation.jl

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,8 +1402,9 @@ function matching_cache_argtypes(𝕃::AbstractLattice, mi::MethodInstance,
14021402
if slotid !== nothing
14031403
# using union-split signature, we may be able to narrow down `Conditional`
14041404
sigt = widenconst(slotid > nargs ? argtypes[slotid] : cache_argtypes[slotid])
1405-
thentype = tmeet(cnd.thentype, sigt)
1406-
elsetype = tmeet(cnd.elsetype, sigt)
1405+
= meet(𝕃)
1406+
thentype = cnd.thentype sigt
1407+
elsetype = cnd.elsetype sigt
14071408
if thentype === Bottom && elsetype === Bottom
14081409
# we accidentally proved this method match is impossible
14091410
# TODO bail out here immediately rather than just propagating Bottom ?
@@ -2119,7 +2120,7 @@ function abstract_call_builtin(interp::AbstractInterpreter, f::Builtin, (; fargs
21192120
else
21202121
thentype = form_partially_defined_struct(argtype2, argtypes[3])
21212122
if thentype !== nothing
2122-
elsetype = argtype2
2123+
elsetype = widenslotwrapper(argtype2)
21232124
if rt === Const(false)
21242125
thentype = Bottom
21252126
elseif rt === Const(true)
@@ -2210,7 +2211,7 @@ function abstract_call_unionall(interp::AbstractInterpreter, argtypes::Vector{An
22102211
return CallMeta(ret, Any, Effects(EFFECTS_TOTAL; nothrow), call.info)
22112212
end
22122213

2213-
function ci_abi(ci::CodeInstance)
2214+
function get_ci_abi(ci::CodeInstance)
22142215
def = ci.def
22152216
isa(def, ABIOverride) && return def.abi
22162217
(def::MethodInstance).specTypes
@@ -2233,7 +2234,7 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt
22332234
if isa(method_or_ci, CodeInstance)
22342235
our_world = sv.world.this
22352236
argtype = argtypes_to_type(pushfirst!(argtype_tail(argtypes, 4), ft))
2236-
specsig = ci_abi(method_or_ci)
2237+
specsig = get_ci_abi(method_or_ci)
22372238
defdef = get_ci_mi(method_or_ci).def
22382239
exct = method_or_ci.exctype
22392240
if !hasintersect(argtype, specsig)
@@ -3229,7 +3230,7 @@ function abstract_eval_isdefined_expr(interp::AbstractInterpreter, e::Expr, ssta
32293230
elseif !vtyp.undef
32303231
rt = Const(true) # definitely assigned previously
32313232
else # form `Conditional` to refine `vtyp.undef` in the then branch
3232-
rt = Conditional(sym, vtyp.typ, vtyp.typ; isdefined=true)
3233+
rt = Conditional(sym, widenslotwrapper(vtyp.typ), widenslotwrapper(vtyp.typ); isdefined=true)
32333234
end
32343235
return RTEffects(rt, Union{}, EFFECTS_TOTAL)
32353236
end
@@ -3497,7 +3498,7 @@ function merge_override_effects!(interp::AbstractInterpreter, effects::Effects,
34973498
# N.B.: We'd like deleted_world here, but we can't add an appropriate edge at this point.
34983499
# However, in order to reach here in the first place, ordinary method lookup would have
34993500
# had to add an edge and appropriate invalidation trigger.
3500-
valid_worlds = WorldRange(m.primary_world, typemax(Int))
3501+
valid_worlds = WorldRange(m.primary_world, typemax(UInt))
35013502
if sv.world.this in valid_worlds
35023503
update_valid_age!(sv, valid_worlds)
35033504
else

Compiler/src/cicache.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ end
1414
function setindex!(cache::InternalCodeCache, ci::CodeInstance, mi::MethodInstance)
1515
@assert ci.owner === cache.owner
1616
m = mi.def
17-
if isa(m, Method) && m.module != Core
17+
if isa(m, Method)
1818
ccall(:jl_push_newly_inferred, Cvoid, (Any,), ci)
1919
end
2020
ccall(:jl_mi_cache_insert, Cvoid, (Any, Any), mi, ci)

Compiler/src/ssair/show.jl

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ using .Compiler: ALWAYS_FALSE, ALWAYS_TRUE, argextype, BasicBlock, block_for_ins
1212
CachedMethodTable, CFG, compute_basic_blocks, DebugInfoStream, Effects,
1313
EMPTY_SPTYPES, getdebugidx, IncrementalCompact, InferenceResult, InferenceState,
1414
InvalidIRError, IRCode, LimitedAccuracy, NativeInterpreter, scan_ssa_use!,
15-
singleton_type, sptypes_from_meth_instance, StmtRange, Timings, VarState, widenconst
15+
singleton_type, sptypes_from_meth_instance, StmtRange, Timings, VarState, widenconst,
16+
get_ci_mi, get_ci_abi
1617

1718
@nospecialize
1819

@@ -95,16 +96,14 @@ function print_stmt(io::IO, idx::Int, @nospecialize(stmt), code::Union{IRCode,Co
9596
elseif isexpr(stmt, :invoke) && length(stmt.args) >= 2 && isa(stmt.args[1], Union{MethodInstance,CodeInstance})
9697
stmt = stmt::Expr
9798
# TODO: why is this here, and not in Base.show_unquoted
98-
printstyled(io, " invoke "; color = :light_black)
99-
mi = stmt.args[1]
100-
if !(mi isa Core.MethodInstance)
101-
mi = (mi::Core.CodeInstance).def
102-
end
103-
if isa(mi, Core.ABIOverride)
104-
abi = mi.abi
105-
mi = mi.def
99+
ci = stmt.args[1]
100+
if ci isa Core.CodeInstance
101+
printstyled(io, " invoke "; color = :light_black)
102+
mi = get_ci_mi(ci)
103+
abi = get_ci_abi(ci)
106104
else
107-
abi = mi.specTypes
105+
printstyled(io, "dynamic invoke "; color = :yellow)
106+
abi = (ci::Core.MethodInstance).specTypes
108107
end
109108
show_unquoted(io, stmt.args[2], indent)
110109
print(io, "(")

Compiler/src/typeinfer.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ function adjust_effects(ipo_effects::Effects, def::Method, world::UInt)
362362
valid_worlds = WorldRange(0, typemax(UInt))
363363
if is_effect_overridden(override, :consistent)
364364
# See note on `typemax(Int)` instead of `deleted_world` in adjust_effects!
365-
override_valid_worlds = WorldRange(def.primary_world, typemax(Int))
365+
override_valid_worlds = WorldRange(def.primary_world, typemax(UInt))
366366
if world in override_valid_worlds
367367
ipo_effects = Effects(ipo_effects; consistent=ALWAYS_TRUE)
368368
valid_worlds = override_valid_worlds
@@ -1422,7 +1422,7 @@ function compile!(codeinfos::Vector{Any}, workqueue::CompilationQueue;
14221422
# if this method is generally visible to the current compilation world,
14231423
# and this is either the primary world, or not applicable in the primary world
14241424
# then we want to compile and emit this
1425-
if item.def.primary_world <= world <= item.def.deleted_world
1425+
if item.def.primary_world <= world
14261426
ci = typeinf_ext(interp, item, SOURCE_MODE_GET_SOURCE)
14271427
ci isa CodeInstance && push!(workqueue, ci)
14281428
end
@@ -1523,7 +1523,8 @@ function typeinf_ext_toplevel(methods::Vector{Any}, worlds::Vector{UInt}, trim_m
15231523
return codeinfos
15241524
end
15251525

1526-
verify_typeinf_trim(codeinfos::Vector{Any}, onlywarn::Bool) = invokelatest(verify_typeinf_trim, stdout, codeinfos, onlywarn)
1526+
const _verify_trim_world_age = RefValue{UInt}(typemax(UInt))
1527+
verify_typeinf_trim(codeinfos::Vector{Any}, onlywarn::Bool) = Core._call_in_world(_verify_trim_world_age[], verify_typeinf_trim, stdout, codeinfos, onlywarn)
15271528

15281529
function return_type(@nospecialize(f), t::DataType) # this method has a special tfunc
15291530
world = tls_world_age()

Compiler/test/codegen.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,3 +1032,29 @@ end
10321032
const x57872 = "Hello"
10331033
f57872() = (Core.isdefinedglobal(@__MODULE__, Base.compilerbarrier(:const, :x57872)), x57872) # Extra globalref here to force world age bounds
10341034
@test f57872() == (true, "Hello")
1035+
1036+
@noinline f_mutateany(@nospecialize x) = x[] = 1
1037+
g_mutateany() = (y = Ref(0); f_mutateany(y); y[])
1038+
@test g_mutateany() === 1
1039+
1040+
# 58470 tbaa for unionselbyte of heap allocated mutables
1041+
mutable struct Wrapper58470
1042+
x::Union{Nothing,Int}
1043+
end
1044+
1045+
function findsomething58470(dict, inds)
1046+
default = Wrapper58470(nothing)
1047+
for i in inds
1048+
x = get(dict, i, default).x
1049+
if !isnothing(x)
1050+
return x
1051+
end
1052+
end
1053+
return nothing
1054+
end
1055+
1056+
let io = IOBuffer()
1057+
code_llvm(io, findsomething58470, Tuple{Dict{Int64, Wrapper58470}, Vector{Int}}, dump_module=true, raw=true, optimize=false)
1058+
str = String(take!(io))
1059+
@test !occursin("jtbaa_unionselbyte", str)
1060+
end

Compiler/test/inference.jl

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2262,12 +2262,18 @@ struct AliasableFields{S,T}
22622262
f1::S
22632263
f2::T
22642264
end
2265+
struct NullableAliasableFields{S,T}
2266+
f1::S
2267+
f2::T
2268+
NullableAliasableFields(f1::S, f2::T) where {S,T} = new{S,T}(f1, f2)
2269+
NullableAliasableFields(f1::S) where {S} = new{S,Union{}}(f1)
2270+
end
22652271
mutable struct AliasableConstField{S,T}
22662272
const f1::S
22672273
f2::T
22682274
end
22692275

2270-
import .Compiler:
2276+
using .Compiler:
22712277
InferenceLattice, MustAliasesLattice, InterMustAliasesLattice,
22722278
BaseInferenceLattice, SimpleInferenceLattice, IPOResultLattice, typeinf_lattice, ipo_lattice, optimizer_lattice
22732279

@@ -2280,7 +2286,7 @@ Compiler.optimizer_lattice(::MustAliasInterpreter) = SimpleInferenceLattice.inst
22802286
# lattice
22812287
# -------
22822288

2283-
import .Compiler: MustAlias, Const, PartialStruct, , tmerge
2289+
using .Compiler: MustAlias, Const, PartialStruct, , tmerge
22842290
let 𝕃ᵢ = InferenceLattice(MustAliasesLattice(BaseInferenceLattice.instance))
22852291
(@nospecialize(a), @nospecialize(b)) = Compiler.:(𝕃ᵢ, a, b)
22862292
tmerge(@nospecialize(a), @nospecialize(b)) = Compiler.tmerge(𝕃ᵢ, a, b)
@@ -2518,6 +2524,15 @@ jet509_hasitems(list) = length(list) >= 1
25182524
error("list is empty")
25192525
end |> only == Vector{Int}
25202526

2527+
# don't form nested slot wrappers
2528+
@test Base.infer_return_type((NullableAliasableFields{NullableAliasableFields},); interp=MustAliasInterpreter()) do x
2529+
y = getfield(x, :f1)
2530+
if isdefined(y, :f2) && isa(getfield(y, :f2), Int)
2531+
return getfield(y, :f2)
2532+
end
2533+
return 0
2534+
end == Int
2535+
25212536
# === constraint
25222537
# --------------
25232538

base/Base.jl

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ include(strcat(BUILDROOT, "version_git.jl")) # include($BUILDROOT/base/version_g
2323
# a slightly more verbose fashion than usual, because we're running so early.
2424
let os = ccall(:jl_get_UNAME, Any, ())
2525
if os === :Darwin || os === :Apple
26-
if Base.DARWIN_FRAMEWORK
26+
if DARWIN_FRAMEWORK
2727
push!(DL_LOAD_PATH, "@loader_path/Frameworks")
2828
end
2929
push!(DL_LOAD_PATH, "@loader_path")
@@ -306,8 +306,8 @@ a_method_to_overwrite_in_test() = inferencebarrier(1)
306306
(this::IncludeInto)(mapexpr::Function, fname::AbstractString) = include(mapexpr, this.m, fname)
307307

308308
# Compatibility with when Compiler was in Core
309-
@eval Core const Compiler = Main.Base.Compiler
310-
@eval Compiler const fl_parse = Core.Main.Base.fl_parse
309+
@eval Core const Compiler = $Base.Compiler
310+
@eval Compiler const fl_parse = $Base.fl_parse
311311

312312
# External libraries vendored into Base
313313
Core.println("JuliaSyntax/src/JuliaSyntax.jl")
@@ -323,13 +323,13 @@ if is_primary_base_module
323323
# Profiling helper
324324
# triggers printing the report and (optionally) saving a heap snapshot after a SIGINFO/SIGUSR1 profile request
325325
# Needs to be in Base because Profile is no longer loaded on boot
326-
function profile_printing_listener(cond::Base.AsyncCondition)
326+
function profile_printing_listener(cond::AsyncCondition)
327327
profile = nothing
328328
try
329329
while _trywait(cond)
330330
profile = @something(profile, require_stdlib(PkgId(UUID("9abbd945-dff8-562f-b5e8-e1ebf5ef1b79"), "Profile")))::Module
331331
invokelatest(profile.peek_report[])
332-
if Base.get_bool_env("JULIA_PROFILE_PEEK_HEAP_SNAPSHOT", false) === true
332+
if get_bool_env("JULIA_PROFILE_PEEK_HEAP_SNAPSHOT", false) === true
333333
println(stderr, "Saving heap snapshot...")
334334
fname = invokelatest(profile.take_heap_snapshot)
335335
println(stderr, "Heap snapshot saved to `$(fname)`")
@@ -344,8 +344,8 @@ function profile_printing_listener(cond::Base.AsyncCondition)
344344
end
345345

346346
function start_profile_listener()
347-
cond = Base.AsyncCondition()
348-
Base.uv_unref(cond.handle)
347+
cond = AsyncCondition()
348+
uv_unref(cond.handle)
349349
t = errormonitor(Threads.@spawn(profile_printing_listener(cond)))
350350
atexit() do
351351
# destroy this callback when exiting
@@ -405,7 +405,6 @@ end
405405
const _compiler_require_dependencies = Any[]
406406
@Core.latestworld
407407
for i = 1:length(_included_files)
408-
isassigned(_included_files, i) || continue
409408
(mod, file) = _included_files[i]
410409
if mod === Compiler || parentmodule(mod) === Compiler || endswith(file, "/Compiler.jl")
411410
_include_dependency!(_compiler_require_dependencies, true, mod, file, true, false)
@@ -421,7 +420,3 @@ end
421420
@assert length(_compiler_require_dependencies) >= 15
422421

423422
end
424-
425-
# Ensure this file is also tracked
426-
@assert !isassigned(_included_files, 1)
427-
_included_files[1] = (parentmodule(Base), abspath(@__FILE__))

base/Base_compiler.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,5 +384,9 @@ Core._setparser!(fl_parse)
384384

385385
# Further definition of Base will happen in Base.jl if loaded.
386386

387+
# Ensure this file is also tracked
388+
@assert !isassigned(_included_files, 1)
389+
_included_files[1] = (@__MODULE__, ccall(:jl_prepend_cwd, Any, (Any,), "Base_compiler.jl"))
390+
387391
end # module Base
388392
using .Base

base/client.jl

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ stackframe_lineinfo_color() = repl_color("JULIA_STACKFRAME_LINEINFO_COLOR", :bol
3232
stackframe_function_color() = repl_color("JULIA_STACKFRAME_FUNCTION_COLOR", :bold)
3333

3434
function repl_cmd(cmd, out)
35-
shell = shell_split(get(ENV, "JULIA_SHELL", get(ENV, "SHELL", "/bin/sh")))
36-
shell_name = Base.basename(shell[1])
37-
3835
# Immediately expand all arguments, so that typing e.g. ~/bin/foo works.
3936
cmd.exec .= expanduser.(cmd.exec)
4037

@@ -64,19 +61,15 @@ function repl_cmd(cmd, out)
6461
cd(dir)
6562
println(out, pwd())
6663
else
67-
@static if !Sys.iswindows()
68-
if shell_name == "fish"
69-
shell_escape_cmd = "begin; $(shell_escape_posixly(cmd)); and true; end"
70-
else
71-
shell_escape_cmd = "($(shell_escape_posixly(cmd))) && true"
72-
end
64+
if !Sys.iswindows()
65+
shell = shell_split(get(ENV, "JULIA_SHELL", get(ENV, "SHELL", "/bin/sh")))
66+
shell_escape_cmd = shell_escape_posixly(cmd)
7367
cmd = `$shell -c $shell_escape_cmd`
7468
end
7569
try
7670
run(ignorestatus(cmd))
7771
catch
78-
# Windows doesn't shell out right now (complex issue), so Julia tries to run the program itself
79-
# Julia throws an exception if it can't find the program, but the stack trace isn't useful
72+
# Julia throws an exception if it can't find the cmd (which may be the shell itself), but the stack trace isn't useful
8073
lasterr = current_exceptions()
8174
lasterr = ExceptionStack([(exception = e[1], backtrace = [] ) for e in lasterr])
8275
invokelatest(display_error, lasterr)

base/docs/basedocs.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2796,6 +2796,9 @@ a value set.
27962796
If `allow_import` is `false`, the global variable must be defined inside `m`
27972797
and may not be imported from another module.
27982798
2799+
!!! compat "Julia 1.12"
2800+
This function requires Julia 1.12 or later.
2801+
27992802
See also [`@isdefined`](@ref).
28002803
28012804
# Examples

0 commit comments

Comments
 (0)