2828function is_defaultctors (@nospecialize (f))
2929 @assert ! isa (f, Core. SSAValue) && ! isa (f, JuliaInterpreter. SSAValue)
3030 if isa (f, GlobalRef)
31- return f. mod === Core && f. name === :_defaultctors
31+ return (f. mod === Core || f. mod === Base) && f. name === :_defaultctors
32+ else
33+ if isa (f, QuoteNode)
34+ f = f. value
35+ end
36+ if isdefined (Core, :_defaultctors ) && f === Core. _defaultctors
37+ return true
38+ elseif isdefined (Base, :_defaultctors ) && f === Base. _defaultctors
39+ return true
40+ end
3241 end
3342 return false
3443end
@@ -416,17 +425,24 @@ function _methods_by_execution!(
416425 # avoid redefining types unless we have to
417426 pc = next_or_nothing! (frame)
418427 else
428+ # If the RHS is a call, unwrap it and dispatch to the call handler
429+ callstmt = LoweredCodeUtils. getrhs (stmt)
430+ if isa (callstmt, Expr) && callstmt. head === :call
431+ @goto call_dispatch
432+ end
419433 pc = step_expr! (interp, frame, stmt, true )
420434 end
421435 elseif head === :call
422- f = lookup (frame, stmt. args[1 ])
436+ callstmt = stmt
437+ @label call_dispatch
438+ f = lookup (frame, callstmt. args[1 ])
423439 if __bpart__ && f === Core. _typebody!
424- analyze_typebody! (exinfo, interp, frame, stmt )
440+ analyze_typebody! (exinfo, interp, frame, callstmt )
425441 pc = step_expr! (interp, frame, stmt, true )
426- elseif @static ( isdefined (Core, :_defaultctors ) && true ) && f === Core . _defaultctors && length (stmt . args) == 3
442+ elseif is_defaultctors (f ) && length (callstmt . args) == 3
427443 # Create the constructors for a type (i.e., a method definition)
428- T = lookup (frame, stmt . args[2 ])
429- lnn = lookup (frame, stmt . args[3 ])
444+ T = lookup (frame, callstmt . args[2 ])
445+ lnn = lookup (frame, callstmt . args[3 ])
430446 if T isa Type && lnn isa LineNumberNode
431447 empty! (signatures)
432448 uT = Base. unwrap_unionall (T):: DataType
@@ -450,8 +466,8 @@ function _methods_by_execution!(
450466 end
451467 elseif f === Core. eval
452468 # an @eval or eval block: this may contain method definitions, so intercept it.
453- evalmod = lookup (interp, frame, stmt . args[2 ]):: Module
454- evalex = lookup (interp, frame, stmt . args[3 ])
469+ evalmod = lookup (interp, frame, callstmt . args[2 ]):: Module
470+ evalex = lookup (interp, frame, callstmt . args[3 ])
455471 local value = nothing
456472 for (newmod, newex) in ExprSplitter (evalmod, evalex)
457473 if is_doc_expr (newex)
@@ -467,11 +483,11 @@ function _methods_by_execution!(
467483 elseif skip_include && (f === modinclude || f === Core. include || f === Base. include)
468484 # include calls need to be managed carefully from several standpoints, including
469485 # path management and parsing new expressions
470- handle_include! (exinfo, interp, frame, stmt )
486+ handle_include! (exinfo, interp, frame, callstmt )
471487 assign_this! (frame, nothing ) # FIXME : the file might return something different from `nothing`
472488 pc = next_or_nothing! (frame)
473489 elseif f === Base. Docs. doc! # && mode !== :eval
474- fargs = JuliaInterpreter. collect_args (interp, frame, stmt )
490+ fargs = JuliaInterpreter. collect_args (interp, frame, callstmt )
475491 popfirst! (fargs)
476492 length (fargs) == 3 && push! (fargs, Union{}) # add the default sig
477493 dmod:: Module , b:: Base.Docs.Binding , str:: Base.Docs.DocStr , sig = fargs
0 commit comments