Skip to content

Commit 9f0919f

Browse files
committed
bpart: Redesign representation of implicit imports
# Current Design When we explicitly import a binding (via either `using M: x` or `import`), the corresponding bpart representation is a direct pointer to the imported binding. This is necessary, because that is the precise semantic representation of the import. However, for implicit imports (those created via `using M` without explicit symbol name), the situation is a bit different. Here, there is no semantic content to the particular binding being imported. Worse, the binding is not necessarily unique. Our current semantics are essentially that we walk the entire import graph (both explicit and implicit edges) and if all reachable terminal nodes are either (i) the same binding or (ii) constant bindings with the same value, the import is allowed. In this, we are supposed to ignore cycles, although the current implementation has some trouble with this (#57638, #57699). If the import succeeds, in the current implementation, we then record an arbitrary implicit import edge as in the BindingPartition. In essence, we are creating a spanning tree of the import graph (formed from both the implicit and explicit import edges). However, dynamic algorithms for spanning tree maintenance are complicated and we didn't implement any. As a result, it is possible for later edge additions to accidentally introduce cycles (causing #57699). An additional problem, even if we could keep a consistent spanning tree, is that the spanning tree is not unique. In practice, this is not supposed to be observable, but it is still odd to have a non-unique representation for a particular set of imports. That said, we don't really need the spanning tree. The only place that actually uses it is `which(::Module, ::Symbol)` which is not performance sensitive and arguably a bad API for the above reason that the answer is ill-defined. # This PR With all these problems, let's just get rid of the spanning tree all together - as mentioned we don't really need it. Instead, we split the PARTITION_KIND_IMPLICIT into two, one for each of the two cases (importing a global binding, or importing a particular constant value). This is actually a more efficient implementation for the common case of needing to follow a lookup - we no longer need to follow all the import edges. In exchange, more work needs to be done during binding replacement to re-scan the entire import graph. This is probably the right trade-off though, since binding replacement is already a slow path. Fixes #57638, #57699
1 parent 6817691 commit 9f0919f

20 files changed

+482
-305
lines changed

Compiler/src/Compiler.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@ else
3535

3636
@eval baremodule Compiler
3737

38-
# Needs to match UUID defined in Project.toml
39-
ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Compiler,
40-
(0x807dbc54_b67e_4c79, 0x8afb_eafe4df6f2e1))
41-
4238
using Core.Intrinsics, Core.IR
4339

4440
using Core: ABIOverride, Builtin, CodeInstance, IntrinsicFunction, MethodInstance, MethodMatch,
@@ -61,7 +57,7 @@ using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospeciali
6157
generating_output, get_nospecializeinfer_sig, get_world_counter, has_free_typevars,
6258
hasgenerator, hasintersect, indexed_iterate, isType, is_file_tracked, is_function_def,
6359
is_meta_expr, is_meta_expr_head, is_nospecialized, is_nospecializeinfer, is_defined_const_binding,
64-
is_some_const_binding, is_some_guard, is_some_imported, is_valid_intrinsic_elptr,
60+
is_some_const_binding, is_some_guard, is_some_imported, is_some_explicit_imported, is_some_binding_imported, is_valid_intrinsic_elptr,
6561
isbitsunion, isconcretedispatch, isdispatchelem, isexpr, isfieldatomic, isidentityfree,
6662
iskindtype, ismutabletypename, ismutationfree, issingletontype, isvarargtype, isvatuple,
6763
kwerr, lookup_binding_partition, may_invoke_generator, methods, midpoint, moduleroot,
@@ -76,6 +72,10 @@ import Base: ==, _topmod, append!, convert, copy, copy!, findall, first, get, ge
7672
getindex, haskey, in, isempty, isready, iterate, iterate, last, length, max_world,
7773
min_world, popfirst!, push!, resize!, setindex!, size, intersect
7874

75+
# Needs to match UUID defined in Project.toml
76+
ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Compiler,
77+
(0x807dbc54_b67e_4c79, 0x8afb_eafe4df6f2e1))
78+
7979
const getproperty = Core.getfield
8080
const setproperty! = Core.setfield!
8181
const swapproperty! = Core.swapfield!
@@ -131,7 +131,7 @@ something(x::Any, y...) = x
131131
############
132132

133133
baremodule BuildSettings
134-
using Core: ARGS, include
134+
using Core: ARGS, include, Int, ===
135135
using ..Compiler: >, getindex, length
136136

137137
global MAX_METHODS::Int = 3
@@ -191,7 +191,7 @@ macro __SOURCE_FILE__()
191191
end
192192

193193
module IRShow end # relies on string and IO operations defined in Base
194-
baremodule TrimVerifier end # relies on IRShow, so define this afterwards
194+
baremodule TrimVerifier using Core end # relies on IRShow, so define this afterwards
195195

196196
if isdefined(Base, :end_base_include)
197197
# When this module is loaded as the standard library, include these files as usual

Compiler/src/abstractinterpretation.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3287,7 +3287,7 @@ function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, mod::Module,
32873287
if allow_import !== true
32883288
gr = GlobalRef(mod, sym)
32893289
partition = lookup_binding_partition!(interp, gr, sv)
3290-
if allow_import !== true && is_some_imported(binding_kind(partition))
3290+
if allow_import !== true && is_some_binding_imported(binding_kind(partition))
32913291
if allow_import === false
32923292
rt = Const(false)
32933293
else
@@ -3540,7 +3540,7 @@ end
35403540

35413541
function walk_binding_partition(imported_binding::Core.Binding, partition::Core.BindingPartition, world::UInt)
35423542
valid_worlds = WorldRange(partition.min_world, partition.max_world)
3543-
while is_some_imported(binding_kind(partition))
3543+
while is_some_binding_imported(binding_kind(partition))
35443544
imported_binding = partition_restriction(partition)::Core.Binding
35453545
partition = lookup_binding_partition(world, imported_binding)
35463546
valid_worlds = intersect(valid_worlds, WorldRange(partition.min_world, partition.max_world))

Compiler/src/ssair/EscapeAnalysis.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ using Base: Base
1515
# imports
1616
import Base: ==, copy, getindex, setindex!
1717
# usings
18+
using Core
1819
using Core: Builtin, IntrinsicFunction, SimpleVector, ifelse, sizeof
1920
using Core.IR
2021
using Base: # Base definitions

Compiler/test/codegen.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,3 +1007,23 @@ let
10071007
end
10081008
nothing
10091009
end
1010+
1011+
# Test that turning an implicit import into an explicit one doesn't pessimize codegen
1012+
module TurnedIntoExplicit
1013+
using Test
1014+
import ..get_llvm
1015+
1016+
module ReExportBitCast
1017+
export bitcast
1018+
import Base: bitcast
1019+
end
1020+
using .ReExportBitCast
1021+
1022+
f(x::UInt) = bitcast(Float64, x)
1023+
1024+
@test !occursin("jl_apply_generic", get_llvm(f, Tuple{UInt}))
1025+
1026+
import Base: bitcast
1027+
1028+
@test !occursin("jl_apply_generic", get_llvm(f, Tuple{UInt}))
1029+
end

base/Base_compiler.jl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,18 +277,21 @@ include("operators.jl")
277277
include("pointer.jl")
278278
include("refvalue.jl")
279279
include("cmem.jl")
280+
281+
function nextfloat end
282+
function prevfloat end
280283
include("rounding.jl")
281284
include("float.jl")
282285

283-
include("checked.jl")
284-
using .Checked
285-
function cld end
286-
function fld end
287-
288286
# Lazy strings
289287
import Core: String
290288
include("strings/lazy.jl")
291289

290+
function cld end
291+
function fld end
292+
include("checked.jl")
293+
using .Checked
294+
292295
# array structures
293296
include("indices.jl")
294297
include("genericmemory.jl")
@@ -373,3 +376,4 @@ Core._setparser!(fl_parse)
373376
# Further definition of Base will happen in Base.jl if loaded.
374377

375378
end # baremodule Base
379+
using .Base

base/errorshow.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1159,7 +1159,7 @@ function UndefVarError_hint(io::IO, ex::UndefVarError)
11591159
"with the module it should come from.")
11601160
elseif kind === Base.PARTITION_KIND_GUARD
11611161
print(io, "\nSuggestion: check for spelling errors or missing imports.")
1162-
elseif Base.is_some_imported(kind)
1162+
elseif Base.is_some_explicit_imported(kind)
11631163
print(io, "\nSuggestion: this global was defined as `$(Base.partition_restriction(bpart).globalref)` but not assigned a value.")
11641164
end
11651165
elseif scope === :static_parameter

base/invalidation.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,9 @@ function invalidate_code_for_globalref!(b::Core.Binding, invalidated_bpart::Core
151151
latest_bpart = edge.partitions
152152
latest_bpart.max_world == typemax(UInt) || continue
153153
is_some_imported(binding_kind(latest_bpart)) || continue
154-
partition_restriction(latest_bpart) === b || continue
154+
if is_some_binding_imported(binding_kind(latest_bpart))
155+
partition_restriction(latest_bpart) === b || continue
156+
end
155157
invalidate_code_for_globalref!(edge, latest_bpart, latest_bpart, new_max_world)
156158
else
157159
invalidate_method_for_globalref!(gr, edge::Method, invalidated_bpart, new_max_world)
@@ -171,9 +173,9 @@ function invalidate_code_for_globalref!(b::Core.Binding, invalidated_bpart::Core
171173
isdefined(user_binding, :partitions) || continue
172174
latest_bpart = user_binding.partitions
173175
latest_bpart.max_world == typemax(UInt) || continue
174-
binding_kind(latest_bpart) in (PARTITION_KIND_IMPLICIT, PARTITION_KIND_FAILED, PARTITION_KIND_GUARD) || continue
176+
is_some_implicit(binding_kind(latest_bpart)) || continue
175177
new_bpart = need_to_invalidate_export ?
176-
ccall(:jl_maybe_reresolve_implicit, Any, (Any, Any, Csize_t), user_binding, latest_bpart, new_max_world) :
178+
ccall(:jl_maybe_reresolve_implicit, Any, (Any, Csize_t), user_binding, new_max_world) :
177179
latest_bpart
178180
if need_to_invalidate_code || new_bpart !== latest_bpart
179181
invalidate_code_for_globalref!(convert(Core.Binding, user_binding), latest_bpart, new_bpart, new_max_world)

base/iterators.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ using .Base:
1717
any, _counttuple, eachindex, ntuple, zero, prod, reduce, in, firstindex, lastindex,
1818
tail, fieldtypes, min, max, minimum, zero, oneunit, promote, promote_shape, LazyString,
1919
afoldl
20+
using Core
2021
using Core: @doc
2122

2223
using .Base:

base/runtime_internals.jl

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -197,17 +197,18 @@ function _fieldnames(@nospecialize t)
197197
end
198198

199199
# N.B.: Needs to be synced with julia.h
200-
const PARTITION_KIND_CONST = 0x0
201-
const PARTITION_KIND_CONST_IMPORT = 0x1
202-
const PARTITION_KIND_GLOBAL = 0x2
203-
const PARTITION_KIND_IMPLICIT = 0x3
204-
const PARTITION_KIND_EXPLICIT = 0x4
205-
const PARTITION_KIND_IMPORTED = 0x5
206-
const PARTITION_KIND_FAILED = 0x6
207-
const PARTITION_KIND_DECLARED = 0x7
208-
const PARTITION_KIND_GUARD = 0x8
209-
const PARTITION_KIND_UNDEF_CONST = 0x9
210-
const PARTITION_KIND_BACKDATED_CONST = 0xa
200+
const PARTITION_KIND_CONST = 0x0
201+
const PARTITION_KIND_CONST_IMPORT = 0x1
202+
const PARTITION_KIND_GLOBAL = 0x2
203+
const PARTITION_KIND_IMPLICIT_GLOBAL = 0x3
204+
const PARTITION_KIND_IMPLICIT_CONST = 0x4
205+
const PARTITION_KIND_EXPLICIT = 0x5
206+
const PARTITION_KIND_IMPORTED = 0x6
207+
const PARTITION_KIND_FAILED = 0x7
208+
const PARTITION_KIND_DECLARED = 0x8
209+
const PARTITION_KIND_GUARD = 0x9
210+
const PARTITION_KIND_UNDEF_CONST = 0xa
211+
const PARTITION_KIND_BACKDATED_CONST = 0xb
211212

212213
const PARTITION_FLAG_EXPORTED = 0x10
213214
const PARTITION_FLAG_DEPRECATED = 0x20
@@ -218,9 +219,12 @@ const PARTITION_MASK_FLAG = 0xf0
218219

219220
const BINDING_FLAG_ANY_IMPLICIT_EDGES = 0x8
220221

221-
is_defined_const_binding(kind::UInt8) = (kind == PARTITION_KIND_CONST || kind == PARTITION_KIND_CONST_IMPORT || kind == PARTITION_KIND_BACKDATED_CONST)
222+
is_defined_const_binding(kind::UInt8) = (kind == PARTITION_KIND_CONST || kind == PARTITION_KIND_CONST_IMPORT || kind == PARTITION_KIND_IMPLICIT_CONST || kind == PARTITION_KIND_BACKDATED_CONST)
222223
is_some_const_binding(kind::UInt8) = (is_defined_const_binding(kind) || kind == PARTITION_KIND_UNDEF_CONST)
223-
is_some_imported(kind::UInt8) = (kind == PARTITION_KIND_IMPLICIT || kind == PARTITION_KIND_EXPLICIT || kind == PARTITION_KIND_IMPORTED)
224+
is_some_imported(kind::UInt8) = (kind == PARTITION_KIND_IMPLICIT_GLOBAL || kind == PARTITION_KIND_IMPLICIT_CONST || kind == PARTITION_KIND_EXPLICIT || kind == PARTITION_KIND_IMPORTED)
225+
is_some_implicit(kind::UInt8) = (kind == PARTITION_KIND_IMPLICIT_GLOBAL || kind == PARTITION_KIND_IMPLICIT_CONST || kind == PARTITION_KIND_GUARD || kind == PARTITION_KIND_FAILED)
226+
is_some_explicit_imported(kind::UInt8) = (kind == PARTITION_KIND_EXPLICIT || kind == PARTITION_KIND_IMPORTED)
227+
is_some_binding_imported(kind::UInt8) = is_some_explicit_imported(kind) || kind == PARTITION_KIND_IMPLICIT_GLOBAL
224228
is_some_guard(kind::UInt8) = (kind == PARTITION_KIND_GUARD || kind == PARTITION_KIND_FAILED || kind == PARTITION_KIND_UNDEF_CONST)
225229

226230
function lookup_binding_partition(world::UInt, b::Core.Binding)

base/show.jl

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,14 +1023,20 @@ end
10231023
function isvisible(sym::Symbol, parent::Module, from::Module)
10241024
isdeprecated(parent, sym) && return false
10251025
isdefinedglobal(from, sym) || return false
1026+
isdefinedglobal(parent, sym) || return false
10261027
parent_binding = convert(Core.Binding, GlobalRef(parent, sym))
10271028
from_binding = convert(Core.Binding, GlobalRef(from, sym))
10281029
while true
10291030
from_binding === parent_binding && return true
10301031
partition = lookup_binding_partition(tls_world_age(), from_binding)
1031-
is_some_imported(binding_kind(partition)) || break
1032+
is_some_explicit_imported(binding_kind(partition)) || break
10321033
from_binding = partition_restriction(partition)::Core.Binding
10331034
end
1035+
parent_partition = lookup_binding_partition(tls_world_age(), parent_binding)
1036+
from_partition = lookup_binding_partition(tls_world_age(), from_binding)
1037+
if is_defined_const_binding(binding_kind(parent_partition)) && is_defined_const_binding(binding_kind(from_partition))
1038+
return parent_partition.restriction === from_partition.restriction
1039+
end
10341040
return false
10351041
end
10361042

@@ -3398,7 +3404,7 @@ function print_partition(io::IO, partition::Core.BindingPartition)
33983404
if kind == PARTITION_KIND_BACKDATED_CONST
33993405
print(io, "backdated constant binding to ")
34003406
print(io, partition_restriction(partition))
3401-
elseif is_defined_const_binding(kind)
3407+
elseif kind == PARTITION_KIND_CONST
34023408
print(io, "constant binding to ")
34033409
print(io, partition_restriction(partition))
34043410
elseif kind == PARTITION_KIND_UNDEF_CONST
@@ -3409,9 +3415,12 @@ function print_partition(io::IO, partition::Core.BindingPartition)
34093415
print(io, "ambiguous binding - guard entry")
34103416
elseif kind == PARTITION_KIND_DECLARED
34113417
print(io, "weak global binding declared using `global` (implicit type Any)")
3412-
elseif kind == PARTITION_KIND_IMPLICIT
3413-
print(io, "implicit `using` from ")
3418+
elseif kind == PARTITION_KIND_IMPLICIT_GLOBAL
3419+
print(io, "implicit `using` resolved to global ")
34143420
print(io, partition_restriction(partition).globalref)
3421+
elseif kind == PARTITION_KIND_IMPLICIT_CONST
3422+
print(io, "implicit `using` resolved to constant ")
3423+
print(io, partition_restriction(partition))
34153424
elseif kind == PARTITION_KIND_EXPLICIT
34163425
print(io, "explicit `using` from ")
34173426
print(io, partition_restriction(partition).globalref)
@@ -3434,7 +3443,7 @@ function show(io::IO, ::MIME"text/plain", bnd::Core.Binding)
34343443
print(io, "Binding ")
34353444
print(io, bnd.globalref)
34363445
if !isdefined(bnd, :partitions)
3437-
print(io, "No partitions")
3446+
print(io, " - No partitions")
34383447
else
34393448
partition = @atomic bnd.partitions
34403449
while true

base/sysimg.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ Core.include(Base, "Base.jl")
1212
had_compiler && ccall(:jl_init_restored_module, Cvoid, (Any,), Base)
1313
end
1414

15-
using .Base
16-
1715
# Set up Main module
1816
using Base.MainInclude # ans, err, and sometimes Out
1917

src/jl_exported_funcs.inc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@
193193
XX(jl_get_ARCH) \
194194
XX(jl_get_backtrace) \
195195
XX(jl_get_binding) \
196-
XX(jl_get_binding_for_method_def) \
197196
XX(jl_get_binding_wr) \
198197
XX(jl_check_binding_currently_writable) \
199198
XX(jl_get_cpu_name) \

src/julia.h

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,8 @@ typedef struct _jl_weakref_t {
632632
// These binding kinds depend solely on the set of using'd packages and are not explicitly
633633
// declared:
634634
//
635-
// PARTITION_KIND_IMPLICIT
635+
// PARTITION_KIND_IMPLICIT_CONST
636+
// PARTITION_KIND_IMPLICIT_GLOBAL
636637
// PARTITION_KIND_GUARD
637638
// PARTITION_KIND_FAILED
638639
//
@@ -683,37 +684,41 @@ enum jl_partition_kind {
683684
// `global x::T` to implicitly through a syntactic global assignment.
684685
// -> restriction holds the type restriction
685686
PARTITION_KIND_GLOBAL = 0x2,
686-
// Implicit: The binding was implicitly imported from a `using`'d module.
687-
// ->restriction holds the imported binding
688-
PARTITION_KIND_IMPLICIT = 0x3,
687+
// Implicit: The binding was a global, implicitly imported from a `using`'d module.
688+
// ->restriction holds the ultimately imported global binding
689+
PARTITION_KIND_IMPLICIT_GLOBAL = 0x3,
690+
// Implicit: The binding was a constant, implicitly imported from a `using`'d module.
691+
// ->restriction holds the ultimately imported constant value
692+
PARTITION_KIND_IMPLICIT_CONST = 0x4,
689693
// Explicit: The binding was explicitly `using`'d by name
690694
// ->restriction holds the imported binding
691-
PARTITION_KIND_EXPLICIT = 0x4,
695+
PARTITION_KIND_EXPLICIT = 0x5,
692696
// Imported: The binding was explicitly `import`'d by name
693697
// ->restriction holds the imported binding
694-
PARTITION_KIND_IMPORTED = 0x5,
698+
PARTITION_KIND_IMPORTED = 0x6,
695699
// Failed: We attempted to import the binding, but the import was ambiguous
696700
// ->restriction is NULL.
697-
PARTITION_KIND_FAILED = 0x6,
701+
PARTITION_KIND_FAILED = 0x7,
698702
// Declared: The binding was declared using `global` or similar. This acts in most ways like
699703
// PARTITION_KIND_GLOBAL with an `Any` restriction, except that it may be redefined to a stronger
700704
// binding like `const` or an explicit import.
701705
// ->restriction is NULL.
702-
PARTITION_KIND_DECLARED = 0x7,
706+
PARTITION_KIND_DECLARED = 0x8,
703707
// Guard: The binding was looked at, but no global or import was resolved at the time
704708
// ->restriction is NULL.
705-
PARTITION_KIND_GUARD = 0x8,
709+
PARTITION_KIND_GUARD = 0x9,
706710
// Undef Constant: This binding partition is a constant declared using `const`, but
707711
// without a value.
708712
// ->restriction is NULL
709-
PARTITION_KIND_UNDEF_CONST = 0x9,
713+
PARTITION_KIND_UNDEF_CONST = 0xa,
710714
// Backated constant. A constant that was backdated for compatibility. In all other
711715
// ways equivalent to PARTITION_KIND_CONST, but prints a warning on access
712-
PARTITION_KIND_BACKDATED_CONST = 0xa,
716+
PARTITION_KIND_BACKDATED_CONST = 0xb,
713717

714718
// This is not a real binding kind, but can be used to ask for a re-resolution
715719
// of the implicit binding kind
716-
PARTITION_KIND_IMPLICIT_RECOMPUTE = 0xb
720+
PARTITION_FAKE_KIND_IMPLICIT_RECOMPUTE = 0xc,
721+
PARTITION_FAKE_KIND_CYCLE = 0xd
717722
};
718723

719724
static const uint8_t PARTITION_MASK_KIND = 0x0f;
@@ -745,9 +750,9 @@ typedef struct JL_ALIGNED_ATTR(8) _jl_binding_partition_t {
745750
/* union {
746751
* // For ->kind == PARTITION_KIND_GLOBAL
747752
* jl_value_t *type_restriction;
748-
* // For ->kind == PARTITION_KIND_CONST(_IMPORT)
753+
* // For ->kind in (PARTITION_KIND_CONST(_IMPORT), PARTITION_KIND_IMPLICIT_CONST)
749754
* jl_value_t *constval;
750-
* // For ->kind in (PARTITION_KIND_IMPLICIT, PARTITION_KIND_EXPLICIT, PARTITION_KIND_IMPORT)
755+
* // For ->kind in (PARTITION_KIND_IMPLICIT_GLOBAL, PARTITION_KIND_EXPLICIT, PARTITION_KIND_IMPORT)
751756
* jl_binding_t *imported;
752757
* } restriction;
753758
*/
@@ -2085,7 +2090,7 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_type(jl_module_t *m, jl_sym_t *var);
20852090
// get binding for assignment
20862091
JL_DLLEXPORT void jl_check_binding_currently_writable(jl_binding_t *b, jl_module_t *m, jl_sym_t *s);
20872092
JL_DLLEXPORT jl_binding_t *jl_get_binding_wr(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var);
2088-
JL_DLLEXPORT jl_binding_t *jl_get_binding_for_method_def(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var, size_t new_world);
2093+
JL_DLLEXPORT jl_value_t *jl_get_existing_strong_gf(jl_binding_t *b JL_PROPAGATES_ROOT, size_t new_world);
20892094
JL_DLLEXPORT int jl_boundp(jl_module_t *m, jl_sym_t *var, int allow_import);
20902095
JL_DLLEXPORT int jl_defines_or_exports_p(jl_module_t *m, jl_sym_t *var);
20912096
JL_DLLEXPORT int jl_is_const(jl_module_t *m, jl_sym_t *var);

0 commit comments

Comments
 (0)