diff --git a/README.md b/README.md index 789e1ce7..47ea97db 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,8 @@ This work is intended to Note this is a work in progress; many types of syntax are not yet handled. -1. You need a 1.12-DEV build of Julia: At least 1.12.0-DEV.512. Commit `263928f9ad4` is currentl known to work. Note that JuliaLowering relies on Julia internals and may be broken on the latest Julia dev version from time to time. (In fact it is currently broken on the latest `1.12-DEV`.) -2. Check out the main branch of [JuliaSyntax](https://github.com/JuliaLang/JuliaSyntax.jl) +1. You need a 1.13.0-DEV build of Julia: At least 1.13.0-DEV.880. Commit `5ebc5b463ea` is currently known to work. Note that JuliaLowering relies on Julia internals and may be broken on the latest Julia dev version from time to time. +2. Use commit `46723f0` of [JuliaSyntax](https://github.com/JuliaLang/JuliaSyntax.jl) 3. Get the latest version of [JuliaSyntaxFormatter](https://github.com/c42f/JuliaSyntaxFormatter.jl) 4. Run the demo `include("test/demo.jl")` diff --git a/src/ast.jl b/src/ast.jl index 7188eba4..1b718e14 100644 --- a/src/ast.jl +++ b/src/ast.jl @@ -150,7 +150,7 @@ function makeleaf(ctx, srcref, k::Kind, value; kws...) makeleaf(graph, srcref, k; id=value, kws...) elseif k == K"symbolic_label" makeleaf(graph, srcref, k; name_val=value, kws...) - elseif k == K"TOMBSTONE" || k == K"SourceLocation" + elseif k in KSet"TOMBSTONE SourceLocation latestworld latestworld_if_toplevel" makeleaf(graph, srcref, k; kws...) else val = k == K"Integer" ? convert(Int, value) : diff --git a/src/closure_conversion.jl b/src/closure_conversion.jl index 211d6922..b261cf36 100644 --- a/src/closure_conversion.jl +++ b/src/closure_conversion.jl @@ -147,6 +147,7 @@ function convert_global_assignment(ctx, ex, var, rhs0) end push!(stmts, @ast ctx ex [K"=" var rhs]) @ast ctx ex [K"block" + [K"globaldecl" var] stmts... rhs1 ] @@ -337,6 +338,13 @@ function _convert_closures(ctx::ClosureConversionCtx, ex) elseif binfo.is_always_defined || is_self_captured(ctx, var) # Captured but unboxed vars are always defined @ast ctx ex true::K"Bool" + elseif binfo.kind == :global + # Normal isdefined won't work for globals (#56985) + @ast ctx ex [K"call" + "isdefinedglobal"::K"core" + ctx.mod::K"Value" + binfo.name::K"Symbol" + false::K"Bool"] else ex end @@ -344,12 +352,13 @@ function _convert_closures(ctx::ClosureConversionCtx, ex) @assert kind(ex[1]) == K"BindingId" binfo = lookup_binding(ctx, ex[1]) if binfo.kind == :global - @ast ctx ex [K"call" - "set_binding_type!"::K"core" - binfo.mod::K"Value" - binfo.name::K"Symbol" - _convert_closures(ctx, ex[2]) - ] + @ast ctx ex [K"block" + # flisp has this, but our K"assert" handling is in a previous pass + # [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]] + [K"globaldecl" + ex[1] + _convert_closures(ctx, ex[2])] + "nothing"::K"core"] else makeleaf(ctx, ex, K"TOMBSTONE") end @@ -382,6 +391,7 @@ function _convert_closures(ctx::ClosureConversionCtx, ex) type_for_closure(ctx, ex, name_str, field_syms, field_is_box) if !ctx.is_toplevel_seq_point push!(ctx.toplevel_stmts, closure_type_def) + push!(ctx.toplevel_stmts, @ast ctx ex (::K"latestworld_if_toplevel")) closure_type_def = nothing end closure_info = ClosureInfo(closure_type_, field_syms, field_inds) @@ -406,6 +416,7 @@ function _convert_closures(ctx::ClosureConversionCtx, ex) end @ast ctx ex [K"block" closure_type_def + (::K"latestworld_if_toplevel") closure_type := if isempty(type_params) closure_type_ else diff --git a/src/desugaring.jl b/src/desugaring.jl index b45603e5..9661702d 100644 --- a/src/desugaring.jl +++ b/src/desugaring.jl @@ -814,8 +814,7 @@ function expand_generator(ctx, ex) outervars_by_key = Dict{NameKey,typeof(ex)}() for iterspecs in ex[2:end-1] for iterspec in children(iterspecs) - lhs = iterspec[1] - foreach_lhs_var(lhs) do var + foreach_lhs_name(iterspec[1]) do var @assert kind(var) == K"Identifier" # Todo: K"BindingId"? outervars_by_key[NameKey(var)] = var end @@ -1165,16 +1164,19 @@ end # Expand assignments # Expand UnionAll definitions, eg `X{T} = Y{T,T}` -function expand_unionall_def(ctx, srcref, lhs, rhs) +function expand_unionall_def(ctx, srcref, lhs, rhs, is_const=true) if numchildren(lhs) <= 1 throw(LoweringError(lhs, "empty type parameter list in type alias")) end name = lhs[1] - @ast ctx srcref [K"block" - [K"const_if_global" name] - unionall_type := expand_forms_2(ctx, [K"where" rhs lhs[2:end]...]) - expand_forms_2(ctx, [K"=" name unionall_type]) - ] + expand_forms_2( + ctx, + @ast ctx srcref [K"block" + rr := [K"where" rhs lhs[2:end]...] + [is_const ? K"constdecl" : K"assign_or_constdecl_if_global" name rr] + [K"removable" rr] + ] + ) end # Expand general assignment syntax, including @@ -1184,13 +1186,13 @@ end # * Assignments to array elements # * Destructuring # * Typed variable declarations -function expand_assignment(ctx, ex) +function expand_assignment(ctx, ex, is_const=false) @chk numchildren(ex) == 2 lhs = ex[1] rhs = ex[2] kl = kind(lhs) if kl == K"curly" - expand_unionall_def(ctx, ex, lhs, rhs) + expand_unionall_def(ctx, ex, lhs, rhs, is_const) elseif kind(rhs) == K"=" # Expand chains of assignments # a = b = c ==> b=c; a=c @@ -1207,7 +1209,9 @@ function expand_assignment(ctx, ex) tmp_rhs = ssavar(ctx, rhs, "rhs") rr = tmp_rhs end - for i in 1:length(stmts) + # In const a = b = c, only a is const + stmts[1] = @ast ctx ex [(is_const ? K"constdecl" : K"=") stmts[1] rr] + for i in 2:length(stmts) stmts[i] = @ast ctx ex [K"=" stmts[i] rr] end if !isnothing(tmp_rhs) @@ -1220,9 +1224,18 @@ function expand_assignment(ctx, ex) ] ) elseif is_identifier_like(lhs) - sink_assignment(ctx, ex, lhs, expand_forms_2(ctx, rhs)) + if is_const + @ast ctx ex [K"block" + rr := expand_forms_2(ctx, rhs) + [K"constdecl" lhs rr] + [K"removable" rr] + ] + else + sink_assignment(ctx, ex, lhs, expand_forms_2(ctx, rhs)) + end elseif kl == K"." # a.b = rhs ==> setproperty!(a, :b, rhs) + @chk !is_const (ex, "cannot declare `.` form const") @chk numchildren(lhs) == 2 a = lhs[1] b = lhs[2] @@ -1250,16 +1263,23 @@ function expand_assignment(ctx, ex) end elseif kl == K"ref" # a[i1, i2] = rhs + @chk !is_const (ex, "cannot declare ref form const") expand_forms_2(ctx, expand_setindex(ctx, ex)) elseif kl == K"::" && numchildren(lhs) == 2 x = lhs[1] T = lhs[2] - res = if is_identifier_like(x) + res = if is_const + expand_forms_2(ctx, @ast ctx ex [K"const" + [K"=" + lhs[1] + convert_for_type_decl(ctx, ex, rhs, T, true) + ]]) + elseif is_identifier_like(x) # Identifer in lhs[1] is a variable type declaration, eg # x::T = rhs @ast ctx ex [K"block" [K"decl" lhs[1] lhs[2]] - [K"=" lhs[1] rhs] + is_const ? [K"const" [K"=" lhs[1] rhs]] : [K"=" lhs[1] rhs] ] else # Otherwise just a type assertion, eg @@ -1271,6 +1291,7 @@ function expand_assignment(ctx, ex) # needs to be detected somewhere but won't be detected here. Maybe # it shows that remove_argument_side_effects() is not the ideal # solution here? + # TODO: handle underscore? @ast ctx ex [K"block" stmts... [K"::" l1 lhs[2]] @@ -1438,7 +1459,7 @@ function expand_let(ctx, ex) ] elseif kind(lhs) == K"tuple" lhs_locals = SyntaxList(ctx) - foreach_lhs_var(lhs) do var + foreach_lhs_name(lhs) do var push!(lhs_locals, @ast ctx var [K"local" var]) push!(lhs_locals, @ast ctx var [K"always_defined" var]) end @@ -1822,6 +1843,17 @@ function expand_call(ctx, ex) expand_forms_2(ctx, farg) expand_forms_2(ctx, _wrap_unsplatted_args(ctx, ex, args))... ] + elseif kind(farg) == K"Identifier" && farg.name_val == "include" + # world age special case + r = ssavar(ctx, ex) + @ast ctx ex [K"block" + [K"=" r [K"call" + expand_forms_2(ctx, farg) + expand_forms_2(ctx, args)... + ]] + (::K"latestworld_if_toplevel") + r + ] else @ast ctx ex [K"call" expand_forms_2(ctx, farg) @@ -1864,23 +1896,6 @@ end #------------------------------------------------------------------------------- # Expand for loops -# Extract the variable names assigned to from a "fancy assignment left hand -# side" such as nested tuple destructuring. -function foreach_lhs_var(f::Function, ex) - k = kind(ex) - if k == K"Identifier" || k == K"BindingId" - f(ex) - elseif k == K"::" && numchildren(ex) == 2 - foreach_lhs_var(f, ex[1]) - elseif k == K"tuple" || k == K"parameters" - for e in children(ex) - foreach_lhs_var(f, e) - end - end - # k == K"Placeholder" ignored, along with everything else - we assume - # validation is done elsewhere. -end - function expand_for(ctx, ex) iterspecs = ex[1] @@ -1896,7 +1911,7 @@ function expand_for(ctx, ex) @chk kind(iterspec) == K"in" lhs = iterspec[1] if kind(lhs) != K"outer" - foreach_lhs_var(lhs) do var + foreach_lhs_name(lhs) do var push!(copied_vars, @ast ctx var [K"=" var var]) end end @@ -1913,7 +1928,7 @@ function expand_for(ctx, ex) if outer lhs = lhs[1] end - foreach_lhs_var(lhs) do var + foreach_lhs_name(lhs) do var if outer push!(lhs_outer_defs, @ast ctx var var) else @@ -2068,7 +2083,7 @@ end # (x::T, (y::U, z)) # strip out stmts = (local x) (decl x T) (local x) (decl y U) (local z) # and return (x, (y, z)) -function strip_decls!(ctx, stmts, declkind, declkind2, declmeta, ex) +function strip_decls!(ctx, stmts, declkind, declmeta, ex) k = kind(ex) if k == K"Identifier" if !isnothing(declmeta) @@ -2076,9 +2091,6 @@ function strip_decls!(ctx, stmts, declkind, declkind2, declmeta, ex) else push!(stmts, makenode(ctx, ex, declkind, ex)) end - if !isnothing(declkind2) - push!(stmts, makenode(ctx, ex, declkind2, ex)) - end ex elseif k == K"Placeholder" ex @@ -2087,41 +2099,34 @@ function strip_decls!(ctx, stmts, declkind, declkind2, declmeta, ex) name = ex[1] @chk kind(name) == K"Identifier" push!(stmts, makenode(ctx, ex, K"decl", name, ex[2])) - strip_decls!(ctx, stmts, declkind, declkind2, declmeta, ex[1]) + strip_decls!(ctx, stmts, declkind, declmeta, ex[1]) elseif k == K"tuple" || k == K"parameters" cs = SyntaxList(ctx) for e in children(ex) - push!(cs, strip_decls!(ctx, stmts, declkind, declkind2, declmeta, e)) + push!(cs, strip_decls!(ctx, stmts, declkind, declmeta, e)) end makenode(ctx, ex, k, cs) + else + throw(LoweringError(ex, "invalid kind $k in $declkind declaration")) end end -# local x, (y=2), z ==> local x; local y; y = 2; local z -# const x = 1 ==> const x; x = 1 -# global x::T = 1 ==> (block (global x) (decl x T) (x = 1)) -function expand_decls(ctx, ex) +# Separate decls and assignments (which require re-expansion) +# local x, (y=2), z ==> local x; local z; y = 2 +function expand_decls(ctx, ex, is_const=false) declkind = kind(ex) + @assert declkind in KSet"local global" declmeta = get(ex, :meta, nothing) - if numchildren(ex) == 1 && kind(ex[1]) ∈ KSet"const global local" - declkind2 = kind(ex[1]) - bindings = children(ex[1]) - else - declkind2 = nothing - bindings = children(ex) - end + bindings = children(ex) stmts = SyntaxList(ctx) for binding in bindings kb = kind(binding) if is_prec_assignment(kb) @chk numchildren(binding) == 2 - lhs = strip_decls!(ctx, stmts, declkind, declkind2, declmeta, binding[1]) - push!(stmts, @ast ctx binding [kb lhs binding[2]]) - elseif is_sym_decl(binding) - if declkind == K"const" || declkind2 == K"const" - throw(LoweringError(ex, "expected assignment after `const`")) - end - strip_decls!(ctx, stmts, declkind, declkind2, declmeta, binding) + lhs = strip_decls!(ctx, stmts, declkind, declmeta, binding[1]) + push!(stmts, expand_assignment(ctx, @ast ctx binding [kb lhs binding[2]])) + elseif is_sym_decl(binding) && !is_const + strip_decls!(ctx, stmts, declkind, declmeta, binding) else throw(LoweringError(ex, "invalid syntax in variable declaration")) end @@ -2129,6 +2134,49 @@ function expand_decls(ctx, ex) makenode(ctx, ex, K"block", stmts) end +# Iterate over the variable names assigned to from a "fancy assignment left hand +# side" such as nested tuple destructuring, curlies, and calls. +function foreach_lhs_name(f::Function, ex) + k = kind(ex) + if k == K"Placeholder" + # Ignored + elseif is_identifier_like(ex) + f(ex) + elseif (k === K"::" && numchildren(ex) === 2) || k in KSet"call curly where" + foreach_lhs_name(f, ex[1]) + elseif k in KSet"tuple parameters" + for c in children(ex) + foreach_lhs_name(f, c) + end + end + return nothing +end + +function expand_const_decl(ctx, ex) + k = kind(ex[1]) + if k == K"global" + asgn = ex[1][1] + @chk (kind(asgn) == K"=") (ex, "expected assignment after `const`") + globals = SyntaxList(ctx) + foreach_lhs_name(asgn[1]) do x + push!(globals, @ast ctx ex [K"global" x]) + end + @ast ctx ex [K"block" + globals... + expand_assignment(ctx, asgn, true) + ] + elseif k == K"=" + if numchildren(ex[1]) >= 1 && kind(ex[1][1]) == K"tuple" + TODO(ex[1][1], "`const` tuple assignment desugaring") + end + expand_assignment(ctx, ex[1], true) + elseif k == K"local" + throw(LoweringError(ex, "unsupported `const local` declaration")) + else + throw(LoweringError(ex, "expected assignment after `const`")) + end +end + #------------------------------------------------------------------------------- # Expansion of function definitions @@ -3313,19 +3361,22 @@ function expand_abstract_or_primitive_type(ctx, ex) ] [K"=" name newtype_var] [K"call" "_setsuper!"::K"core" newtype_var supertype] - [K"call" "_typebody!"::K"core" newtype_var] + [K"call" "_typebody!"::K"core" false::K"Bool" name] ] ] [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex] ] [K"global" name] - [K"const" name] [K"if" [K"&&" - [K"isdefined" name] + [K"call" + "isdefinedglobal"::K"core" + ctx.mod::K"Value" + name=>K"Symbol" + false::K"Bool"] [K"call" "_equiv_typedef"::K"core" name newtype_var] ] nothing_(ctx, ex) - [K"=" name newtype_var] + [K"constdecl" name newtype_var] ] nothing_(ctx, ex) ] @@ -3744,6 +3795,24 @@ function _constructor_min_initalized(ex::SyntaxTree) end end +# Let S be a struct we're defining in module M. Below is a hack to allow its +# field types to refer to S as M.S. See #56497. +function insert_struct_shim(ctx, fieldtypes, name) + function replace_type(ex) + if kind(ex) == K"." && + numchildren(ex) == 2 && + kind(ex[2]) == K"Symbol" && + ex[2].name_val == name.name_val + @ast ctx ex [K"call" "struct_name_shim"::K"core" ex[1] ex[2] ctx.mod::K"Value" name] + elseif numchildren(ex) > 0 + mapchildren(replace_type, ctx, ex) + else + ex + end + end + map(replace_type, fieldtypes) +end + function expand_struct_def(ctx, ex, docs) @chk numchildren(ex) == 2 type_sig = ex[1] @@ -3764,6 +3833,9 @@ function expand_struct_def(ctx, ex, docs) min_initialized = minimum((_constructor_min_initalized(e) for e in inner_defs), init=length(field_names)) newtype_var = ssavar(ctx, ex, "struct_type") + hasprev = ssavar(ctx, ex, "hasprev") + prev = ssavar(ctx, ex, "prev") + newdef = ssavar(ctx, ex, "newdef") layer = new_scope_layer(ctx, struct_name) global_struct_name = adopt_scope(struct_name, layer) if !isempty(typevar_names) @@ -3827,9 +3899,9 @@ function expand_struct_def(ctx, ex, docs) @ast ctx ex [K"block" [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex] ] [K"scope_block"(scope_type=:hard) + # Needed for later constdecl to work, though plain global form may be removed soon. + [K"global" global_struct_name] [K"block" - [K"global" global_struct_name] - [K"const" global_struct_name] [K"local" struct_name] [K"always_defined" struct_name] typevar_stmts... @@ -3848,35 +3920,38 @@ function expand_struct_def(ctx, ex, docs) ] [K"=" struct_name newtype_var] [K"call"(supertype) "_setsuper!"::K"core" newtype_var supertype] - [K"if" - [K"isdefined" global_struct_name] - [K"if" - [K"call" "_equiv_typedef"::K"core" global_struct_name newtype_var] - [K"block" - # If this is compatible with an old definition, use - # the existing type object and throw away the new - # type - [K"=" struct_name global_struct_name] - if !isempty(typevar_names) - # And resassign the typevar_names - these may be - # referenced in the definition of the field - # types below - [K"=" - [K"tuple" typevar_names...] - prev_typevars - ] - end - ] - # Otherwise do an assignment to trigger an error - [K"=" global_struct_name struct_name] + [K"=" hasprev + [K"&&" [K"call" "isdefinedglobal"::K"core" + ctx.mod::K"Value" + struct_name=>K"Symbol" + false::K"Bool"] + [K"call" "_equiv_typedef"::K"core" global_struct_name newtype_var] + ]] + [K"=" prev [K"if" hasprev global_struct_name false::K"Bool"]] + [K"if" hasprev + [K"block" + # if this is compatible with an old definition, use the old parameters, but the + # new object. This will fail to capture recursive cases, but the call to typebody! + # below is permitted to choose either type definition to put into the binding table + if !isempty(typevar_names) + # And resassign the typevar_names - these may be + # referenced in the definition of the field + # types below + [K"=" [K"tuple" typevar_names...] prev_typevars] + end ] - [K"=" global_struct_name struct_name] - ] - [K"call"(type_body) - "_typebody!"::K"core" - struct_name - [K"call" "svec"::K"core" field_types...] ] + [K"=" newdef + [K"call"(type_body) + "_typebody!"::K"core" + prev + newtype_var + [K"call" "svec"::K"core" insert_struct_shim(ctx, field_types, struct_name)...] + ]] + [K"constdecl" + global_struct_name + newdef + ] # Default constructors if isempty(inner_defs) default_inner_constructors(ctx, ex, global_struct_name, @@ -4271,12 +4346,14 @@ function expand_forms_2(ctx::DesugaringContext, ex::SyntaxTree, docs=nothing) ] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) - elseif k == K"local" || k == K"global" || k == K"const" - if numchildren(ex) == 1 && kind(ex[1]) == K"Identifier" - # Don't recurse when already simplified - `local x`, etc - ex + elseif k == K"const" + expand_const_decl(ctx, ex) + elseif k == K"local" || k == K"global" + if k == K"global" && kind(ex[1]) == K"const" + # Normalize `global const` to `const global` + expand_const_decl(ctx, @ast ctx ex [K"const" [K"global" ex[1][1]]]) else - expand_forms_2(ctx, expand_decls(ctx, ex)) + expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) diff --git a/src/eval.jl b/src/eval.jl index eb4f2806..98722d62 100644 --- a/src/eval.jl +++ b/src/eval.jl @@ -12,6 +12,16 @@ function macroexpand(mod::Module, ex) ex1 end +function codeinfo_has_image_globalref(@nospecialize(e)) + if e isa GlobalRef + return 0x00 !== @ccall jl_object_in_image(e.mod::Any)::UInt8 + elseif e isa Core.CodeInfo + return any(codeinfo_has_image_globalref, e.code) + else + return false + end +end + _CodeInfo_need_ver = v"1.12.0-DEV.512" if VERSION < _CodeInfo_need_ver function _CodeInfo(args...) @@ -20,19 +30,29 @@ if VERSION < _CodeInfo_need_ver else # debuginfo changed completely as of https://github.com/JuliaLang/julia/pull/52415 # nargs / isva was added as of https://github.com/JuliaLang/julia/pull/54341 + # field rettype added in https://github.com/JuliaLang/julia/pull/54655 + # field has_image_globalref added in https://github.com/JuliaLang/julia/pull/57433 # CodeInfo constructor. TODO: Should be in Core let fns = fieldnames(Core.CodeInfo) fts = fieldtypes(Core.CodeInfo) conversions = [:(convert($t, $n)) for (t,n) in zip(fts, fns)] - expected_fns = (:code, :debuginfo, :ssavaluetypes, :ssaflags, :slotnames, :slotflags, :slottypes, :parent, :method_for_inference_limit_heuristics, :edges, :min_world, :max_world, :nargs, :propagate_inbounds, :has_fcall, :nospecializeinfer, :isva, :inlining, :constprop, :purity, :inlining_cost) - expected_fts = (Vector{Any}, Core.DebugInfo, Any, Vector{UInt32}, Vector{Symbol}, Vector{UInt8}, Any, Any, Any, Any, UInt64, UInt64, UInt64, Bool, Bool, Bool, Bool, UInt8, UInt8, UInt16, UInt16) + expected_fns = (:code, :debuginfo, :ssavaluetypes, :ssaflags, :slotnames, :slotflags, :slottypes, :rettype, :parent, :edges, :min_world, :max_world, :method_for_inference_limit_heuristics, :nargs, :propagate_inbounds, :has_fcall, :has_image_globalref, :nospecializeinfer, :isva, :inlining, :constprop, :purity, :inlining_cost) + expected_fts = (Vector{Any}, Core.DebugInfo, Any, Vector{UInt32}, Vector{Symbol}, Vector{UInt8}, Any, Any, Any, Any, UInt64, UInt64, Any, UInt64, Bool, Bool, Bool, Bool, Bool, UInt8, UInt8, UInt16, UInt16) - code = if fns != expected_fns || fts != expected_fts + code = if fns != expected_fns + unexpected_fns = collect(setdiff(Set(fns), Set(expected_fns))) + missing_fns = collect(setdiff(Set(expected_fns), Set(fns))) :(function _CodeInfo(args...) - error("Unrecognized CodeInfo layout: Maybe version $VERSION is to new for this version of JuliaLowering?") - end) + error("Unrecognized CodeInfo fields: Maybe version $VERSION is too new for this version of JuliaLowering?" + * isempty(unexpected_fns) ? "" : "\nUnexpected fields found: $($unexpected_fns)" + * isempty(missing_fns) ? "" : "\nMissing fields: $($missing_fns)") + end) + elseif fts != expected_fts + :(function _CodeInfo(args...) + error("Unrecognized CodeInfo field types: Maybe version $VERSION is too new for this version of JuliaLowering?") + end) else :(function _CodeInfo($(fns...)) $(Expr(:new, :(Core.CodeInfo), conversions...)) @@ -142,6 +162,8 @@ function to_code_info(ex, mod, funcname, slots) debuginfo = finish_ir_debug_info!(current_codelocs_stack) + has_image_globalref = any(codeinfo_has_image_globalref, stmts) + # TODO: Set ssaflags based on call site annotations: # - @inbounds annotations # - call site @inline / @noinline @@ -172,6 +194,7 @@ function to_code_info(ex, mod, funcname, slots) max_world = typemax(Csize_t) isva = false inlining_cost = 0xffff + rettype = Any _CodeInfo( stmts, @@ -181,14 +204,16 @@ function to_code_info(ex, mod, funcname, slots) slotnames, slotflags, slottypes, + rettype, parent, - method_for_inference_limit_heuristics, edges, min_world, max_world, + method_for_inference_limit_heuristics, nargs, propagate_inbounds, has_fcall, + has_image_globalref, nospecializeinfer, isva, inlining, @@ -213,12 +238,7 @@ function to_lowered_expr(mod, ex, ssa_offset=0) elseif k == K"top" GlobalRef(Base, Symbol(ex.name_val)) elseif k == K"globalref" - if mod === ex.mod - # Implicitly refers to name in parent module. - Symbol(ex.name_val) - else - GlobalRef(ex.mod, Symbol(ex.name_val)) - end + GlobalRef(ex.mod, Symbol(ex.name_val)) elseif k == K"Identifier" # Implicitly refers to name in parent module # TODO: Should we even have plain identifiers at this point or should @@ -268,8 +288,6 @@ function to_lowered_expr(mod, ex, ssa_offset=0) Core.NewvarNode(to_lowered_expr(mod, ex[1], ssa_offset)) elseif k == K"new_opaque_closure" args = map(e->to_lowered_expr(mod, e, ssa_offset), children(ex)) - # TODO: put allow_partial back in once we update to the latest julia - splice!(args, 4) # allow_partial Expr(:new_opaque_closure, args...) elseif k == K"meta" args = Any[to_lowered_expr(mod, e, ssa_offset) for e in children(ex)] @@ -288,9 +306,11 @@ function to_lowered_expr(mod, ex, ssa_offset=0) k == K"splatnew" ? :splatnew : k == K"=" ? :(=) : k == K"global" ? :global : - k == K"const" ? :const : + k == K"constdecl" ? :const : k == K"leave" ? :leave : k == K"isdefined" ? :isdefined : + k == K"latestworld" ? :latestworld : + k == K"globaldecl" ? :globaldecl : k == K"pop_exception" ? :pop_exception : k == K"captured_local" ? :captured_local : k == K"gc_preserve_begin" ? :gc_preserve_begin : diff --git a/src/kinds.jl b/src/kinds.jl index 6a1a4ecc..741307ba 100644 --- a/src/kinds.jl +++ b/src/kinds.jl @@ -96,7 +96,7 @@ function _register_kinds() "_opaque_closure" # The enclosed statements must be executed at top level "toplevel_butfirst" - "const_if_global" + "assign_or_constdecl_if_global" "moved_local" "label" "trycatchelse" @@ -111,6 +111,8 @@ function _register_kinds() # A local variable captured into a global method. Contains the # `index` of the associated `Box` in the rewrite list. "captured_local" + # Causes the linearization pass to conditionally emit a world age increment + "latestworld_if_toplevel" "END_LOWERING_KINDS" # The following kinds are emitted by lowering and used in Julia's untyped IR @@ -121,8 +123,12 @@ function _register_kinds() "slot" # Static parameter to a `CodeInfo` code object ("type parameters" to methods) "static_parameter" - # Reference to a global variable within a module + # References/declares a global variable within a module "globalref" + "globaldecl" + # Two-argument constant declaration and assignment. + # Translated to :const in the IR for now (we use K"const" already in parsing). + "constdecl" # Unconditional goto "goto" # Conditional goto @@ -143,6 +149,8 @@ function _register_kinds() "new_opaque_closure" # Wrapper for the lambda of around opaque closure methods "opaque_closure_method" + # World age increment + "latestworld" "END_IR_KINDS" ]) end diff --git a/src/linear_ir.jl b/src/linear_ir.jl index 0bb91f97..b83bf099 100644 --- a/src/linear_ir.jl +++ b/src/linear_ir.jl @@ -3,24 +3,17 @@ function is_valid_ir_argument(ctx, ex) k = kind(ex) - if is_simple_atom(ctx, ex) || k == K"inert" || k == K"top" || k == K"core" + if is_simple_atom(ctx, ex) || k in KSet"inert top core quote" true elseif k == K"BindingId" binfo = lookup_binding(ctx, ex) bk = binfo.kind - # TODO: Can we allow bk == :local || bk == :argument || bk == :static_parameter ??? - # Why does flisp seem to allow (slot) and (static_parameter), but these - # aren't yet converted to by existing lowering?? - if bk == :global - # Globals are nothrow when they are defined - we assume a previously - # defined global can never be set to undefined. (TODO: This could be - # broken when precompiling a module `B` in the presence of a badly - # behaved module `A`, which inconsistently defines globals during - # `A.__init__()`??) - is_defined_nothrow_global(binfo.mod, Symbol(binfo.name)) - else - false - end + bk === :slot + # TODO: We should theoretically be able to allow `bk === + # :static_parameter` for slightly more compact IR, but it's uncertain + # what the compiler is built to tolerate. Notably, flisp allows + # static_parameter, but doesn't produce this form until a later pass, so + # it doesn't end up in the IR. else false end @@ -69,7 +62,7 @@ end Context for creating linear IR. One of these is created per lambda expression to flatten the body down to -a sequence of statements (linear IR). +a sequence of statements (linear IR), which eventually becomes one CodeInfo. """ struct LinearIRContext{GraphType} <: AbstractLoweringContext graph::GraphType @@ -334,18 +327,35 @@ function emit_break(ctx, ex) emit_jump(ctx, ex, target) end -function emit_assignment(ctx, srcref, lhs, rhs) +# `op` may be either K"=" (where global assignments are converted to setglobal!) +# or K"constdecl". flisp: emit-assignment-or-setglobal +function emit_simple_assignment(ctx, srcref, lhs, rhs, op=K"=") + binfo = lookup_binding(ctx, lhs.var_id) + if binfo.kind == :global && op == K"=" + emit(ctx, @ast ctx srcref [ + K"call" + "setglobal!"::K"core" + binfo.mod::K"Value" + binfo.name::K"Symbol" + rhs + ]) + else + emit(ctx, srcref, op, lhs, rhs) + end +end + +function emit_assignment(ctx, srcref, lhs, rhs, op=K"=") if !isnothing(rhs) if is_valid_ir_rvalue(ctx, lhs, rhs) - emit(ctx, srcref, K"=", lhs, rhs) + emit_simple_assignment(ctx, srcref, lhs, rhs, op) else r = emit_assign_tmp(ctx, rhs) - emit(ctx, srcref, K"=", lhs, r) + emit_simple_assignment(ctx, srcref, lhs, r, op) end else # in unreachable code (such as after return); still emit the assignment # so that the structure of those uses is preserved - emit(ctx, @ast ctx srcref [K"=" lhs "nothing"::K"core"]) + emit_simple_assignment(ctx, srcref, lhs, @ast ctx srcref "nothing"::K"core", op) nothing end end @@ -370,6 +380,11 @@ function emit_label(ctx, srcref) l end +function emit_latestworld(ctx, srcref) + (isempty(ctx.code) || kind(last(ctx.code)) != K"latestworld") && + emit(ctx, makeleaf(ctx, srcref, K"latestworld")) +end + function compile_condition_term(ctx, ex) cond = compile(ctx, ex, true, false) if !is_valid_body_ir_argument(ctx, cond) @@ -640,25 +655,27 @@ function compile(ctx::LinearIRContext, ex, needs_value, in_tail_pos) emit(ctx, callex) nothing end - elseif k == K"=" + elseif k == K"=" || k == K"constdecl" lhs = ex[1] - if kind(lhs) == K"Placeholder" + res = if kind(lhs) == K"Placeholder" compile(ctx, ex[2], needs_value, in_tail_pos) else rhs = compile(ctx, ex[2], true, false) # TODO look up arg-map for renaming if lhs was reassigned if needs_value && !isnothing(rhs) r = emit_assign_tmp(ctx, rhs) - emit(ctx, ex, K"=", lhs, r) + emit_simple_assignment(ctx, ex, lhs, r, k) if in_tail_pos emit_return(ctx, ex, r) else r end else - emit_assignment(ctx, ex, lhs, rhs) + emit_assignment(ctx, ex, lhs, rhs, k) end end + k == K"constdecl" && emit_latestworld(ctx, ex) + res elseif k == K"block" || k == K"scope_block" nc = numchildren(ex) if nc == 0 @@ -767,7 +784,7 @@ function compile(ctx::LinearIRContext, ex, needs_value, in_tail_pos) # TODO # throw(LoweringError(ex, # "Global method definition needs to be placed at the top level, or use `eval`")) - if numchildren(ex) == 1 + res = if numchildren(ex) == 1 if in_tail_pos emit_return(ctx, ex) elseif needs_value @@ -792,6 +809,8 @@ function compile(ctx::LinearIRContext, ex, needs_value, in_tail_pos) @assert !needs_value && !in_tail_pos nothing end + emit_latestworld(ctx, ex) + res elseif k == K"opaque_closure_method" @ast ctx ex [K"opaque_closure_method" ex[1] @@ -811,12 +830,19 @@ function compile(ctx::LinearIRContext, ex, needs_value, in_tail_pos) end elseif k == K"gc_preserve_begin" makenode(ctx, ex, k, compile_args(ctx, children(ex))) - elseif k == K"gc_preserve_end" || k == K"global" || k == K"const" + elseif k == K"gc_preserve_end" if needs_value throw(LoweringError(ex, "misplaced kind $k in value position")) end emit(ctx, ex) nothing + elseif k == K"global" + if needs_value + throw(LoweringError(ex, "misplaced global declaration in value position")) + end + emit(ctx, ex) + ctx.is_toplevel_thunk && emit_latestworld(ctx, ex) + nothing elseif k == K"meta" emit(ctx, ex) if needs_value @@ -862,6 +888,21 @@ function compile(ctx::LinearIRContext, ex, needs_value, in_tail_pos) # TODO: also exclude deleted vars emit(ctx, ex) end + elseif k == K"globaldecl" + if needs_value + throw(LoweringError(ex, "misplaced global declaration")) + end + if numchildren(ex) == 1 || is_identifier_like(ex[2]) + emit(ctx, ex) + else + rr = emit_assign_tmp(ctx, ex[2]) + emit(ctx, @ast ctx ex [K"globaldecl" ex[1] rr]) + end + ctx.is_toplevel_thunk && emit_latestworld(ctx, ex) + elseif k == K"latestworld" + emit_latestworld(ctx, ex) + elseif k == K"latestworld_if_toplevel" + ctx.is_toplevel_thunk && emit_latestworld(ctx, ex) else throw(LoweringError(ex, "Invalid syntax; $(repr(k))")) end diff --git a/src/runtime.jl b/src/runtime.jl index a3d9c2ce..23252400 100644 --- a/src/runtime.jl +++ b/src/runtime.jl @@ -130,7 +130,7 @@ function eval_closure_type(mod, closure_type_name, field_names, field_is_box) length(field_names)) Core._setsuper!(type, Core.Function) Base.eval(mod, :(const $closure_type_name = $type)) - Core._typebody!(type, Core.svec(field_types...)) + Core._typebody!(false, type, Core.svec(field_types...)) type end @@ -209,9 +209,8 @@ function module_import(into_mod::Module, is_using::Bool, end function module_public(mod::Module, is_exported::Bool, identifiers...) - for ident in identifiers - @ccall jl_module_public(mod::Module, Symbol(ident)::Symbol, is_exported::Cint)::Cvoid - end + # symbol jl_module_public is no longer exported as of #57765 + eval(mod, Expr((is_exported ? :export : :public), map(Symbol, identifiers)...)) end #-------------------------------------------------- @@ -282,7 +281,7 @@ end # expression into a CodeInfo. # # `args` passed into stub by the Julia runtime are (parent_func, static_params..., arg_types...) -function (g::GeneratedFunctionStub)(world::UInt, source::LineNumberNode, @nospecialize args...) +function (g::GeneratedFunctionStub)(world::UInt, source::Method, @nospecialize args...) # Some of the lowering pipeline from lower() and the pass-specific setup is # re-implemented here because generated functions are very much (but not # entirely) like macro expansion. @@ -334,7 +333,7 @@ function (g::GeneratedFunctionStub)(world::UInt, source::LineNumberNode, @nospec ctx2, ex2 = expand_forms_2( ctx1, ex1) # Wrap expansion in a non-toplevel lambda and run scope resolution - ex2 = @ast ctx2 source [K"lambda"(is_toplevel_thunk=false) + ex2 = @ast ctx2 ex0 [K"lambda"(is_toplevel_thunk=false) [K"block" (string(n)::K"Identifier" for n in g.argnames)... ] @@ -371,18 +370,7 @@ end # # (This should do what fl_defined_julia_global does for flisp lowering) function is_defined_and_owned_global(mod, name) - b = _get_module_binding(mod, name) - !isnothing(b) && isdefined(b, :owner) && b.owner === b -end - -# Return true if `name` is defined in `mod`, the sense that accessing it is nothrow. -# Has no side effects, unlike isdefined() -# -# (This should do what fl_nothrow_julia_global does for flisp lowering) -function is_defined_nothrow_global(mod, name) - b = _get_module_binding(mod, name) - !isnothing(b) && isdefined(b, :owner) || return false - isdefined(b.owner, :value) + Base.binding_kind(mod, name) === Base.PARTITION_KIND_GLOBAL end # "Reserve" a binding: create the binding if it doesn't exist but do not assign diff --git a/src/scope_analysis.jl b/src/scope_analysis.jl index 343b5c6b..c0f65953 100644 --- a/src/scope_analysis.jl +++ b/src/scope_analysis.jl @@ -44,7 +44,11 @@ function _find_scope_vars!(ctx, assignments, locals, destructured_args, globals, end elseif k == K"global" _insert_if_not_present!(globals, NameKey(ex[1]), ex) - elseif k == K"=" + elseif k == K"assign_or_constdecl_if_global" + # like v = val, except that if `v` turns out global(either implicitly or + # by explicit `global`), it gains an implicit `const` + _insert_if_not_present!(assignments, NameKey(ex[1]), ex) + elseif k == K"=" || k == K"constdecl" v = decl_var(ex[1]) if !(kind(v) in KSet"BindingId globalref Placeholder") _insert_if_not_present!(assignments, NameKey(v), v) @@ -561,13 +565,12 @@ function _resolve_scopes(ctx, ex::SyntaxTree) end end resolved - elseif k == K"const_if_global" + elseif k == K"assign_or_constdecl_if_global" id = _resolve_scopes(ctx, ex[1]) - if lookup_binding(ctx, id).kind == :global - @ast ctx ex [K"const" id] - else - makeleaf(ctx, ex, K"TOMBSTONE") - end + bk = lookup_binding(ctx, id).kind + @assert numchildren(ex) === 2 + assignment_kind = bk == :global ? K"constdecl" : K"=" + @ast ctx ex _resolve_scopes(ctx, [assignment_kind ex[1] ex[2]]) else mapchildren(e->_resolve_scopes(ctx, e), ctx, ex) end @@ -677,7 +680,7 @@ function analyze_variables!(ctx, ex) if kind(ex[1]) != K"BindingId" || lookup_binding(ctx, ex[1]).kind !== :local analyze_variables!(ctx, ex[1]) end - elseif k == K"const" + elseif k == K"constdecl" id = ex[1] if lookup_binding(ctx, id).kind == :local throw(LoweringError(ex, "unsupported `const` declaration on local variable")) diff --git a/src/syntax_graph.jl b/src/syntax_graph.jl index bdbf98e0..35c9b188 100644 --- a/src/syntax_graph.jl +++ b/src/syntax_graph.jl @@ -431,6 +431,7 @@ function _value_string(ex) k == K"Symbol" ? ":$(ex.name_val)" : k == K"globalref" ? "$(ex.mod).$(ex.name_val)" : k == K"slot" ? "slot" : + k == K"latestworld" ? "latestworld" : k == K"static_parameter" ? "static_parameter" : k == K"symbolic_label" ? "label:$(ex.name_val)" : k == K"symbolic_goto" ? "goto:$(ex.name_val)" : diff --git a/src/utils.jl b/src/utils.jl index 5d749f05..15c1b27b 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -47,12 +47,11 @@ function showprov(io::IO, exs::AbstractVector; print(io, "\n\n") end k = kind(ex) - if isnothing(note) # use provided `note` otherwise - note = i > 1 && k == K"macrocall" ? "in macro expansion" : - i > 1 && k == K"$" ? "interpolated here" : - "in source" - end - highlight(io, sr; note=note, highlight_kwargs...) + ex_note = !isnothing(note) ? note : + i > 1 && k == K"macrocall" ? "in macro expansion" : + i > 1 && k == K"$" ? "interpolated here" : + "in source" + highlight(io, sr; note=ex_note, highlight_kwargs...) if include_location line, _ = source_location(sr) diff --git a/test/assignments.jl b/test/assignments.jl index 0f7fa488..d15706c2 100644 --- a/test/assignments.jl +++ b/test/assignments.jl @@ -23,6 +23,16 @@ let end """) == 42 +# Assignment in value but not tail position +@test JuliaLowering.include_string(test_mod, """ +let + x = begin + y = 42 + end + x +end +""") == 42 + @test JuliaLowering.include_string(test_mod, """ let x = [] diff --git a/test/assignments_ir.jl b/test/assignments_ir.jl index 9a1393c2..9789fc6e 100644 --- a/test/assignments_ir.jl +++ b/test/assignments_ir.jl @@ -23,6 +23,21 @@ end 5 (= slot₃/c %₂) 6 (return %₂) +######################################## +# Assignment in value but not tail position +let + x = begin + y = 42 + end + x +end +#--------------------- +1 42 +2 (= slot₂/y %₁) +3 (= slot₁/x %₁) +4 slot₁/x +5 (return %₄) + ######################################## # short form function def, not chain of assignments begin @@ -31,20 +46,22 @@ begin end #--------------------- 1 (method TestMod.b) -2 TestMod.b -3 (call core.Typeof %₂) -4 (call core.svec %₃) -5 (call core.svec) -6 SourceLocation::3:9 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.b +4 (call core.Typeof %₃) +5 (call core.svec %₄) +6 (call core.svec) +7 SourceLocation::3:9 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(!read) slot₂/c(!read)] 1 TestMod.d 2 (= slot₂/c %₁) 3 (return %₁) -9 TestMod.b -10 (= slot₁/a %₉) -11 (return %₉) +10 latestworld +11 TestMod.b +12 (= slot₁/a %₁₁) +13 (return %₁₁) ######################################## # a.b = ... => setproperty! assignment @@ -117,17 +134,17 @@ end # UnionAll expansion at global scope results in const decl X{T} = Y{T,T} #--------------------- -1 (const TestMod.X) -2 (call core.TypeVar :T) -3 (= slot₁/T %₂) -4 slot₁/T -5 TestMod.Y +1 (call core.TypeVar :T) +2 (= slot₁/T %₁) +3 slot₁/T +4 TestMod.Y +5 slot₁/T 6 slot₁/T -7 slot₁/T -8 (call core.apply_type %₅ %₆ %₇) -9 (call core.UnionAll %₄ %₈) -10 (= TestMod.X %₉) -11 (return %₉) +7 (call core.apply_type %₄ %₅ %₆) +8 (call core.UnionAll %₃ %₇) +9 (constdecl TestMod.X %₈) +10 latestworld +11 (return %₈) ######################################## # UnionAll expansion in local scope diff --git a/test/closures_ir.jl b/test/closures_ir.jl index 6d6d1339..6495b745 100644 --- a/test/closures_ir.jl +++ b/test/closures_ir.jl @@ -15,16 +15,17 @@ end 5 (call core.svec :x) 6 (call core.svec true) 7 (call JuliaLowering.eval_closure_type TestMod :#f##0 %₅ %₆) -8 TestMod.#f##0 -9 slot₂/x -10 (new %₈ %₉) -11 (= slot₁/f %₁₀) -12 TestMod.#f##0 -13 (call core.svec %₁₂ core.Any) -14 (call core.svec) -15 SourceLocation::3:14 -16 (call core.svec %₁₃ %₁₄ %₁₅) -17 --- method core.nothing %₁₆ +8 latestworld +9 TestMod.#f##0 +10 slot₂/x +11 (new %₉ %₁₀) +12 (= slot₁/f %₁₁) +13 TestMod.#f##0 +14 (call core.svec %₁₃ core.Any) +15 (call core.svec) +16 SourceLocation::3:14 +17 (call core.svec %₁₄ %₁₅ %₁₆) +18 --- method core.nothing %₁₇ slots: [slot₁/#self#(!read) slot₂/y slot₃/x(!read)] 1 TestMod.+ 2 (call core.getfield slot₁/#self# :x) @@ -36,8 +37,9 @@ end 8 (call core.getfield %₂ :contents) 9 (call %₁ %₈ slot₂/y) 10 (return %₉) -18 slot₁/f -19 (return %₁₈) +19 latestworld +20 slot₁/f +21 (return %₂₀) ######################################## # Closure declaration with no methods @@ -50,11 +52,12 @@ end 1 (call core.svec) 2 (call core.svec) 3 (call JuliaLowering.eval_closure_type TestMod :#no_method_f##0 %₁ %₂) -4 TestMod.#no_method_f##0 -5 (new %₄) -6 (= slot₁/no_method_f %₅) -7 slot₁/no_method_f -8 (return %₇) +4 latestworld +5 TestMod.#no_method_f##0 +6 (new %₅) +7 (= slot₁/no_method_f %₆) +8 slot₁/no_method_f +9 (return %₈) ######################################## # Closure which sets the value of a captured variable @@ -72,23 +75,25 @@ end 5 (call core.svec :x) 6 (call core.svec true) 7 (call JuliaLowering.eval_closure_type TestMod :#f##1 %₅ %₆) -8 TestMod.#f##1 -9 slot₂/x -10 (new %₈ %₉) -11 (= slot₁/f %₁₀) -12 TestMod.#f##1 -13 (call core.svec %₁₂ core.Any) -14 (call core.svec) -15 SourceLocation::3:14 -16 (call core.svec %₁₃ %₁₄ %₁₅) -17 --- method core.nothing %₁₆ +8 latestworld +9 TestMod.#f##1 +10 slot₂/x +11 (new %₉ %₁₀) +12 (= slot₁/f %₁₁) +13 TestMod.#f##1 +14 (call core.svec %₁₃ core.Any) +15 (call core.svec) +16 SourceLocation::3:14 +17 (call core.svec %₁₄ %₁₅ %₁₆) +18 --- method core.nothing %₁₇ slots: [slot₁/#self#(!read) slot₂/y(!read)] 1 2 2 (call core.getfield slot₁/#self# :x) 3 (call core.setfield! %₂ :contents %₁) 4 (return %₁) -18 slot₁/f -19 (return %₁₈) +19 latestworld +20 slot₁/f +21 (return %₂₀) ######################################## # Function where arguments are captured into a closure and assigned @@ -101,27 +106,30 @@ function f(x) end #--------------------- 1 (method TestMod.f) -2 (call core.svec :x) -3 (call core.svec true) -4 (call JuliaLowering.eval_closure_type TestMod :#f#g##0 %₂ %₃) -5 TestMod.#f#g##0 -6 (call core.svec %₅) -7 (call core.svec) -8 SourceLocation::2:14 -9 (call core.svec %₆ %₇ %₈) -10 --- method core.nothing %₉ +2 latestworld +3 (call core.svec :x) +4 (call core.svec true) +5 (call JuliaLowering.eval_closure_type TestMod :#f#g##0 %₃ %₄) +6 latestworld +7 TestMod.#f#g##0 +8 (call core.svec %₇) +9 (call core.svec) +10 SourceLocation::2:14 +11 (call core.svec %₈ %₉ %₁₀) +12 --- method core.nothing %₁₁ slots: [slot₁/#self#(!read)] 1 10 2 (call core.getfield slot₁/#self# :x) 3 (call core.setfield! %₂ :contents %₁) 4 (return %₁) -11 TestMod.f -12 (call core.Typeof %₁₁) -13 (call core.svec %₁₂ core.Any) -14 (call core.svec) -15 SourceLocation::1:10 -16 (call core.svec %₁₃ %₁₄ %₁₅) -17 --- method core.nothing %₁₆ +13 latestworld +14 TestMod.f +15 (call core.Typeof %₁₄) +16 (call core.svec %₁₅ core.Any) +17 (call core.svec) +18 SourceLocation::1:10 +19 (call core.svec %₁₆ %₁₇ %₁₈) +20 --- method core.nothing %₁₉ slots: [slot₁/#self#(!read) slot₂/x slot₃/g(called) slot₄/x(!read)] 1 (= slot₂/x (call core.Box slot₂/x)) 2 TestMod.#f#g##0 @@ -137,8 +145,9 @@ end 12 slot₄/x 13 (call core.getfield %₇ :contents) 14 (return %₁₃) -18 TestMod.f -19 (return %₁₈) +21 latestworld +22 TestMod.f +23 (return %₂₂) ######################################## # Closure where a local `x` is captured but not boxed @@ -150,26 +159,29 @@ function f(x) end #--------------------- 1 (method TestMod.f) -2 (call core.svec :x) -3 (call core.svec false) -4 (call JuliaLowering.eval_closure_type TestMod :#f#g##1 %₂ %₃) -5 TestMod.#f#g##1 -6 (call core.svec %₅) -7 (call core.svec) -8 SourceLocation::2:14 -9 (call core.svec %₆ %₇ %₈) -10 --- method core.nothing %₉ +2 latestworld +3 (call core.svec :x) +4 (call core.svec false) +5 (call JuliaLowering.eval_closure_type TestMod :#f#g##1 %₃ %₄) +6 latestworld +7 TestMod.#f#g##1 +8 (call core.svec %₇) +9 (call core.svec) +10 SourceLocation::2:14 +11 (call core.svec %₈ %₉ %₁₀) +12 --- method core.nothing %₁₁ slots: [slot₁/#self#(!read) slot₂/y(!read)] 1 (call core.getfield slot₁/#self# :x) 2 (= slot₂/y %₁) 3 (return %₁) -11 TestMod.f -12 (call core.Typeof %₁₁) -13 (call core.svec %₁₂ core.Any) -14 (call core.svec) -15 SourceLocation::1:10 -16 (call core.svec %₁₃ %₁₄ %₁₅) -17 --- method core.nothing %₁₆ +13 latestworld +14 TestMod.f +15 (call core.Typeof %₁₄) +16 (call core.svec %₁₅ core.Any) +17 (call core.svec) +18 SourceLocation::1:10 +19 (call core.svec %₁₆ %₁₇ %₁₈) +20 --- method core.nothing %₁₉ slots: [slot₁/#self#(!read) slot₂/x slot₃/g slot₄/z(!read)] 1 TestMod.#f#g##1 2 (call core.typeof slot₂/x) @@ -179,8 +191,9 @@ end 6 slot₂/x 7 (= slot₄/z %₆) 8 (return %₆) -18 TestMod.f -19 (return %₁₈) +21 latestworld +22 TestMod.f +23 (return %₂₂) ######################################## # Closure where a static parameter of an outer function is captured @@ -191,30 +204,33 @@ function f(::T) where T end #--------------------- 1 (method TestMod.f) -2 (call core.svec :T) -3 (call core.svec false) -4 (call JuliaLowering.eval_closure_type TestMod :#f#g##2 %₂ %₃) -5 TestMod.#f#g##2 -6 (call core.svec %₅) -7 (call core.svec) -8 SourceLocation::2:14 -9 (call core.svec %₆ %₇ %₈) -10 --- method core.nothing %₉ +2 latestworld +3 (call core.svec :T) +4 (call core.svec false) +5 (call JuliaLowering.eval_closure_type TestMod :#f#g##2 %₃ %₄) +6 latestworld +7 TestMod.#f#g##2 +8 (call core.svec %₇) +9 (call core.svec) +10 SourceLocation::2:14 +11 (call core.svec %₈ %₉ %₁₀) +12 --- method core.nothing %₁₁ slots: [slot₁/#self#(!read)] 1 TestMod.use 2 (call core.getfield slot₁/#self# :T) 3 (call %₁ %₂) 4 (return %₃) -11 (= slot₁/T (call core.TypeVar :T)) -12 TestMod.f -13 (call core.Typeof %₁₂) -14 slot₁/T -15 (call core.svec %₁₃ %₁₄) -16 slot₁/T -17 (call core.svec %₁₆) -18 SourceLocation::1:10 -19 (call core.svec %₁₅ %₁₇ %₁₈) -20 --- method core.nothing %₁₉ +13 latestworld +14 (= slot₁/T (call core.TypeVar :T)) +15 TestMod.f +16 (call core.Typeof %₁₅) +17 slot₁/T +18 (call core.svec %₁₆ %₁₇) +19 slot₁/T +20 (call core.svec %₁₉) +21 SourceLocation::1:10 +22 (call core.svec %₁₈ %₂₀ %₂₁) +23 --- method core.nothing %₂₂ slots: [slot₁/#self#(!read) slot₂/_(!read) slot₃/g] 1 TestMod.#f#g##2 2 static_parameter₁ @@ -225,8 +241,9 @@ end 7 (= slot₃/g %₆) 8 slot₃/g 9 (return %₈) -21 TestMod.f -22 (return %₂₁) +24 latestworld +25 TestMod.f +26 (return %₂₅) ######################################## # Closure captures with `isdefined` @@ -243,15 +260,17 @@ function f(x) end #--------------------- 1 (method TestMod.f) -2 (call core.svec :x :y) -3 (call core.svec false true) -4 (call JuliaLowering.eval_closure_type TestMod :#f#g##3 %₂ %₃) -5 TestMod.#f#g##3 -6 (call core.svec %₅) -7 (call core.svec) -8 SourceLocation::2:14 -9 (call core.svec %₆ %₇ %₈) -10 --- method core.nothing %₉ +2 latestworld +3 (call core.svec :x :y) +4 (call core.svec false true) +5 (call JuliaLowering.eval_closure_type TestMod :#f#g##3 %₃ %₄) +6 latestworld +7 TestMod.#f#g##3 +8 (call core.svec %₇) +9 (call core.svec) +10 SourceLocation::2:14 +11 (call core.svec %₈ %₉ %₁₀) +12 --- method core.nothing %₁₁ slots: [slot₁/#self#(!read) slot₂/z] 1 (= slot₂/z 3) 2 (call core.getfield slot₁/#self# :y) @@ -259,13 +278,14 @@ end 4 (isdefined slot₂/z) 5 (call core.tuple true %₃ %₄) 6 (return %₅) -11 TestMod.f -12 (call core.Typeof %₁₁) -13 (call core.svec %₁₂ core.Any) -14 (call core.svec) -15 SourceLocation::1:10 -16 (call core.svec %₁₃ %₁₄ %₁₅) -17 --- method core.nothing %₁₆ +13 latestworld +14 TestMod.f +15 (call core.Typeof %₁₄) +16 (call core.svec %₁₅ core.Any) +17 (call core.svec) +18 SourceLocation::1:10 +19 (call core.svec %₁₆ %₁₇ %₁₈) +20 --- method core.nothing %₁₉ slots: [slot₁/#self#(!read) slot₂/x slot₃/g slot₄/y] 1 (= slot₄/y (call core.Box)) 2 TestMod.#f#g##3 @@ -281,8 +301,9 @@ end 12 (call core.isdefined %₁₁ :contents) 13 (call core.tuple %₁₂ true) 14 (return %₁₃) -18 TestMod.f -19 (return %₁₈) +21 latestworld +22 TestMod.f +23 (return %₂₂) ######################################## # Nested captures - here `g` captures `x` because it is needed to initialize @@ -322,13 +343,14 @@ end 3 slot₁/x 4 (call core.setfield! %₃ :contents %₂) 5 (method TestMod.f) -6 TestMod.f -7 (call core.Typeof %₆) -8 (call core.svec %₇) -9 (call core.svec) -10 SourceLocation::3:14 -11 (call core.svec %₈ %₉ %₁₀) -12 --- code_info +6 latestworld +7 TestMod.f +8 (call core.Typeof %₇) +9 (call core.svec %₈) +10 (call core.svec) +11 SourceLocation::3:14 +12 (call core.svec %₉ %₁₀ %₁₁) +13 --- code_info slots: [slot₁/#self#(!read) slot₂/x(!read)] 1 TestMod.+ 2 (captured_local 1) @@ -342,12 +364,13 @@ end 10 (captured_local 1) 11 (call core.setfield! %₁₀ :contents %₉) 12 (return %₉) -13 slot₁/x -14 (call core.svec %₁₃) -15 (call JuliaLowering.replace_captured_locals! %₁₂ %₁₄) -16 --- method core.nothing %₁₁ %₁₅ -17 TestMod.f -18 (return %₁₇) +14 slot₁/x +15 (call core.svec %₁₄) +16 (call JuliaLowering.replace_captured_locals! %₁₃ %₁₅) +17 --- method core.nothing %₁₂ %₁₆ +18 latestworld +19 TestMod.f +20 (return %₁₉) ######################################## # Anonymous function syntax with -> @@ -356,19 +379,21 @@ x -> x*x 1 (call core.svec) 2 (call core.svec) 3 (call JuliaLowering.eval_closure_type TestMod :#->##0 %₁ %₂) -4 TestMod.#->##0 -5 (new %₄) -6 TestMod.#->##0 -7 (call core.svec %₆ core.Any) -8 (call core.svec) -9 SourceLocation::1:1 -10 (call core.svec %₇ %₈ %₉) -11 --- method core.nothing %₁₀ +4 latestworld +5 TestMod.#->##0 +6 (new %₅) +7 TestMod.#->##0 +8 (call core.svec %₇ core.Any) +9 (call core.svec) +10 SourceLocation::1:1 +11 (call core.svec %₈ %₉ %₁₀) +12 --- method core.nothing %₁₁ slots: [slot₁/#self#(!read) slot₂/x] 1 TestMod.* 2 (call %₁ slot₂/x slot₂/x) 3 (return %₂) -12 (return %₅) +13 latestworld +14 (return %₆) ######################################## # Anonymous function syntax with `function` @@ -379,19 +404,21 @@ end 1 (call core.svec) 2 (call core.svec) 3 (call JuliaLowering.eval_closure_type TestMod :##anon###0 %₁ %₂) -4 TestMod.##anon###0 -5 (new %₄) -6 TestMod.##anon###0 -7 (call core.svec %₆ core.Any) -8 (call core.svec) -9 SourceLocation::1:10 -10 (call core.svec %₇ %₈ %₉) -11 --- method core.nothing %₁₀ +4 latestworld +5 TestMod.##anon###0 +6 (new %₅) +7 TestMod.##anon###0 +8 (call core.svec %₇ core.Any) +9 (call core.svec) +10 SourceLocation::1:10 +11 (call core.svec %₈ %₉ %₁₀) +12 --- method core.nothing %₁₁ slots: [slot₁/#self#(!read) slot₂/x] 1 TestMod.* 2 (call %₁ slot₂/x slot₂/x) 3 (return %₂) -12 (return %₅) +13 latestworld +14 (return %₆) ######################################## # `do` blocks @@ -407,21 +434,23 @@ end 6 (call core.svec) 7 (call core.svec) 8 (call JuliaLowering.eval_closure_type TestMod :#do##0 %₆ %₇) -9 TestMod.#do##0 -10 (call core.svec %₉ core.Any) -11 (call core.svec) -12 SourceLocation::1:13 -13 (call core.svec %₁₀ %₁₁ %₁₂) -14 --- method core.nothing %₁₃ +9 latestworld +10 TestMod.#do##0 +11 (call core.svec %₁₀ core.Any) +12 (call core.svec) +13 SourceLocation::1:13 +14 (call core.svec %₁₁ %₁₂ %₁₃) +15 --- method core.nothing %₁₄ slots: [slot₁/#self#(!read) slot₂/y] 1 TestMod.+ 2 (call %₁ slot₂/y 2) 3 (return %₂) -15 TestMod.#do##0 -16 (new %₁₅) -17 TestMod.x -18 (call core.kwcall %₅ %₁ %₁₆ %₁₇) -19 (return %₁₈) +16 latestworld +17 TestMod.#do##0 +18 (new %₁₇) +19 TestMod.x +20 (call core.kwcall %₅ %₁ %₁₈ %₁₉) +21 (return %₂₀) ######################################## # Error: Static parameter clashing with closure name @@ -510,17 +539,18 @@ end 3 (call core.svec :recursive_b) 4 (call core.svec true) 5 (call JuliaLowering.eval_closure_type TestMod :#recursive_a##0 %₃ %₄) -6 TestMod.#recursive_a##0 -7 slot₂/recursive_b -8 (new %₆ %₇) -9 slot₁/recursive_a -10 (call core.setfield! %₉ :contents %₈) -11 TestMod.#recursive_a##0 -12 (call core.svec %₁₁) -13 (call core.svec) -14 SourceLocation::2:14 -15 (call core.svec %₁₂ %₁₃ %₁₄) -16 --- method core.nothing %₁₅ +6 latestworld +7 TestMod.#recursive_a##0 +8 slot₂/recursive_b +9 (new %₇ %₈) +10 slot₁/recursive_a +11 (call core.setfield! %₁₀ :contents %₉) +12 TestMod.#recursive_a##0 +13 (call core.svec %₁₂) +14 (call core.svec) +15 SourceLocation::2:14 +16 (call core.svec %₁₃ %₁₄ %₁₅) +17 --- method core.nothing %₁₆ slots: [slot₁/#self#(!read) slot₂/recursive_b(!read)] 1 (call core.getfield slot₁/#self# :recursive_b) 2 (call core.isdefined %₁ :contents) @@ -531,20 +561,22 @@ end 7 (call core.getfield %₁ :contents) 8 (call %₇) 9 (return %₈) -17 (call core.svec :recursive_a) -18 (call core.svec true) -19 (call JuliaLowering.eval_closure_type TestMod :#recursive_b##0 %₁₇ %₁₈) -20 TestMod.#recursive_b##0 -21 slot₁/recursive_a -22 (new %₂₀ %₂₁) -23 slot₂/recursive_b -24 (call core.setfield! %₂₃ :contents %₂₂) -25 TestMod.#recursive_b##0 -26 (call core.svec %₂₅) -27 (call core.svec) -28 SourceLocation::5:14 -29 (call core.svec %₂₆ %₂₇ %₂₈) -30 --- method core.nothing %₂₉ +18 latestworld +19 (call core.svec :recursive_a) +20 (call core.svec true) +21 (call JuliaLowering.eval_closure_type TestMod :#recursive_b##0 %₁₉ %₂₀) +22 latestworld +23 TestMod.#recursive_b##0 +24 slot₁/recursive_a +25 (new %₂₃ %₂₄) +26 slot₂/recursive_b +27 (call core.setfield! %₂₆ :contents %₂₅) +28 TestMod.#recursive_b##0 +29 (call core.svec %₂₈) +30 (call core.svec) +31 SourceLocation::5:14 +32 (call core.svec %₂₉ %₃₀ %₃₁) +33 --- method core.nothing %₃₂ slots: [slot₁/#self#(!read) slot₂/recursive_a(!read)] 1 (call core.getfield slot₁/#self# :recursive_a) 2 (call core.isdefined %₁ :contents) @@ -555,14 +587,15 @@ end 7 (call core.getfield %₁ :contents) 8 (call %₇) 9 (return %₈) -31 slot₂/recursive_b -32 (call core.isdefined %₃₁ :contents) -33 (gotoifnot %₃₂ label₃₅) -34 (goto label₃₇) -35 (newvar slot₄/recursive_b) -36 slot₄/recursive_b -37 (call core.getfield %₃₁ :contents) -38 (return %₃₇) +34 latestworld +35 slot₂/recursive_b +36 (call core.isdefined %₃₅ :contents) +37 (gotoifnot %₃₆ label₃₉) +38 (goto label₄₁) +39 (newvar slot₄/recursive_b) +40 slot₄/recursive_b +41 (call core.getfield %₃₅ :contents) +42 (return %₄₁) ######################################## # Closure with keywords @@ -580,26 +613,28 @@ end 6 (call core.svec :#f_kw_closure#0) 7 (call core.svec true) 8 (call JuliaLowering.eval_closure_type TestMod :#f_kw_closure##0 %₆ %₇) -9 TestMod.#f_kw_closure##0 -10 slot₂/#f_kw_closure#0 -11 (new %₉ %₁₀) -12 (= slot₃/f_kw_closure %₁₁) -13 (call core.svec :y) -14 (call core.svec true) -15 (call JuliaLowering.eval_closure_type TestMod :##f_kw_closure#0##0 %₁₃ %₁₄) -16 TestMod.##f_kw_closure#0##0 -17 slot₁/y -18 (new %₁₆ %₁₇) -19 slot₂/#f_kw_closure#0 -20 (call core.setfield! %₁₉ :contents %₁₈) -21 TestMod.##f_kw_closure#0##0 -22 TestMod.X -23 TestMod.#f_kw_closure##0 -24 (call core.svec %₂₁ %₂₂ %₂₃) -25 (call core.svec) -26 SourceLocation::2:14 -27 (call core.svec %₂₄ %₂₅ %₂₆) -28 --- method core.nothing %₂₇ +9 latestworld +10 TestMod.#f_kw_closure##0 +11 slot₂/#f_kw_closure#0 +12 (new %₁₀ %₁₁) +13 (= slot₃/f_kw_closure %₁₂) +14 (call core.svec :y) +15 (call core.svec true) +16 (call JuliaLowering.eval_closure_type TestMod :##f_kw_closure#0##0 %₁₄ %₁₅) +17 latestworld +18 TestMod.##f_kw_closure#0##0 +19 slot₁/y +20 (new %₁₈ %₁₉) +21 slot₂/#f_kw_closure#0 +22 (call core.setfield! %₂₁ :contents %₂₀) +23 TestMod.##f_kw_closure#0##0 +24 TestMod.X +25 TestMod.#f_kw_closure##0 +26 (call core.svec %₂₃ %₂₄ %₂₅) +27 (call core.svec) +28 SourceLocation::2:14 +29 (call core.svec %₂₆ %₂₇ %₂₈) +30 --- method core.nothing %₂₉ slots: [slot₁/#self#(!read) slot₂/x slot₃/#self#(!read) slot₄/y(!read)] 1 (meta :nkw 1) 2 TestMod.+ @@ -612,13 +647,14 @@ end 9 (call core.getfield %₃ :contents) 10 (call %₂ slot₂/x %₉) 11 (return %₁₀) -29 (call core.typeof core.kwcall) -30 TestMod.#f_kw_closure##0 -31 (call core.svec %₂₉ core.NamedTuple %₃₀) -32 (call core.svec) -33 SourceLocation::2:14 -34 (call core.svec %₃₁ %₃₂ %₃₃) -35 --- code_info +31 latestworld +32 (call core.typeof core.kwcall) +33 TestMod.#f_kw_closure##0 +34 (call core.svec %₃₂ core.NamedTuple %₃₃) +35 (call core.svec) +36 SourceLocation::2:14 +37 (call core.svec %₃₄ %₃₅ %₃₆) +38 --- code_info slots: [slot₁/#self#(!read) slot₂/kws slot₃/#self# slot₄/kwtmp slot₅/x(!read) slot₆/#f_kw_closure#0(!read)] 1 (newvar slot₅/x) 2 (call core.isdefined slot₂/kws :x) @@ -652,16 +688,17 @@ end 30 (call core.getfield %₂₄ :contents) 31 (call %₃₀ %₁₆ slot₃/#self#) 32 (return %₃₁) -36 slot₂/#f_kw_closure#0 -37 (call core.svec %₃₆) -38 (call JuliaLowering.replace_captured_locals! %₃₅ %₃₇) -39 --- method core.nothing %₃₄ %₃₈ -40 TestMod.#f_kw_closure##0 -41 (call core.svec %₄₀) -42 (call core.svec) -43 SourceLocation::2:14 -44 (call core.svec %₄₁ %₄₂ %₄₃) -45 --- method core.nothing %₄₄ +39 slot₂/#f_kw_closure#0 +40 (call core.svec %₃₉) +41 (call JuliaLowering.replace_captured_locals! %₃₈ %₄₀) +42 --- method core.nothing %₃₇ %₄₁ +43 latestworld +44 TestMod.#f_kw_closure##0 +45 (call core.svec %₄₄) +46 (call core.svec) +47 SourceLocation::2:14 +48 (call core.svec %₄₅ %₄₆ %₄₇) +49 --- method core.nothing %₄₈ slots: [slot₁/#self# slot₂/#f_kw_closure#0(!read)] 1 (call core.getfield slot₁/#self# :#f_kw_closure#0) 2 (call core.isdefined %₁ :contents) @@ -673,8 +710,9 @@ end 8 TestMod.x_default 9 (call %₇ %₈ slot₁/#self#) 10 (return %₉) -46 slot₃/f_kw_closure -47 (return %₄₆) +50 latestworld +51 slot₃/f_kw_closure +52 (return %₅₁) ######################################## # Closure capturing a typed local must also capture the type expression diff --git a/test/decls.jl b/test/decls.jl index 08484dfa..7684fa33 100644 --- a/test/decls.jl +++ b/test/decls.jl @@ -9,7 +9,7 @@ begin end """) === 1 -# In value position, yeild the right hand side, not `x` +# In value position, yield the right hand side, not `x` @test JuliaLowering.include_string(test_mod, """ local x::Int = 1.0 """) === 1.0 @@ -33,6 +33,30 @@ let end """) === (1, 20) +# Global const mixes +@test JuliaLowering.include_string(test_mod, "global x_g = 1") === 1 +@test Base.isdefinedglobal(test_mod, :x_g) +@test !Base.isconst(test_mod, :x_g) +@test test_mod.x_g === 1 + +@test JuliaLowering.include_string(test_mod, "const x_c = 1") === 1 +@test Base.isdefinedglobal(test_mod, :x_c) +@test Base.isconst(test_mod, :x_c) +@test test_mod.x_c === 1 + +@test JuliaLowering.include_string(test_mod, "global const x_gc = 1") === 1 +@test Base.isdefinedglobal(test_mod, :x_gc) +@test Base.isconst(test_mod, :x_gc) +@test test_mod.x_gc === 1 + +@test JuliaLowering.include_string(test_mod, "const global x_cg = 1") === 1 +@test Base.isdefinedglobal(test_mod, :x_cg) +@test Base.isconst(test_mod, :x_cg) +@test test_mod.x_cg === 1 +# Possibly worth testing excessive global/const keywords or invalid combinations +# (local + global/const) once we decide whether that's a parse error or a +# lowering error + # Global decls with types @test JuliaLowering.include_string(test_mod, """ global a_typed_global::Int = 10.0 @@ -49,4 +73,23 @@ end @test Core.get_binding_type(test_mod, :a_typed_global_2) === Int @test test_mod.a_typed_global_2 === 10 +@test JuliaLowering.include_string(test_mod, "const x_c_T::Int = 9") === 9 +@test Base.isdefinedglobal(test_mod, :x_c_T) +@test Base.isconst(test_mod, :x_c_T) + +@testset "typed const redeclaration" begin + # redeclaration of the same value used to be allowed + @test_throws ErrorException JuliaLowering.include_string(test_mod, "x_c_T = 9") + @test_throws ErrorException JuliaLowering.include_string(test_mod, "x_c_T = 10") + # redeclaration with const should be OK + @test JuliaLowering.include_string(test_mod, "const x_c_T::Int = 0") === 0 +end + +# Tuple/destructuring assignments +@test JuliaLowering.include_string(test_mod, "(a0, a1, a2) = [1,2,3]") == [1,2,3] + + +# Unsupported for now +@test_throws LoweringError JuliaLowering.include_string(test_mod, "const a,b,c = 1,2,3") + end diff --git a/test/decls_ir.jl b/test/decls_ir.jl index a8b9fd98..7b8c2d37 100644 --- a/test/decls_ir.jl +++ b/test/decls_ir.jl @@ -21,63 +21,109 @@ local x::T = 1 # const const xx = 10 #--------------------- -1 (const TestMod.xx) -2 (= TestMod.xx 10) -3 (return 10) +1 10 +2 (constdecl TestMod.xx %₁) +3 latestworld +4 (return %₁) ######################################## # Typed const const xx::T = 10 #--------------------- 1 TestMod.T -2 (call core.set_binding_type! TestMod :xx %₁) -3 (const TestMod.xx) -4 (call core.get_binding_type TestMod :xx) -5 (= slot₁/tmp 10) -6 slot₁/tmp -7 (call core.isa %₆ %₄) -8 (gotoifnot %₇ label₁₀) -9 (goto label₁₂) +2 (= slot₁/tmp 10) +3 slot₁/tmp +4 (call core.isa %₃ %₁) +5 (gotoifnot %₄ label₇) +6 (goto label₁₀) +7 slot₁/tmp +8 (call top.convert %₁ %₇) +9 (= slot₁/tmp (call core.typeassert %₈ %₁)) 10 slot₁/tmp -11 (= slot₁/tmp (call top.convert %₄ %₁₀)) +11 (constdecl TestMod.xx %₁₀) +12 latestworld +13 (return %₁₀) + +######################################## +# Error: Const tuple +const xxx,xxxx,xxxxx = 10,20,30 +#--------------------- +LoweringError: +const xxx,xxxx,xxxxx = 10,20,30 +# └─────────────┘ ── Lowering TODO: `const` tuple assignment desugaring + +######################################## +# Const in chain: only first is const +const c0 = v0 = v1 = 123 +#--------------------- +1 123 +2 (constdecl TestMod.c0 %₁) +3 latestworld +4 (globaldecl TestMod.v0) +5 latestworld +6 (call core.get_binding_type TestMod :v0) +7 (= slot₁/tmp %₁) +8 slot₁/tmp +9 (call core.isa %₈ %₆) +10 (gotoifnot %₉ label₁₂) +11 (goto label₁₄) 12 slot₁/tmp -13 (= TestMod.xx %₁₂) -14 (return 10) +13 (= slot₁/tmp (call top.convert %₆ %₁₂)) +14 slot₁/tmp +15 (call core.setglobal! TestMod :v0 %₁₄) +16 (globaldecl TestMod.v1) +17 latestworld +18 (call core.get_binding_type TestMod :v1) +19 (= slot₂/tmp %₁) +20 slot₂/tmp +21 (call core.isa %₂₀ %₁₈) +22 (gotoifnot %₂₁ label₂₄) +23 (goto label₂₆) +24 slot₂/tmp +25 (= slot₂/tmp (call top.convert %₁₈ %₂₄)) +26 slot₂/tmp +27 (call core.setglobal! TestMod :v1 %₂₆) +28 (return %₁) ######################################## # Global assignment xx = 10 #--------------------- -1 (call core.get_binding_type TestMod :xx) -2 (= slot₁/tmp 10) -3 slot₁/tmp -4 (call core.isa %₃ %₁) -5 (gotoifnot %₄ label₇) -6 (goto label₉) -7 slot₁/tmp -8 (= slot₁/tmp (call top.convert %₁ %₇)) +1 (globaldecl TestMod.xx) +2 latestworld +3 (call core.get_binding_type TestMod :xx) +4 (= slot₁/tmp 10) +5 slot₁/tmp +6 (call core.isa %₅ %₃) +7 (gotoifnot %₆ label₉) +8 (goto label₁₁) 9 slot₁/tmp -10 (= TestMod.xx %₉) -11 (return 10) +10 (= slot₁/tmp (call top.convert %₃ %₉)) +11 slot₁/tmp +12 (call core.setglobal! TestMod :xx %₁₁) +13 (return 10) ######################################## # Typed global assignment global xx::T = 10 #--------------------- -1 TestMod.T -2 (call core.set_binding_type! TestMod :xx %₁) +1 (globaldecl TestMod.xx TestMod.T) +2 latestworld 3 (global TestMod.xx) -4 (call core.get_binding_type TestMod :xx) -5 (= slot₁/tmp 10) -6 slot₁/tmp -7 (call core.isa %₆ %₄) -8 (gotoifnot %₇ label₁₀) -9 (goto label₁₂) -10 slot₁/tmp -11 (= slot₁/tmp (call top.convert %₄ %₁₀)) -12 slot₁/tmp -13 (= TestMod.xx %₁₂) -14 (return 10) +4 latestworld +5 (globaldecl TestMod.xx) +6 latestworld +7 (call core.get_binding_type TestMod :xx) +8 (= slot₁/tmp 10) +9 slot₁/tmp +10 (call core.isa %₉ %₇) +11 (gotoifnot %₁₀ label₁₃) +12 (goto label₁₅) +13 slot₁/tmp +14 (= slot₁/tmp (call top.convert %₇ %₁₃)) +15 slot₁/tmp +16 (call core.setglobal! TestMod :xx %₁₅) +17 (return 10) ######################################## # Error: x declared twice @@ -99,7 +145,7 @@ const local x = 1 #--------------------- LoweringError: const local x = 1 -# ╙ ── unsupported `const` declaration on local variable +└───────────────┘ ── unsupported `const local` declaration ######################################## # Error: Const not supported on locals @@ -110,7 +156,7 @@ end LoweringError: let const x = 1 -# ╙ ── unsupported `const` declaration on local variable +# └────┘ ── unsupported `const` declaration on local variable end ######################################## @@ -122,13 +168,14 @@ function f(x) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃ core.Any) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄ core.Any) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(!read) slot₂/x slot₃/tmp(!read) slot₄/tmp(!read)] 1 1 2 TestMod.Int @@ -156,8 +203,9 @@ end 24 (= slot₂/x %₂₃) 25 slot₂/x 26 (return %₂₅) -9 TestMod.f -10 (return %₉) +10 latestworld +11 TestMod.f +12 (return %₁₁) ######################################## # Error: global type decls only allowed at top level diff --git a/test/functions_ir.jl b/test/functions_ir.jl index 9abb27e9..5ea648c2 100644 --- a/test/functions_ir.jl +++ b/test/functions_ir.jl @@ -4,8 +4,9 @@ function f end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (return %₂) +2 latestworld +3 TestMod.f +4 (return %₃) ######################################## # Functions with placeholder arg @@ -14,19 +15,21 @@ function f(x, _, y) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃ core.Any core.Any core.Any) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄ core.Any core.Any core.Any) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(!read) slot₂/x slot₃/_(!read) slot₄/y] 1 TestMod.+ 2 (call %₁ slot₂/x slot₄/y) 3 (return %₂) -9 TestMod.f -10 (return %₉) +10 latestworld +11 TestMod.f +12 (return %₁₁) ######################################## # Functions with argument types only, no name @@ -35,19 +38,21 @@ function f(::T, x) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 TestMod.T -5 (call core.svec %₃ %₄ core.Any) -6 (call core.svec) -7 SourceLocation::1:10 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 TestMod.T +6 (call core.svec %₄ %₅ core.Any) +7 (call core.svec) +8 SourceLocation::1:10 +9 (call core.svec %₆ %₇ %₈) +10 --- method core.nothing %₉ slots: [slot₁/#self#(!read) slot₂/_(!read) slot₃/x] 1 slot₃/x 2 (return %₁) -10 TestMod.f -11 (return %₁₀) +11 latestworld +12 TestMod.f +13 (return %₁₂) ######################################## # Functions argument types @@ -56,19 +61,21 @@ function f(x, y::T) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 TestMod.T -5 (call core.svec %₃ core.Any %₄) -6 (call core.svec) -7 SourceLocation::1:10 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 TestMod.T +6 (call core.svec %₄ core.Any %₅) +7 (call core.svec) +8 SourceLocation::1:10 +9 (call core.svec %₆ %₇ %₈) +10 --- method core.nothing %₉ slots: [slot₁/#self#(!read) slot₂/x(!read) slot₃/y(!read)] 1 TestMod.body 2 (return %₁) -10 TestMod.f -11 (return %₁₀) +11 latestworld +12 TestMod.f +13 (return %₁₂) ######################################## # Functions with slurp of Any @@ -77,19 +84,21 @@ function f(x, ys...) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.apply_type core.Vararg core.Any) -5 (call core.svec %₃ core.Any %₄) -6 (call core.svec) -7 SourceLocation::1:10 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.apply_type core.Vararg core.Any) +6 (call core.svec %₄ core.Any %₅) +7 (call core.svec) +8 SourceLocation::1:10 +9 (call core.svec %₆ %₇ %₈) +10 --- method core.nothing %₉ slots: [slot₁/#self#(!read) slot₂/x(!read) slot₃/ys(!read)] 1 TestMod.body 2 (return %₁) -10 TestMod.f -11 (return %₁₀) +11 latestworld +12 TestMod.f +13 (return %₁₂) ######################################## # Functions with slurp of T @@ -98,20 +107,22 @@ function f(x, ys::T...) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 TestMod.T -5 (call core.apply_type core.Vararg %₄) -6 (call core.svec %₃ core.Any %₅) -7 (call core.svec) -8 SourceLocation::1:10 -9 (call core.svec %₆ %₇ %₈) -10 --- method core.nothing %₉ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 TestMod.T +6 (call core.apply_type core.Vararg %₅) +7 (call core.svec %₄ core.Any %₆) +8 (call core.svec) +9 SourceLocation::1:10 +10 (call core.svec %₇ %₈ %₉) +11 --- method core.nothing %₁₀ slots: [slot₁/#self#(!read) slot₂/x(!read) slot₃/ys(!read)] 1 TestMod.body 2 (return %₁) -11 TestMod.f -12 (return %₁₁) +12 latestworld +13 TestMod.f +14 (return %₁₃) ######################################## # Error: Function with slurp not in last position arg @@ -132,30 +143,32 @@ function f(::T, ::U, ::V) where T where {U,V} end #--------------------- 1 (method TestMod.f) -2 (= slot₂/U (call core.TypeVar :U)) -3 (= slot₃/V (call core.TypeVar :V)) -4 (= slot₁/T (call core.TypeVar :T)) -5 TestMod.f -6 (call core.Typeof %₅) -7 slot₁/T -8 slot₂/U -9 slot₃/V -10 (call core.svec %₆ %₇ %₈ %₉) -11 slot₂/U -12 slot₃/V -13 slot₁/T -14 (call core.svec %₁₁ %₁₂ %₁₃) -15 SourceLocation::1:10 -16 (call core.svec %₁₀ %₁₄ %₁₅) -17 --- method core.nothing %₁₆ +2 latestworld +3 (= slot₂/U (call core.TypeVar :U)) +4 (= slot₃/V (call core.TypeVar :V)) +5 (= slot₁/T (call core.TypeVar :T)) +6 TestMod.f +7 (call core.Typeof %₆) +8 slot₁/T +9 slot₂/U +10 slot₃/V +11 (call core.svec %₇ %₈ %₉ %₁₀) +12 slot₂/U +13 slot₃/V +14 slot₁/T +15 (call core.svec %₁₂ %₁₃ %₁₄) +16 SourceLocation::1:10 +17 (call core.svec %₁₁ %₁₅ %₁₆) +18 --- method core.nothing %₁₇ slots: [slot₁/#self#(!read) slot₂/_(!read) slot₃/_(!read) slot₄/_(!read)] 1 static_parameter₃ 2 static_parameter₁ 3 static_parameter₂ 4 (call core.tuple %₁ %₂ %₃) 5 (return %₄) -18 TestMod.f -19 (return %₁₈) +19 latestworld +20 TestMod.f +21 (return %₂₀) ######################################## # Static parameter with bounds and used with apply_type in argument @@ -164,25 +177,27 @@ function f(::S{T}) where X <: T <: Y end #--------------------- 1 (method TestMod.f) -2 TestMod.X -3 TestMod.Y -4 (= slot₁/T (call core.TypeVar :T %₂ %₃)) -5 TestMod.f -6 (call core.Typeof %₅) -7 TestMod.S -8 slot₁/T -9 (call core.apply_type %₇ %₈) -10 (call core.svec %₆ %₉) -11 slot₁/T -12 (call core.svec %₁₁) -13 SourceLocation::1:10 -14 (call core.svec %₁₀ %₁₂ %₁₃) -15 --- method core.nothing %₁₄ +2 latestworld +3 TestMod.X +4 TestMod.Y +5 (= slot₁/T (call core.TypeVar :T %₃ %₄)) +6 TestMod.f +7 (call core.Typeof %₆) +8 TestMod.S +9 slot₁/T +10 (call core.apply_type %₈ %₉) +11 (call core.svec %₇ %₁₀) +12 slot₁/T +13 (call core.svec %₁₂) +14 SourceLocation::1:10 +15 (call core.svec %₁₁ %₁₃ %₁₄) +16 --- method core.nothing %₁₅ slots: [slot₁/#self#(!read) slot₂/_(!read)] 1 static_parameter₁ 2 (return %₁) -16 TestMod.f -17 (return %₁₆) +17 latestworld +18 TestMod.f +19 (return %₁₈) ######################################## # Static parameter which is used only in the bounds of another static parameter @@ -192,28 +207,30 @@ function f(x, y::S) where {T, S<:AbstractVector{T}} end #--------------------- 1 (method TestMod.f) -2 (= slot₂/T (call core.TypeVar :T)) -3 TestMod.AbstractVector -4 slot₂/T -5 (call core.apply_type %₃ %₄) -6 (= slot₁/S (call core.TypeVar :S %₅)) -7 TestMod.f -8 (call core.Typeof %₇) -9 slot₁/S -10 (call core.svec %₈ core.Any %₉) -11 slot₂/T -12 slot₁/S -13 (call core.svec %₁₁ %₁₂) -14 SourceLocation::1:10 -15 (call core.svec %₁₀ %₁₃ %₁₄) -16 --- method core.nothing %₁₅ +2 latestworld +3 (= slot₂/T (call core.TypeVar :T)) +4 TestMod.AbstractVector +5 slot₂/T +6 (call core.apply_type %₄ %₅) +7 (= slot₁/S (call core.TypeVar :S %₆)) +8 TestMod.f +9 (call core.Typeof %₈) +10 slot₁/S +11 (call core.svec %₉ core.Any %₁₀) +12 slot₂/T +13 slot₁/S +14 (call core.svec %₁₂ %₁₃) +15 SourceLocation::1:10 +16 (call core.svec %₁₁ %₁₄ %₁₅) +17 --- method core.nothing %₁₆ slots: [slot₁/#self#(!read) slot₂/x(!read) slot₃/y(!read)] 1 static_parameter₁ 2 static_parameter₂ 3 (call core.tuple %₁ %₂) 4 (return %₃) -17 TestMod.f -18 (return %₁₇) +18 latestworld +19 TestMod.f +20 (return %₁₉) ######################################## # Error: Static parameter which is unused @@ -237,13 +254,14 @@ function f(x)::Int end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃ core.Any) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄ core.Any) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(!read) slot₂/x slot₃/tmp(!read)] 1 TestMod.Int 2 (gotoifnot slot₂/x label₃) @@ -257,8 +275,9 @@ end 10 (= slot₃/tmp (call core.typeassert %₉ %₁)) 11 slot₃/tmp 12 (return %₁₁) -9 TestMod.f -10 (return %₉) +10 latestworld +11 TestMod.f +12 (return %₁₁) ######################################## # Callable type @@ -275,7 +294,8 @@ end slots: [slot₁/#self#(!read) slot₂/x] 1 slot₂/x 2 (return %₁) -7 (return core.nothing) +7 latestworld +8 (return core.nothing) ######################################## # Callable type with instance @@ -292,7 +312,8 @@ end slots: [slot₁/y slot₂/x] 1 (call core.tuple slot₁/y slot₂/x) 2 (return %₁) -7 (return core.nothing) +7 latestworld +8 (return core.nothing) ######################################## # `where` params used in callable object type @@ -313,7 +334,8 @@ end slots: [slot₁/x(!read)] 1 static_parameter₁ 2 (return %₁) -11 (return core.nothing) +11 latestworld +12 (return core.nothing) ######################################## # Function with module ref in name @@ -330,7 +352,8 @@ end 8 --- method core.nothing %₇ slots: [slot₁/#self#(!read)] 1 (return core.nothing) -9 (return core.nothing) +9 latestworld +10 (return core.nothing) ######################################## # Error: Invalid dotop function name @@ -359,44 +382,48 @@ function f(x::T, y::S=1, z::U=2) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 TestMod.T -5 (call core.svec %₃ %₄) -6 (call core.svec) -7 SourceLocation::1:10 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 TestMod.T +6 (call core.svec %₄ %₅) +7 (call core.svec) +8 SourceLocation::1:10 +9 (call core.svec %₆ %₇ %₈) +10 --- method core.nothing %₉ slots: [slot₁/#self#(called) slot₂/x] 1 (call slot₁/#self# slot₂/x 1 2) 2 (return %₁) -10 TestMod.f -11 (call core.Typeof %₁₀) -12 TestMod.T -13 TestMod.S -14 (call core.svec %₁₁ %₁₂ %₁₃) -15 (call core.svec) -16 SourceLocation::1:10 -17 (call core.svec %₁₄ %₁₅ %₁₆) -18 --- method core.nothing %₁₇ +11 latestworld +12 TestMod.f +13 (call core.Typeof %₁₂) +14 TestMod.T +15 TestMod.S +16 (call core.svec %₁₃ %₁₄ %₁₅) +17 (call core.svec) +18 SourceLocation::1:10 +19 (call core.svec %₁₆ %₁₇ %₁₈) +20 --- method core.nothing %₁₉ slots: [slot₁/#self#(called) slot₂/x slot₃/y] 1 (call slot₁/#self# slot₂/x slot₃/y 2) 2 (return %₁) -19 TestMod.f -20 (call core.Typeof %₁₉) -21 TestMod.T -22 TestMod.S -23 TestMod.U -24 (call core.svec %₂₀ %₂₁ %₂₂ %₂₃) -25 (call core.svec) -26 SourceLocation::1:10 -27 (call core.svec %₂₄ %₂₅ %₂₆) -28 --- method core.nothing %₂₇ +21 latestworld +22 TestMod.f +23 (call core.Typeof %₂₂) +24 TestMod.T +25 TestMod.S +26 TestMod.U +27 (call core.svec %₂₃ %₂₄ %₂₅ %₂₆) +28 (call core.svec) +29 SourceLocation::1:10 +30 (call core.svec %₂₇ %₂₈ %₂₉) +31 --- method core.nothing %₃₀ slots: [slot₁/#self#(!read) slot₂/x slot₃/y slot₄/z(!read)] 1 (call core.tuple slot₂/x slot₃/y) 2 (return %₁) -29 TestMod.f -30 (return %₂₉) +32 latestworld +33 TestMod.f +34 (return %₃₃) ######################################## # Default positional args which depend on other args @@ -405,38 +432,42 @@ function f(x=1, y=x) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(called)] 1 (call slot₁/#self# 1) 2 (return %₁) -9 TestMod.f -10 (call core.Typeof %₉) -11 (call core.svec %₁₀ core.Any) -12 (call core.svec) -13 SourceLocation::1:10 -14 (call core.svec %₁₁ %₁₂ %₁₃) -15 --- method core.nothing %₁₄ +10 latestworld +11 TestMod.f +12 (call core.Typeof %₁₁) +13 (call core.svec %₁₂ core.Any) +14 (call core.svec) +15 SourceLocation::1:10 +16 (call core.svec %₁₃ %₁₄ %₁₅) +17 --- method core.nothing %₁₆ slots: [slot₁/#self#(called) slot₂/x] 1 (call slot₁/#self# slot₂/x slot₂/x) 2 (return %₁) -16 TestMod.f -17 (call core.Typeof %₁₆) -18 (call core.svec %₁₇ core.Any core.Any) -19 (call core.svec) -20 SourceLocation::1:10 -21 (call core.svec %₁₈ %₁₉ %₂₀) -22 --- method core.nothing %₂₁ +18 latestworld +19 TestMod.f +20 (call core.Typeof %₁₉) +21 (call core.svec %₂₀ core.Any core.Any) +22 (call core.svec) +23 SourceLocation::1:10 +24 (call core.svec %₂₁ %₂₂ %₂₃) +25 --- method core.nothing %₂₄ slots: [slot₁/#self#(!read) slot₂/x slot₃/y] 1 (call core.tuple slot₂/x slot₃/y) 2 (return %₁) -23 TestMod.f -24 (return %₂₃) +26 latestworld +27 TestMod.f +28 (return %₂₇) ######################################## # Default positional args with missing arg names (implicit placeholders) @@ -445,41 +476,45 @@ function f(::Int, y=1, z=2) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 TestMod.Int -5 (call core.svec %₃ %₄) -6 (call core.svec) -7 SourceLocation::1:10 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 TestMod.Int +6 (call core.svec %₄ %₅) +7 (call core.svec) +8 SourceLocation::1:10 +9 (call core.svec %₆ %₇ %₈) +10 --- method core.nothing %₉ slots: [slot₁/#self#(called) slot₂/_] 1 (call slot₁/#self# slot₂/_ 1 2) 2 (return %₁) -10 TestMod.f -11 (call core.Typeof %₁₀) -12 TestMod.Int -13 (call core.svec %₁₁ %₁₂ core.Any) -14 (call core.svec) -15 SourceLocation::1:10 -16 (call core.svec %₁₃ %₁₄ %₁₅) -17 --- method core.nothing %₁₆ +11 latestworld +12 TestMod.f +13 (call core.Typeof %₁₂) +14 TestMod.Int +15 (call core.svec %₁₃ %₁₄ core.Any) +16 (call core.svec) +17 SourceLocation::1:10 +18 (call core.svec %₁₅ %₁₆ %₁₇) +19 --- method core.nothing %₁₈ slots: [slot₁/#self#(called) slot₂/_ slot₃/y] 1 (call slot₁/#self# slot₂/_ slot₃/y 2) 2 (return %₁) -18 TestMod.f -19 (call core.Typeof %₁₈) -20 TestMod.Int -21 (call core.svec %₁₉ %₂₀ core.Any core.Any) -22 (call core.svec) -23 SourceLocation::1:10 -24 (call core.svec %₂₁ %₂₂ %₂₃) -25 --- method core.nothing %₂₄ +20 latestworld +21 TestMod.f +22 (call core.Typeof %₂₁) +23 TestMod.Int +24 (call core.svec %₂₂ %₂₃ core.Any core.Any) +25 (call core.svec) +26 SourceLocation::1:10 +27 (call core.svec %₂₄ %₂₅ %₂₆) +28 --- method core.nothing %₂₇ slots: [slot₁/#self#(!read) slot₂/_(!read) slot₃/y slot₄/z] 1 (call core.tuple slot₃/y slot₄/z) 2 (return %₁) -26 TestMod.f -27 (return %₂₆) +29 latestworld +30 TestMod.f +31 (return %₃₀) ######################################## # Default positional args with placeholders @@ -488,30 +523,33 @@ function f(_::Int, x=1) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 TestMod.Int -5 (call core.svec %₃ %₄) -6 (call core.svec) -7 SourceLocation::1:10 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 TestMod.Int +6 (call core.svec %₄ %₅) +7 (call core.svec) +8 SourceLocation::1:10 +9 (call core.svec %₆ %₇ %₈) +10 --- method core.nothing %₉ slots: [slot₁/#self#(called) slot₂/_] 1 (call slot₁/#self# slot₂/_ 1) 2 (return %₁) -10 TestMod.f -11 (call core.Typeof %₁₀) -12 TestMod.Int -13 (call core.svec %₁₁ %₁₂ core.Any) -14 (call core.svec) -15 SourceLocation::1:10 -16 (call core.svec %₁₃ %₁₄ %₁₅) -17 --- method core.nothing %₁₆ +11 latestworld +12 TestMod.f +13 (call core.Typeof %₁₂) +14 TestMod.Int +15 (call core.svec %₁₃ %₁₄ core.Any) +16 (call core.svec) +17 SourceLocation::1:10 +18 (call core.svec %₁₅ %₁₆ %₁₇) +19 --- method core.nothing %₁₈ slots: [slot₁/#self#(!read) slot₂/_(!read) slot₃/x] 1 slot₃/x 2 (return %₁) -18 TestMod.f -19 (return %₁₈) +20 latestworld +21 TestMod.f +22 (return %₂₁) ######################################## # Positional args with defaults and `where` clauses @@ -520,55 +558,59 @@ function f(x::T, y::S=1, z::U=2) where {T,S<:T,U<:S} end #--------------------- 1 (method TestMod.f) -2 (= slot₂/T (call core.TypeVar :T)) -3 slot₂/T -4 (= slot₁/S (call core.TypeVar :S %₃)) -5 slot₁/S -6 (= slot₃/U (call core.TypeVar :U %₅)) -7 TestMod.f -8 (call core.Typeof %₇) -9 slot₂/T -10 (call core.svec %₈ %₉) -11 slot₂/T -12 (call core.svec %₁₁) -13 SourceLocation::1:10 -14 (call core.svec %₁₀ %₁₂ %₁₃) -15 --- method core.nothing %₁₄ +2 latestworld +3 (= slot₂/T (call core.TypeVar :T)) +4 slot₂/T +5 (= slot₁/S (call core.TypeVar :S %₄)) +6 slot₁/S +7 (= slot₃/U (call core.TypeVar :U %₆)) +8 TestMod.f +9 (call core.Typeof %₈) +10 slot₂/T +11 (call core.svec %₉ %₁₀) +12 slot₂/T +13 (call core.svec %₁₂) +14 SourceLocation::1:10 +15 (call core.svec %₁₁ %₁₃ %₁₄) +16 --- method core.nothing %₁₅ slots: [slot₁/#self#(called) slot₂/x] 1 (call slot₁/#self# slot₂/x 1 2) 2 (return %₁) -16 TestMod.f -17 (call core.Typeof %₁₆) -18 slot₂/T -19 slot₁/S -20 (call core.svec %₁₇ %₁₈ %₁₉) -21 slot₂/T -22 slot₁/S -23 (call core.svec %₂₁ %₂₂) -24 SourceLocation::1:10 -25 (call core.svec %₂₀ %₂₃ %₂₄) -26 --- method core.nothing %₂₅ +17 latestworld +18 TestMod.f +19 (call core.Typeof %₁₈) +20 slot₂/T +21 slot₁/S +22 (call core.svec %₁₉ %₂₀ %₂₁) +23 slot₂/T +24 slot₁/S +25 (call core.svec %₂₃ %₂₄) +26 SourceLocation::1:10 +27 (call core.svec %₂₂ %₂₅ %₂₆) +28 --- method core.nothing %₂₇ slots: [slot₁/#self#(called) slot₂/x slot₃/y] 1 (call slot₁/#self# slot₂/x slot₃/y 2) 2 (return %₁) -27 TestMod.f -28 (call core.Typeof %₂₇) -29 slot₂/T -30 slot₁/S -31 slot₃/U -32 (call core.svec %₂₈ %₂₉ %₃₀ %₃₁) -33 slot₂/T -34 slot₁/S -35 slot₃/U -36 (call core.svec %₃₃ %₃₄ %₃₅) -37 SourceLocation::1:10 -38 (call core.svec %₃₂ %₃₆ %₃₇) -39 --- method core.nothing %₃₈ +29 latestworld +30 TestMod.f +31 (call core.Typeof %₃₀) +32 slot₂/T +33 slot₁/S +34 slot₃/U +35 (call core.svec %₃₁ %₃₂ %₃₃ %₃₄) +36 slot₂/T +37 slot₁/S +38 slot₃/U +39 (call core.svec %₃₆ %₃₇ %₃₈) +40 SourceLocation::1:10 +41 (call core.svec %₃₅ %₃₉ %₄₀) +42 --- method core.nothing %₄₁ slots: [slot₁/#self#(!read) slot₂/x slot₃/y slot₄/z] 1 (call core.tuple slot₂/x slot₃/y slot₄/z) 2 (return %₁) -40 TestMod.f -41 (return %₄₀) +43 latestworld +44 TestMod.f +45 (return %₄₄) ######################################## # Positional args and type parameters with transitive dependencies @@ -579,56 +621,60 @@ function f(x, y::S=[1], z::U=2) where {T, S<:AbstractVector{T}, U} end #--------------------- 1 (method TestMod.f) -2 (= slot₂/T (call core.TypeVar :T)) -3 TestMod.AbstractVector -4 slot₂/T -5 (call core.apply_type %₃ %₄) -6 (= slot₁/S (call core.TypeVar :S %₅)) -7 (= slot₃/U (call core.TypeVar :U)) -8 TestMod.f -9 (call core.Typeof %₈) -10 (call core.svec %₉ core.Any) -11 (call core.svec) -12 SourceLocation::1:10 -13 (call core.svec %₁₀ %₁₁ %₁₂) -14 --- method core.nothing %₁₃ +2 latestworld +3 (= slot₂/T (call core.TypeVar :T)) +4 TestMod.AbstractVector +5 slot₂/T +6 (call core.apply_type %₄ %₅) +7 (= slot₁/S (call core.TypeVar :S %₆)) +8 (= slot₃/U (call core.TypeVar :U)) +9 TestMod.f +10 (call core.Typeof %₉) +11 (call core.svec %₁₀ core.Any) +12 (call core.svec) +13 SourceLocation::1:10 +14 (call core.svec %₁₁ %₁₂ %₁₃) +15 --- method core.nothing %₁₄ slots: [slot₁/#self#(called) slot₂/x] 1 (call top.vect 1) 2 (call slot₁/#self# slot₂/x %₁ 2) 3 (return %₂) -15 TestMod.f -16 (call core.Typeof %₁₅) -17 slot₁/S -18 (call core.svec %₁₆ core.Any %₁₇) -19 slot₂/T -20 slot₁/S -21 (call core.svec %₁₉ %₂₀) -22 SourceLocation::1:10 -23 (call core.svec %₁₈ %₂₁ %₂₂) -24 --- method core.nothing %₂₃ +16 latestworld +17 TestMod.f +18 (call core.Typeof %₁₇) +19 slot₁/S +20 (call core.svec %₁₈ core.Any %₁₉) +21 slot₂/T +22 slot₁/S +23 (call core.svec %₂₁ %₂₂) +24 SourceLocation::1:10 +25 (call core.svec %₂₀ %₂₃ %₂₄) +26 --- method core.nothing %₂₅ slots: [slot₁/#self#(called) slot₂/x slot₃/y] 1 (call slot₁/#self# slot₂/x slot₃/y 2) 2 (return %₁) -25 TestMod.f -26 (call core.Typeof %₂₅) -27 slot₁/S -28 slot₃/U -29 (call core.svec %₂₆ core.Any %₂₇ %₂₈) -30 slot₂/T -31 slot₁/S -32 slot₃/U -33 (call core.svec %₃₀ %₃₁ %₃₂) -34 SourceLocation::1:10 -35 (call core.svec %₂₉ %₃₃ %₃₄) -36 --- method core.nothing %₃₅ +27 latestworld +28 TestMod.f +29 (call core.Typeof %₂₈) +30 slot₁/S +31 slot₃/U +32 (call core.svec %₂₉ core.Any %₃₀ %₃₁) +33 slot₂/T +34 slot₁/S +35 slot₃/U +36 (call core.svec %₃₃ %₃₄ %₃₅) +37 SourceLocation::1:10 +38 (call core.svec %₃₂ %₃₆ %₃₇) +39 --- method core.nothing %₃₈ slots: [slot₁/#self#(!read) slot₂/x slot₃/y slot₄/z] 1 static_parameter₁ 2 static_parameter₂ 3 static_parameter₃ 4 (call core.tuple slot₂/x slot₃/y slot₄/z %₁ %₂ %₃) 5 (return %₄) -37 TestMod.f -38 (return %₃₇) +40 latestworld +41 TestMod.f +42 (return %₄₁) ######################################## # Default positional args are allowed before trailing slurp with no default @@ -637,29 +683,32 @@ function f(x=1, ys...) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(called)] 1 (call slot₁/#self# 1) 2 (return %₁) -9 TestMod.f -10 (call core.Typeof %₉) -11 (call core.apply_type core.Vararg core.Any) -12 (call core.svec %₁₀ core.Any %₁₁) -13 (call core.svec) -14 SourceLocation::1:10 -15 (call core.svec %₁₂ %₁₃ %₁₄) -16 --- method core.nothing %₁₅ +10 latestworld +11 TestMod.f +12 (call core.Typeof %₁₁) +13 (call core.apply_type core.Vararg core.Any) +14 (call core.svec %₁₂ core.Any %₁₃) +15 (call core.svec) +16 SourceLocation::1:10 +17 (call core.svec %₁₄ %₁₅ %₁₆) +18 --- method core.nothing %₁₇ slots: [slot₁/#self#(!read) slot₂/x(!read) slot₃/ys] 1 slot₃/ys 2 (return %₁) -17 TestMod.f -18 (return %₁₇) +19 latestworld +20 TestMod.f +21 (return %₂₀) ######################################## # Error: Default positional args before non-default arg @@ -676,33 +725,36 @@ end ######################################## # Positional arg with slurp and default function f(xs...=1) - xs -end -#--------------------- -1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ + xs +end +#--------------------- +1 (method TestMod.f) +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(called)] 1 (call slot₁/#self# 1) 2 (return %₁) -9 TestMod.f -10 (call core.Typeof %₉) -11 (call core.apply_type core.Vararg core.Any) -12 (call core.svec %₁₀ %₁₁) -13 (call core.svec) -14 SourceLocation::1:10 -15 (call core.svec %₁₂ %₁₃ %₁₄) -16 --- method core.nothing %₁₅ +10 latestworld +11 TestMod.f +12 (call core.Typeof %₁₁) +13 (call core.apply_type core.Vararg core.Any) +14 (call core.svec %₁₂ %₁₃) +15 (call core.svec) +16 SourceLocation::1:10 +17 (call core.svec %₁₄ %₁₅ %₁₆) +18 --- method core.nothing %₁₇ slots: [slot₁/#self#(!read) slot₂/xs] 1 slot₂/xs 2 (return %₁) -17 TestMod.f -18 (return %₁₇) +19 latestworld +20 TestMod.f +21 (return %₂₀) ######################################## # Positional arg with slurp and splatted default value @@ -711,30 +763,33 @@ function f(xs...=(1,2)...) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#] 1 (call core.tuple 1 2) 2 (call core._apply_iterate top.iterate slot₁/#self# %₁) 3 (return %₂) -9 TestMod.f -10 (call core.Typeof %₉) -11 (call core.apply_type core.Vararg core.Any) -12 (call core.svec %₁₀ %₁₁) -13 (call core.svec) -14 SourceLocation::1:10 -15 (call core.svec %₁₂ %₁₃ %₁₄) -16 --- method core.nothing %₁₅ +10 latestworld +11 TestMod.f +12 (call core.Typeof %₁₁) +13 (call core.apply_type core.Vararg core.Any) +14 (call core.svec %₁₂ %₁₃) +15 (call core.svec) +16 SourceLocation::1:10 +17 (call core.svec %₁₄ %₁₅ %₁₆) +18 --- method core.nothing %₁₇ slots: [slot₁/#self#(!read) slot₂/xs] 1 slot₂/xs 2 (return %₁) -17 TestMod.f -18 (return %₁₇) +19 latestworld +20 TestMod.f +21 (return %₂₀) ######################################## # Trivial function argument destructuring @@ -742,13 +797,14 @@ function f(x, (y,z), w) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃ core.Any core.Any core.Any) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄ core.Any core.Any core.Any) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(!read) slot₂/x(!read) slot₃/destructured_arg slot₄/w(!read) slot₅/iterstate slot₆/y(!read) slot₇/z(!read)] 1 (call top.indexed_iterate slot₃/destructured_arg 1) 2 (= slot₆/y (call core.getfield %₁ 1)) @@ -757,8 +813,9 @@ end 5 (call top.indexed_iterate slot₃/destructured_arg 2 %₄) 6 (= slot₇/z (call core.getfield %₅ 1)) 7 (return core.nothing) -9 TestMod.f -10 (return %₉) +10 latestworld +11 TestMod.f +12 (return %₁₁) ######################################## # Function argument destructuring combined with splats, types and and defaults @@ -766,32 +823,35 @@ function f((x,)::T...=rhs) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(called)] 1 TestMod.rhs 2 (call slot₁/#self# %₁) 3 (return %₂) -9 TestMod.f -10 (call core.Typeof %₉) -11 TestMod.T -12 (call core.apply_type core.Vararg %₁₁) -13 (call core.svec %₁₀ %₁₂) -14 (call core.svec) -15 SourceLocation::1:10 -16 (call core.svec %₁₃ %₁₄ %₁₅) -17 --- method core.nothing %₁₆ +10 latestworld +11 TestMod.f +12 (call core.Typeof %₁₁) +13 TestMod.T +14 (call core.apply_type core.Vararg %₁₃) +15 (call core.svec %₁₂ %₁₄) +16 (call core.svec) +17 SourceLocation::1:10 +18 (call core.svec %₁₅ %₁₆ %₁₇) +19 --- method core.nothing %₁₈ slots: [slot₁/#self#(!read) slot₂/destructured_arg slot₃/x(!read)] 1 (call top.indexed_iterate slot₂/destructured_arg 1) 2 (= slot₃/x (call core.getfield %₁ 1)) 3 (return core.nothing) -18 TestMod.f -19 (return %₁₈) +20 latestworld +21 TestMod.f +22 (return %₂₁) ######################################## # Function argument destructuring combined with splats, types and and defaults @@ -799,24 +859,26 @@ function f(x=default_x)::T end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(called)] 1 TestMod.default_x 2 (call slot₁/#self# %₁) 3 (return %₂) -9 TestMod.f -10 (call core.Typeof %₉) -11 (call core.svec %₁₀ core.Any) -12 (call core.svec) -13 SourceLocation::1:10 -14 (call core.svec %₁₁ %₁₂ %₁₃) -15 --- method core.nothing %₁₄ +10 latestworld +11 TestMod.f +12 (call core.Typeof %₁₁) +13 (call core.svec %₁₂ core.Any) +14 (call core.svec) +15 SourceLocation::1:10 +16 (call core.svec %₁₃ %₁₄ %₁₅) +17 --- method core.nothing %₁₆ slots: [slot₁/#self#(!read) slot₂/x(!read) slot₃/tmp(!read)] 1 TestMod.T 2 (= slot₃/tmp core.nothing) @@ -829,8 +891,9 @@ end 9 (= slot₃/tmp (call core.typeassert %₈ %₁)) 10 slot₃/tmp 11 (return %₁₀) -16 TestMod.f -17 (return %₁₆) +18 latestworld +19 TestMod.f +20 (return %₁₉) ######################################## # Duplicate destructured placeholders ok @@ -838,21 +901,23 @@ function f((_,), (_,)) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃ core.Any core.Any) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄ core.Any core.Any) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(!read) slot₂/destructured_arg slot₃/destructured_arg] 1 (call top.indexed_iterate slot₂/destructured_arg 1) 2 (call core.getfield %₁ 1) 3 (call top.indexed_iterate slot₃/destructured_arg 1) 4 (call core.getfield %₃ 1) 5 (return core.nothing) -9 TestMod.f -10 (return %₉) +10 latestworld +11 TestMod.f +12 (return %₁₁) ######################################## # Slot flags @@ -861,20 +926,22 @@ function f(@nospecialize(x), g, y) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃ core.Any core.Any core.Any) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄ core.Any core.Any core.Any) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(!read) slot₂/x(nospecialize,!read) slot₃/g(called) slot₄/y] 1 TestMod.+ 2 (call slot₃/g) 3 (call %₁ %₂ slot₄/y) 4 (return %₃) -9 TestMod.f -10 (return %₉) +10 latestworld +11 TestMod.f +12 (return %₁₁) ######################################## # Function return without arguments @@ -884,19 +951,21 @@ function f() end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(!read)] 1 (return core.nothing) 2 TestMod.after_return 3 (return %₂) -9 TestMod.f -10 (return %₉) +10 latestworld +11 TestMod.f +12 (return %₁₁) ######################################## # Binding docs to functions @@ -907,19 +976,21 @@ function f() end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃) -5 (call core.svec) -6 SourceLocation::4:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄) +6 (call core.svec) +7 SourceLocation::4:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(!read)] 1 (return core.nothing) -9 TestMod.f -10 (call JuliaLowering.bind_docs! %₉ "some docs\n" %₇) +10 latestworld 11 TestMod.f -12 (return %₁₁) +12 (call JuliaLowering.bind_docs! %₁₁ "some docs\n" %₈) +13 TestMod.f +14 (return %₁₃) ######################################## # Binding docs to callable type @@ -937,9 +1008,10 @@ end 6 --- method core.nothing %₅ slots: [slot₁/x(!read)] 1 (return core.nothing) -7 TestMod.T -8 (call JuliaLowering.bind_docs! %₇ "some docs\n" %₅) -9 (return core.nothing) +7 latestworld +8 TestMod.T +9 (call JuliaLowering.bind_docs! %₈ "some docs\n" %₅) +10 (return core.nothing) ######################################## # Keyword function with defaults. @@ -956,57 +1028,62 @@ function f_kw_simple(a::Int=1, b::Float64=1.0; x::Char='a', y::Bool=true) end #--------------------- 1 (method TestMod.f_kw_simple) -2 (method TestMod.#f_kw_simple#0) -3 TestMod.#f_kw_simple#0 -4 (call core.Typeof %₃) -5 TestMod.Char -6 TestMod.Bool -7 TestMod.f_kw_simple -8 (call core.Typeof %₇) -9 TestMod.Int -10 TestMod.Float64 -11 (call core.svec %₄ %₅ %₆ %₈ %₉ %₁₀) -12 (call core.svec) -13 SourceLocation::1:10 -14 (call core.svec %₁₁ %₁₂ %₁₃) -15 --- method core.nothing %₁₄ +2 latestworld +3 (method TestMod.#f_kw_simple#0) +4 latestworld +5 TestMod.#f_kw_simple#0 +6 (call core.Typeof %₅) +7 TestMod.Char +8 TestMod.Bool +9 TestMod.f_kw_simple +10 (call core.Typeof %₉) +11 TestMod.Int +12 TestMod.Float64 +13 (call core.svec %₆ %₇ %₈ %₁₀ %₁₁ %₁₂) +14 (call core.svec) +15 SourceLocation::1:10 +16 (call core.svec %₁₃ %₁₄ %₁₅) +17 --- method core.nothing %₁₆ slots: [slot₁/#self#(!read) slot₂/x slot₃/y slot₄/#self#(!read) slot₅/a slot₆/b] 1 (meta :nkw 2) 2 (call core.tuple slot₅/a slot₆/b slot₂/x slot₃/y) 3 (return %₂) -16 (call core.typeof core.kwcall) -17 TestMod.f_kw_simple -18 (call core.Typeof %₁₇) -19 (call core.svec %₁₆ core.NamedTuple %₁₈) -20 (call core.svec) -21 SourceLocation::1:10 -22 (call core.svec %₁₉ %₂₀ %₂₁) -23 --- method core.nothing %₂₂ +18 latestworld +19 (call core.typeof core.kwcall) +20 TestMod.f_kw_simple +21 (call core.Typeof %₂₀) +22 (call core.svec %₁₉ core.NamedTuple %₂₁) +23 (call core.svec) +24 SourceLocation::1:10 +25 (call core.svec %₂₂ %₂₃ %₂₄) +26 --- method core.nothing %₂₅ slots: [slot₁/#self#(called) slot₂/kws slot₃/#self#] 1 (call slot₁/#self# slot₂/kws slot₃/#self# 1 1.0) 2 (return %₁) -24 (call core.typeof core.kwcall) -25 TestMod.f_kw_simple -26 (call core.Typeof %₂₅) -27 TestMod.Int -28 (call core.svec %₂₄ core.NamedTuple %₂₆ %₂₇) -29 (call core.svec) -30 SourceLocation::1:10 -31 (call core.svec %₂₈ %₂₉ %₃₀) -32 --- method core.nothing %₃₁ +27 latestworld +28 (call core.typeof core.kwcall) +29 TestMod.f_kw_simple +30 (call core.Typeof %₂₉) +31 TestMod.Int +32 (call core.svec %₂₈ core.NamedTuple %₃₀ %₃₁) +33 (call core.svec) +34 SourceLocation::1:10 +35 (call core.svec %₃₂ %₃₃ %₃₄) +36 --- method core.nothing %₃₅ slots: [slot₁/#self#(called) slot₂/kws slot₃/#self# slot₄/a] 1 (call slot₁/#self# slot₂/kws slot₃/#self# slot₄/a 1.0) 2 (return %₁) -33 (call core.typeof core.kwcall) -34 TestMod.f_kw_simple -35 (call core.Typeof %₃₄) -36 TestMod.Int -37 TestMod.Float64 -38 (call core.svec %₃₃ core.NamedTuple %₃₅ %₃₆ %₃₇) -39 (call core.svec) -40 SourceLocation::1:10 -41 (call core.svec %₃₈ %₃₉ %₄₀) -42 --- method core.nothing %₄₁ +37 latestworld +38 (call core.typeof core.kwcall) +39 TestMod.f_kw_simple +40 (call core.Typeof %₃₉) +41 TestMod.Int +42 TestMod.Float64 +43 (call core.svec %₃₈ core.NamedTuple %₄₀ %₄₁ %₄₂) +44 (call core.svec) +45 SourceLocation::1:10 +46 (call core.svec %₄₃ %₄₄ %₄₅) +47 --- method core.nothing %₄₆ slots: [slot₁/#self#(!read) slot₂/kws slot₃/#self# slot₄/a slot₅/b slot₆/kwtmp slot₇/x(!read) slot₈/y(!read)] 1 (newvar slot₇/x) 2 (newvar slot₈/y) @@ -1048,42 +1125,46 @@ end 38 TestMod.#f_kw_simple#0 39 (call %₃₈ %₁₆ %₃₀ slot₃/#self# slot₄/a slot₅/b) 40 (return %₃₉) -43 TestMod.f_kw_simple -44 (call core.Typeof %₄₃) -45 (call core.svec %₄₄) -46 (call core.svec) -47 SourceLocation::1:10 -48 (call core.svec %₄₅ %₄₆ %₄₇) -49 --- method core.nothing %₄₈ +48 latestworld +49 TestMod.f_kw_simple +50 (call core.Typeof %₄₉) +51 (call core.svec %₅₀) +52 (call core.svec) +53 SourceLocation::1:10 +54 (call core.svec %₅₁ %₅₂ %₅₃) +55 --- method core.nothing %₅₄ slots: [slot₁/#self#(called)] 1 (call slot₁/#self# 1 1.0) 2 (return %₁) -50 TestMod.f_kw_simple -51 (call core.Typeof %₅₀) -52 TestMod.Int -53 (call core.svec %₅₁ %₅₂) -54 (call core.svec) -55 SourceLocation::1:10 -56 (call core.svec %₅₃ %₅₄ %₅₅) -57 --- method core.nothing %₅₆ +56 latestworld +57 TestMod.f_kw_simple +58 (call core.Typeof %₅₇) +59 TestMod.Int +60 (call core.svec %₅₈ %₅₉) +61 (call core.svec) +62 SourceLocation::1:10 +63 (call core.svec %₆₀ %₆₁ %₆₂) +64 --- method core.nothing %₆₃ slots: [slot₁/#self#(called) slot₂/a] 1 (call slot₁/#self# slot₂/a 1.0) 2 (return %₁) -58 TestMod.f_kw_simple -59 (call core.Typeof %₅₈) -60 TestMod.Int -61 TestMod.Float64 -62 (call core.svec %₅₉ %₆₀ %₆₁) -63 (call core.svec) -64 SourceLocation::1:10 -65 (call core.svec %₆₂ %₆₃ %₆₄) -66 --- method core.nothing %₆₅ +65 latestworld +66 TestMod.f_kw_simple +67 (call core.Typeof %₆₆) +68 TestMod.Int +69 TestMod.Float64 +70 (call core.svec %₆₇ %₆₈ %₆₉) +71 (call core.svec) +72 SourceLocation::1:10 +73 (call core.svec %₇₀ %₇₁ %₇₂) +74 --- method core.nothing %₇₃ slots: [slot₁/#self# slot₂/a slot₃/b] 1 TestMod.#f_kw_simple#0 2 (call %₁ 'a' true slot₁/#self# slot₂/a slot₃/b) 3 (return %₂) -67 TestMod.f_kw_simple -68 (return %₆₇) +75 latestworld +76 TestMod.f_kw_simple +77 (return %₇₆) ######################################## # Keyword slurping - simple forwarding of all kws @@ -1092,50 +1173,55 @@ function f_kw_slurp_simple(; all_kws...) end #--------------------- 1 (method TestMod.f_kw_slurp_simple) -2 (method TestMod.#f_kw_slurp_simple#0) -3 TestMod.#f_kw_slurp_simple#0 -4 (call core.Typeof %₃) -5 (call top.pairs core.NamedTuple) -6 TestMod.f_kw_slurp_simple -7 (call core.Typeof %₆) -8 (call core.svec %₄ %₅ %₇) -9 (call core.svec) -10 SourceLocation::1:10 -11 (call core.svec %₈ %₉ %₁₀) -12 --- method core.nothing %₁₁ +2 latestworld +3 (method TestMod.#f_kw_slurp_simple#0) +4 latestworld +5 TestMod.#f_kw_slurp_simple#0 +6 (call core.Typeof %₅) +7 (call top.pairs core.NamedTuple) +8 TestMod.f_kw_slurp_simple +9 (call core.Typeof %₈) +10 (call core.svec %₆ %₇ %₉) +11 (call core.svec) +12 SourceLocation::1:10 +13 (call core.svec %₁₀ %₁₁ %₁₂) +14 --- method core.nothing %₁₃ slots: [slot₁/#self#(!read) slot₂/all_kws slot₃/#self#(!read)] 1 (meta :nkw 1) 2 slot₂/all_kws 3 (return %₂) -13 (call core.typeof core.kwcall) -14 TestMod.f_kw_slurp_simple -15 (call core.Typeof %₁₄) -16 (call core.svec %₁₃ core.NamedTuple %₁₅) -17 (call core.svec) -18 SourceLocation::1:10 -19 (call core.svec %₁₆ %₁₇ %₁₈) -20 --- method core.nothing %₁₉ +15 latestworld +16 (call core.typeof core.kwcall) +17 TestMod.f_kw_slurp_simple +18 (call core.Typeof %₁₇) +19 (call core.svec %₁₆ core.NamedTuple %₁₈) +20 (call core.svec) +21 SourceLocation::1:10 +22 (call core.svec %₁₉ %₂₀ %₂₁) +23 --- method core.nothing %₂₂ slots: [slot₁/#self#(!read) slot₂/kws slot₃/#self# slot₄/all_kws(!read)] 1 (newvar slot₄/all_kws) 2 (call top.pairs slot₂/kws) 3 TestMod.#f_kw_slurp_simple#0 4 (call %₃ %₂ slot₃/#self#) 5 (return %₄) -21 TestMod.f_kw_slurp_simple -22 (call core.Typeof %₂₁) -23 (call core.svec %₂₂) -24 (call core.svec) -25 SourceLocation::1:10 -26 (call core.svec %₂₃ %₂₄ %₂₅) -27 --- method core.nothing %₂₆ +24 latestworld +25 TestMod.f_kw_slurp_simple +26 (call core.Typeof %₂₅) +27 (call core.svec %₂₆) +28 (call core.svec) +29 SourceLocation::1:10 +30 (call core.svec %₂₇ %₂₈ %₂₉) +31 --- method core.nothing %₃₀ slots: [slot₁/#self#] 1 TestMod.#f_kw_slurp_simple#0 2 (call core.NamedTuple) 3 (call top.pairs %₂) 4 (call %₁ %₃ slot₁/#self#) 5 (return %₄) -28 TestMod.f_kw_slurp_simple -29 (return %₂₈) +32 latestworld +33 TestMod.f_kw_slurp_simple +34 (return %₃₃) ######################################## # Keyword slurping @@ -1144,29 +1230,32 @@ function f_kw_slurp(; x=x_default, non_x_kws...) end #--------------------- 1 (method TestMod.f_kw_slurp) -2 (method TestMod.#f_kw_slurp#0) -3 TestMod.#f_kw_slurp#0 -4 (call core.Typeof %₃) -5 (call top.pairs core.NamedTuple) -6 TestMod.f_kw_slurp -7 (call core.Typeof %₆) -8 (call core.svec %₄ core.Any %₅ %₇) -9 (call core.svec) -10 SourceLocation::1:10 -11 (call core.svec %₈ %₉ %₁₀) -12 --- method core.nothing %₁₁ +2 latestworld +3 (method TestMod.#f_kw_slurp#0) +4 latestworld +5 TestMod.#f_kw_slurp#0 +6 (call core.Typeof %₅) +7 (call top.pairs core.NamedTuple) +8 TestMod.f_kw_slurp +9 (call core.Typeof %₈) +10 (call core.svec %₆ core.Any %₇ %₉) +11 (call core.svec) +12 SourceLocation::1:10 +13 (call core.svec %₁₀ %₁₁ %₁₂) +14 --- method core.nothing %₁₃ slots: [slot₁/#self#(!read) slot₂/x(!read) slot₃/non_x_kws(!read) slot₄/#self#(!read)] 1 (meta :nkw 2) 2 TestMod.all_kws 3 (return %₂) -13 (call core.typeof core.kwcall) -14 TestMod.f_kw_slurp -15 (call core.Typeof %₁₄) -16 (call core.svec %₁₃ core.NamedTuple %₁₅) -17 (call core.svec) -18 SourceLocation::1:10 -19 (call core.svec %₁₆ %₁₇ %₁₈) -20 --- method core.nothing %₁₉ +15 latestworld +16 (call core.typeof core.kwcall) +17 TestMod.f_kw_slurp +18 (call core.Typeof %₁₇) +19 (call core.svec %₁₆ core.NamedTuple %₁₈) +20 (call core.svec) +21 SourceLocation::1:10 +22 (call core.svec %₁₉ %₂₀ %₂₁) +23 --- method core.nothing %₂₂ slots: [slot₁/#self#(!read) slot₂/kws slot₃/#self# slot₄/kwtmp slot₅/non_x_kws(!read) slot₆/x(!read)] 1 (newvar slot₅/non_x_kws) 2 (newvar slot₆/x) @@ -1185,13 +1274,14 @@ end 15 TestMod.#f_kw_slurp#0 16 (call %₁₅ %₁₀ %₁₄ slot₃/#self#) 17 (return %₁₆) -21 TestMod.f_kw_slurp -22 (call core.Typeof %₂₁) -23 (call core.svec %₂₂) -24 (call core.svec) -25 SourceLocation::1:10 -26 (call core.svec %₂₃ %₂₄ %₂₅) -27 --- method core.nothing %₂₆ +24 latestworld +25 TestMod.f_kw_slurp +26 (call core.Typeof %₂₅) +27 (call core.svec %₂₆) +28 (call core.svec) +29 SourceLocation::1:10 +30 (call core.svec %₂₇ %₂₈ %₂₉) +31 --- method core.nothing %₃₀ slots: [slot₁/#self#] 1 TestMod.#f_kw_slurp#0 2 TestMod.x_default @@ -1199,8 +1289,9 @@ end 4 (call top.pairs %₃) 5 (call %₁ %₂ %₄ slot₁/#self#) 6 (return %₅) -28 TestMod.f_kw_slurp -29 (return %₂₈) +32 latestworld +33 TestMod.f_kw_slurp +34 (return %₃₃) ######################################## # Static parameters used in keywords, with and without the static parameter @@ -1213,41 +1304,44 @@ function f_kw_sparams(x::X; a::A=a_def, b::X=b_def) where {X,A} end #--------------------- 1 (method TestMod.f_kw_sparams) -2 (method TestMod.#f_kw_sparams#0) -3 (= slot₂/X (call core.TypeVar :X)) -4 (= slot₁/A (call core.TypeVar :A)) -5 TestMod.#f_kw_sparams#0 -6 (call core.Typeof %₅) -7 slot₁/A -8 slot₂/X -9 TestMod.f_kw_sparams -10 (call core.Typeof %₉) -11 slot₂/X -12 (call core.svec %₆ %₇ %₈ %₁₀ %₁₁) +2 latestworld +3 (method TestMod.#f_kw_sparams#0) +4 latestworld +5 (= slot₂/X (call core.TypeVar :X)) +6 (= slot₁/A (call core.TypeVar :A)) +7 TestMod.#f_kw_sparams#0 +8 (call core.Typeof %₇) +9 slot₁/A +10 slot₂/X +11 TestMod.f_kw_sparams +12 (call core.Typeof %₁₁) 13 slot₂/X -14 slot₁/A -15 (call core.svec %₁₃ %₁₄) -16 SourceLocation::1:10 -17 (call core.svec %₁₂ %₁₅ %₁₆) -18 --- method core.nothing %₁₇ +14 (call core.svec %₈ %₉ %₁₀ %₁₂ %₁₃) +15 slot₂/X +16 slot₁/A +17 (call core.svec %₁₅ %₁₆) +18 SourceLocation::1:10 +19 (call core.svec %₁₄ %₁₇ %₁₈) +20 --- method core.nothing %₁₉ slots: [slot₁/#self#(!read) slot₂/a(!read) slot₃/b(!read) slot₄/#self#(!read) slot₅/x(!read)] 1 (meta :nkw 2) 2 static_parameter₁ 3 static_parameter₂ 4 (call core.tuple %₂ %₃) 5 (return %₄) -19 (= slot₄/X (call core.TypeVar :X)) -20 (= slot₃/A (call core.TypeVar :A)) -21 (call core.typeof core.kwcall) -22 TestMod.f_kw_sparams -23 (call core.Typeof %₂₂) -24 slot₄/X -25 (call core.svec %₂₁ core.NamedTuple %₂₃ %₂₄) -26 slot₄/X -27 (call core.svec %₂₆) -28 SourceLocation::1:10 -29 (call core.svec %₂₅ %₂₇ %₂₈) -30 --- method core.nothing %₂₉ +21 latestworld +22 (= slot₄/X (call core.TypeVar :X)) +23 (= slot₃/A (call core.TypeVar :A)) +24 (call core.typeof core.kwcall) +25 TestMod.f_kw_sparams +26 (call core.Typeof %₂₅) +27 slot₄/X +28 (call core.svec %₂₄ core.NamedTuple %₂₆ %₂₇) +29 slot₄/X +30 (call core.svec %₂₉) +31 SourceLocation::1:10 +32 (call core.svec %₂₈ %₃₀ %₃₁) +33 --- method core.nothing %₃₂ slots: [slot₁/#self#(!read) slot₂/kws slot₃/#self# slot₄/x slot₅/kwtmp slot₆/a(!read) slot₇/b(!read)] 1 (newvar slot₆/a) 2 (newvar slot₇/b) @@ -1284,25 +1378,27 @@ end 33 TestMod.#f_kw_sparams#0 34 (call %₃₃ %₁₀ %₂₅ slot₃/#self# slot₄/x) 35 (return %₃₄) -31 (= slot₆/X (call core.TypeVar :X)) -32 (= slot₅/A (call core.TypeVar :A)) -33 TestMod.f_kw_sparams -34 (call core.Typeof %₃₃) -35 slot₆/X -36 (call core.svec %₃₄ %₃₅) -37 slot₆/X -38 (call core.svec %₃₇) -39 SourceLocation::1:10 -40 (call core.svec %₃₆ %₃₈ %₃₉) -41 --- method core.nothing %₄₀ +34 latestworld +35 (= slot₆/X (call core.TypeVar :X)) +36 (= slot₅/A (call core.TypeVar :A)) +37 TestMod.f_kw_sparams +38 (call core.Typeof %₃₇) +39 slot₆/X +40 (call core.svec %₃₈ %₃₉) +41 slot₆/X +42 (call core.svec %₄₁) +43 SourceLocation::1:10 +44 (call core.svec %₄₀ %₄₂ %₄₃) +45 --- method core.nothing %₄₄ slots: [slot₁/#self# slot₂/x] 1 TestMod.#f_kw_sparams#0 2 TestMod.a_def 3 TestMod.b_def 4 (call %₁ %₂ %₃ slot₁/#self# slot₂/x) 5 (return %₄) -42 TestMod.f_kw_sparams -43 (return %₄₂) +46 latestworld +47 TestMod.f_kw_sparams +48 (return %₄₇) ######################################## # Error: Static parameter which is unused in keyword body arg types @@ -1363,31 +1459,35 @@ end end #--------------------- 1 (method TestMod.f_only_generated) -2 (method TestMod.#f_only_generated@generator#0) -3 TestMod.#f_only_generated@generator#0 -4 (call core.Typeof %₃) -5 (call core.svec %₄ JuliaLowering.MacroContext core.Any core.Any core.Any) -6 (call core.svec) -7 SourceLocation::1:21 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +2 latestworld +3 (method TestMod.#f_only_generated@generator#0) +4 latestworld +5 TestMod.#f_only_generated@generator#0 +6 (call core.Typeof %₅) +7 (call core.svec %₆ JuliaLowering.MacroContext core.Any core.Any core.Any) +8 (call core.svec) +9 SourceLocation::1:21 +10 (call core.svec %₇ %₈ %₉) +11 --- method core.nothing %₁₀ slots: [slot₁/#self#(!read) slot₂/__context__(!read) slot₃/#self#(!read) slot₄/x(nospecialize) slot₅/y(nospecialize)] 1 TestMod.generator_code 2 (call %₁ slot₄/x slot₅/y) 3 (return %₂) -10 TestMod.f_only_generated -11 (call core.Typeof %₁₀) -12 (call core.svec %₁₁ core.Any core.Any) -13 (call core.svec) -14 SourceLocation::1:21 -15 (call core.svec %₁₂ %₁₃ %₁₄) -16 --- method core.nothing %₁₅ +12 latestworld +13 TestMod.f_only_generated +14 (call core.Typeof %₁₃) +15 (call core.svec %₁₄ core.Any core.Any) +16 (call core.svec) +17 SourceLocation::1:21 +18 (call core.svec %₁₅ %₁₆ %₁₇) +19 --- method core.nothing %₁₈ slots: [slot₁/#self#(!read) slot₂/x(!read) slot₃/y(!read)] 1 (meta :generated (new JuliaLowering.GeneratedFunctionStub TestMod.#f_only_generated@generator#0 SourceRef(SourceFile("@generated function f_only_generated(x, y)\n generator_code(x,y)\nend", 0, nothing, 1, [1, 44, 68, 71]), 1, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"macrocall", 0x0000), 0x00000046, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"@", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"MacroName", 0x0000), 0x00000009, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"function", 0x0000), 0x0000003b, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"function", 0x0001), 0x00000008, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"call", 0x0000), 0x00000016, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000010, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"(", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K",", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K")", 0x0001), 0x00000001, nothing)]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"block", 0x0000), 0x00000019, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"NewlineWs", 0x0001), 0x00000005, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"call", 0x0000), 0x00000013, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x0000000e, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"(", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K",", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K")", 0x0001), 0x00000001, nothing)]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"NewlineWs", 0x0001), 0x00000001, nothing)]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"end", 0x0001), 0x00000003, nothing)])])) (call core.svec :#self# :x :y) (call core.svec))) 2 (meta :generated_only) 3 (return core.nothing) -17 TestMod.f_only_generated -18 (return %₁₇) +20 latestworld +21 TestMod.f_only_generated +22 (return %₂₁) ######################################## # Partially generated function with `if @generated` @@ -1404,26 +1504,29 @@ function f_partially_generated(x, y) end #--------------------- 1 (method TestMod.f_partially_generated) -2 (method TestMod.#f_partially_generated@generator#0) -3 TestMod.#f_partially_generated@generator#0 -4 (call core.Typeof %₃) -5 (call core.svec %₄ JuliaLowering.MacroContext core.Any core.Any core.Any) -6 (call core.svec) -7 SourceLocation::1:10 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +2 latestworld +3 (method TestMod.#f_partially_generated@generator#0) +4 latestworld +5 TestMod.#f_partially_generated@generator#0 +6 (call core.Typeof %₅) +7 (call core.svec %₆ JuliaLowering.MacroContext core.Any core.Any core.Any) +8 (call core.svec) +9 SourceLocation::1:10 +10 (call core.svec %₇ %₈ %₉) +11 --- method core.nothing %₁₀ slots: [slot₁/#self#(!read) slot₂/__context__(!read) slot₃/#self#(!read) slot₄/x(nospecialize,!read) slot₅/y(nospecialize,!read)] 1 (call JuliaLowering.interpolate_ast (inert (block (= maybe_gen_stuff (call some_gen_stuff x y))))) 2 (call core.tuple %₁) 3 (call JuliaLowering.interpolate_ast (inert (block (block (= nongen_stuff (call bothgen x y)) ($ (block (call JuliaLowering.interpolate_ast (inert (block (= maybe_gen_stuff (call some_gen_stuff x y))))))) (tuple-p nongen_stuff maybe_gen_stuff)))) %₂) 4 (return %₃) -10 TestMod.f_partially_generated -11 (call core.Typeof %₁₀) -12 (call core.svec %₁₁ core.Any core.Any) -13 (call core.svec) -14 SourceLocation::1:10 -15 (call core.svec %₁₂ %₁₃ %₁₄) -16 --- method core.nothing %₁₅ +12 latestworld +13 TestMod.f_partially_generated +14 (call core.Typeof %₁₃) +15 (call core.svec %₁₄ core.Any core.Any) +16 (call core.svec) +17 SourceLocation::1:10 +18 (call core.svec %₁₅ %₁₆ %₁₇) +19 --- method core.nothing %₁₈ slots: [slot₁/#self#(!read) slot₂/x slot₃/y slot₄/maybe_gen_stuff slot₅/nongen_stuff] 1 (meta :generated (new JuliaLowering.GeneratedFunctionStub TestMod.#f_partially_generated@generator#0 SourceRef(SourceFile("function f_partially_generated(x, y)\n nongen_stuff = bothgen(x, y)\n if @generated\n quote\n maybe_gen_stuff = some_gen_stuff(x, y)\n end\n else\n maybe_gen_stuff = some_nongen_stuff(x, y)\n end\n (nongen_stuff, maybe_gen_stuff)\nend", 0, nothing, 1, [1, 38, 71, 89, 103, 154, 166, 175, 225, 233, 269, 272]), 1, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"function", 0x0000), 0x0000010f, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"function", 0x0001), 0x00000008, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"call", 0x0000), 0x0000001b, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000015, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"(", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K",", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K")", 0x0001), 0x00000001, nothing)]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"block", 0x0000), 0x000000e8, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"NewlineWs", 0x0001), 0x00000005, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"=", 0x0000), 0x0000001c, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x0000000c, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"=", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"call", 0x0000), 0x0000000d, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000007, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"(", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K",", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K")", 0x0001), 0x00000001, nothing)])]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"NewlineWs", 0x0001), 0x00000005, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"if", 0x0000), 0x0000009d, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"if", 0x0001), 0x00000002, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"macrocall", 0x0000), 0x0000000a, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"@", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"MacroName", 0x0000), 0x00000009, nothing)]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"block", 0x0000), 0x00000052, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"NewlineWs", 0x0001), 0x00000009, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"quote", 0x0000), 0x00000044, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"block", 0x0000), 0x00000044, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"quote", 0x0001), 0x00000005, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"NewlineWs", 0x0001), 0x0000000d, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"=", 0x0000), 0x00000026, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x0000000f, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"=", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"call", 0x0000), 0x00000014, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x0000000e, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"(", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K",", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K")", 0x0001), 0x00000001, nothing)])]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"NewlineWs", 0x0001), 0x00000009, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"end", 0x0001), 0x00000003, nothing)])]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"NewlineWs", 0x0001), 0x00000005, nothing)]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"else", 0x0001), 0x00000004, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"block", 0x0000), 0x00000037, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"NewlineWs", 0x0001), 0x00000009, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"=", 0x0000), 0x00000029, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x0000000f, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"=", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"call", 0x0000), 0x00000017, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000011, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"(", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K",", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K")", 0x0001), 0x00000001, nothing)])]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"NewlineWs", 0x0001), 0x00000005, nothing)]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"end", 0x0001), 0x00000003, nothing)]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"NewlineWs", 0x0001), 0x00000005, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"tuple", 0x0020), 0x0000001f, JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}[JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"(", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x0000000c, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K",", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Whitespace", 0x0001), 0x00000001, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"Identifier", 0x0000), 0x0000000f, nothing), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K")", 0x0001), 0x00000001, nothing)]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"NewlineWs", 0x0001), 0x00000001, nothing)]), JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K"end", 0x0001), 0x00000003, nothing)])) (call core.svec :#self# :x :y) (call core.svec))) 2 TestMod.bothgen @@ -1434,6 +1537,7 @@ end 7 slot₄/maybe_gen_stuff 8 (call core.tuple %₆ %₇) 9 (return %₈) -17 TestMod.f_partially_generated -18 (return %₁₇) +20 latestworld +21 TestMod.f_partially_generated +22 (return %₂₁) diff --git a/test/generators_ir.jl b/test/generators_ir.jl index 22b2a3ab..7ab7e182 100644 --- a/test/generators_ir.jl +++ b/test/generators_ir.jl @@ -5,21 +5,23 @@ 1 (call core.svec) 2 (call core.svec) 3 (call JuliaLowering.eval_closure_type TestMod :#->##0 %₁ %₂) -4 TestMod.#->##0 -5 (call core.svec %₄ core.Any) -6 (call core.svec) -7 SourceLocation::1:2 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +4 latestworld +5 TestMod.#->##0 +6 (call core.svec %₅ core.Any) +7 (call core.svec) +8 SourceLocation::1:2 +9 (call core.svec %₆ %₇ %₈) +10 --- method core.nothing %₉ slots: [slot₁/#self#(!read) slot₂/x] 1 TestMod.+ 2 (call %₁ slot₂/x 1) 3 (return %₂) -10 TestMod.#->##0 -11 (new %₁₀) -12 TestMod.xs -13 (call top.Generator %₁₁ %₁₂) -14 (return %₁₃) +11 latestworld +12 TestMod.#->##0 +13 (new %₁₂) +14 TestMod.xs +15 (call top.Generator %₁₃ %₁₄) +16 (return %₁₅) ######################################## # Product iteration @@ -28,12 +30,13 @@ 1 (call core.svec) 2 (call core.svec) 3 (call JuliaLowering.eval_closure_type TestMod :#->##1 %₁ %₂) -4 TestMod.#->##1 -5 (call core.svec %₄ core.Any) -6 (call core.svec) -7 SourceLocation::1:2 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +4 latestworld +5 TestMod.#->##1 +6 (call core.svec %₅ core.Any) +7 (call core.svec) +8 SourceLocation::1:2 +9 (call core.svec %₆ %₇ %₈) +10 --- method core.nothing %₉ slots: [slot₁/#self#(!read) slot₂/destructured_arg slot₃/iterstate slot₄/x slot₅/y] 1 (call top.indexed_iterate slot₂/destructured_arg 1) 2 (= slot₄/x (call core.getfield %₁ 1)) @@ -46,13 +49,14 @@ 9 slot₅/y 10 (call %₇ %₈ %₉) 11 (return %₁₀) -10 TestMod.#->##1 -11 (new %₁₀) -12 TestMod.xs -13 TestMod.ys -14 (call top.product %₁₂ %₁₃) -15 (call top.Generator %₁₁ %₁₄) -16 (return %₁₅) +11 latestworld +12 TestMod.#->##1 +13 (new %₁₂) +14 TestMod.xs +15 TestMod.ys +16 (call top.product %₁₄ %₁₅) +17 (call top.Generator %₁₃ %₁₆) +18 (return %₁₇) ######################################## # Use `identity` as the Generator function when possible eg in filters @@ -61,12 +65,13 @@ 1 (call core.svec) 2 (call core.svec) 3 (call JuliaLowering.eval_closure_type TestMod :#->##2 %₁ %₂) -4 TestMod.#->##2 -5 (call core.svec %₄ core.Any) -6 (call core.svec) -7 SourceLocation::1:29 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +4 latestworld +5 TestMod.#->##2 +6 (call core.svec %₅ core.Any) +7 (call core.svec) +8 SourceLocation::1:29 +9 (call core.svec %₆ %₇ %₈) +10 --- method core.nothing %₉ slots: [slot₁/#self#(!read) slot₂/destructured_arg slot₃/iterstate slot₄/x slot₅/y(!read)] 1 (call top.indexed_iterate slot₂/destructured_arg 1) 2 (= slot₄/x (call core.getfield %₁ 1)) @@ -78,12 +83,13 @@ 8 slot₄/x 9 (call %₇ %₈) 10 (return %₉) -10 TestMod.#->##2 -11 (new %₁₀) -12 TestMod.iter -13 (call top.Filter %₁₁ %₁₂) -14 (call top.Generator top.identity %₁₃) -15 (return %₁₄) +11 latestworld +12 TestMod.#->##2 +13 (new %₁₂) +14 TestMod.iter +15 (call top.Filter %₁₃ %₁₄) +16 (call top.Generator top.identity %₁₅) +17 (return %₁₆) ######################################## # Use of placeholders in iteration vars @@ -92,19 +98,21 @@ 1 (call core.svec) 2 (call core.svec) 3 (call JuliaLowering.eval_closure_type TestMod :#->##3 %₁ %₂) -4 TestMod.#->##3 -5 (call core.svec %₄ core.Any) -6 (call core.svec) -7 SourceLocation::1:2 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +4 latestworld +5 TestMod.#->##3 +6 (call core.svec %₅ core.Any) +7 (call core.svec) +8 SourceLocation::1:2 +9 (call core.svec %₆ %₇ %₈) +10 --- method core.nothing %₉ slots: [slot₁/#self#(!read) slot₂/_(!read)] 1 (return 1) -10 TestMod.#->##3 -11 (new %₁₀) -12 TestMod.xs -13 (call top.Generator %₁₁ %₁₂) -14 (return %₁₃) +11 latestworld +12 TestMod.#->##3 +13 (new %₁₂) +14 TestMod.xs +15 (call top.Generator %₁₃ %₁₄) +16 (return %₁₅) ######################################## # Error: Use of placeholders in body @@ -121,12 +129,13 @@ LoweringError: 1 (call core.svec) 2 (call core.svec) 3 (call JuliaLowering.eval_closure_type TestMod :#->##5 %₁ %₂) -4 TestMod.#->##5 -5 (call core.svec %₄ core.Any) -6 (call core.svec) -7 SourceLocation::1:2 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +4 latestworld +5 TestMod.#->##5 +6 (call core.svec %₅ core.Any) +7 (call core.svec) +8 SourceLocation::1:2 +9 (call core.svec %₆ %₇ %₈) +10 --- method core.nothing %₉ slots: [slot₁/#self#(!read) slot₂/destructured_arg slot₃/iterstate slot₄/x(!read) slot₅/y(!read)] 1 (call top.indexed_iterate slot₂/destructured_arg 1) 2 (= slot₄/x (call core.getfield %₁ 1)) @@ -140,11 +149,12 @@ LoweringError: 10 (= slot₅/y (call core.getfield %₉ 1)) 11 TestMod.body 12 (return %₁₁) -10 TestMod.#->##5 -11 (new %₁₀) -12 TestMod.iter -13 (call top.Generator %₁₁ %₁₂) -14 (return %₁₃) +11 latestworld +12 TestMod.#->##5 +13 (new %₁₂) +14 TestMod.iter +15 (call top.Generator %₁₃ %₁₄) +16 (return %₁₅) ######################################## # return permitted in quoted syntax in generator @@ -153,20 +163,22 @@ LoweringError: 1 (call core.svec) 2 (call core.svec) 3 (call JuliaLowering.eval_closure_type TestMod :#->##6 %₁ %₂) -4 TestMod.#->##6 -5 (call core.svec %₄ core.Any) -6 (call core.svec) -7 SourceLocation::1:4 -8 (call core.svec %₅ %₆ %₇) -9 --- method core.nothing %₈ +4 latestworld +5 TestMod.#->##6 +6 (call core.svec %₅ core.Any) +7 (call core.svec) +8 SourceLocation::1:4 +9 (call core.svec %₆ %₇ %₈) +10 --- method core.nothing %₉ slots: [slot₁/#self#(!read) slot₂/_(!read)] 1 (call JuliaLowering.interpolate_ast (inert (return x))) 2 (return %₁) -10 TestMod.#->##6 -11 (new %₁₀) -12 TestMod.iter -13 (call top.Generator %₁₁ %₁₂) -14 (return %₁₃) +11 latestworld +12 TestMod.#->##6 +13 (new %₁₂) +14 TestMod.iter +15 (call top.Generator %₁₃ %₁₄) +16 (return %₁₅) ######################################## # Error: `return` not permitted in generator body @@ -183,26 +195,29 @@ LoweringError: 1 (call core.svec) 2 (call core.svec) 3 (call JuliaLowering.eval_closure_type TestMod :#->##7 %₁ %₂) -4 (call core.svec) +4 latestworld 5 (call core.svec) -6 (call JuliaLowering.eval_closure_type TestMod :#->#->##0 %₄ %₅) -7 TestMod.#->#->##0 -8 (call core.svec %₇ core.Any) -9 (call core.svec) -10 SourceLocation::1:2 -11 (call core.svec %₈ %₉ %₁₀) -12 --- method core.nothing %₁₁ +6 (call core.svec) +7 (call JuliaLowering.eval_closure_type TestMod :#->#->##0 %₅ %₆) +8 latestworld +9 TestMod.#->#->##0 +10 (call core.svec %₉ core.Any) +11 (call core.svec) +12 SourceLocation::1:2 +13 (call core.svec %₁₀ %₁₁ %₁₂) +14 --- method core.nothing %₁₃ slots: [slot₁/#self#(!read) slot₂/x slot₃/x] 1 slot₂/x 2 (= slot₃/x %₁) 3 slot₃/x 4 (return %₃) -13 TestMod.#->##7 -14 (call core.svec %₁₃ core.Any) -15 (call core.svec) -16 SourceLocation::1:2 -17 (call core.svec %₁₄ %₁₅ %₁₆) -18 --- method core.nothing %₁₇ +15 latestworld +16 TestMod.#->##7 +17 (call core.svec %₁₆ core.Any) +18 (call core.svec) +19 SourceLocation::1:2 +20 (call core.svec %₁₇ %₁₈ %₁₉) +21 --- method core.nothing %₂₀ slots: [slot₁/#self#(!read) slot₂/x(!read)] 1 TestMod.#->#->##0 2 (new %₁) @@ -210,13 +225,14 @@ LoweringError: 4 (call %₃ 1 2) 5 (call top.Generator %₂ %₄) 6 (return %₅) -19 TestMod.#->##7 -20 (new %₁₉) -21 TestMod.: -22 (call %₂₁ 1 3) -23 (call top.Generator %₂₀ %₂₂) -24 (call top.Flatten %₂₃) -25 (return %₂₄) +22 latestworld +23 TestMod.#->##7 +24 (new %₂₃) +25 TestMod.: +26 (call %₂₅ 1 3) +27 (call top.Generator %₂₄ %₂₆) +28 (call top.Flatten %₂₇) +29 (return %₂₈) ######################################## # Comprehension lowers to generator with collect diff --git a/test/macros_ir.jl b/test/macros_ir.jl index e1c6460c..65de7733 100644 --- a/test/macros_ir.jl +++ b/test/macros_ir.jl @@ -25,19 +25,21 @@ macro add_one(ex) end #--------------------- 1 (method TestMod.@add_one) -2 TestMod.@add_one -3 (call core.Typeof %₂) -4 (call core.svec %₃ JuliaLowering.MacroContext core.Any) -5 (call core.svec) -6 SourceLocation::1:7 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.@add_one +4 (call core.Typeof %₃) +5 (call core.svec %₄ JuliaLowering.MacroContext core.Any) +6 (call core.svec) +7 SourceLocation::1:7 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(!read) slot₂/__context__(!read) slot₃/ex] 1 (call core.tuple slot₃/ex) 2 (call JuliaLowering.interpolate_ast (inert (block (call-i ($ ex) + 1))) %₁) 3 (return %₂) -9 TestMod.@add_one -10 (return %₉) +10 latestworld +11 TestMod.@add_one +12 (return %₁₁) ######################################## # Macro using `__context__` @@ -46,19 +48,21 @@ macro foo(ex) end #--------------------- 1 (method TestMod.@foo) -2 TestMod.@foo -3 (call core.Typeof %₂) -4 (call core.svec %₃ JuliaLowering.MacroContext core.Any) -5 (call core.svec) -6 SourceLocation::1:7 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.@foo +4 (call core.Typeof %₃) +5 (call core.svec %₄ JuliaLowering.MacroContext core.Any) +6 (call core.svec) +7 SourceLocation::1:7 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(!read) slot₂/__context__ slot₃/ex(!read) slot₄/ctx(!read)] 1 slot₂/__context__ 2 (= slot₄/ctx %₁) 3 (return %₁) -9 TestMod.@foo -10 (return %₉) +10 latestworld +11 TestMod.@foo +12 (return %₁₁) ######################################## # Scope for symbols emitted by macros is the module where the method was diff --git a/test/misc.jl b/test/misc.jl index 90bc32cc..c391f0cc 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -46,4 +46,12 @@ cf_float = JuliaLowering.include_string(test_mod, """ """) @test @ccall($cf_float(2::Float64, 3::Float64)::Float64) == 32.0 +@testset "CodeInfo: has_image_globalref" begin + elower(mod, s) = JuliaLowering.to_lowered_expr( + mod, JuliaLowering.lower( + mod, parsestmt(JuliaLowering.SyntaxTree, s))) + @test elower(test_mod, "x + y").args[1].has_image_globalref === false + @test elower(Main, "x + y").args[1].has_image_globalref === true +end + end diff --git a/test/misc_ir.jl b/test/misc_ir.jl index d073cf97..15fa0229 100644 --- a/test/misc_ir.jl +++ b/test/misc_ir.jl @@ -390,3 +390,12 @@ LoweringError: x... └──┘ ── `...` expression outside call +######################################## +# `include` should increment world age +include("hi.jl") +#--------------------- +1 TestMod.include +2 (call %₁ "hi.jl") +3 latestworld +4 (return %₂) + diff --git a/test/modules.jl b/test/modules.jl index 66595ee6..97cb536f 100644 --- a/test/modules.jl +++ b/test/modules.jl @@ -13,7 +13,8 @@ end @test A.g() == "hi" @test A.include isa Function @test A.Base === Base -@test A.eval(:(x = -1)) == -1 && A.x == -1 +@test A.eval(:(x = -1)) == -1 +@test A.x == -1 B = JuliaLowering.include_string(test_mod, """ baremodule B diff --git a/test/quoting.jl b/test/quoting.jl index 0d747654..32b91730 100644 --- a/test/quoting.jl +++ b/test/quoting.jl @@ -47,6 +47,22 @@ end end end # @ string:5""" +@test sprint(io->showprov(io, ex[1][3]; note="foo")) == raw""" + begin + x = 10 + y = :(g(z)) + # └──┘ ── foo + quote + f($(x+1), $y) + # @ string:3 + + y = :(g(z)) + quote + f($(x+1), $y) + # └┘ ── foo + end + end + # @ string:5""" # Test expression flags are preserved during interpolation diff --git a/test/scopes_ir.jl b/test/scopes_ir.jl index c0013a39..da1f3529 100644 --- a/test/scopes_ir.jl +++ b/test/scopes_ir.jl @@ -73,19 +73,21 @@ end 1 (call core.svec) 2 (call core.svec) 3 (call JuliaLowering.eval_closure_type TestMod :#f##0 %₁ %₂) -4 TestMod.#f##0 -5 (new %₄) -6 (= slot₁/f %₅) -7 TestMod.#f##0 -8 (call core.svec %₇) -9 (call core.svec) -10 SourceLocation::1:5 -11 (call core.svec %₈ %₉ %₁₀) -12 --- method core.nothing %₁₁ +4 latestworld +5 TestMod.#f##0 +6 (new %₅) +7 (= slot₁/f %₆) +8 TestMod.#f##0 +9 (call core.svec %₈) +10 (call core.svec) +11 SourceLocation::1:5 +12 (call core.svec %₉ %₁₀ %₁₁) +13 --- method core.nothing %₁₂ slots: [slot₁/#self#(!read)] 1 TestMod.body 2 (return %₁) -13 (return core.nothing) +14 latestworld +15 (return core.nothing) ######################################## # Error: Invalid `let` var with K"::" @@ -142,18 +144,20 @@ end 3 slot₁/y 4 (call core.setfield! %₃ :contents %₂) 5 (method TestMod.f) -6 TestMod.f -7 (call core.Typeof %₆) -8 (call core.svec %₇ core.Any) -9 (call core.svec) -10 SourceLocation::3:14 -11 (call core.svec %₈ %₉ %₁₀) -12 --- method core.nothing %₁₁ +6 latestworld +7 TestMod.f +8 (call core.Typeof %₇) +9 (call core.svec %₈ core.Any) +10 (call core.svec) +11 SourceLocation::3:14 +12 (call core.svec %₉ %₁₀ %₁₁) +13 --- method core.nothing %₁₂ slots: [slot₁/#self#(!read) slot₂/x(!read)] 1 (call core.tuple false true true) 2 (return %₁) -13 TestMod.f -14 (return %₁₃) +14 latestworld +15 TestMod.f +16 (return %₁₅) ######################################## # @islocal with global @@ -163,7 +167,8 @@ begin end #--------------------- 1 (global TestMod.x) -2 (return false) +2 latestworld +3 (return false) ######################################## # @locals with local and global @@ -175,13 +180,14 @@ end #--------------------- 1 (newvar slot₁/y) 2 (global TestMod.x) -3 (call core.apply_type top.Dict core.Symbol core.Any) -4 (call %₃) -5 (isdefined slot₁/y) -6 (gotoifnot %₅ label₉) -7 slot₁/y -8 (call top.setindex! %₄ %₇ :y) -9 (return %₄) +3 latestworld +4 (call core.apply_type top.Dict core.Symbol core.Any) +5 (call %₄) +6 (isdefined slot₁/y) +7 (gotoifnot %₆ label₁₀) +8 slot₁/y +9 (call top.setindex! %₅ %₈ :y) +10 (return %₅) ######################################## # @locals with function args (TODO: static parameters) @@ -190,21 +196,23 @@ function f(z) end #--------------------- 1 (method TestMod.f) -2 TestMod.f -3 (call core.Typeof %₂) -4 (call core.svec %₃ core.Any) -5 (call core.svec) -6 SourceLocation::1:10 -7 (call core.svec %₄ %₅ %₆) -8 --- method core.nothing %₇ +2 latestworld +3 TestMod.f +4 (call core.Typeof %₃) +5 (call core.svec %₄ core.Any) +6 (call core.svec) +7 SourceLocation::1:10 +8 (call core.svec %₅ %₆ %₇) +9 --- method core.nothing %₈ slots: [slot₁/#self#(!read) slot₂/z] 1 (call core.apply_type top.Dict core.Symbol core.Any) 2 (call %₁) 3 (gotoifnot true label₅) 4 (call top.setindex! %₂ slot₂/z :z) 5 (return %₂) -9 TestMod.f -10 (return %₉) +10 latestworld +11 TestMod.f +12 (return %₁₁) ######################################## # Error: Duplicate function argument names @@ -267,7 +275,7 @@ LoweringError: let local x global x -# └──────┘ ── Variable `x` declared both local and global +# ╙ ── Variable `x` declared both local and global end ######################################## @@ -279,7 +287,7 @@ end LoweringError: function f(x) local x -# └─────┘ ── local variable name `x` conflicts with an argument +# ╙ ── local variable name `x` conflicts with an argument end ######################################## @@ -291,7 +299,7 @@ end LoweringError: function f(x) global x -# └──────┘ ── global variable name `x` conflicts with an argument +# ╙ ── global variable name `x` conflicts with an argument end ######################################## @@ -304,7 +312,7 @@ end LoweringError: function f((x,)) global x -# └──────┘ ── Variable `x` declared both local and global +# ╙ ── Variable `x` declared both local and global end ######################################## @@ -316,7 +324,7 @@ end LoweringError: function f(::T) where T local T -# └─────┘ ── local variable name `T` conflicts with a static parameter +# ╙ ── local variable name `T` conflicts with a static parameter end ######################################## @@ -328,7 +336,7 @@ end LoweringError: function f(::T) where T global T -# └──────┘ ── global variable name `T` conflicts with a static parameter +# ╙ ── global variable name `T` conflicts with a static parameter end ######################################## @@ -343,7 +351,7 @@ LoweringError: function f(::T) where T let local T -# └─────┘ ── local variable name `T` conflicts with a static parameter +# ╙ ── local variable name `T` conflicts with a static parameter end end @@ -359,7 +367,7 @@ LoweringError: function f(::T) where T let global T -# └──────┘ ── global variable name `T` conflicts with a static parameter +# ╙ ── global variable name `T` conflicts with a static parameter end end @@ -418,6 +426,6 @@ end #--------------------- 1 1 2 (= slot₁/x %₁) -3 (isdefined TestMod.y) +3 (call core.isdefinedglobal TestMod :y false) 4 (return %₃) diff --git a/test/typedefs.jl b/test/typedefs.jl index d2f0594b..be509eeb 100644 --- a/test/typedefs.jl +++ b/test/typedefs.jl @@ -251,12 +251,13 @@ end """) @test fieldtypes(test_mod.M36104.T36104) == (Vector{test_mod.M36104.T36104},) @test_throws ErrorException("expected") JuliaLowering.include_string(test_mod, """struct X36104; x::error("expected"); end""") -@test isdefined(test_mod, :X36104) +@test !isdefined(test_mod, :X36104) JuliaLowering.include_string(test_mod, "struct X36104; x::Int; end") @test fieldtypes(test_mod.X36104) == (Int,) JuliaLowering.include_string(test_mod, "primitive type P36104 8 end") -@test_throws ErrorException("invalid redefinition of constant TestMod.P36104") #= - =# JuliaLowering.include_string(test_mod, "primitive type P36104 16 end") +JuliaLowering.include_string(test_mod, "const orig_P36104 = P36104") +JuliaLowering.include_string(test_mod, "primitive type P36104 16 end") +@test test_mod.P36104 !== test_mod.orig_P36104 # Struct with outer constructor where one typevar is constrained by the other # See https://github.com/JuliaLang/julia/issues/27269) diff --git a/test/typedefs_ir.jl b/test/typedefs_ir.jl index 14f0b1cc..0785a8f2 100644 --- a/test/typedefs_ir.jl +++ b/test/typedefs_ir.jl @@ -191,17 +191,19 @@ abstract type A end 2 (call core._abstracttype TestMod :A %₁) 3 (= slot₁/A %₂) 4 (call core._setsuper! %₂ core.Any) -5 (call core._typebody! %₂) -6 (global TestMod.A) -7 (const TestMod.A) -8 (isdefined TestMod.A) -9 (gotoifnot %₈ label₁₄) -10 TestMod.A -11 (call core._equiv_typedef %₁₀ %₂) -12 (gotoifnot %₁₁ label₁₄) -13 (goto label₁₅) -14 (= TestMod.A %₂) -15 (return core.nothing) +5 slot₁/A +6 (call core._typebody! false %₅) +7 (global TestMod.A) +8 latestworld +9 (call core.isdefinedglobal TestMod :A false) +10 (gotoifnot %₉ label₁₅) +11 TestMod.A +12 (call core._equiv_typedef %₁₁ %₂) +13 (gotoifnot %₁₂ label₁₅) +14 (goto label₁₇) +15 (constdecl TestMod.A %₂) +16 latestworld +17 (return core.nothing) ######################################## # Abstract type definition with supertype @@ -212,17 +214,19 @@ abstract type A <: B end 3 (= slot₁/A %₂) 4 TestMod.B 5 (call core._setsuper! %₂ %₄) -6 (call core._typebody! %₂) -7 (global TestMod.A) -8 (const TestMod.A) -9 (isdefined TestMod.A) -10 (gotoifnot %₉ label₁₅) -11 TestMod.A -12 (call core._equiv_typedef %₁₁ %₂) -13 (gotoifnot %₁₂ label₁₅) -14 (goto label₁₆) -15 (= TestMod.A %₂) -16 (return core.nothing) +6 slot₁/A +7 (call core._typebody! false %₆) +8 (global TestMod.A) +9 latestworld +10 (call core.isdefinedglobal TestMod :A false) +11 (gotoifnot %₁₀ label₁₆) +12 TestMod.A +13 (call core._equiv_typedef %₁₂ %₂) +14 (gotoifnot %₁₃ label₁₆) +15 (goto label₁₈) +16 (constdecl TestMod.A %₂) +17 latestworld +18 (return core.nothing) ######################################## # Abstract type definition with multiple typevars @@ -237,17 +241,19 @@ abstract type A{X, Y <: X} end 7 (call core._abstracttype TestMod :A %₆) 8 (= slot₁/A %₇) 9 (call core._setsuper! %₇ core.Any) -10 (call core._typebody! %₇) -11 (global TestMod.A) -12 (const TestMod.A) -13 (isdefined TestMod.A) -14 (gotoifnot %₁₃ label₁₉) -15 TestMod.A -16 (call core._equiv_typedef %₁₅ %₇) -17 (gotoifnot %₁₆ label₁₉) -18 (goto label₂₀) -19 (= TestMod.A %₇) -20 (return core.nothing) +10 slot₁/A +11 (call core._typebody! false %₁₀) +12 (global TestMod.A) +13 latestworld +14 (call core.isdefinedglobal TestMod :A false) +15 (gotoifnot %₁₄ label₂₀) +16 TestMod.A +17 (call core._equiv_typedef %₁₆ %₇) +18 (gotoifnot %₁₇ label₂₀) +19 (goto label₂₂) +20 (constdecl TestMod.A %₇) +21 latestworld +22 (return core.nothing) ######################################## # Error: Abstract type definition with bad signature @@ -293,17 +299,19 @@ primitive type P 8 end 2 (call core._primitivetype TestMod :P %₁ 8) 3 (= slot₁/P %₂) 4 (call core._setsuper! %₂ core.Any) -5 (call core._typebody! %₂) -6 (global TestMod.P) -7 (const TestMod.P) -8 (isdefined TestMod.P) -9 (gotoifnot %₈ label₁₄) -10 TestMod.P -11 (call core._equiv_typedef %₁₀ %₂) -12 (gotoifnot %₁₁ label₁₄) -13 (goto label₁₅) -14 (= TestMod.P %₂) -15 (return core.nothing) +5 slot₁/P +6 (call core._typebody! false %₅) +7 (global TestMod.P) +8 latestworld +9 (call core.isdefinedglobal TestMod :P false) +10 (gotoifnot %₉ label₁₅) +11 TestMod.P +12 (call core._equiv_typedef %₁₁ %₂) +13 (gotoifnot %₁₂ label₁₅) +14 (goto label₁₇) +15 (constdecl TestMod.P %₂) +16 latestworld +17 (return core.nothing) ######################################## # Complex primitive type definition @@ -318,17 +326,19 @@ primitive type P{X,Y} <: Z 32 end 7 (= slot₁/P %₆) 8 TestMod.Z 9 (call core._setsuper! %₆ %₈) -10 (call core._typebody! %₆) -11 (global TestMod.P) -12 (const TestMod.P) -13 (isdefined TestMod.P) -14 (gotoifnot %₁₃ label₁₉) -15 TestMod.P -16 (call core._equiv_typedef %₁₅ %₆) -17 (gotoifnot %₁₆ label₁₉) -18 (goto label₂₀) -19 (= TestMod.P %₆) -20 (return core.nothing) +10 slot₁/P +11 (call core._typebody! false %₁₀) +12 (global TestMod.P) +13 latestworld +14 (call core.isdefinedglobal TestMod :P false) +15 (gotoifnot %₁₄ label₂₀) +16 TestMod.P +17 (call core._equiv_typedef %₁₆ %₆) +18 (gotoifnot %₁₇ label₂₀) +19 (goto label₂₂) +20 (constdecl TestMod.P %₆) +21 latestworld +22 (return core.nothing) ######################################## # Primitive type definition with computed size (should this be allowed??) @@ -340,17 +350,19 @@ primitive type P P_nbits() end 4 (call core._primitivetype TestMod :P %₁ %₃) 5 (= slot₁/P %₄) 6 (call core._setsuper! %₄ core.Any) -7 (call core._typebody! %₄) -8 (global TestMod.P) -9 (const TestMod.P) -10 (isdefined TestMod.P) -11 (gotoifnot %₁₀ label₁₆) -12 TestMod.P -13 (call core._equiv_typedef %₁₂ %₄) -14 (gotoifnot %₁₃ label₁₆) -15 (goto label₁₇) -16 (= TestMod.P %₄) -17 (return core.nothing) +7 slot₁/P +8 (call core._typebody! false %₇) +9 (global TestMod.P) +10 latestworld +11 (call core.isdefinedglobal TestMod :P false) +12 (gotoifnot %₁₁ label₁₇) +13 TestMod.P +14 (call core._equiv_typedef %₁₃ %₄) +15 (gotoifnot %₁₄ label₁₇) +16 (goto label₁₉) +17 (constdecl TestMod.P %₄) +18 latestworld +19 (return core.nothing) ######################################## # Empty struct @@ -358,41 +370,44 @@ struct X end #--------------------- 1 (global TestMod.X) -2 (const TestMod.X) +2 latestworld 3 (call core.svec) 4 (call core.svec) 5 (call core.svec) 6 (call core._structtype TestMod :X %₃ %₄ %₅ false 0) 7 (= slot₁/X %₆) 8 (call core._setsuper! %₆ core.Any) -9 (isdefined TestMod.X) -10 (gotoifnot %₉ label₂₀) +9 (call core.isdefinedglobal TestMod :X false) +10 (gotoifnot %₉ label₁₄) 11 TestMod.X -12 (call core._equiv_typedef %₁₁ %₆) -13 (gotoifnot %₁₂ label₁₇) -14 TestMod.X -15 (= slot₁/X %₁₄) -16 (goto label₁₉) -17 slot₁/X -18 (= TestMod.X %₁₇) -19 (goto label₂₂) -20 slot₁/X -21 (= TestMod.X %₂₀) -22 slot₁/X +12 (= slot₂/if_val (call core._equiv_typedef %₁₁ %₆)) +13 (goto label₁₅) +14 (= slot₂/if_val false) +15 slot₂/if_val +16 (gotoifnot %₁₅ label₂₀) +17 TestMod.X +18 (= slot₃/if_val %₁₇) +19 (goto label₂₁) +20 (= slot₃/if_val false) +21 slot₃/if_val +22 (gotoifnot %₁₅ label₂₃) 23 (call core.svec) -24 (call core._typebody! %₂₂ %₂₃) -25 TestMod.X -26 (call core.apply_type core.Type %₂₅) -27 (call core.svec %₂₆) -28 (call core.svec) -29 SourceLocation::1:1 -30 (call core.svec %₂₇ %₂₈ %₂₉) -31 --- method core.nothing %₃₀ +24 (call core._typebody! %₂₁ %₆ %₂₃) +25 (constdecl TestMod.X %₂₄) +26 latestworld +27 TestMod.X +28 (call core.apply_type core.Type %₂₇) +29 (call core.svec %₂₈) +30 (call core.svec) +31 SourceLocation::1:1 +32 (call core.svec %₂₉ %₃₀ %₃₁) +33 --- method core.nothing %₃₂ slots: [slot₁/#self#(!read)] 1 TestMod.X 2 (new %₁) 3 (return %₂) -32 (return core.nothing) +34 latestworld +35 (return core.nothing) ######################################## # Basic struct @@ -403,41 +418,43 @@ struct X end #--------------------- 1 (global TestMod.X) -2 (const TestMod.X) +2 latestworld 3 (call core.svec) 4 (call core.svec :a :b :c) 5 (call core.svec) 6 (call core._structtype TestMod :X %₃ %₄ %₅ false 3) 7 (= slot₁/X %₆) 8 (call core._setsuper! %₆ core.Any) -9 (isdefined TestMod.X) -10 (gotoifnot %₉ label₂₀) +9 (call core.isdefinedglobal TestMod :X false) +10 (gotoifnot %₉ label₁₄) 11 TestMod.X -12 (call core._equiv_typedef %₁₁ %₆) -13 (gotoifnot %₁₂ label₁₇) -14 TestMod.X -15 (= slot₁/X %₁₄) -16 (goto label₁₉) -17 slot₁/X -18 (= TestMod.X %₁₇) -19 (goto label₂₂) -20 slot₁/X -21 (= TestMod.X %₂₀) -22 slot₁/X +12 (= slot₂/if_val (call core._equiv_typedef %₁₁ %₆)) +13 (goto label₁₅) +14 (= slot₂/if_val false) +15 slot₂/if_val +16 (gotoifnot %₁₅ label₂₀) +17 TestMod.X +18 (= slot₃/if_val %₁₇) +19 (goto label₂₁) +20 (= slot₃/if_val false) +21 slot₃/if_val +22 (gotoifnot %₁₅ label₂₃) 23 TestMod.T 24 (call core.svec core.Any %₂₃ core.Any) -25 (call core._typebody! %₂₂ %₂₄) -26 TestMod.T -27 (call core.=== core.Any %₂₆) -28 (gotoifnot %₂₇ label₃₀) -29 (goto label₃₇) -30 TestMod.X -31 (call core.apply_type core.Type %₃₀) -32 (call core.svec %₃₁ core.Any core.Any core.Any) -33 (call core.svec) -34 SourceLocation::1:1 -35 (call core.svec %₃₂ %₃₃ %₃₄) -36 --- method core.nothing %₃₅ +25 (call core._typebody! %₂₁ %₆ %₂₄) +26 (constdecl TestMod.X %₂₅) +27 latestworld +28 TestMod.T +29 (call core.=== core.Any %₂₈) +30 (gotoifnot %₂₉ label₃₂) +31 (goto label₄₀) +32 TestMod.X +33 (call core.apply_type core.Type %₃₂) +34 (call core.svec %₃₃ core.Any core.Any core.Any) +35 (call core.svec) +36 SourceLocation::1:1 +37 (call core.svec %₃₄ %₃₅ %₃₆) +38 --- method core.nothing %₃₇ slots: [slot₁/#ctor-self# slot₂/a slot₃/b slot₄/c slot₅/tmp] 1 (call core.fieldtype slot₁/#ctor-self# 2) 2 slot₃/b @@ -451,19 +468,21 @@ end 10 slot₅/tmp 11 (new slot₁/#ctor-self# slot₂/a %₁₀ slot₄/c) 12 (return %₁₁) -37 TestMod.X -38 (call core.apply_type core.Type %₃₇) -39 TestMod.T -40 (call core.svec %₃₈ core.Any %₃₉ core.Any) -41 (call core.svec) -42 SourceLocation::1:1 -43 (call core.svec %₄₀ %₄₁ %₄₂) -44 --- method core.nothing %₄₃ +39 latestworld +40 TestMod.X +41 (call core.apply_type core.Type %₄₀) +42 TestMod.T +43 (call core.svec %₄₁ core.Any %₄₂ core.Any) +44 (call core.svec) +45 SourceLocation::1:1 +46 (call core.svec %₄₃ %₄₄ %₄₅) +47 --- method core.nothing %₄₆ slots: [slot₁/#self#(!read) slot₂/a slot₃/b slot₄/c] 1 TestMod.X 2 (new %₁ slot₂/a slot₃/b slot₄/c) 3 (return %₂) -45 (return core.nothing) +48 latestworld +49 (return core.nothing) ######################################## # Struct with supertype and type params @@ -471,7 +490,7 @@ struct X{U, S <: V <: T} <: Z end #--------------------- 1 (global TestMod.X) -2 (const TestMod.X) +2 latestworld 3 (= slot₂/U (call core.TypeVar :U)) 4 TestMod.S 5 TestMod.T @@ -485,50 +504,53 @@ end 13 (= slot₄/X %₁₂) 14 TestMod.Z 15 (call core._setsuper! %₁₂ %₁₄) -16 (isdefined TestMod.X) -17 (gotoifnot %₁₆ label₃₇) +16 (call core.isdefinedglobal TestMod :X false) +17 (gotoifnot %₁₆ label₂₁) 18 TestMod.X -19 (call core._equiv_typedef %₁₈ %₁₂) -20 (gotoifnot %₁₉ label₃₄) -21 TestMod.X -22 (= slot₄/X %₂₁) -23 TestMod.X -24 (call top.getproperty %₂₃ :body) -25 (call top.getproperty %₂₄ :body) -26 (call top.getproperty %₂₅ :parameters) -27 (call top.indexed_iterate %₂₆ 1) -28 (= slot₂/U (call core.getfield %₂₇ 1)) -29 (= slot₁/iterstate (call core.getfield %₂₇ 2)) -30 slot₁/iterstate -31 (call top.indexed_iterate %₂₆ 2 %₃₀) -32 (= slot₃/V (call core.getfield %₃₁ 1)) -33 (goto label₃₆) -34 slot₄/X -35 (= TestMod.X %₃₄) -36 (goto label₃₉) -37 slot₄/X -38 (= TestMod.X %₃₇) -39 slot₄/X +19 (= slot₅/if_val (call core._equiv_typedef %₁₈ %₁₂)) +20 (goto label₂₂) +21 (= slot₅/if_val false) +22 slot₅/if_val +23 (gotoifnot %₂₂ label₂₇) +24 TestMod.X +25 (= slot₆/if_val %₂₄) +26 (goto label₂₈) +27 (= slot₆/if_val false) +28 slot₆/if_val +29 (gotoifnot %₂₂ label₄₀) +30 TestMod.X +31 (call top.getproperty %₃₀ :body) +32 (call top.getproperty %₃₁ :body) +33 (call top.getproperty %₃₂ :parameters) +34 (call top.indexed_iterate %₃₃ 1) +35 (= slot₂/U (call core.getfield %₃₄ 1)) +36 (= slot₁/iterstate (call core.getfield %₃₄ 2)) +37 slot₁/iterstate +38 (call top.indexed_iterate %₃₃ 2 %₃₇) +39 (= slot₃/V (call core.getfield %₃₈ 1)) 40 (call core.svec) -41 (call core._typebody! %₃₉ %₄₀) -42 slot₂/U -43 slot₃/V -44 TestMod.X -45 slot₂/U -46 slot₃/V -47 (call core.apply_type %₄₄ %₄₅ %₄₆) -48 (call core.apply_type core.Type %₄₇) -49 (call core.UnionAll %₄₃ %₄₈) -50 (call core.UnionAll %₄₂ %₄₉) -51 (call core.svec %₅₀) -52 (call core.svec) -53 SourceLocation::1:1 -54 (call core.svec %₅₁ %₅₂ %₅₃) -55 --- method core.nothing %₅₄ +41 (call core._typebody! %₂₈ %₁₂ %₄₀) +42 (constdecl TestMod.X %₄₁) +43 latestworld +44 slot₂/U +45 slot₃/V +46 TestMod.X +47 slot₂/U +48 slot₃/V +49 (call core.apply_type %₄₆ %₄₇ %₄₈) +50 (call core.apply_type core.Type %₄₉) +51 (call core.UnionAll %₄₅ %₅₀) +52 (call core.UnionAll %₄₄ %₅₁) +53 (call core.svec %₅₂) +54 (call core.svec) +55 SourceLocation::1:1 +56 (call core.svec %₅₃ %₅₄ %₅₅) +57 --- method core.nothing %₅₆ slots: [slot₁/#ctor-self#] 1 (new slot₁/#ctor-self#) 2 (return %₁) -56 (return core.nothing) +58 latestworld +59 (return core.nothing) ######################################## # Struct with const and atomic fields @@ -539,41 +561,44 @@ struct X end #--------------------- 1 (global TestMod.X) -2 (const TestMod.X) +2 latestworld 3 (call core.svec) 4 (call core.svec :a :b :c) 5 (call core.svec 1 :const 2 :atomic 3 :atomic 3 :const) 6 (call core._structtype TestMod :X %₃ %₄ %₅ false 3) 7 (= slot₁/X %₆) 8 (call core._setsuper! %₆ core.Any) -9 (isdefined TestMod.X) -10 (gotoifnot %₉ label₂₀) +9 (call core.isdefinedglobal TestMod :X false) +10 (gotoifnot %₉ label₁₄) 11 TestMod.X -12 (call core._equiv_typedef %₁₁ %₆) -13 (gotoifnot %₁₂ label₁₇) -14 TestMod.X -15 (= slot₁/X %₁₄) -16 (goto label₁₉) -17 slot₁/X -18 (= TestMod.X %₁₇) -19 (goto label₂₂) -20 slot₁/X -21 (= TestMod.X %₂₀) -22 slot₁/X +12 (= slot₂/if_val (call core._equiv_typedef %₁₁ %₆)) +13 (goto label₁₅) +14 (= slot₂/if_val false) +15 slot₂/if_val +16 (gotoifnot %₁₅ label₂₀) +17 TestMod.X +18 (= slot₃/if_val %₁₇) +19 (goto label₂₁) +20 (= slot₃/if_val false) +21 slot₃/if_val +22 (gotoifnot %₁₅ label₂₃) 23 (call core.svec core.Any core.Any core.Any) -24 (call core._typebody! %₂₂ %₂₃) -25 TestMod.X -26 (call core.apply_type core.Type %₂₅) -27 (call core.svec %₂₆ core.Any core.Any core.Any) -28 (call core.svec) -29 SourceLocation::1:1 -30 (call core.svec %₂₇ %₂₈ %₂₉) -31 --- method core.nothing %₃₀ +24 (call core._typebody! %₂₁ %₆ %₂₃) +25 (constdecl TestMod.X %₂₄) +26 latestworld +27 TestMod.X +28 (call core.apply_type core.Type %₂₇) +29 (call core.svec %₂₈ core.Any core.Any core.Any) +30 (call core.svec) +31 SourceLocation::1:1 +32 (call core.svec %₂₉ %₃₀ %₃₁) +33 --- method core.nothing %₃₂ slots: [slot₁/#self#(!read) slot₂/a slot₃/b slot₄/c] 1 TestMod.X 2 (new %₁ slot₂/a slot₃/b slot₄/c) 3 (return %₂) -32 (return core.nothing) +34 latestworld +35 (return core.nothing) ######################################## # Documented struct @@ -588,50 +613,53 @@ struct X end #--------------------- 1 (global TestMod.X) -2 (const TestMod.X) +2 latestworld 3 (call core.svec) 4 (call core.svec :a :b) 5 (call core.svec) 6 (call core._structtype TestMod :X %₃ %₄ %₅ false 2) 7 (= slot₁/X %₆) 8 (call core._setsuper! %₆ core.Any) -9 (isdefined TestMod.X) -10 (gotoifnot %₉ label₂₀) +9 (call core.isdefinedglobal TestMod :X false) +10 (gotoifnot %₉ label₁₄) 11 TestMod.X -12 (call core._equiv_typedef %₁₁ %₆) -13 (gotoifnot %₁₂ label₁₇) -14 TestMod.X -15 (= slot₁/X %₁₄) -16 (goto label₁₉) -17 slot₁/X -18 (= TestMod.X %₁₇) -19 (goto label₂₂) -20 slot₁/X -21 (= TestMod.X %₂₀) -22 slot₁/X +12 (= slot₂/if_val (call core._equiv_typedef %₁₁ %₆)) +13 (goto label₁₅) +14 (= slot₂/if_val false) +15 slot₂/if_val +16 (gotoifnot %₁₅ label₂₀) +17 TestMod.X +18 (= slot₃/if_val %₁₇) +19 (goto label₂₁) +20 (= slot₃/if_val false) +21 slot₃/if_val +22 (gotoifnot %₁₅ label₂₃) 23 (call core.svec core.Any core.Any) -24 (call core._typebody! %₂₂ %₂₃) -25 TestMod.X -26 (call core.apply_type core.Type %₂₅) -27 (call core.svec %₂₆ core.Any core.Any) -28 (call core.svec) -29 SourceLocation::4:1 -30 (call core.svec %₂₇ %₂₈ %₂₉) -31 --- method core.nothing %₃₀ +24 (call core._typebody! %₂₁ %₆ %₂₃) +25 (constdecl TestMod.X %₂₄) +26 latestworld +27 TestMod.X +28 (call core.apply_type core.Type %₂₇) +29 (call core.svec %₂₈ core.Any core.Any) +30 (call core.svec) +31 SourceLocation::4:1 +32 (call core.svec %₂₉ %₃₀ %₃₁) +33 --- method core.nothing %₃₂ slots: [slot₁/#self#(!read) slot₂/a slot₃/b] 1 TestMod.X 2 (new %₁ slot₂/a slot₃/b) 3 (return %₂) -32 JuliaLowering.bind_docs! -33 (call core.tuple :field_docs) -34 (call core.apply_type core.NamedTuple %₃₃) -35 (call core.svec 1 "field a docs" 2 "field b docs") -36 (call core.tuple %₃₅) -37 (call %₃₄ %₃₆) -38 TestMod.X -39 SourceLocation::4:1 -40 (call core.kwcall %₃₇ %₃₂ %₃₈ "X docs\n" %₃₉) -41 (return core.nothing) +34 latestworld +35 JuliaLowering.bind_docs! +36 (call core.tuple :field_docs) +37 (call core.apply_type core.NamedTuple %₃₆) +38 (call core.svec 1 "field a docs" 2 "field b docs") +39 (call core.tuple %₃₈) +40 (call %₃₇ %₃₉) +41 TestMod.X +42 SourceLocation::4:1 +43 (call core.kwcall %₄₀ %₃₅ %₄₁ "X docs\n" %₄₂) +44 (return core.nothing) ######################################## # Struct with outer constructor @@ -640,7 +668,7 @@ struct X{U} end #--------------------- 1 (global TestMod.X) -2 (const TestMod.X) +2 latestworld 3 (= slot₁/U (call core.TypeVar :U)) 4 slot₁/U 5 (call core.svec %₄) @@ -649,39 +677,41 @@ end 8 (call core._structtype TestMod :X %₅ %₆ %₇ false 1) 9 (= slot₂/X %₈) 10 (call core._setsuper! %₈ core.Any) -11 (isdefined TestMod.X) -12 (gotoifnot %₁₁ label₂₇) +11 (call core.isdefinedglobal TestMod :X false) +12 (gotoifnot %₁₁ label₁₆) 13 TestMod.X -14 (call core._equiv_typedef %₁₃ %₈) -15 (gotoifnot %₁₄ label₂₄) -16 TestMod.X -17 (= slot₂/X %₁₆) -18 TestMod.X -19 (call top.getproperty %₁₈ :body) -20 (call top.getproperty %₁₉ :parameters) -21 (call top.indexed_iterate %₂₀ 1) -22 (= slot₁/U (call core.getfield %₂₁ 1)) -23 (goto label₂₆) -24 slot₂/X -25 (= TestMod.X %₂₄) -26 (goto label₂₉) -27 slot₂/X -28 (= TestMod.X %₂₇) -29 slot₂/X +14 (= slot₃/if_val (call core._equiv_typedef %₁₃ %₈)) +15 (goto label₁₇) +16 (= slot₃/if_val false) +17 slot₃/if_val +18 (gotoifnot %₁₇ label₂₂) +19 TestMod.X +20 (= slot₄/if_val %₁₉) +21 (goto label₂₃) +22 (= slot₄/if_val false) +23 slot₄/if_val +24 (gotoifnot %₁₇ label₃₀) +25 TestMod.X +26 (call top.getproperty %₂₅ :body) +27 (call top.getproperty %₂₆ :parameters) +28 (call top.indexed_iterate %₂₇ 1) +29 (= slot₁/U (call core.getfield %₂₈ 1)) 30 slot₁/U 31 (call core.svec %₃₀) -32 (call core._typebody! %₂₉ %₃₁) -33 slot₁/U -34 TestMod.X +32 (call core._typebody! %₂₃ %₈ %₃₁) +33 (constdecl TestMod.X %₃₂) +34 latestworld 35 slot₁/U -36 (call core.apply_type %₃₄ %₃₅) -37 (call core.apply_type core.Type %₃₆) -38 (call core.UnionAll %₃₃ %₃₇) -39 (call core.svec %₃₈ core.Any) -40 (call core.svec) -41 SourceLocation::1:1 -42 (call core.svec %₃₉ %₄₀ %₄₁) -43 --- method core.nothing %₄₂ +36 TestMod.X +37 slot₁/U +38 (call core.apply_type %₃₆ %₃₇) +39 (call core.apply_type core.Type %₃₈) +40 (call core.UnionAll %₃₅ %₃₉) +41 (call core.svec %₄₀ core.Any) +42 (call core.svec) +43 SourceLocation::1:1 +44 (call core.svec %₄₁ %₄₂ %₄₃) +45 --- method core.nothing %₄₄ slots: [slot₁/#ctor-self# slot₂/x slot₃/tmp] 1 (call core.fieldtype slot₁/#ctor-self# 1) 2 slot₂/x @@ -695,22 +725,24 @@ end 10 slot₃/tmp 11 (new slot₁/#ctor-self# %₁₀) 12 (return %₁₁) -44 TestMod.X -45 (call core.apply_type core.Type %₄₄) -46 slot₁/U -47 (call core.svec %₄₅ %₄₆) -48 slot₁/U -49 (call core.svec %₄₈) -50 SourceLocation::1:1 -51 (call core.svec %₄₇ %₄₉ %₅₀) -52 --- method core.nothing %₅₁ +46 latestworld +47 TestMod.X +48 (call core.apply_type core.Type %₄₇) +49 slot₁/U +50 (call core.svec %₄₈ %₄₉) +51 slot₁/U +52 (call core.svec %₅₁) +53 SourceLocation::1:1 +54 (call core.svec %₅₀ %₅₂ %₅₃) +55 --- method core.nothing %₅₄ slots: [slot₁/#self#(!read) slot₂/x] 1 TestMod.X 2 static_parameter₁ 3 (call core.apply_type %₁ %₂) 4 (new %₃ slot₂/x) 5 (return %₄) -53 (return core.nothing) +56 latestworld +57 (return core.nothing) ######################################## # Struct with outer constructor where one typevar is constrained by the other @@ -720,7 +752,7 @@ struct X{T, S <: Vector{T}} end #--------------------- 1 (global TestMod.X) -2 (const TestMod.X) +2 latestworld 3 (= slot₃/T (call core.TypeVar :T)) 4 TestMod.Vector 5 slot₃/T @@ -734,49 +766,51 @@ end 13 (call core._structtype TestMod :X %₁₀ %₁₁ %₁₂ false 1) 14 (= slot₄/X %₁₃) 15 (call core._setsuper! %₁₃ core.Any) -16 (isdefined TestMod.X) -17 (gotoifnot %₁₆ label₃₇) +16 (call core.isdefinedglobal TestMod :X false) +17 (gotoifnot %₁₆ label₂₁) 18 TestMod.X -19 (call core._equiv_typedef %₁₈ %₁₃) -20 (gotoifnot %₁₉ label₃₄) -21 TestMod.X -22 (= slot₄/X %₂₁) -23 TestMod.X -24 (call top.getproperty %₂₃ :body) -25 (call top.getproperty %₂₄ :body) -26 (call top.getproperty %₂₅ :parameters) -27 (call top.indexed_iterate %₂₆ 1) -28 (= slot₃/T (call core.getfield %₂₇ 1)) -29 (= slot₁/iterstate (call core.getfield %₂₇ 2)) -30 slot₁/iterstate -31 (call top.indexed_iterate %₂₆ 2 %₃₀) -32 (= slot₂/S (call core.getfield %₃₁ 1)) -33 (goto label₃₆) -34 slot₄/X -35 (= TestMod.X %₃₄) -36 (goto label₃₉) -37 slot₄/X -38 (= TestMod.X %₃₇) -39 slot₄/X +19 (= slot₅/if_val (call core._equiv_typedef %₁₈ %₁₃)) +20 (goto label₂₂) +21 (= slot₅/if_val false) +22 slot₅/if_val +23 (gotoifnot %₂₂ label₂₇) +24 TestMod.X +25 (= slot₆/if_val %₂₄) +26 (goto label₂₈) +27 (= slot₆/if_val false) +28 slot₆/if_val +29 (gotoifnot %₂₂ label₄₀) +30 TestMod.X +31 (call top.getproperty %₃₀ :body) +32 (call top.getproperty %₃₁ :body) +33 (call top.getproperty %₃₂ :parameters) +34 (call top.indexed_iterate %₃₃ 1) +35 (= slot₃/T (call core.getfield %₃₄ 1)) +36 (= slot₁/iterstate (call core.getfield %₃₄ 2)) +37 slot₁/iterstate +38 (call top.indexed_iterate %₃₃ 2 %₃₇) +39 (= slot₂/S (call core.getfield %₃₈ 1)) 40 TestMod.Vector 41 slot₂/S 42 (call core.apply_type %₄₀ %₄₁) 43 (call core.svec %₄₂) -44 (call core._typebody! %₃₉ %₄₃) -45 slot₃/T -46 slot₂/S -47 TestMod.X -48 slot₃/T -49 slot₂/S -50 (call core.apply_type %₄₇ %₄₈ %₄₉) -51 (call core.apply_type core.Type %₅₀) -52 (call core.UnionAll %₄₆ %₅₁) -53 (call core.UnionAll %₄₅ %₅₂) -54 (call core.svec %₅₃ core.Any) -55 (call core.svec) -56 SourceLocation::1:1 -57 (call core.svec %₅₄ %₅₅ %₅₆) -58 --- method core.nothing %₅₇ +44 (call core._typebody! %₂₈ %₁₃ %₄₃) +45 (constdecl TestMod.X %₄₄) +46 latestworld +47 slot₃/T +48 slot₂/S +49 TestMod.X +50 slot₃/T +51 slot₂/S +52 (call core.apply_type %₄₉ %₅₀ %₅₁) +53 (call core.apply_type core.Type %₅₂) +54 (call core.UnionAll %₄₈ %₅₃) +55 (call core.UnionAll %₄₇ %₅₄) +56 (call core.svec %₅₅ core.Any) +57 (call core.svec) +58 SourceLocation::1:1 +59 (call core.svec %₅₆ %₅₇ %₅₈) +60 --- method core.nothing %₅₉ slots: [slot₁/#ctor-self# slot₂/v slot₃/tmp] 1 (call core.fieldtype slot₁/#ctor-self# 1) 2 slot₂/v @@ -790,18 +824,19 @@ end 10 slot₃/tmp 11 (new slot₁/#ctor-self# %₁₀) 12 (return %₁₁) -59 TestMod.X -60 (call core.apply_type core.Type %₅₉) -61 TestMod.Vector -62 slot₂/S -63 (call core.apply_type %₆₁ %₆₂) -64 (call core.svec %₆₀ %₆₃) -65 slot₃/T -66 slot₂/S -67 (call core.svec %₆₅ %₆₆) -68 SourceLocation::1:1 -69 (call core.svec %₆₄ %₆₇ %₆₈) -70 --- method core.nothing %₆₉ +61 latestworld +62 TestMod.X +63 (call core.apply_type core.Type %₆₂) +64 TestMod.Vector +65 slot₂/S +66 (call core.apply_type %₆₄ %₆₅) +67 (call core.svec %₆₃ %₆₆) +68 slot₃/T +69 slot₂/S +70 (call core.svec %₆₈ %₆₉) +71 SourceLocation::1:1 +72 (call core.svec %₆₇ %₇₀ %₇₁) +73 --- method core.nothing %₇₂ slots: [slot₁/#self#(!read) slot₂/v] 1 TestMod.X 2 static_parameter₁ @@ -809,7 +844,8 @@ end 4 (call core.apply_type %₁ %₂ %₃) 5 (new %₄ slot₂/v) 6 (return %₅) -71 (return core.nothing) +74 latestworld +75 (return core.nothing) ######################################## # User defined inner constructors and helper functions for structs without type params @@ -827,53 +863,57 @@ end #--------------------- 1 (= slot₂/f (call core.Box)) 2 (global TestMod.X) -3 (const TestMod.X) +3 latestworld 4 (call core.svec) 5 (call core.svec :x) 6 (call core.svec) 7 (call core._structtype TestMod :X %₄ %₅ %₆ false 1) 8 (= slot₁/X %₇) 9 (call core._setsuper! %₇ core.Any) -10 (isdefined TestMod.X) -11 (gotoifnot %₁₀ label₂₁) +10 (call core.isdefinedglobal TestMod :X false) +11 (gotoifnot %₁₀ label₁₅) 12 TestMod.X -13 (call core._equiv_typedef %₁₂ %₇) -14 (gotoifnot %₁₃ label₁₈) -15 TestMod.X -16 (= slot₁/X %₁₅) -17 (goto label₂₀) -18 slot₁/X -19 (= TestMod.X %₁₈) -20 (goto label₂₃) -21 slot₁/X -22 (= TestMod.X %₂₁) -23 slot₁/X +13 (= slot₄/if_val (call core._equiv_typedef %₁₂ %₇)) +14 (goto label₁₆) +15 (= slot₄/if_val false) +16 slot₄/if_val +17 (gotoifnot %₁₆ label₂₁) +18 TestMod.X +19 (= slot₅/if_val %₁₈) +20 (goto label₂₂) +21 (= slot₅/if_val false) +22 slot₅/if_val +23 (gotoifnot %₁₆ label₂₄) 24 (call core.svec core.Any) -25 (call core._typebody! %₂₃ %₂₄) -26 (call core.svec) -27 (call core.svec) -28 (call JuliaLowering.eval_closure_type TestMod :#f##0 %₂₆ %₂₇) -29 TestMod.#f##0 -30 (new %₂₉) -31 slot₂/f -32 (call core.setfield! %₃₁ :contents %₃₀) -33 TestMod.#f##0 -34 (call core.svec %₃₃) -35 (call core.svec) -36 SourceLocation::3:5 -37 (call core.svec %₃₄ %₃₅ %₃₆) -38 --- method core.nothing %₃₇ +25 (call core._typebody! %₂₂ %₇ %₂₄) +26 (constdecl TestMod.X %₂₅) +27 latestworld +28 (call core.svec) +29 (call core.svec) +30 (call JuliaLowering.eval_closure_type TestMod :#f##0 %₂₈ %₂₉) +31 latestworld +32 TestMod.#f##0 +33 (new %₃₂) +34 slot₂/f +35 (call core.setfield! %₃₄ :contents %₃₃) +36 TestMod.#f##0 +37 (call core.svec %₃₆) +38 (call core.svec) +39 SourceLocation::3:5 +40 (call core.svec %₃₇ %₃₈ %₃₉) +41 --- method core.nothing %₄₀ slots: [slot₁/#self#(!read)] 1 TestMod.X 2 (new %₁ 1) 3 (return %₂) -39 TestMod.X -40 (call core.apply_type core.Type %₃₉) -41 (call core.svec %₄₀) -42 (call core.svec) -43 SourceLocation::4:5 -44 (call core.svec %₄₁ %₄₂ %₄₃) -45 --- code_info +42 latestworld +43 TestMod.X +44 (call core.apply_type core.Type %₄₃) +45 (call core.svec %₄₄) +46 (call core.svec) +47 SourceLocation::4:5 +48 (call core.svec %₄₅ %₄₆ %₄₇) +49 --- code_info slots: [slot₁/#ctor-self#(!read) slot₂/f(!read)] 1 (captured_local 1) 2 (call core.isdefined %₁ :contents) @@ -884,28 +924,30 @@ end 7 (call core.getfield %₁ :contents) 8 (call %₇) 9 (return %₈) -46 slot₂/f -47 (call core.svec %₄₆) -48 (call JuliaLowering.replace_captured_locals! %₄₅ %₄₇) -49 --- method core.nothing %₄₄ %₄₈ -50 TestMod.X -51 (call core.apply_type core.Type %₅₀) -52 (call core.svec %₅₁ core.Any) -53 (call core.svec) -54 SourceLocation::5:5 -55 (call core.svec %₅₂ %₅₃ %₅₄) -56 --- method core.nothing %₅₅ +50 slot₂/f +51 (call core.svec %₅₀) +52 (call JuliaLowering.replace_captured_locals! %₄₉ %₅₁) +53 --- method core.nothing %₄₈ %₅₂ +54 latestworld +55 TestMod.X +56 (call core.apply_type core.Type %₅₅) +57 (call core.svec %₅₆ core.Any) +58 (call core.svec) +59 SourceLocation::5:5 +60 (call core.svec %₅₇ %₅₈ %₅₉) +61 --- method core.nothing %₆₀ slots: [slot₁/#ctor-self# slot₂/x] 1 slot₁/#ctor-self# 2 (new %₁ slot₂/x) 3 (return %₂) -57 TestMod.X -58 (call core.apply_type core.Type %₅₇) -59 (call core.svec %₅₈ core.Any core.Any) -60 (call core.svec) -61 SourceLocation::6:5 -62 (call core.svec %₅₉ %₆₀ %₆₁) -63 --- method core.nothing %₆₂ +62 latestworld +63 TestMod.X +64 (call core.apply_type core.Type %₆₃) +65 (call core.svec %₆₄ core.Any core.Any) +66 (call core.svec) +67 SourceLocation::6:5 +68 (call core.svec %₆₅ %₆₆ %₆₇) +69 --- method core.nothing %₆₈ slots: [slot₁/#ctor-self# slot₂/y slot₃/z slot₄/tmp(!read)] 1 TestMod.ReallyXIPromise 2 slot₁/#ctor-self# @@ -921,21 +963,23 @@ end 12 (= slot₄/tmp (call core.typeassert %₁₁ %₁)) 13 slot₄/tmp 14 (return %₁₃) -64 TestMod.X -65 (call core.apply_type core.Type %₆₄) -66 (call core.svec %₆₅ core.Any core.Any core.Any) -67 (call core.svec) -68 SourceLocation::10:5 -69 (call core.svec %₆₆ %₆₇ %₆₈) -70 --- method core.nothing %₆₉ +70 latestworld +71 TestMod.X +72 (call core.apply_type core.Type %₇₁) +73 (call core.svec %₇₂ core.Any core.Any core.Any) +74 (call core.svec) +75 SourceLocation::10:5 +76 (call core.svec %₇₃ %₇₄ %₇₅) +77 --- method core.nothing %₇₆ slots: [slot₁/#ctor-self# slot₂/a slot₃/b(!read) slot₄/c(!read)] 1 slot₁/#ctor-self# 2 (new %₁ slot₂/a) 3 (return %₂) -71 TestMod.X -72 (call core.apply_type core.Type %₇₁) -73 (call JuliaLowering.bind_docs! %₇₂ "Docs for X constructor\n" %₆₉) -74 (return core.nothing) +78 latestworld +79 TestMod.X +80 (call core.apply_type core.Type %₇₉) +81 (call JuliaLowering.bind_docs! %₈₀ "Docs for X constructor\n" %₇₆) +82 (return core.nothing) ######################################## # User defined inner constructors and helper functions for structs with type params @@ -948,7 +992,7 @@ end #--------------------- 1 (newvar slot₅/f) 2 (global TestMod.X) -3 (const TestMod.X) +3 latestworld 4 (= slot₂/S (call core.TypeVar :S)) 5 (= slot₃/T (call core.TypeVar :T)) 6 slot₂/S @@ -959,76 +1003,81 @@ end 11 (call core._structtype TestMod :X %₈ %₉ %₁₀ false 1) 12 (= slot₄/X %₁₁) 13 (call core._setsuper! %₁₁ core.Any) -14 (isdefined TestMod.X) -15 (gotoifnot %₁₄ label₃₅) +14 (call core.isdefinedglobal TestMod :X false) +15 (gotoifnot %₁₄ label₁₉) 16 TestMod.X -17 (call core._equiv_typedef %₁₆ %₁₁) -18 (gotoifnot %₁₇ label₃₂) -19 TestMod.X -20 (= slot₄/X %₁₉) -21 TestMod.X -22 (call top.getproperty %₂₁ :body) -23 (call top.getproperty %₂₂ :body) -24 (call top.getproperty %₂₃ :parameters) -25 (call top.indexed_iterate %₂₄ 1) -26 (= slot₂/S (call core.getfield %₂₅ 1)) -27 (= slot₁/iterstate (call core.getfield %₂₅ 2)) -28 slot₁/iterstate -29 (call top.indexed_iterate %₂₄ 2 %₂₈) -30 (= slot₃/T (call core.getfield %₂₉ 1)) -31 (goto label₃₄) -32 slot₄/X -33 (= TestMod.X %₃₂) -34 (goto label₃₇) -35 slot₄/X -36 (= TestMod.X %₃₅) -37 slot₄/X +17 (= slot₈/if_val (call core._equiv_typedef %₁₆ %₁₁)) +18 (goto label₂₀) +19 (= slot₈/if_val false) +20 slot₈/if_val +21 (gotoifnot %₂₀ label₂₅) +22 TestMod.X +23 (= slot₉/if_val %₂₂) +24 (goto label₂₆) +25 (= slot₉/if_val false) +26 slot₉/if_val +27 (gotoifnot %₂₀ label₃₈) +28 TestMod.X +29 (call top.getproperty %₂₈ :body) +30 (call top.getproperty %₂₉ :body) +31 (call top.getproperty %₃₀ :parameters) +32 (call top.indexed_iterate %₃₁ 1) +33 (= slot₂/S (call core.getfield %₃₂ 1)) +34 (= slot₁/iterstate (call core.getfield %₃₂ 2)) +35 slot₁/iterstate +36 (call top.indexed_iterate %₃₁ 2 %₃₅) +37 (= slot₃/T (call core.getfield %₃₆ 1)) 38 (call core.svec core.Any) -39 (call core._typebody! %₃₇ %₃₈) -40 TestMod.X -41 TestMod.A -42 TestMod.B -43 (call core.apply_type %₄₀ %₄₁ %₄₂) -44 (call core.apply_type core.Type %₄₃) -45 (call core.svec %₄₄) -46 (call core.svec) -47 SourceLocation::3:5 -48 (call core.svec %₄₅ %₄₆ %₄₇) -49 --- method core.nothing %₄₈ +39 (call core._typebody! %₂₆ %₁₁ %₃₈) +40 (constdecl TestMod.X %₃₉) +41 latestworld +42 TestMod.X +43 TestMod.A +44 TestMod.B +45 (call core.apply_type %₄₂ %₄₃ %₄₄) +46 (call core.apply_type core.Type %₄₅) +47 (call core.svec %₄₆) +48 (call core.svec) +49 SourceLocation::3:5 +50 (call core.svec %₄₇ %₄₈ %₄₉) +51 --- method core.nothing %₅₀ slots: [slot₁/#ctor-self#] 1 slot₁/#ctor-self# 2 (new %₁ 1) 3 (return %₂) -50 (= slot₆/U (call core.TypeVar :U)) -51 (= slot₇/V (call core.TypeVar :V)) -52 TestMod.X -53 slot₆/U -54 slot₇/V -55 (call core.apply_type %₅₂ %₅₃ %₅₄) -56 (call core.apply_type core.Type %₅₅) -57 (call core.svec %₅₆) -58 slot₆/U -59 slot₇/V -60 (call core.svec %₅₈ %₅₉) -61 SourceLocation::4:5 -62 (call core.svec %₅₇ %₆₀ %₆₁) -63 --- method core.nothing %₆₂ +52 latestworld +53 (= slot₆/U (call core.TypeVar :U)) +54 (= slot₇/V (call core.TypeVar :V)) +55 TestMod.X +56 slot₆/U +57 slot₇/V +58 (call core.apply_type %₅₅ %₅₆ %₅₇) +59 (call core.apply_type core.Type %₅₈) +60 (call core.svec %₅₉) +61 slot₆/U +62 slot₇/V +63 (call core.svec %₆₁ %₆₂) +64 SourceLocation::4:5 +65 (call core.svec %₆₀ %₆₃ %₆₄) +66 --- method core.nothing %₆₅ slots: [slot₁/#ctor-self#] 1 slot₁/#ctor-self# 2 (new %₁ 1) 3 (return %₂) -64 (call core.svec) -65 (call core.svec) -66 (call JuliaLowering.eval_closure_type TestMod :#f##1 %₆₄ %₆₅) -67 TestMod.#f##1 -68 (new %₆₇) -69 (= slot₅/f %₆₈) -70 TestMod.#f##1 -71 (call core.svec %₇₀) -72 (call core.svec) -73 SourceLocation::5:5 -74 (call core.svec %₇₁ %₇₂ %₇₃) -75 --- method core.nothing %₇₄ +67 latestworld +68 (call core.svec) +69 (call core.svec) +70 (call JuliaLowering.eval_closure_type TestMod :#f##1 %₆₈ %₆₉) +71 latestworld +72 TestMod.#f##1 +73 (new %₇₂) +74 (= slot₅/f %₇₃) +75 TestMod.#f##1 +76 (call core.svec %₇₅) +77 (call core.svec) +78 SourceLocation::5:5 +79 (call core.svec %₇₆ %₇₇ %₇₈) +80 --- method core.nothing %₇₉ slots: [slot₁/#self#(!read)] 1 TestMod.X 2 TestMod.A @@ -1036,7 +1085,8 @@ end 4 (call core.apply_type %₁ %₂ %₃) 5 (new %₄ 1) 6 (return %₅) -76 (return core.nothing) +81 latestworld +82 (return core.nothing) ######################################## # new() calls with splats; `Any` fields @@ -1047,42 +1097,45 @@ struct X end #--------------------- 1 (global TestMod.X) -2 (const TestMod.X) +2 latestworld 3 (call core.svec) 4 (call core.svec :x :y) 5 (call core.svec) 6 (call core._structtype TestMod :X %₃ %₄ %₅ false 2) 7 (= slot₁/X %₆) 8 (call core._setsuper! %₆ core.Any) -9 (isdefined TestMod.X) -10 (gotoifnot %₉ label₂₀) +9 (call core.isdefinedglobal TestMod :X false) +10 (gotoifnot %₉ label₁₄) 11 TestMod.X -12 (call core._equiv_typedef %₁₁ %₆) -13 (gotoifnot %₁₂ label₁₇) -14 TestMod.X -15 (= slot₁/X %₁₄) -16 (goto label₁₉) -17 slot₁/X -18 (= TestMod.X %₁₇) -19 (goto label₂₂) -20 slot₁/X -21 (= TestMod.X %₂₀) -22 slot₁/X +12 (= slot₂/if_val (call core._equiv_typedef %₁₁ %₆)) +13 (goto label₁₅) +14 (= slot₂/if_val false) +15 slot₂/if_val +16 (gotoifnot %₁₅ label₂₀) +17 TestMod.X +18 (= slot₃/if_val %₁₇) +19 (goto label₂₁) +20 (= slot₃/if_val false) +21 slot₃/if_val +22 (gotoifnot %₁₅ label₂₃) 23 (call core.svec core.Any core.Any) -24 (call core._typebody! %₂₂ %₂₃) -25 TestMod.X -26 (call core.apply_type core.Type %₂₅) -27 (call core.svec %₂₆ core.Any) -28 (call core.svec) -29 SourceLocation::4:5 -30 (call core.svec %₂₇ %₂₈ %₂₉) -31 --- method core.nothing %₃₀ +24 (call core._typebody! %₂₁ %₆ %₂₃) +25 (constdecl TestMod.X %₂₄) +26 latestworld +27 TestMod.X +28 (call core.apply_type core.Type %₂₇) +29 (call core.svec %₂₈ core.Any) +30 (call core.svec) +31 SourceLocation::4:5 +32 (call core.svec %₂₉ %₃₀ %₃₁) +33 --- method core.nothing %₃₂ slots: [slot₁/#ctor-self# slot₂/xs] 1 slot₁/#ctor-self# 2 (call core._apply_iterate top.iterate core.tuple slot₂/xs) 3 (splatnew %₁ %₂) 4 (return %₃) -32 (return core.nothing) +34 latestworld +35 (return core.nothing) ######################################## # new() calls with splats; typed fields @@ -1093,7 +1146,7 @@ struct X{T} end #--------------------- 1 (global TestMod.X) -2 (const TestMod.X) +2 latestworld 3 (= slot₁/T (call core.TypeVar :T)) 4 slot₁/T 5 (call core.svec %₄) @@ -1102,40 +1155,42 @@ end 8 (call core._structtype TestMod :X %₅ %₆ %₇ false 2) 9 (= slot₂/X %₈) 10 (call core._setsuper! %₈ core.Any) -11 (isdefined TestMod.X) -12 (gotoifnot %₁₁ label₂₇) +11 (call core.isdefinedglobal TestMod :X false) +12 (gotoifnot %₁₁ label₁₆) 13 TestMod.X -14 (call core._equiv_typedef %₁₃ %₈) -15 (gotoifnot %₁₄ label₂₄) -16 TestMod.X -17 (= slot₂/X %₁₆) -18 TestMod.X -19 (call top.getproperty %₁₈ :body) -20 (call top.getproperty %₁₉ :parameters) -21 (call top.indexed_iterate %₂₀ 1) -22 (= slot₁/T (call core.getfield %₂₁ 1)) -23 (goto label₂₆) -24 slot₂/X -25 (= TestMod.X %₂₄) -26 (goto label₂₉) -27 slot₂/X -28 (= TestMod.X %₂₇) -29 slot₂/X +14 (= slot₄/if_val (call core._equiv_typedef %₁₃ %₈)) +15 (goto label₁₇) +16 (= slot₄/if_val false) +17 slot₄/if_val +18 (gotoifnot %₁₇ label₂₂) +19 TestMod.X +20 (= slot₅/if_val %₁₉) +21 (goto label₂₃) +22 (= slot₅/if_val false) +23 slot₅/if_val +24 (gotoifnot %₁₇ label₃₀) +25 TestMod.X +26 (call top.getproperty %₂₅ :body) +27 (call top.getproperty %₂₆ :parameters) +28 (call top.indexed_iterate %₂₇ 1) +29 (= slot₁/T (call core.getfield %₂₈ 1)) 30 slot₁/T 31 TestMod.A 32 (call core.svec %₃₀ %₃₁) -33 (call core._typebody! %₂₉ %₃₂) -34 (= slot₃/T (call core.TypeVar :T)) -35 TestMod.X -36 slot₃/T -37 (call core.apply_type %₃₅ %₃₆) -38 (call core.apply_type core.Type %₃₇) -39 (call core.svec %₃₈ core.Any) -40 slot₃/T -41 (call core.svec %₄₀) -42 SourceLocation::4:5 -43 (call core.svec %₃₉ %₄₁ %₄₂) -44 --- method core.nothing %₄₃ +33 (call core._typebody! %₂₃ %₈ %₃₂) +34 (constdecl TestMod.X %₃₃) +35 latestworld +36 (= slot₃/T (call core.TypeVar :T)) +37 TestMod.X +38 slot₃/T +39 (call core.apply_type %₃₇ %₃₈) +40 (call core.apply_type core.Type %₃₉) +41 (call core.svec %₄₀ core.Any) +42 slot₃/T +43 (call core.svec %₄₂) +44 SourceLocation::4:5 +45 (call core.svec %₄₁ %₄₃ %₄₄) +46 --- method core.nothing %₄₅ slots: [slot₁/#ctor-self# slot₂/xs slot₃/tmp slot₄/tmp] 1 (call core._apply_iterate top.iterate core.tuple slot₂/xs) 2 (call core.nfields %₁) @@ -1168,7 +1223,8 @@ end 29 slot₄/tmp 30 (new %₁₁ %₂₀ %₂₉) 31 (return %₃₀) -45 (return core.nothing) +47 latestworld +48 (return core.nothing) ######################################## # Error: new doesn't accept keywords