Skip to content

Commit 83a9910

Browse files
Kenoclaude
andauthored
Provide more robustness for some lowering differences (#144)
* Provide more robustness for some lowering differences This allows some variants for struct lowering, in particular using the `declare_` intrinsic rather than `=` and allowing an assignment around `typebody!`. This was developed with JuliaLang/julia#60569. This may or may not be needed in the final version of that PR, but it's good for this code to be less brittle there regardless since those are reasonable lowerings. * Guard is_declare_global with isdefined check Core.declare_global only exists on Julia nightly (the typegroup branch). Without this guard, accessing Core.declare_global throws UndefVarError on Julia 1.10/1.12/release, matching the existing pattern used by is_declare_const. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Keno Fischer <Keno@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7f924a7 commit 83a9910

1 file changed

Lines changed: 37 additions & 9 deletions

File tree

src/utils.jl

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,37 +152,65 @@ function istypedef(stmt)
152152
return false
153153
end
154154

155+
# Check if stmt is a Core.declare_global(...) call
156+
function is_declare_global(@nospecialize(stmt))
157+
isexpr(stmt, :call) || return false
158+
f = stmt.args[1]
159+
@static if isdefined(Core, :declare_global)
160+
is_global_ref(f, Core, :declare_global) && return true
161+
is_quotenode_egal(f, Core.declare_global) && return true
162+
end
163+
return false
164+
end
165+
166+
# Check if stmt is a Core.declare_const(...) call
167+
function is_declare_const(@nospecialize(stmt))
168+
isexpr(stmt, :call) || return false
169+
f = stmt.args[1]
170+
@static if isdefined(Core, :declare_const)
171+
is_global_ref(f, Core, :declare_const) && return true
172+
is_quotenode_egal(f, Core.declare_const) && return true
173+
end
174+
return false
175+
end
176+
155177
# Given a typedef at `src.code[idx]`, return the range of statement indices that encompass the typedef.
156178
# The range does not include any constructor methods.
157179
function typedef_range(src::CodeInfo, idx)
158180
stmt = src.code[idx]
159181
istypedef(stmt) || error(stmt, " is not a typedef")
160182
stmt = stmt::Expr
161183
isanonymous_typedef(stmt) && return idx:idx
162-
# Search backwards to the previous :global
184+
# Search backwards to the previous :global or Core.declare_global
163185
istart = idx
164186
while istart >= 1
165-
isexpr(src.code[istart], :global) && break
166-
isexpr(src.code[istart], :latestworld) && break
187+
s = src.code[istart]
188+
isexpr(s, :global) && break
189+
is_declare_global(s) && break
167190
istart -= 1
168191
end
169-
istart >= 1 || error("no initial :global found")
192+
istart >= 1 || error("no initial :global or declare_global found")
170193
iend, n = idx, length(src.code)
171194
have_typebody = have_equivtypedef = false
172195
while iend <= n
173196
stmt = src.code[iend]
174197
if isa(stmt, Expr)
175198
stmt.head === :global && break
176199
stmt.head === :latestworld && break
177-
if stmt.head === :call
178-
if (is_global_ref(stmt.args[1], Core, :_typebody!) || is_quotenode_egal(stmt.args[1], Core._typebody!))
200+
# New lowering uses Core.declare_const for the final binding
201+
is_declare_const(stmt) && break
202+
# Unwrap assignments (e.g. `_1 = Core._typebody!(...)`) to find the call
203+
callstmt = stmt.head === :(=) ? getrhs(stmt) : stmt
204+
if isa(callstmt, Expr) && callstmt.head === :call
205+
if (is_global_ref(callstmt.args[1], Core, :_typebody!) || is_quotenode_egal(callstmt.args[1], Core._typebody!))
179206
have_typebody = true
180-
elseif (is_global_ref(stmt.args[1], Core, :_equiv_typedef) || is_quotenode_egal(stmt.args[1], Core._equiv_typedef))
207+
elseif (is_global_ref(callstmt.args[1], Core, :_equiv_typedef) || is_quotenode_egal(callstmt.args[1], Core._equiv_typedef))
181208
have_equivtypedef = true
182-
# Advance to the type-assignment
209+
# Advance to the type-assignment (or declare_const call)
183210
while iend <= n
184211
stmt = src.code[iend]
185212
get_lhs_rhs(stmt) !== nothing && break
213+
is_declare_const(stmt) && break
186214
iend += 1
187215
end
188216
end
@@ -195,7 +223,7 @@ function typedef_range(src::CodeInfo, idx)
195223
is_return(stmt) && break
196224
iend += 1
197225
end
198-
iend <= n || (@show src; error("no final :global found"))
226+
iend <= n || (@show src; error("no final :global or declare_const found"))
199227
return istart:iend-1
200228
end
201229

0 commit comments

Comments
 (0)