Skip to content

Commit 0f26966

Browse files
authored
Make sure Core.Compiler can throw kwarg mismatch errors (#50174)
The _new_NamedTuple helper was in a Base-only branch, causing ``` julia> Core.eval(Core.Compiler, quote f(;a=1) = a end) f (generic function with 1 method) julia> Core.Compiler.f(;b=2) ERROR: UndefVarError: `_new_NamedTuple` not defined Stacktrace: [1] macro expansion @ Core.Compiler ./namedtuple.jl:0 [inlined] [2] structdiff(a::@NamedTuple{b::Int64}, b::Type{NamedTuple{(:a,)}}) @ Core.Compiler ./namedtuple.jl:421 [3] top-level scope @ REPL[2]:1 ``` After this change, we have the expected ``` julia> Core.eval(Core.Compiler, quote f(;a=1) = a end) f (generic function with 1 method) julia> Core.Compiler.f(;b=2) ERROR: MethodError: no method matching f(; b::Int64) Closest candidates are: f(; a) got unsupported keyword argument "b" @ Core REPL[13]:1 Stacktrace: [1] kwerr(kw::@NamedTuple{b::Int64}, args::Function) @ Core.Compiler ./error.jl:165 [2] top-level scope @ REPL[14]:1 ```
1 parent 5db2c27 commit 0f26966

File tree

2 files changed

+11
-6
lines changed

2 files changed

+11
-6
lines changed

base/namedtuple.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,6 @@ function NamedTuple{names, T}(nt::NamedTuple) where {names, T <: Tuple}
133133
end
134134
end
135135

136-
# Like NamedTuple{names, T} as a constructor, but omits the additional
137-
# `convert` call, when the types are known to match the fields
138-
@eval function _new_NamedTuple(T::Type{NamedTuple{NTN, NTT}} where {NTN, NTT}, args::Tuple)
139-
$(Expr(:splatnew, :T, :args))
140-
end
141-
142136
function NamedTuple{names}(nt::NamedTuple) where {names}
143137
if @generated
144138
idx = Int[ fieldindex(nt, names[n]) for n in 1:length(names) ]
@@ -161,6 +155,12 @@ NamedTuple{names, Union{}}(itr::Tuple) where {names} = throw(MethodError(NamedTu
161155

162156
end # if Base
163157

158+
# Like NamedTuple{names, T} as a constructor, but omits the additional
159+
# `convert` call, when the types are known to match the fields
160+
@eval function _new_NamedTuple(T::Type{NamedTuple{NTN, NTT}} where {NTN, NTT}, args::Tuple)
161+
$(Expr(:splatnew, :T, :args))
162+
end
163+
164164
length(t::NamedTuple) = nfields(t)
165165
iterate(t::NamedTuple, iter=1) = iter > nfields(t) ? nothing : (getfield(t, iter), iter + 1)
166166
rest(t::NamedTuple) = t

test/compiler/AbstractInterpreter.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,3 +348,8 @@ let NoinlineModule = Module()
348348
@test count(iscall((src, inlined_usually)), src.code) == 0
349349
end
350350
end
351+
352+
# Make sure that Core.Compiler has enough NamedTuple infrastructure
353+
# to properly give error messages for basic kwargs...
354+
Core.eval(Core.Compiler, quote f(;a=1) = a end)
355+
@test_throws MethodError Core.Compiler.f(;b=2)

0 commit comments

Comments
 (0)