Skip to content

Commit 7e37de4

Browse files
kamalojasv181KristofferC
andauthored
improve type definition super type errors (JuliaLang#34510)
Makes the error message more precise and descriptive for each error that could occur when defining a new subtype. Co-authored-by: KristofferC <kristoffer.carlsson@juliacomputing.com>
1 parent 934b40c commit 7e37de4

File tree

3 files changed

+38
-11
lines changed

3 files changed

+38
-11
lines changed

src/builtins.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,16 +1563,25 @@ JL_CALLABLE(jl_f__primitivetype)
15631563

15641564
static void jl_set_datatype_super(jl_datatype_t *tt, jl_value_t *super)
15651565
{
1566-
if (!jl_is_datatype(super) || !jl_is_abstracttype(super) ||
1567-
tt->super != NULL ||
1568-
tt->name == ((jl_datatype_t*)super)->name ||
1569-
jl_is_tuple_type(super) ||
1570-
jl_is_namedtuple_type(super) ||
1571-
jl_subtype(super, (jl_value_t*)jl_type_type) ||
1572-
jl_subtype(super, (jl_value_t*)jl_builtin_type)) {
1573-
jl_errorf("invalid subtyping in definition of %s",
1574-
jl_symbol_name(tt->name->name));
1575-
}
1566+
const char *error = NULL;
1567+
if (!jl_is_datatype(super))
1568+
error = "can only subtype data types";
1569+
else if (tt->super != NULL)
1570+
error = "type already has a supertype";
1571+
else if (tt->name == ((jl_datatype_t*)super)->name)
1572+
error = "a type cannot subtype itself";
1573+
else if (jl_is_tuple_type(super))
1574+
error = "cannot subtype a tuple type";
1575+
else if (jl_is_namedtuple_type(super))
1576+
error = "cannot subtype a named tuple type";
1577+
else if (jl_subtype(super, (jl_value_t*)jl_type_type))
1578+
error = "cannot add subtypes to Type";
1579+
else if (jl_subtype(super, (jl_value_t*)jl_builtin_type))
1580+
error = "cannot add subtypes to Core.Builtin";
1581+
else if (!jl_is_abstracttype(super))
1582+
error = "can only subtype abstract types";
1583+
if (error)
1584+
jl_errorf("invalid subtyping in definition of %s: %s.", jl_symbol_name(tt->name->name), error);
15761585
tt->super = (jl_datatype_t*)super;
15771586
jl_gc_wb(tt, tt->super);
15781587
}

test/errorshow.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,3 +903,21 @@ end
903903
@test contains(err_str, "maybe you meant `import/using .Bar`")
904904
end
905905
end
906+
907+
for (expr, errmsg) in
908+
[
909+
(:(struct Foo <: 1 end), "can only subtype data types"),
910+
(:(struct Foo <: Float64 end), "can only subtype abstract types"),
911+
(:(struct Foo <: Foo end), "a type cannot subtype itself"),
912+
(:(struct Foo <: Tuple{Float64} end), "cannot subtype a tuple type"),
913+
(:(struct Foo <: NamedTuple{(:a,), Tuple{Int64}} end), "cannot subtype a named tuple type"),
914+
(:(struct Foo <: Type{Float64} end), "cannot add subtypes to Type"),
915+
(:(struct Foo <: Type{Float64} end), "cannot add subtypes to Type"),
916+
(:(struct Foo <: typeof(Core.apply_type) end), "cannot add subtypes to Core.Builtin"),
917+
]
918+
err = try @eval $expr
919+
catch e
920+
e
921+
end
922+
@test contains(sprint(showerror, err), errmsg)
923+
end

test/subtype.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1247,7 +1247,7 @@ end
12471247

12481248
# Issue #19414
12491249
let ex = try struct A19414 <: Base.AbstractSet end catch e; e end
1250-
@test isa(ex, ErrorException) && ex.msg == "invalid subtyping in definition of A19414"
1250+
@test isa(ex, ErrorException) && ex.msg == "invalid subtyping in definition of A19414: can only subtype data types."
12511251
end
12521252

12531253
# issue #20103, OP and comments

0 commit comments

Comments
 (0)