diff --git a/bin/generate_builtins.jl b/bin/generate_builtins.jl index cbda53dca5aa8..291bfca88cf1d 100644 --- a/bin/generate_builtins.jl +++ b/bin/generate_builtins.jl @@ -8,7 +8,7 @@ const RECENTLY_ADDED = Core.Builtin[ Core.get_binding_type, Core.set_binding_type!, Core.getglobal, Core.setglobal!, Core.modifyfield!, Core.replacefield!, Core.swapfield!, -] +] const kwinvoke = Core.kwfunc(Core.invoke) function scopedname(f) @@ -175,11 +175,13 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) print(io, """ $head f === $fstr - argswrapped = getargs(args, frame) if !expand + argswrapped = getargs(args, frame) return Some{Any}($fstr(argswrapped...)) end - return Expr(:call, $fstr, argswrapped...) + # This uses the original arguments to avoid looking them up twice + # See #442 + return Expr(:call, invoke, args[2:end]...) """) continue elseif f === Core._call_latest diff --git a/src/builtins.jl b/src/builtins.jl index 003ebf09859d2..b01ecefa7b53d 100644 --- a/src/builtins.jl +++ b/src/builtins.jl @@ -191,11 +191,13 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) return Some{Any}(getglobal(getargs(args, frame)...)) end elseif f === invoke - argswrapped = getargs(args, frame) if !expand + argswrapped = getargs(args, frame) return Some{Any}(invoke(argswrapped...)) end - return Expr(:call, invoke, argswrapped...) + # This uses the original arguments to avoid looking them up twice + # See #442 + return Expr(:call, invoke, args[2:end]...) elseif f === isa if nargs == 2 return Some{Any}(isa(@lookup(frame, args[2]), @lookup(frame, args[3]))) diff --git a/test/interpret.jl b/test/interpret.jl index 0741ba72b4afd..78cc8cdec5a39 100644 --- a/test/interpret.jl +++ b/test/interpret.jl @@ -727,9 +727,12 @@ end D = Diagonal([1.0, 2.0]) @test @interpret(f(D)) === f(D) - # issue #441 + # issue #441 & #535 flog() = @info "logging macros" - @test @interpret flog() === nothing + @test_logs (:info, "logging macros") @test @interpret flog() === nothing + flog2() = @error "this error is ok" + frame = JuliaInterpreter.enter_call(flog2) + @test_logs (:error, "this error is ok") @test debug_command(frame, :c) === nothing end struct A396