diff --git a/src/nlp_expr.jl b/src/nlp_expr.jl index 1c5c93c6c87..bd4b354d952 100644 --- a/src/nlp_expr.jl +++ b/src/nlp_expr.jl @@ -673,9 +673,10 @@ function _evaluate_expr( return convert(Float64, expr) end -struct _ConcreteExpression{T} +struct _ConcreteExpression head::Symbol - args::Vector{T} + args::Vector{Real} + _ConcreteExpression(head::Symbol) = new(head, Real[]) end function _evaluate_expr( @@ -683,7 +684,7 @@ function _evaluate_expr( f::Function, expr::GenericNonlinearExpr, ) - ret = _ConcreteExpression{Float64}(expr.head, Float64[]) + ret = _ConcreteExpression(expr.head) stack = Any[] for arg in reverse(expr.args) push!(stack, (ret, arg)) @@ -691,7 +692,7 @@ function _evaluate_expr( while !isempty(stack) parent, arg = pop!(stack) if arg isa MOI.ScalarNonlinearFunction - new_ret = _ConcreteExpression{Float64}(arg.head, Float64[]) + new_ret = _ConcreteExpression(arg.head) push!(parent.args, new_ret) for child in reverse(arg.args) push!(stack, (new_ret, child)) diff --git a/test/test_nlp_expr.jl b/test/test_nlp_expr.jl index 28dd26f8f0e..64477eda9fb 100644 --- a/test/test_nlp_expr.jl +++ b/test/test_nlp_expr.jl @@ -382,6 +382,22 @@ function test_evaluate_expr_stackoverflow() return end +function test_evaluate_expr_stackoverflow_user_defined_function() + N = 10_000 + f(x, y) = *(x, y) + model = Model() + @variable(model, x[1:N], start = 0) + @operator(model, op_f, 2, f) + y = x[1] + for i in 2:N + y = op_f(x[i], y) + end + @test value(start_value, y) == 0.0 + set_start_value.(x, 1.0) + @test value(start_value, y) == 1.0 + return +end + function test_nlobjective_with_nlexpr() model = Model() @variable(model, x)