Skip to content

Commit 99eb121

Browse files
authored
Test: improve type stabilities (#59082)
Also simplifies code a bit, by removing unnecessary branches.
1 parent 1cab9a7 commit 99eb121

File tree

3 files changed

+33
-32
lines changed

3 files changed

+33
-32
lines changed

stdlib/Test/src/Test.jl

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -217,14 +217,19 @@ struct Error <: Result
217217
context::Union{Nothing, String}
218218
source::LineNumberNode
219219

220-
function Error(test_type::Symbol, orig_expr, value, bt, source::LineNumberNode, context::Union{Nothing, String}=nothing)
221-
if test_type === :test_error
222-
bt = scrub_exc_stack(bt, nothing, extract_file(source))
223-
end
224-
if test_type === :test_error || test_type === :nontest_error
225-
bt_str = try # try the latest world for this, since we might have eval'd new code for show
220+
function Error(test_type::Symbol, orig_expr, value, excs::Union{Base.ExceptionStack,Nothing},
221+
source::LineNumberNode, context::Union{Nothing, String}=nothing)
222+
@nospecialize orig_expr value
223+
bt_str = ""
224+
if !isnothing(excs)
225+
if test_type === :test_error
226+
excs = scrub_exc_stack(excs, nothing, extract_file(source))
227+
end
228+
if test_type === :test_error || test_type === :nontest_error
229+
bt_str = try
230+
# try the latest world for this, since we might have eval'd new code for show
226231
# Apply REPL backtrace scrubbing to hide REPL internals, similar to how REPL.jl handles it
227-
Base.invokelatest(sprint, Base.show_exception_stack, Base.scrub_repl_backtrace(bt); context=stdout)
232+
Base.invokelatest(sprint, Base.show_exception_stack, Base.scrub_repl_backtrace(excs); context=stdout)
228233
catch ex
229234
"#=ERROR showing exception stack=# " *
230235
try
@@ -233,8 +238,7 @@ struct Error <: Result
233238
"of type " * string(typeof(ex))
234239
end
235240
end
236-
else
237-
bt_str = ""
241+
end
238242
end
239243
value = try # try the latest world for this, since we might have eval'd new code for show
240244
Base.invokelatest(sprint, show, value, context = :limit => true)
@@ -346,7 +350,7 @@ end
346350

347351
struct Threw <: ExecutionResult
348352
exception
349-
backtrace::Union{Nothing,Vector{Any}}
353+
current_exceptions::Base.ExceptionStack
350354
source::LineNumberNode
351355
end
352356

@@ -746,7 +750,7 @@ end
746750

747751
# An internal function, called by the code generated by the @test
748752
# macro to actually perform the evaluation and manage the result.
749-
function do_test(result::ExecutionResult, orig_expr)
753+
function do_test(result::ExecutionResult, @nospecialize orig_expr)
750754
# get_testset() returns the most recently added test set
751755
# We then call record() with this test set and the test result
752756
if isa(result, Returned)
@@ -768,13 +772,13 @@ function do_test(result::ExecutionResult, orig_expr)
768772
# The predicate couldn't be evaluated without throwing an
769773
# exception, so that is an Error and not a Fail
770774
@assert isa(result, Threw)
771-
testres = Error(:test_error, orig_expr, result.exception, result.backtrace::Vector{Any}, result.source, nothing)
775+
testres = Error(:test_error, orig_expr, result.exception, result.current_exceptions, result.source, nothing)
772776
end
773777
isa(testres, Pass) || trigger_test_failure_break(result)
774778
record(get_testset(), testres)
775779
end
776780

777-
function do_broken_test(result::ExecutionResult, orig_expr)
781+
function do_broken_test(result::ExecutionResult, @nospecialize orig_expr)
778782
testres = Broken(:test, orig_expr)
779783
# Assume the test is broken and only change if the result is true
780784
if isa(result, Returned)
@@ -860,7 +864,7 @@ end
860864

861865
# An internal function, called by the code generated by @test_throws
862866
# to evaluate and catch the thrown exception - if it exists
863-
function do_test_throws(result::ExecutionResult, orig_expr, extype)
867+
function do_test_throws(result::ExecutionResult, @nospecialize(orig_expr), extype)
864868
if isa(result, Threw)
865869
# Check that the right type of exception was thrown
866870
success = false
@@ -908,20 +912,17 @@ function do_test_throws(result::ExecutionResult, orig_expr, extype)
908912
if success
909913
testres = Pass(:test_throws, orig_expr, extype, exc, result.source, message_only)
910914
else
911-
if result.backtrace !== nothing
912-
bt = scrub_exc_stack(result.backtrace, nothing, extract_file(result.source))
913-
bt_str = try # try the latest world for this, since we might have eval'd new code for show
914-
Base.invokelatest(sprint, Base.show_exception_stack, bt; context=stdout)
915-
catch ex
916-
"#=ERROR showing exception stack=# " *
917-
try
918-
sprint(Base.showerror, ex, catch_backtrace(); context=stdout)
919-
catch
920-
"of type " * string(typeof(ex))
921-
end
922-
end
923-
else
924-
bt_str = nothing
915+
excs = result.current_exceptions
916+
bt = scrub_exc_stack(excs, nothing, extract_file(result.source))
917+
bt_str = try # try the latest world for this, since we might have eval'd new code for show
918+
Base.invokelatest(sprint, Base.show_exception_stack, bt; context=stdout)
919+
catch ex
920+
"#=ERROR showing exception stack=# " *
921+
try
922+
sprint(Base.showerror, ex, catch_backtrace(); context=stdout)
923+
catch
924+
"of type " * string(typeof(ex))
925+
end
925926
end
926927
testres = Fail(:test_throws_wrong, orig_expr, extype, exc, nothing, result.source, message_only, bt_str)
927928
end
@@ -1073,7 +1074,7 @@ end
10731074
A simple fallback test set that throws immediately on a failure.
10741075
"""
10751076
struct FallbackTestSet <: AbstractTestSet end
1076-
fallback_testset = FallbackTestSet()
1077+
const fallback_testset = FallbackTestSet()
10771078

10781079
struct FallbackTestSetException <: Exception
10791080
msg::String

stdlib/Test/test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ let retval_tests = @testset NoThrowTestSet begin
390390
ts = Test.DefaultTestSet("Mock for testing retval of record(::DefaultTestSet, ::T <: Result) methods")
391391
pass_mock = Test.Pass(:test, 1, 2, 3, LineNumberNode(0, "A Pass Mock"))
392392
@test Test.record(ts, pass_mock) isa Test.Pass
393-
error_mock = Test.Error(:test, 1, 2, 3, LineNumberNode(0, "An Error Mock"), nothing)
393+
error_mock = Test.Error(:test, 1, 2, nothing, LineNumberNode(0, "An Error Mock"), nothing)
394394
@test Test.record(ts, error_mock; print_result=false) isa Test.Error
395395
fail_mock = Test.Fail(:test, 1, 2, 3, nothing, LineNumberNode(0, "A Fail Mock"), false)
396396
@test Test.record(ts, fail_mock; print_result=false) isa Test.Fail

test/runtests.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ cd(@__DIR__) do
414414
# deserialization errors or something similar. Record this testset as Errored.
415415
fake = Test.DefaultTestSet(testname)
416416
fake.time_end = fake.time_start + duration
417-
Test.record(fake, Test.Error(:nontest_error, testname, nothing, Any[(resp, [])], LineNumberNode(1), nothing))
417+
Test.record(fake, Test.Error(:nontest_error, testname, nothing, Base.ExceptionStack(Any[(resp, [])]), LineNumberNode(1), nothing))
418418
Test.push_testset(fake)
419419
Test.record(o_ts, fake)
420420
Test.pop_testset()
@@ -423,7 +423,7 @@ cd(@__DIR__) do
423423
for test in all_tests
424424
(test in completed_tests) && continue
425425
fake = Test.DefaultTestSet(test)
426-
Test.record(fake, Test.Error(:test_interrupted, test, nothing, [("skipped", [])], LineNumberNode(1), nothing))
426+
Test.record(fake, Test.Error(:test_interrupted, test, nothing, Base.ExceptionStack(Any[("skipped", [])]), LineNumberNode(1), nothing))
427427
Test.push_testset(fake)
428428
Test.record(o_ts, fake)
429429
Test.pop_testset()

0 commit comments

Comments
 (0)