From 8683d6f1abfebc018c849ae2700f641952367770 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sun, 10 Feb 2019 22:25:21 -0600 Subject: [PATCH] Handle world-age errors in incremental lowering --- src/interpret.jl | 11 +++++++++++ test/juliatests.jl | 12 +++++++----- test/utils.jl | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/interpret.jl b/src/interpret.jl index 83ed8eed2851f..9ea3977698e0a 100644 --- a/src/interpret.jl +++ b/src/interpret.jl @@ -406,6 +406,17 @@ function _step_expr!(stack, frame, @nospecialize(node), pc::JuliaProgramCounter, rhs = @lookup(frame, node) end catch err + # Check for world age errors, which generally indicate a failure to go back to toplevel + if isa(err, MethodError) + is_arg_types = isa(err.args, DataType) + arg_types = is_arg_types ? err.args : Base.typesof(err.args...) + if (err.world != typemax(UInt) && + hasmethod(err.f, arg_types) && + !hasmethod(err.f, arg_types, world = err.world)) + @warn "likely failure to return to toplevel, try Base.invokelatest" + rethrow(err) + end + end isempty(frame.exception_frames) && rethrow(err) frame.last_exception[] = err return JuliaProgramCounter(frame.exception_frames[end]) diff --git a/test/juliatests.jl b/test/juliatests.jl index 0b22c18b3e3db..ef921af9d376b 100644 --- a/test/juliatests.jl +++ b/test/juliatests.jl @@ -13,14 +13,16 @@ else @warn "Julia's test/ directory not found, skipping Julia tests" end -module JuliaTests end +module JuliaTests +using Test +end @testset "Julia tests" begin stack = JuliaStackFrame[] function runtest(frame) empty!(stack) - empty!(JuliaInterpreter.framedict) - empty!(JuliaInterpreter.genframedict) + # empty!(JuliaInterpreter.framedict) + # empty!(JuliaInterpreter.genframedict) return JuliaInterpreter.finish_and_return!(stack, frame, true) end function dotest!(failed, test) @@ -29,13 +31,13 @@ module JuliaTests end if isexpr(ex, :error) @warn "error parsing $test: $ex" else - ex = Expr(:toplevel, :(using Test), ex) try lower_incrementally(runtest, JuliaTests, ex) println("Succeeded on ", test) catch err @show test err push!(failed, (test, err)) + # rethrow(err) end end end @@ -44,7 +46,7 @@ module JuliaTests end delayed = [] failed = [] for test in tests - if startswith(test, "compiler") + if startswith(test, "compiler") || test == "subarray" push!(delayed, test) else dotest!(failed, test) diff --git a/test/utils.jl b/test/utils.jl index 57ff7d2ca4d48..345ed0baa2a56 100644 --- a/test/utils.jl +++ b/test/utils.jl @@ -76,7 +76,7 @@ function lower!(@nospecialize(f), docexprs, mod::Module, ex::Expr) lwr = Meta.lower(mod, ex) if isexpr(lwr, :thunk) frame = JuliaInterpreter.prepare_thunk(mod, lwr) - f(frame) + Base.invokelatest(f, frame) # if previous thunks define new methods, we need to update world age elseif isa(lwr, Expr) && (lwr.head == :export || lwr.head == :using || lwr.head == :import) elseif isa(lwr, Symbol) || isa(lwr, Nothing) else