Skip to content

Commit

Permalink
fix method definition error for bad vararg (#51300)
Browse files Browse the repository at this point in the history
We had the ordering of tests incorrect, so Vararg was not correctly
checked for validity during method definition.

Fixes #51228
  • Loading branch information
vtjnash authored and NHDaly committed Sep 20, 2023
1 parent a4ee695 commit 386876f
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 9 deletions.
19 changes: 10 additions & 9 deletions src/method.c
Original file line number Diff line number Diff line change
Expand Up @@ -1044,9 +1044,16 @@ JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata,

for (i = 0; i < na; i++) {
jl_value_t *elt = jl_svecref(atypes, i);
int isvalid = jl_is_type(elt) || jl_is_typevar(elt) || jl_is_vararg(elt);
if (elt == jl_bottom_type || (jl_is_vararg(elt) && jl_unwrap_vararg(elt) == jl_bottom_type))
isvalid = 0;
if (jl_is_vararg(elt)) {
if (i < na-1)
jl_exceptionf(jl_argumenterror_type,
"Vararg on non-final argument in method definition for %s at %s:%d",
jl_symbol_name(name),
jl_symbol_name(file),
line);
elt = jl_unwrap_vararg(elt);
}
int isvalid = (jl_is_type(elt) || jl_is_typevar(elt) || jl_is_vararg(elt)) && elt != jl_bottom_type;
if (!isvalid) {
jl_sym_t *argname = (jl_sym_t*)jl_array_ptr_ref(f->slotnames, i);
if (argname == jl_unused_sym)
Expand All @@ -1064,12 +1071,6 @@ JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata,
jl_symbol_name(file),
line);
}
if (jl_is_vararg(elt) && i < na-1)
jl_exceptionf(jl_argumenterror_type,
"Vararg on non-final argument in method definition for %s at %s:%d",
jl_symbol_name(name),
jl_symbol_name(file),
line);
}
for (i = jl_svec_len(tvars); i > 0; i--) {
jl_value_t *tv = jl_svecref(tvars, i - 1);
Expand Down
4 changes: 4 additions & 0 deletions test/syntax.jl
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,10 @@ let m_error, error_out, filename = Base.source_path()
m_error = try @eval foo(types::NTuple{N}, values::Vararg{Any,N}, c) where {N} = nothing; catch e; e; end
error_out = sprint(showerror, m_error)
@test startswith(error_out, "ArgumentError: Vararg on non-final argument")

m_error = try @eval method_c6(a::Vararg{:A}) = 1; catch e; e; end
error_out = sprint(showerror, m_error)
@test startswith(error_out, "ArgumentError: invalid type for argument a in method definition for method_c6 at $filename:")
end

# issue #7272
Expand Down

0 comments on commit 386876f

Please sign in to comment.