• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #38002

06 Feb 2025 06:14AM UTC coverage: 20.322% (-2.4%) from 22.722%
#38002

push

local

web-flow
bpart: Fully switch to partitioned semantics (#57253)

This is the final PR in the binding partitions series (modulo bugs and
tweaks), i.e. it closes #54654 and thus closes #40399, which was the
original design sketch.

This thus activates the full designed semantics for binding partitions,
in particular allowing safe replacement of const bindings. It in
particular allows struct redefinitions. This thus closes
timholy/Revise.jl#18 and also closes #38584.

The biggest semantic change here is probably that this gets rid of the
notion of "resolvedness" of a binding. Previously, a lot of the behavior
of our implementation depended on when bindings were "resolved", which
could happen at basically an arbitrary point (in the compiler, in REPL
completion, in a different thread), making a lot of the semantics around
bindings ill- or at least implementation-defined. There are several
related issues in the bugtracker, so this closes #14055 closes #44604
closes #46354 closes #30277

It is also the last step to close #24569.
It also supports bindings for undef->defined transitions and thus closes
#53958 closes #54733 - however, this is not activated yet for
performance reasons and may need some further optimization.

Since resolvedness no longer exists, we need to replace it with some
hopefully more well-defined semantics. I will describe the semantics
below, but before I do I will make two notes:

1. There are a number of cases where these semantics will behave
slightly differently than the old semantics absent some other task going
around resolving random bindings.
2. The new behavior (except for the replacement stuff) was generally
permissible under the old semantics if the bindings happened to be
resolved at the right time.

With all that said, there are essentially three "strengths" of bindings:

1. Implicit Bindings: Anything implicitly obtained from `using Mod`, "no
binding", plus slightly more exotic corner cases around conflicts

2. Weakly declared bindin... (continued)

11 of 111 new or added lines in 7 files covered. (9.91%)

1273 existing lines in 68 files now uncovered.

9908 of 48755 relevant lines covered (20.32%)

105126.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

31.18
/base/boot.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
# commented-out definitions are implemented in C
4

5
#abstract type Any <: Any end
6
#abstract type Type{T} end
7

8
#abstract type Vararg{T} end
9

10
#mutable struct Symbol
11
## opaque
12
#end
13

14
#mutable struct TypeName
15
#    name::Symbol
16
#end
17

18
#mutable struct DataType <: Type
19
#    name::TypeName
20
#    super::Type
21
#    parameters::Tuple
22
#    names::Tuple
23
#    types::Tuple
24
#    ctor
25
#    instance
26
#    size::Int32
27
#    abstract::Bool
28
#    mutable::Bool
29
#    pointerfree::Bool
30
#end
31

32
#struct Union <: Type
33
#    a
34
#    b
35
#end
36

37
#mutable struct TypeVar
38
#    name::Symbol
39
#    lb::Type
40
#    ub::Type
41
#end
42

43
#struct UnionAll
44
#    var::TypeVar
45
#    body
46
#end
47

48
#struct Nothing
49
#end
50
#const nothing = Nothing()
51

52
#abstract type AbstractArray{T,N} end
53
#abstract type DenseArray{T,N} <: AbstractArray{T,N} end
54

55
#primitive type AddrSpace{Backend::Module} 8 end
56
#const CPU = bitcast(AddrSpace{Core}, 0x00)
57

58
#struct GenericMemory{kind::Symbol, T, AS::AddrSpace}
59
#   length::Int
60
#   const data::Ptr{Cvoid} # make this GenericPtr{addrspace, Cvoid}
61
#   Union{ # hidden data
62
#       elements :: NTuple{length, T}
63
#       owner :: Any
64
#   }
65
#end
66

67
#struct GenericMemoryRef{kind::Symbol, T, AS::AddrSpace}
68
#    mem::GenericMemory{kind, T, AS}
69
#    data::Ptr{Cvoid} # make this GenericPtr{addrspace, Cvoid}
70
#end
71

72
#mutable struct Array{T,N} <: DenseArray{T,N}
73
#  ref::MemoryRef{T}
74
#  size::NTuple{N,Int}
75
#end
76

77
#mutable struct Module
78
## opaque
79
#end
80

81
#mutable struct SimpleVector
82
## opaque
83
#end
84

85
#mutable struct String
86
## opaque
87
#end
88

89
#mutable struct Method
90
#...
91
#end
92

93
#mutable struct MethodInstance
94
#...
95
#end
96

97
#mutable struct CodeInstance
98
#...
99
#end
100

101
#mutable struct CodeInfo
102
#...
103
#end
104

105
#mutable struct TypeMapLevel
106
#...
107
#end
108

109
#mutable struct TypeMapEntry
110
#...
111
#end
112

113
#abstract type Ref{T} end
114
#primitive type Ptr{T} <: Ref{T} {32|64} end
115

116
# types for the front end
117

118
#mutable struct Expr
119
#    head::Symbol
120
#    args::Array{Any,1}
121
#end
122

123
#struct LineNumberNode
124
#    line::Int
125
#    file::Union{Symbol,Nothing}
126
#end
127

128
#struct LegacyLineInfoNode end # only used internally during lowering
129

130
#struct DebugInfo
131
#    def::Any # (Union{Symbol, Method, MethodInstance})
132
#    linetable::Any # (Union{Nothing,DebugInfo})
133
#    edges::SimpleVector # Vector{DebugInfo}
134
#    codelocs::String # compressed Vector{UInt8}
135
#end
136

137
#struct GotoNode
138
#    label::Int
139
#end
140

141
#struct GotoIfNot
142
#    cond::Any
143
#    dest::Int
144
#end
145

146
#struct ReturnNode
147
#    val::Any
148
#end
149

150
#struct PiNode
151
#    val
152
#    typ
153
#end
154

155
#struct PhiNode
156
#    edges::Vector{Int32}
157
#    values::Vector{Any}
158
#end
159

160
#struct PhiCNode
161
#    values::Vector{Any}
162
#end
163

164
#struct UpsilonNode
165
#    val
166
#end
167

168
#struct QuoteNode
169
#    value
170
#end
171

172
#struct GlobalRef
173
#    mod::Module
174
#    name::Symbol
175
#end
176

177
#mutable struct Task
178
#    next::Any
179
#    queue::Any
180
#    storage::Any
181
#    donenotify::Any
182
#    result::Any
183
#    scope::Any
184
#    code::Any
185
#    @atomic _state::UInt8
186
#    sticky::UInt8
187
#    priority::UInt16
188
#    @atomic _isexception::UInt8
189
#    pad00::UInt8
190
#    pad01::UInt8
191
#    pad02::UInt8
192
#    rngState0::UInt64
193
#    rngState1::UInt64
194
#    rngState2::UInt64
195
#    rngState3::UInt64
196
#    rngState4::UInt64
197
#    const metrics_enabled::Bool
198
#    pad10::UInt8
199
#    pad11::UInt8
200
#    pad12::UInt8
201
#    @atomic first_enqueued_at::UInt64
202
#    @atomic last_started_running_at::UInt64
203
#    @atomic running_time_ns::UInt64
204
#    @atomic finished_at::UInt64
205
#end
206

207
export
208
    # key types
209
    Any, DataType, Vararg, NTuple,
210
    Tuple, Type, UnionAll, TypeVar, Union, Nothing, Cvoid,
211
    AbstractArray, DenseArray, NamedTuple, Pair,
212
    # special objects
213
    Function, Method, Module, Symbol, Task, UndefInitializer, undef, WeakRef, VecElement,
214
    Array, Memory, MemoryRef, AtomicMemory, AtomicMemoryRef, GenericMemory, GenericMemoryRef,
215
    # numeric types
216
    Number, Real, Integer, Bool, Ref, Ptr,
217
    AbstractFloat, Float16, Float32, Float64,
218
    Signed, Int, Int8, Int16, Int32, Int64, Int128,
219
    Unsigned, UInt, UInt8, UInt16, UInt32, UInt64, UInt128,
220
    # string types
221
    AbstractChar, Char, AbstractString, String, IO,
222
    # errors
223
    ErrorException, BoundsError, DivideError, DomainError, Exception,
224
    InterruptException, InexactError, OutOfMemoryError, ReadOnlyMemoryError,
225
    OverflowError, StackOverflowError, SegmentationFault, UndefRefError, UndefVarError,
226
    TypeError, ArgumentError, MethodError, AssertionError, LoadError, InitError,
227
    UndefKeywordError, ConcurrencyViolationError, FieldError,
228
    # AST representation
229
    Expr, QuoteNode, LineNumberNode, GlobalRef,
230
    # object model functions
231
    fieldtype, getfield, setfield!, swapfield!, modifyfield!, replacefield!, setfieldonce!,
232
    nfields, throw, tuple, ===, isdefined,
233
    # access to globals
234
    getglobal, setglobal!, swapglobal!, modifyglobal!, replaceglobal!, setglobalonce!, isdefinedglobal,
235
    # ifelse, sizeof    # not exported, to avoid conflicting with Base
236
    # type reflection
237
    <:, typeof, isa, typeassert,
238
    # method reflection
239
    applicable, invoke,
240
    # constants
241
    nothing, Main
242

243
const getproperty = getfield # TODO: use `getglobal` for modules instead
244
const setproperty! = setfield!
245

246
abstract type Number end
247
abstract type Real     <: Number end
248
abstract type AbstractFloat <: Real end
249
abstract type Integer  <: Real end
250
abstract type Signed   <: Integer end
251
abstract type Unsigned <: Integer end
252

253
primitive type Float16 <: AbstractFloat 16 end
254
primitive type Float32 <: AbstractFloat 32 end
255
primitive type Float64 <: AbstractFloat 64 end
256

257
primitive type BFloat16 <: AbstractFloat 16 end
258

259
#primitive type Bool <: Integer 8 end
260
abstract type AbstractChar end
261
primitive type Char <: AbstractChar 32 end
262

263
primitive type Int8    <: Signed   8 end
264
#primitive type UInt8   <: Unsigned 8 end
265
primitive type Int16   <: Signed   16 end
266
#primitive type UInt16  <: Unsigned 16 end
267
#primitive type Int32   <: Signed   32 end
268
#primitive type UInt32  <: Unsigned 32 end
269
#primitive type Int64   <: Signed   64 end
270
#primitive type UInt64  <: Unsigned 64 end
271
primitive type Int128  <: Signed   128 end
272
primitive type UInt128 <: Unsigned 128 end
273

274
if Int === Int64
275
    const UInt = UInt64
276
else
277
    const UInt = UInt32
278
end
279

280
function Typeof end
281
ccall(:jl_toplevel_eval_in, Any, (Any, Any),
282
      Core, quote
283
      (f::typeof(Typeof))(x) = ($(_expr(:meta,:nospecialize,:x)); isa(x,Type) ? Type{x} : typeof(x))
376✔
284
      end)
285

286
function iterate end
287

288
macro nospecialize(x)
289
    _expr(:meta, :nospecialize, x)
290
end
291
Expr(@nospecialize args...) = _expr(args...)
13,497✔
292

293
macro latestworld() Expr(:latestworld) end
294

295
_is_internal(__module__) = __module__ === Core
×
296
# can be used in place of `@assume_effects :total` (supposed to be used for bootstrapping)
297
macro _total_meta()
298
    return _is_internal(__module__) && Expr(:meta, Expr(:purity,
299
        #=:consistent=#true,
300
        #=:effect_free=#true,
301
        #=:nothrow=#true,
302
        #=:terminates_globally=#true,
303
        #=:terminates_locally=#false,
304
        #=:notaskstate=#true,
305
        #=:inaccessiblememonly=#true,
306
        #=:noub=#true,
307
        #=:noub_if_noinbounds=#false,
308
        #=:consistent_overlay=#false,
309
        #=:nortcall=#true))
310
end
311
# can be used in place of `@assume_effects :foldable` (supposed to be used for bootstrapping)
312
macro _foldable_meta()
313
    return _is_internal(__module__) && Expr(:meta, Expr(:purity,
314
        #=:consistent=#true,
315
        #=:effect_free=#true,
316
        #=:nothrow=#false,
317
        #=:terminates_globally=#true,
318
        #=:terminates_locally=#false,
319
        #=:notaskstate=#true,
320
        #=:inaccessiblememonly=#true,
321
        #=:noub=#true,
322
        #=:noub_if_noinbounds=#false,
323
        #=:consistent_overlay=#false,
324
        #=:nortcall=#true))
325
end
326

327
macro inline()   Expr(:meta, :inline)   end
328
macro noinline() Expr(:meta, :noinline) end
329

330
macro _boundscheck() Expr(:boundscheck) end
331

332
# n.b. the effects and model of these is refined in inference abstractinterpretation.jl
333
TypeVar(@nospecialize(n)) = _typevar(n::Symbol, Union{}, Any)
×
334
TypeVar(@nospecialize(n), @nospecialize(ub)) = _typevar(n::Symbol, Union{}, ub)
×
335
TypeVar(@nospecialize(n), @nospecialize(lb), @nospecialize(ub)) = _typevar(n::Symbol, lb, ub)
×
336
UnionAll(@nospecialize(v), @nospecialize(t)) = ccall(:jl_type_unionall, Any, (Any, Any), v::TypeVar, t)
×
337

338
const Memory{T} = GenericMemory{:not_atomic, T, CPU}
339
const MemoryRef{T} = GenericMemoryRef{:not_atomic, T, CPU}
340

341
# simple convert for use by constructors of types in Core
342
# note that there is no actual conversion defined here,
343
# so the methods and ccall's in Core aren't permitted to use convert
344
convert(::Type{Any}, @nospecialize(x)) = x
×
345
convert(::Type{T}, x::T) where {T} = x
×
346
cconvert(::Type{T}, x) where {T} = convert(T, x)
×
347
unsafe_convert(::Type{T}, x::T) where {T} = x
×
348

349
# will be inserted by the frontend for closures
350
_typeof_captured_variable(@nospecialize t) = (@_total_meta; t isa Type && has_free_typevars(t) ? typeof(t) : Typeof(t))
318✔
351

352
has_free_typevars(@nospecialize t) = (@_total_meta; ccall(:jl_has_free_typevars, Int32, (Any,), t) === Int32(1))
26,209✔
353

354
# dispatch token indicating a kwarg (keyword sorter) call
355
function kwcall end
356
# deprecated internal functions:
357
kwfunc(@nospecialize(f)) = kwcall
×
358
kwftype(@nospecialize(t)) = typeof(kwcall)
×
359

360
# Let the compiler assume that calling Union{} as a constructor does not need
361
# to be considered ever (which comes up often as Type{<:T} inference, and
362
# occasionally in user code from eltype).
363
Union{}(a...) = throw(ArgumentError("cannot construct a value of type Union{} for return result"))
×
364
kwcall(kwargs, ::Type{Union{}}, a...) = Union{}(a...)
×
365

366
abstract type Exception end
367
struct ErrorException <: Exception
UNCOV
368
    msg::AbstractString
×
369
end
370

371
struct BoundsError <: Exception
372
    a::Any
373
    i::Any
374
    BoundsError() = new()
×
375
    BoundsError(@nospecialize(a)) = (@noinline; new(a))
×
376
    BoundsError(@nospecialize(a), i) = (@noinline; new(a,i))
×
377
end
378
struct DivideError         <: Exception end
379
struct OutOfMemoryError    <: Exception end
380
struct ReadOnlyMemoryError <: Exception end
381
struct SegmentationFault   <: Exception end
382
struct StackOverflowError  <: Exception end
383
struct UndefRefError       <: Exception end
384
struct UndefVarError <: Exception
385
    var::Symbol
386
    world::UInt
387
    scope # a Module or Symbol or other object describing the context where this variable was looked for (e.g. Main or :local or :static_parameter)
388
    UndefVarError(var::Symbol) = new(var, ccall(:jl_get_tls_world_age, UInt, ()))
×
389
    UndefVarError(var::Symbol, @nospecialize scope) = new(var, ccall(:jl_get_tls_world_age, UInt, ()), scope)
×
390
end
391
struct ConcurrencyViolationError <: Exception
392
    msg::AbstractString
14✔
393
end
394
struct MissingCodeError <: Exception
395
    mi::MethodInstance
396
end
397
struct InterruptException <: Exception end
398
struct DomainError <: Exception
399
    val
400
    msg::AbstractString
401
    DomainError(@nospecialize(val)) = (@noinline; new(val, ""))
×
402
    DomainError(@nospecialize(val), @nospecialize(msg)) = (@noinline; new(val, msg))
1✔
403
end
404
struct TypeError <: Exception
405
    # `func` is the name of the builtin function that encountered a type error,
406
    # the name of the type that hit an error in its definition or application, or
407
    # some other brief description of where the error happened.
408
    # `context` optionally adds extra detail, e.g. the name of the type parameter
409
    # that got a bad value.
410
    func::Symbol
411
    context::Union{AbstractString,Symbol}
412
    expected::Type
413
    got
414
    TypeError(func, context, @nospecialize(expected::Type), @nospecialize(got)) =
×
415
        new(func, context, expected, got)
416
end
417
TypeError(where, @nospecialize(expected::Type), @nospecialize(got)) =
×
418
    TypeError(Symbol(where), "", expected, got)
419
struct InexactError <: Exception
420
    func::Symbol
421
    args
422
    InexactError(f::Symbol, @nospecialize(args...)) = (@noinline; new(f, args))
×
423
end
424
struct OverflowError <: Exception
425
    msg::AbstractString
×
426
end
427

428
struct ArgumentError <: Exception
429
    msg::AbstractString
5✔
430
end
431
struct UndefKeywordError <: Exception
432
    var::Symbol
433
end
434

435
const typemax_UInt = Intrinsics.sext_int(UInt, 0xFF)
436
const typemax_Int = Core.Intrinsics.udiv_int(Core.Intrinsics.sext_int(Int, 0xFF), 2)
437

438
struct MethodError <: Exception
439
    f
440
    args
441
    world::UInt
442
    MethodError(@nospecialize(f), @nospecialize(args), world::UInt) = new(f, args, world)
×
443
end
444
MethodError(@nospecialize(f), @nospecialize(args)) = MethodError(f, args, typemax_UInt)
×
445

446
struct AssertionError <: Exception
447
    msg::AbstractString
2✔
448
end
449
AssertionError() = AssertionError("")
×
450

451
struct FieldError <: Exception
452
    type::DataType
453
    field::Symbol
454
end
455

456
abstract type WrappedException <: Exception end
457

458
struct LoadError <: WrappedException
459
    file::AbstractString
×
460
    line::Int
461
    error
462
end
463

464
struct InitError <: WrappedException
465
    mod::Symbol
466
    error
467
end
468

469
struct ABIOverride
470
    abi::Type
471
    def::MethodInstance
472
    ABIOverride(@nospecialize(abi::Type), def::MethodInstance) = new(abi, def)
×
473
end
474

475
struct PrecompilableError <: Exception end
476

477
String(s::String) = s  # no constructor yet
×
478

479
const Cvoid = Nothing
480
Nothing() = nothing
×
481

482
# This should always be inlined
483
getptls() = ccall(:jl_get_ptls_states, Ptr{Cvoid}, ())
6✔
484

485
include(m::Module, fname::String) = (@noinline; ccall(:jl_load_, Any, (Any, Any), m, fname))
×
486
eval(m::Module, @nospecialize(e)) = (@noinline; ccall(:jl_toplevel_eval_in, Any, (Any, Any), m, e))
1✔
487

488
struct EvalInto <: Function
489
    m::Module
490
end
491
(this::EvalInto)(@nospecialize(e)) = eval(this.m, e)
1✔
492

493
mutable struct Box
494
    contents::Any
495
    Box(@nospecialize(x)) = new(x)
338✔
496
    Box() = new()
506,052✔
497
end
498

499
# constructors for built-in types
500

501
mutable struct WeakRef
502
    value
503
    WeakRef() = WeakRef(nothing)
×
504
    WeakRef(@nospecialize(v)) = ccall(:jl_gc_new_weakref_th, Ref{WeakRef},
6✔
505
                                      (Ptr{Cvoid}, Any), getptls(), v)
506
end
507

508
Tuple{}() = ()
×
509

510
struct VecElement{T}
511
    value::T
512
    VecElement{T}(value::T) where {T} = new(value) # disable converting constructor in Core
×
513
end
514
VecElement(arg::T) where {T} = VecElement{T}(arg)
×
515

516
eval(Core, quote
517
    GotoNode(label::Int) = $(Expr(:new, :GotoNode, :label))
59,271✔
518
    NewvarNode(slot::SlotNumber) = $(Expr(:new, :NewvarNode, :slot))
×
519
    QuoteNode(@nospecialize value) = $(Expr(:new, :QuoteNode, :value))
2,090✔
520
    SSAValue(id::Int) = $(Expr(:new, :SSAValue, :id))
1,187,557✔
521
    Argument(n::Int) = $(Expr(:new, :Argument, :n))
3,890✔
522
    ReturnNode(@nospecialize val) = $(Expr(:new, :ReturnNode, :val))
21,804✔
523
    ReturnNode() = $(Expr(:new, :ReturnNode)) # unassigned val indicates unreachable
×
524
    GotoIfNot(@nospecialize(cond), dest::Int) = $(Expr(:new, :GotoIfNot, :cond, :dest))
81,914✔
525
    EnterNode(dest::Int) = $(Expr(:new, :EnterNode, :dest))
377✔
526
    EnterNode(dest::Int, @nospecialize(scope)) = $(Expr(:new, :EnterNode, :dest, :scope))
×
527
    LineNumberNode(l::Int) = $(Expr(:new, :LineNumberNode, :l, nothing))
×
528
    function LineNumberNode(l::Int, @nospecialize(f))
529
        isa(f, String) && (f = Symbol(f))
×
530
        return $(Expr(:new, :LineNumberNode, :l, :f))
40✔
531
    end
532
    DebugInfo(def::Union{Method,MethodInstance,Symbol}, linetable::Union{Nothing,DebugInfo}, edges::SimpleVector, codelocs::String) =
1,876✔
533
        $(Expr(:new, :DebugInfo, :def, :linetable, :edges, :codelocs))
UNCOV
534
    DebugInfo(def::Union{Method,MethodInstance,Symbol}) =
×
535
        $(Expr(:new, :DebugInfo, :def, nothing, Core.svec(), ""))
536
    SlotNumber(n::Int) = $(Expr(:new, :SlotNumber, :n))
289✔
537
    PhiNode(edges::Array{Int32, 1}, values::Array{Any, 1}) = $(Expr(:new, :PhiNode, :edges, :values))
40,857✔
538
    PiNode(@nospecialize(val), @nospecialize(typ)) = $(Expr(:new, :PiNode, :val, :typ))
16,886✔
539
    PhiCNode(values::Array{Any, 1}) = $(Expr(:new, :PhiCNode, :values))
1,705✔
540
    UpsilonNode(@nospecialize(val)) = $(Expr(:new, :UpsilonNode, :val))
2,002✔
541
    UpsilonNode() = $(Expr(:new, :UpsilonNode))
×
542
    Const(@nospecialize(v)) = $(Expr(:new, :Const, :v))
407,613✔
543
    _PartialStruct(@nospecialize(typ), fields::Array{Any, 1}) = $(Expr(:new, :PartialStruct, :typ, :fields))
888✔
544
    PartialOpaque(@nospecialize(typ), @nospecialize(env), parent::MethodInstance, source) = $(Expr(:new, :PartialOpaque, :typ, :env, :parent, :source))
×
545
    InterConditional(slot::Int, @nospecialize(thentype), @nospecialize(elsetype)) = $(Expr(:new, :InterConditional, :slot, :thentype, :elsetype))
4,363✔
546
    MethodMatch(@nospecialize(spec_types), sparams::SimpleVector, method::Method, fully_covers::Bool) = $(Expr(:new, :MethodMatch, :spec_types, :sparams, :method, :fully_covers))
1✔
547
end)
548

549
const NullDebugInfo = DebugInfo(:none)
550

551
struct LineInfoNode # legacy support for aiding Serializer.deserialize of old IR
552
    mod::Module
553
    method
554
    file::Symbol
555
    line::Int32
556
    inlined_at::Int32
557
    LineInfoNode(mod::Module, @nospecialize(method), file::Symbol, line::Int32, inlined_at::Int32) = new(mod, method, file, line, inlined_at)
×
558
end
559

560

561
function CodeInstance(
562
    mi::Union{MethodInstance, ABIOverride}, owner, @nospecialize(rettype), @nospecialize(exctype), @nospecialize(inferred_const),
563
    @nospecialize(inferred), const_flags::Int32, min_world::UInt, max_world::UInt,
564
    effects::UInt32, @nospecialize(analysis_results),
565
    di::Union{DebugInfo,Nothing}, edges::SimpleVector)
566
    return ccall(:jl_new_codeinst, Ref{CodeInstance},
194✔
567
        (Any, Any, Any, Any, Any, Any, Int32, UInt, UInt, UInt32, Any, Any, Any),
568
        mi, owner, rettype, exctype, inferred_const, inferred, const_flags, min_world, max_world,
569
        effects, analysis_results, di, edges)
570
end
571
GlobalRef(m::Module, s::Symbol) = ccall(:jl_module_globalref, Ref{GlobalRef}, (Any, Any), m, s)
709✔
572
Module(name::Symbol=:anonymous, std_imports::Bool=true, default_names::Bool=true) = ccall(:jl_f_new_module, Ref{Module}, (Any, Bool, Bool), name, std_imports, default_names)
×
573

574
function _Task(@nospecialize(f), reserved_stack::Int, completion_future)
575
    return ccall(:jl_new_task, Ref{Task}, (Any, Any, Int), f, completion_future, reserved_stack)
8,770✔
576
end
577

578
const NTuple{N,T} = Tuple{Vararg{T,N}}
579

580
## primitive Array constructors
581
struct UndefInitializer end
582
const undef = UndefInitializer()
583

584
# type and dimensionality specified
585
(self::Type{GenericMemory{kind,T,addrspace}})(::UndefInitializer, m::Int) where {T,addrspace,kind} = memorynew(self, m)
3,212,651✔
586
(self::Type{GenericMemory{kind,T,addrspace}})(::UndefInitializer, d::NTuple{1,Int}) where {T,kind,addrspace} = self(undef, getfield(d,1))
×
587
# empty vector constructor
588
(self::Type{GenericMemory{kind,T,addrspace}})() where {T,kind,addrspace} = self(undef, 0)
304,776✔
589

590
memoryref(mem::GenericMemory) = memoryrefnew(mem)
5,292,336✔
591
memoryref(mem::GenericMemory, i::Integer) = memoryrefnew(memoryrefnew(mem), Int(i), @_boundscheck)
330,340✔
592
memoryref(ref::GenericMemoryRef, i::Integer) = memoryrefnew(ref, Int(i), @_boundscheck)
1,781,741✔
593
GenericMemoryRef(mem::GenericMemory) = memoryref(mem)
×
594
GenericMemoryRef(mem::GenericMemory, i::Integer) = memoryref(mem, i)
×
595
GenericMemoryRef(mem::GenericMemoryRef, i::Integer) = memoryref(mem, i)
×
596

597
const AtomicMemory{T} = GenericMemory{:atomic, T, CPU}
598
const AtomicMemoryRef{T} = GenericMemoryRef{:atomic, T, CPU}
599

600
# construction helpers for Array
601
new_as_memoryref(self::Type{GenericMemoryRef{kind,T,addrspace}}, m::Int) where {T,kind,addrspace} = memoryref(fieldtype(self, :mem)(undef, m))
×
602

603
# checked-multiply intrinsic function for dimensions
604
_checked_mul_dims() = 1, false
×
605
_checked_mul_dims(m::Int) = m, Intrinsics.ule_int(typemax_Int, m) # equivalently: (m + 1) < 1
×
606
function _checked_mul_dims(m::Int, n::Int)
×
607
    b = Intrinsics.checked_smul_int(m, n)
×
608
    a = getfield(b, 1)
×
609
    ovflw = getfield(b, 2)
×
610
    ovflw = Intrinsics.or_int(ovflw, Intrinsics.ule_int(typemax_Int, m))
×
611
    ovflw = Intrinsics.or_int(ovflw, Intrinsics.ule_int(typemax_Int, n))
×
612
    return a, ovflw
×
613
end
614
function _checked_mul_dims(m::Int, d::Int...)
×
615
    @_foldable_meta # the compiler needs to know this loop terminates
×
616
    a = m
×
617
    i = 1
×
618
    ovflw = false
×
619
    neg = Intrinsics.ule_int(typemax_Int, m)
×
620
    zero = false # if m==0 we won't have overflow since we go left to right
×
621
    while Intrinsics.sle_int(i, nfields(d))
×
622
        di = getfield(d, i)
×
623
        b = Intrinsics.checked_smul_int(a, di)
×
624
        zero = Intrinsics.or_int(zero, di === 0)
×
625
        ovflw = Intrinsics.or_int(ovflw, getfield(b, 2))
×
626
        neg = Intrinsics.or_int(neg, Intrinsics.ule_int(typemax_Int, di))
×
627
        a = getfield(b, 1)
×
628
        i = Intrinsics.add_int(i, 1)
×
629
   end
×
630
   return a, Intrinsics.or_int(neg, Intrinsics.and_int(ovflw, Intrinsics.not_int(zero)))
×
631
end
632

633
# convert a set of dims to a length, with overflow checking
634
checked_dims() = 1
×
635
checked_dims(m::Int) = m # defer this check to Memory constructor instead
×
636
function checked_dims(d::Int...)
×
637
    b = _checked_mul_dims(d...)
×
638
    getfield(b, 2) && throw(ArgumentError("invalid Array dimensions"))
×
639
    return getfield(b, 1)
×
640
end
641

642
# type and dimensionality specified, accepting dims as series of Ints
643
eval(Core, :(function (self::Type{Array{T,1}})(::UndefInitializer, m::Int) where {T}
4✔
644
    mem = fieldtype(fieldtype(self, :ref), :mem)(undef, m)
1,917,409✔
645
    return $(Expr(:new, :self, :(memoryref(mem)), :((m,))))
1,917,410✔
646
end))
647
eval(Core, :(function (self::Type{Array{T,2}})(::UndefInitializer, m::Int, n::Int) where {T}
×
648
    return $(Expr(:new, :self, :(new_as_memoryref(fieldtype(self, :ref), checked_dims(m, n))), :((m, n))))
×
649
end))
650
eval(Core, :(function (self::Type{Array{T,3}})(::UndefInitializer, m::Int, n::Int, o::Int) where {T}
×
651
    return $(Expr(:new, :self, :(new_as_memoryref(fieldtype(self, :ref), checked_dims(m, n, o))), :((m, n, o))))
×
652
end))
653
eval(Core, :(function (self::Type{Array{T, N}})(::UndefInitializer, d::Vararg{Int, N}) where {T, N}
×
654
    return $(Expr(:new, :self, :(new_as_memoryref(fieldtype(self, :ref), checked_dims(d...))), :d))
×
655
end))
656
# type and dimensionality specified, accepting dims as tuples of Ints
657
(self::Type{Array{T,1}})(::UndefInitializer, d::NTuple{1, Int}) where {T} = self(undef, getfield(d, 1))
864,121✔
658
(self::Type{Array{T,2}})(::UndefInitializer, d::NTuple{2, Int}) where {T} = self(undef, getfield(d, 1), getfield(d, 2))
×
659
(self::Type{Array{T,3}})(::UndefInitializer, d::NTuple{3, Int}) where {T} = self(undef, getfield(d, 1), getfield(d, 2), getfield(d, 3))
×
660
(self::Type{Array{T,N}})(::UndefInitializer, d::NTuple{N, Int}) where {T, N} = self(undef, d...)
×
661
# type but not dimensionality specified
662
Array{T}(::UndefInitializer, m::Int) where {T} = Array{T, 1}(undef, m)
172✔
663
Array{T}(::UndefInitializer, m::Int, n::Int) where {T} = Array{T, 2}(undef, m, n)
×
664
Array{T}(::UndefInitializer, m::Int, n::Int, o::Int) where {T} = Array{T, 3}(undef, m, n, o)
×
665
Array{T}(::UndefInitializer, d::NTuple{N, Int}) where {T, N} = Array{T, N}(undef, d)
2✔
666
# empty vector constructor
667
(self::Type{Array{T, 1}})() where {T} = self(undef, 0)
152,392✔
668

669
(Array{T, N} where T)(x::AbstractArray{S, N}) where {S, N} = Array{S, N}(x)
×
670

671
Array(A::AbstractArray{T, N})    where {T, N}   = Array{T, N}(A)
16,516✔
672
Array{T}(A::AbstractArray{S, N}) where {T, N, S} = Array{T, N}(A)
×
673

674
AbstractArray{T}(A::AbstractArray{S, N}) where {T, S, N} = AbstractArray{T, N}(A)
×
675

676
# primitive Symbol constructors
677

678
## Helper for proper GC rooting without unsafe_convert
679
eval(Core, quote
680
    _Symbol(ptr::Ptr{UInt8}, sz::Int, root::Any) = $(Expr(:foreigncall, QuoteNode(:jl_symbol_n),
104✔
681
        Ref{Symbol}, svec(Ptr{UInt8}, Int), 0, QuoteNode(:ccall), :ptr, :sz, :root))
682
end)
683

684
function Symbol(s::String)
104✔
685
    @_foldable_meta
×
686
    @noinline
×
687
    return _Symbol(ccall(:jl_string_ptr, Ptr{UInt8}, (Any,), s), sizeof(s), s)
104✔
688
end
689
function Symbol(a::Array{UInt8, 1})
×
690
    @noinline
×
691
    return _Symbol(bitcast(Ptr{UInt8}, a.ref.ptr_or_offset), getfield(a.size, 1), a.ref.mem)
×
692
end
693
Symbol(s::Symbol) = s
×
694

695
# module providing the IR object model
696
module IR
697

698
export CodeInfo, MethodInstance, CodeInstance, GotoNode, GotoIfNot, ReturnNode,
699
    NewvarNode, SSAValue, SlotNumber, Argument,
700
    PiNode, PhiNode, PhiCNode, UpsilonNode, DebugInfo,
701
    Const, PartialStruct, InterConditional, EnterNode, memoryref
702

703
using Core: CodeInfo, MethodInstance, CodeInstance, GotoNode, GotoIfNot, ReturnNode,
704
    NewvarNode, SSAValue, SlotNumber, Argument,
705
    PiNode, PhiNode, PhiCNode, UpsilonNode, DebugInfo,
706
    Const, PartialStruct, InterConditional, EnterNode, memoryref
707

708
end # module IR
709

710
# docsystem basics
711
macro doc(x...)
712
    docex = atdoc(__source__, __module__, x...)
713
    isa(docex, Expr) && docex.head === :escape && return docex
714
    return Expr(:escape, Expr(:var"hygienic-scope", docex, typeof(atdoc).name.module, __source__))
715
end
716
macro __doc__(x)
717
    return Expr(:escape, Expr(:block, Expr(:meta, :doc), x))
718
end
719

720
isbasicdoc(@nospecialize x) = (isa(x, Expr) && x.head === :.) || isa(x, Union{QuoteNode, Symbol})
×
721
firstarg(arg1, args...) = arg1
×
722
iscallexpr(ex::Expr) = (isa(ex, Expr) && ex.head === :where) ? iscallexpr(firstarg(ex.args...)) : (isa(ex, Expr) && ex.head === :call)
×
723
iscallexpr(ex) = false
×
724
function ignoredoc(source, mod, str, expr)
×
725
    (isbasicdoc(expr) || iscallexpr(expr)) && return Expr(:escape, nothing)
×
726
    Expr(:escape, expr)
×
727
end
728

729
global atdoc = ignoredoc
730
atdoc!(λ)    = global atdoc = λ
×
731

732
# macros for big integer syntax
733
macro int128_str end
734
macro uint128_str end
735
macro big_str end
736

737
# macro for command syntax
738
macro cmd end
739

740

741
# simple stand-alone print definitions for debugging
742
abstract type IO end
743
struct CoreSTDOUT <: IO end
744
struct CoreSTDERR <: IO end
745
const stdout = CoreSTDOUT()
746
const stderr = CoreSTDERR()
747
io_pointer(::CoreSTDOUT) = Intrinsics.pointerref(Intrinsics.cglobal(:jl_uv_stdout, Ptr{Cvoid}), 1, 1)
×
748
io_pointer(::CoreSTDERR) = Intrinsics.pointerref(Intrinsics.cglobal(:jl_uv_stderr, Ptr{Cvoid}), 1, 1)
×
749

750
unsafe_write(io::IO, x::Ptr{UInt8}, nb::UInt) =
×
751
    (ccall(:jl_uv_puts, Cvoid, (Ptr{Cvoid}, Ptr{UInt8}, UInt), io_pointer(io), x, nb); nb)
×
752
unsafe_write(io::IO, x::Ptr{UInt8}, nb::Int) =
×
753
    (ccall(:jl_uv_puts, Cvoid, (Ptr{Cvoid}, Ptr{UInt8}, Int), io_pointer(io), x, nb); nb)
×
754
write(io::IO, x::UInt8) =
×
755
    (ccall(:jl_uv_putb, Cvoid, (Ptr{Cvoid}, UInt8), io_pointer(io), x); 1)
756
function write(io::IO, x::String)
757
    nb = sizeof(x)
×
758
    unsafe_write(io, ccall(:jl_string_ptr, Ptr{UInt8}, (Any,), x), nb)
×
759
    return nb
×
760
end
761

762
show(io::IO, @nospecialize x) = ccall(:jl_static_show, Cvoid, (Ptr{Cvoid}, Any), io_pointer(io), x)
×
763
print(io::IO, x::AbstractChar) = ccall(:jl_uv_putc, Cvoid, (Ptr{Cvoid}, Char), io_pointer(io), x)
×
764
print(io::IO, x::String) = (write(io, x); nothing)
×
765
print(io::IO, @nospecialize x) = show(io, x)
×
766
print(io::IO, @nospecialize(x), @nospecialize a...) = (print(io, x); print(io, a...))
×
767
println(io::IO) = (write(io, 0x0a); nothing) # 0x0a = '\n'
×
768
println(io::IO, @nospecialize x...) = (print(io, x...); println(io))
×
769

770
show(@nospecialize a) = show(stdout, a)
×
771
print(@nospecialize a...) = print(stdout, a...)
×
772
println(@nospecialize a...) = println(stdout, a...)
×
773

774
struct GeneratedFunctionStub
775
    gen
776
    argnames::SimpleVector
777
    spnames::SimpleVector
778
end
779

780
# If the generator is a subtype of this trait, inference caches the generated unoptimized
781
# code, sacrificing memory space to improve the performance of subsequent inferences.
782
# This tradeoff is not appropriate in general cases (e.g., for `GeneratedFunctionStub`s
783
# generated from the front end), but it can be justified for generators involving complex
784
# code transformations, such as a Cassette-like system.
785
abstract type CachedGenerator end
786

787
NamedTuple() = NamedTuple{(),Tuple{}}(())
×
788

789
eval(Core, :(NamedTuple{names}(args::Tuple) where {names} =
510,528✔
790
             $(Expr(:splatnew, :(NamedTuple{names,typeof(args)}), :args))))
791

792
using .Intrinsics: sle_int, add_int
793

794
eval(Core, :((NT::Type{NamedTuple{names,T}})(args::T) where {names, T <: Tuple} =
×
795
             $(Expr(:splatnew, :NT, :args))))
796

797
# constructors for built-in types
798

799
import .Intrinsics: eq_int, trunc_int, lshr_int, sub_int, shl_int, bitcast, sext_int, zext_int, and_int
800

801
function is_top_bit_set(x)
802
    @inline
×
803
    eq_int(trunc_int(UInt8, lshr_int(x, sub_int(shl_int(sizeof(x), 3), 1))), trunc_int(UInt8, 1))
23,194,119✔
804
end
805

806
function is_top_bit_set(x::Union{Int8,UInt8})
807
    @inline
×
808
    eq_int(lshr_int(x, 7), trunc_int(typeof(x), 1))
×
809
end
810

811
# n.b. This function exists for CUDA to overload to configure error behavior (see #48097)
812
throw_inexacterror(func::Symbol, to, val) = throw(InexactError(func, to, val))
×
813

814
function check_sign_bit(::Type{To}, x) where {To}
815
    @inline
×
816
    # the top bit is the sign bit of x but "sign bit" sounds better in stacktraces
817
    # n.b. if x is signed, then sizeof(x) === sizeof(To), otherwise sizeof(x) >= sizeof(To)
818
    is_top_bit_set(x) && throw_inexacterror(sizeof(x) === sizeof(To) ? :convert : :trunc, To, x)
23,559,381✔
819
    x
×
820
end
821

822
function checked_trunc_sint(::Type{To}, x::From) where {To,From}
4✔
823
    @inline
4✔
824
    y = trunc_int(To, x)
265,823✔
825
    back = sext_int(From, y)
265,823✔
826
    eq_int(x, back) || throw_inexacterror(:trunc, To, x)
265,823✔
827
    y
4✔
828
end
829

830
function checked_trunc_uint(::Type{To}, x::From) where {To,From}
831
    @inline
×
832
    y = trunc_int(To, x)
441,247✔
833
    back = zext_int(From, y)
441,247✔
834
    eq_int(x, back) || throw_inexacterror(:trunc, To, x)
441,247✔
835
    y
×
836
end
837

838
toInt8(x::Int8)       = x
×
839
toInt8(x::Int16)      = checked_trunc_sint(Int8, x)
×
840
toInt8(x::Int32)      = checked_trunc_sint(Int8, x)
×
841
toInt8(x::Int64)      = checked_trunc_sint(Int8, x)
×
842
toInt8(x::Int128)     = checked_trunc_sint(Int8, x)
×
843
toInt8(x::UInt8)      = bitcast(Int8, check_sign_bit(Int8, x))
×
844
toInt8(x::UInt16)     = checked_trunc_sint(Int8, check_sign_bit(Int8, x))
×
845
toInt8(x::UInt32)     = checked_trunc_sint(Int8, check_sign_bit(Int8, x))
×
846
toInt8(x::UInt64)     = checked_trunc_sint(Int8, check_sign_bit(Int8, x))
×
847
toInt8(x::UInt128)    = checked_trunc_sint(Int8, check_sign_bit(Int8, x))
×
848
toInt8(x::Bool)       = and_int(bitcast(Int8, x), Int8(1))
×
849
toInt16(x::Int8)      = sext_int(Int16, x)
×
850
toInt16(x::Int16)     = x
×
851
toInt16(x::Int32)     = checked_trunc_sint(Int16, x)
×
852
toInt16(x::Int64)     = checked_trunc_sint(Int16, x)
6,071✔
853
toInt16(x::Int128)    = checked_trunc_sint(Int16, x)
×
854
toInt16(x::UInt8)     = zext_int(Int16, x)
×
855
toInt16(x::UInt16)    = bitcast(Int16, check_sign_bit(Int16, x))
×
856
toInt16(x::UInt32)    = checked_trunc_sint(Int16, check_sign_bit(Int16, x))
×
857
toInt16(x::UInt64)    = checked_trunc_sint(Int16, check_sign_bit(Int16, x))
×
858
toInt16(x::UInt128)   = checked_trunc_sint(Int16, check_sign_bit(Int16, x))
×
859
toInt16(x::Bool)      = and_int(zext_int(Int16, x), Int16(1))
×
UNCOV
860
toInt32(x::Int8)      = sext_int(Int32, x)
×
861
toInt32(x::Int16)     = sext_int(Int32, x)
×
862
toInt32(x::Int32)     = x
×
863
toInt32(x::Int64)     = checked_trunc_sint(Int32, x)
257,595✔
864
toInt32(x::Int128)    = checked_trunc_sint(Int32, x)
×
865
toInt32(x::UInt8)     = zext_int(Int32, x)
12,303✔
866
toInt32(x::UInt16)    = zext_int(Int32, x)
×
867
toInt32(x::UInt32)    = bitcast(Int32, check_sign_bit(Int32, x))
×
UNCOV
868
toInt32(x::UInt64)    = checked_trunc_sint(Int32, check_sign_bit(Int32, x))
×
869
toInt32(x::UInt128)   = checked_trunc_sint(Int32, check_sign_bit(Int32, x))
×
870
toInt32(x::Bool)      = and_int(zext_int(Int32, x), Int32(1))
722✔
871
toInt64(x::Int8)      = sext_int(Int64, x)
21,324✔
872
toInt64(x::Int16)     = sext_int(Int64, x)
1,182✔
873
toInt64(x::Int32)     = sext_int(Int64, x)
612,410✔
874
toInt64(x::Int64)     = x
9,692✔
875
toInt64(x::Int128)    = checked_trunc_sint(Int64, x)
×
876
toInt64(x::UInt8)     = zext_int(Int64, x)
5,351,757✔
877
toInt64(x::UInt16)    = zext_int(Int64, x)
4,140✔
878
toInt64(x::UInt32)    = zext_int(Int64, x)
102,585✔
879
toInt64(x::UInt64)    = bitcast(Int64, check_sign_bit(Int64, x))
21,661,184✔
880
toInt64(x::UInt128)   = checked_trunc_sint(Int64, check_sign_bit(Int64, x))
×
881
toInt64(x::Bool)      = and_int(zext_int(Int64, x), Int64(1))
607,559✔
882
toInt128(x::Int8)     = sext_int(Int128, x)
×
883
toInt128(x::Int16)    = sext_int(Int128, x)
×
884
toInt128(x::Int32)    = sext_int(Int128, x)
×
885
toInt128(x::Int64)    = sext_int(Int128, x)
×
886
toInt128(x::Int128)   = x
×
887
toInt128(x::UInt8)    = zext_int(Int128, x)
×
888
toInt128(x::UInt16)   = zext_int(Int128, x)
×
889
toInt128(x::UInt32)   = zext_int(Int128, x)
×
890
toInt128(x::UInt64)   = zext_int(Int128, x)
×
891
toInt128(x::UInt128)  = bitcast(Int128, check_sign_bit(Int128, x))
×
892
toInt128(x::Bool)     = and_int(zext_int(Int128, x), Int128(1))
×
893
toUInt8(x::Int8)      = bitcast(UInt8, check_sign_bit(UInt8, x))
×
894
toUInt8(x::Int16)     = checked_trunc_uint(UInt8, x)
×
895
toUInt8(x::Int32)     = checked_trunc_uint(UInt8, x)
120✔
896
toUInt8(x::Int64)     = checked_trunc_uint(UInt8, x)
72✔
897
toUInt8(x::Int128)    = checked_trunc_uint(UInt8, x)
×
898
toUInt8(x::UInt8)     = x
×
899
toUInt8(x::UInt16)    = checked_trunc_uint(UInt8, x)
×
900
toUInt8(x::UInt32)    = checked_trunc_uint(UInt8, x)
81,965✔
901
toUInt8(x::UInt64)    = checked_trunc_uint(UInt8, x)
×
902
toUInt8(x::UInt128)   = checked_trunc_uint(UInt8, x)
×
903
toUInt8(x::Bool)      = and_int(bitcast(UInt8, x), UInt8(1))
23,949✔
904
toUInt16(x::Int8)     = sext_int(UInt16, check_sign_bit(UInt16, x))
×
905
toUInt16(x::Int16)    = bitcast(UInt16, check_sign_bit(UInt16, x))
×
906
toUInt16(x::Int32)    = checked_trunc_uint(UInt16, x)
×
907
toUInt16(x::Int64)    = checked_trunc_uint(UInt16, x)
167,854✔
908
toUInt16(x::Int128)   = checked_trunc_uint(UInt16, x)
×
909
toUInt16(x::UInt8)    = zext_int(UInt16, x)
×
910
toUInt16(x::UInt16)   = x
×
911
toUInt16(x::UInt32)   = checked_trunc_uint(UInt16, x)
16✔
912
toUInt16(x::UInt64)   = checked_trunc_uint(UInt16, x)
×
913
toUInt16(x::UInt128)  = checked_trunc_uint(UInt16, x)
×
914
toUInt16(x::Bool)     = and_int(zext_int(UInt16, x), UInt16(1))
×
915
toUInt32(x::Int8)     = sext_int(UInt32, check_sign_bit(UInt32, x))
×
916
toUInt32(x::Int16)    = sext_int(UInt32, check_sign_bit(UInt32, x))
×
917
toUInt32(x::Int32)    = bitcast(UInt32, check_sign_bit(UInt32, x))
8,034✔
918
toUInt32(x::Int64)    = checked_trunc_uint(UInt32, x)
7,739✔
919
toUInt32(x::Int128)   = checked_trunc_uint(UInt32, x)
×
920
toUInt32(x::UInt8)    = zext_int(UInt32, x)
1,593,898✔
921
toUInt32(x::UInt16)   = zext_int(UInt32, x)
16✔
922
toUInt32(x::UInt32)   = x
×
923
toUInt32(x::UInt64)   = checked_trunc_uint(UInt32, x)
14✔
924
toUInt32(x::UInt128)  = checked_trunc_uint(UInt32, x)
×
925
toUInt32(x::Bool)     = and_int(zext_int(UInt32, x), UInt32(1))
2,528✔
926
toUInt64(x::Int8)     = sext_int(UInt64, check_sign_bit(UInt64, x))
×
927
toUInt64(x::Int16)    = sext_int(UInt64, check_sign_bit(UInt64, x))
×
UNCOV
928
toUInt64(x::Int32)    = sext_int(UInt64, check_sign_bit(UInt64, x))
×
929
toUInt64(x::Int64)    = bitcast(UInt64, check_sign_bit(UInt64, x))
1,889,831✔
930
toUInt64(x::Int128)   = checked_trunc_uint(UInt64, x)
×
931
toUInt64(x::UInt8)    = zext_int(UInt64, x)
69,715,698✔
932
toUInt64(x::UInt16)   = zext_int(UInt64, x)
6,101✔
933
toUInt64(x::UInt32)   = zext_int(UInt64, x)
143,728✔
934
toUInt64(x::UInt64)   = x
×
935
toUInt64(x::UInt128)  = checked_trunc_uint(UInt64, x)
183,388✔
936
toUInt64(x::Bool)     = and_int(zext_int(UInt64, x), UInt64(1))
131✔
937
toUInt128(x::Int8)    = sext_int(UInt128, check_sign_bit(UInt128, x))
×
938
toUInt128(x::Int16)   = sext_int(UInt128, check_sign_bit(UInt128, x))
×
939
toUInt128(x::Int32)   = sext_int(UInt128, check_sign_bit(UInt128, x))
×
UNCOV
940
toUInt128(x::Int64)   = sext_int(UInt128, check_sign_bit(UInt128, x))
×
941
toUInt128(x::Int128)  = bitcast(UInt128, check_sign_bit(UInt128, x))
×
942
toUInt128(x::UInt8)   = zext_int(UInt128, x)
1✔
943
toUInt128(x::UInt16)  = zext_int(UInt128, x)
×
944
toUInt128(x::UInt32)  = zext_int(UInt128, x)
128✔
945
toUInt128(x::UInt64)  = zext_int(UInt128, x)
90✔
946
toUInt128(x::UInt128) = x
×
947
toUInt128(x::Bool)    = and_int(zext_int(UInt128, x), UInt128(1))
×
948

949
# TODO: this is here to work around the 4 method limit in inference (#23210).
950
const BuiltinInts = Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8, Bool}
951
Int8(x::BuiltinInts)    = toInt8(x)::Int8
×
952
Int16(x::BuiltinInts)   = toInt16(x)::Int16
6,071✔
953
Int32(x::BuiltinInts)   = toInt32(x)::Int32
270,620✔
954
Int64(x::BuiltinInts)   = toInt64(x)::Int64
28,371,845✔
955
Int128(x::BuiltinInts)  = toInt128(x)::Int128
×
956
UInt8(x::BuiltinInts)   = toUInt8(x)::UInt8
106,320✔
957
UInt16(x::BuiltinInts)  = toUInt16(x)::UInt16
167,870✔
958
UInt32(x::BuiltinInts)  = toUInt32(x)::UInt32
1,612,231✔
959
UInt64(x::BuiltinInts)  = toUInt64(x)::UInt64
71,938,877✔
960
UInt128(x::BuiltinInts) = toUInt128(x)::UInt128
219✔
961

962
(::Type{T})(x::T) where {T<:Number} = x
×
963

964
Int(x::Ptr)  = bitcast(Int, x)
×
965
UInt(x::Ptr) = bitcast(UInt, x)
1,639,962✔
966
if Int === Int32
967
Int64(x::Ptr) = Int64(UInt32(x))
×
968
UInt64(x::Ptr) = UInt64(UInt32(x))
×
969
end
970
(PT::Type{Ptr{T}} where T)(x::Union{Int,UInt,Ptr}=0) = bitcast(PT, x)
577,684✔
971
(AS::Type{AddrSpace{Backend}} where Backend)(x::UInt8) = bitcast(AS, x)
×
972

973
Signed(x::UInt8)    = Int8(x)
×
974
Unsigned(x::Int8)   = UInt8(x)
×
975
Signed(x::UInt16)   = Int16(x)
×
976
Unsigned(x::Int16)  = UInt16(x)
×
977
Signed(x::UInt32)   = Int32(x)
×
978
Unsigned(x::Int32)  = UInt32(x)
×
979
Signed(x::UInt64)   = Int64(x)
×
980
Unsigned(x::Int64)  = UInt64(x)
×
981
Signed(x::UInt128)  = Int128(x)
×
982
Unsigned(x::Int128) = UInt128(x)
×
983

984
Signed(x::Union{Float16, Float32, Float64, Bool})   = Int(x)
×
985
Unsigned(x::Union{Float16, Float32, Float64, Bool}) = UInt(x)
×
986

987
Integer(x::Integer) = x
×
988
Integer(x::Union{Float16, Float32, Float64}) = Int(x)
×
989

990
# During definition of struct type `B`, if an `A.B` expression refers to
991
# the eventual global name of the struct, then return the partially-initialized
992
# type object.
993
# TODO: remove. This is a shim for backwards compatibility.
994
function struct_name_shim(@nospecialize(x), name::Symbol, mod::Module, @nospecialize(t))
×
995
    return x === mod ? t : getfield(x, name)
×
996
end
997

998
# Binding for the julia parser, called as
999
#
1000
#    Core._parse(text, filename, lineno, offset, options)
1001
#
1002
# Parse Julia code from the buffer `text`, starting at `offset` and attributing
1003
# it to `filename`. `text` may be a `String` or `svec(ptr::Ptr{UInt8},
1004
# len::Int)` for a raw unmanaged buffer. `options` should be one of `:atom`,
1005
# `:statement` or `:all`, indicating how much the parser will consume.
1006
#
1007
# `_parse` must return an `svec` containing an `Expr` and the new offset as an
1008
# `Int`.
1009
#
1010
# The internal jl_parse will call into Core._parse if not `nothing`.
1011
_parse = nothing
1012

1013
_setparser!(parser) = setglobal!(Core, :_parse, parser)
1✔
1014

1015
# support for deprecated uses of internal _apply function
1016
_apply(x...) = Core._apply_iterate(Main.Base.iterate, x...)
×
1017

1018
struct Pair{A, B}
1019
    first::A
1020
    second::B
1021
    # if we didn't inline this, it's probably because the callsite was actually dynamic
1022
    # to avoid potentially compiling many copies of this, we mark the arguments with `@nospecialize`
1023
    # but also mark the whole function with `@inline` to ensure we will inline it whenever possible
1024
    # (even if `convert(::Type{A}, a::A)` for some reason was expensive)
1025
    Pair(a, b) = new{typeof(a), typeof(b)}(a, b)
4,712✔
1026
    function Pair{A, B}(@nospecialize(a), @nospecialize(b)) where {A, B}
1027
        @inline
×
1028
        return new(a::A, b::B)
476,176✔
1029
    end
1030
end
1031

1032
function _hasmethod(@nospecialize(tt)) # this function has a special tfunc
2✔
1033
    world = ccall(:jl_get_tls_world_age, UInt, ()) # tls_world_age()
2✔
1034
    return Intrinsics.not_int(ccall(:jl_gf_invoke_lookup, Any, (Any, Any, UInt), tt, nothing, world) === nothing)
2✔
1035
end
1036

1037
# for backward compat
1038
arrayref(inbounds::Bool, A::Array, i::Int...) = Main.Base.getindex(A, i...)
×
1039
const_arrayref(inbounds::Bool, A::Array, i::Int...) = Main.Base.getindex(A, i...)
×
1040
arrayset(inbounds::Bool, A::Array{T}, x::Any, i::Int...) where {T} = Main.Base.setindex!(A, x::T, i...)
×
1041
arraysize(a::Array) = a.size
×
1042
arraysize(a::Array, i::Int) = sle_int(i, nfields(a.size)) ? getfield(a.size, i) : 1
×
1043
export arrayref, arrayset, arraysize, const_arrayref
1044
const check_top_bit = check_sign_bit
1045

1046
# For convenience
1047
EnterNode(old::EnterNode, new_dest::Int) = isdefined(old, :scope) ?
754✔
1048
    EnterNode(new_dest, old.scope) : EnterNode(new_dest)
1049

1050
# typename(_).constprop_heuristic
1051
const FORCE_CONST_PROP      = 0x1
1052
const ARRAY_INDEX_HEURISTIC = 0x2
1053
const ITERATE_HEURISTIC     = 0x3
1054
const SAMETYPE_HEURISTIC    = 0x4
1055

1056
# `typename` has special tfunc support in inference to improve
1057
# the result for `Type{Union{...}}`. It is defined here, so that the Compiler
1058
# can look it up by value.
1059
struct TypeNameError <: Exception
1060
    a
1061
    TypeNameError(@nospecialize(a)) = new(a)
×
1062
end
1063

1064
typename(a) = throw(TypeNameError(a))
×
1065
typename(a::DataType) = a.name
10,494✔
1066
function typename(a::Union)
×
1067
    ta = typename(a.a)
×
1068
    tb = typename(a.b)
×
1069
    ta === tb || throw(TypeNameError(a))
×
1070
    return tb
×
1071
end
1072
typename(union::UnionAll) = typename(union.body)
×
1073

1074
# Special inference support to avoid execess specialization of these methods.
1075
# TODO: Replace this by a generic heuristic.
1076
(>:)(@nospecialize(a), @nospecialize(b)) = (b <: a)
×
1077
(!==)(@nospecialize(a), @nospecialize(b)) = Intrinsics.not_int(a === b)
1,217✔
1078

1079
include(Core, "optimized_generics.jl")
1080

1081
ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Core, true)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc