Skip to content

Commit 26efc09

Browse files
committed
add some "no invalidations" tests
Test that adding certain type-method pairs doesn't cause any invalidation. Currently the new type subtypes `Integer` in all cases. Some of the tests are marked as broken. Merging this will make the contribution process more demanding: when someone makes a PR they might need to fix unrelated type stability issues, or decrease `max_methods` for some function before being able to merge their initial PR. However that's better than ignoring the constant danger of type instability/invalidation regressions making the sysimage and precompilation less useful.
1 parent 148493d commit 26efc09

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed

test/choosetests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const TESTNAMES = [
1616
"operators", "ordering", "path", "ccall", "parse", "loading", "gmp",
1717
"sorting", "spawn", "backtrace", "exceptions",
1818
"file", "read", "version", "namedtuple",
19-
"mpfr", "broadcast", "complex",
19+
"mpfr", "broadcast", "complex", "no_invalidations",
2020
"floatapprox", "stdlib", "reflection", "regex", "float16",
2121
"combinatorics", "sysinfo", "env", "rounding", "ranges", "mod2pi",
2222
"euler", "show", "client", "terminfo",

test/no_invalidations.jl

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# This file is a part of Julia. License is MIT: https://julialang.org/license
2+
3+
using Test
4+
5+
module ThereAreNoInvalidations
6+
function julia_expr_cmd(expr::Expr)
7+
`$(Base.julia_cmd()) -e $expr`
8+
end
9+
function readline_julia_expr_cmd(expr::Expr)
10+
open(readline, julia_expr_cmd(expr))
11+
end
12+
function invalidations_expr(expr::Expr)
13+
quote
14+
try
15+
let invs = ccall(:jl_debug_method_invalidation, Any, (Cint,), 1)
16+
@eval $expr
17+
invs
18+
end
19+
finally
20+
ccall(:jl_debug_method_invalidation, Any, (Cint,), 0)
21+
end
22+
end
23+
end
24+
function there_are_no_invalidations_expr(expr::Expr)
25+
e = invalidations_expr(expr)
26+
quote
27+
let invalidations = $e
28+
show(isempty(invalidations))
29+
end
30+
end
31+
end
32+
function there_are_no_invalidations(expr::Expr)
33+
e = there_are_no_invalidations_expr(expr)
34+
s = readline_julia_expr_cmd(e)
35+
parse(Bool, s)
36+
end
37+
end
38+
39+
function type_expr(f, supertype::Type)
40+
type_name = :T
41+
rest = f(type_name)
42+
quote
43+
struct $type_name <: $supertype end
44+
$rest
45+
end
46+
end
47+
48+
function test_expr(f, supertype::Type = Integer)
49+
e = type_expr(f, supertype)
50+
ThereAreNoInvalidations.there_are_no_invalidations(e)
51+
end
52+
53+
@testset "no invalidations test set" begin
54+
int_types = (Bool, Int8, UInt8, Int16, UInt16, Int, UInt, BigInt)
55+
@testset "construction of old int type from new type" begin
56+
broken = (Int8, UInt8, UInt16, Int, UInt)
57+
@testset "T: $T" for T int_types
58+
@test test_expr(n -> :(Base.$T(::$n) = $T(0))) broken=(T broken)
59+
end
60+
end
61+
@testset "construction of new int type from old type" begin
62+
broken = ()
63+
@testset "T: $T" for T int_types
64+
@test test_expr(n -> :($n(::$T) = $n())) broken=(T broken)
65+
end
66+
end
67+
@testset "arithmetic between old int types and new int type" begin
68+
ops = (:+, :*)
69+
broken = ()
70+
@testset "T: $T" for T int_types
71+
@testset "op: $op" for op ops
72+
@test (
73+
test_expr(n -> :(Base.$op(::$n, m::$T) = m)) &&
74+
test_expr(n -> :(Base.$op(m::$T, ::$n) = m))
75+
) broken=((T, op) broken)
76+
end
77+
end
78+
end
79+
@testset "promotion between old int types and new int type" begin
80+
broken = (Bool, UInt8, Int)
81+
@testset "T: $T" for T int_types
82+
@test (
83+
test_expr(n -> :(Base.promote_rule(::Type{$T}, ::Type{$n}) = $T)) &&
84+
test_expr(n -> :(Base.promote_rule(::Type{$n}, ::Type{$T}) = $T))
85+
) broken=(T broken)
86+
end
87+
end
88+
@testset "unary functions" begin
89+
@test test_expr(n -> :(Base.zero(::$n) = $n())) broken=true
90+
@test test_expr(n -> :(Base.one(::$n) = $n())) broken=true
91+
end
92+
end

0 commit comments

Comments
 (0)