@@ -137,7 +137,16 @@ function eval_or_rgf(expr::Expr; eval_expression = false, eval_module = @__MODUL
137137 if eval_expression
138138 return eval_module. eval (expr)
139139 else
140- return drop_expr (RuntimeGeneratedFunction (eval_module, eval_module, expr))
140+ # Only function-definition expressions benefit from RuntimeGeneratedFunction (avoids
141+ # world-age issues with new methods). Module-level references such as
142+ # `:(ModelingToolkitBase._oop_unimplemented)` are not function definitions; wrapping
143+ # them in an RGF would fail. Evaluate them directly instead — no new method is
144+ # introduced so there is no world-age concern.
145+ if Meta. isexpr (expr, :function ) || Meta. isexpr (expr, :-> )
146+ return drop_expr (RuntimeGeneratedFunction (eval_module, eval_module, expr))
147+ else
148+ return eval_module. eval (expr)
149+ end
141150 end
142151end
143152
@@ -595,12 +604,36 @@ Base.@nospecializeinfer function build_function_wrapper(
595604 end
596605
597606 optimize = resolve_optimize_option (optimize)
598- return Symbolics. codegen_function (ir, expr, args; wrap_code, similarto, cse, optimize, kwargs... )
607+ result = Symbolics. codegen_function (ir, expr, args; wrap_code, similarto, cse, optimize, kwargs... )
608+ # When iip_config disables one side, Symbolics generates an anonymous `unimplemented`
609+ # function expression. Replace it here — where we know which side is disabled — with a
610+ # reference to a named module-level function so all downstream paths (expression=Val{true},
611+ # eval_expression=true, distributed serialization) get a stable, serializable callable.
612+ iip_config = get (kwargs, :iip_config , (true , true ))
613+ if result isa NTuple{2 , Expr}
614+ oop_expr, iip_expr = result
615+ if ! iip_config[1 ]
616+ oop_expr = OOP_UNIMPLEMENTED_EXPR
617+ end
618+ if ! iip_config[2 ]
619+ iip_expr = IIP_UNIMPLEMENTED_EXPR
620+ end
621+ result = (oop_expr, iip_expr)
622+ end
623+ return result
599624end
600625
601626resolve_optimize_option (x) = x
602627resolve_optimize_option (:: Nothing ) = nothing
603628
629+ # Module-level fallback functions for the disabled side of an `iip_config` pair.
630+ # Using named module-level functions ensures correct serialization across all codegen paths
631+ # (expression=Val{true} evaluated by the user, eval_expression=true, distributed workers).
632+ _oop_unimplemented (args... ) = throw (Symbolics. FunctionUnimplementedError (" out-of-place" ))
633+ _iip_unimplemented (args... ) = throw (Symbolics. FunctionUnimplementedError (" in-place" ))
634+ const OOP_UNIMPLEMENTED_EXPR = :($ ModelingToolkitBase. _oop_unimplemented)
635+ const IIP_UNIMPLEMENTED_EXPR = :($ ModelingToolkitBase. _iip_unimplemented)
636+
604637"""
605638 $(TYPEDEF)
606639
0 commit comments