Skip to content

@kwdef fails on structs with supertypes #29307

Closed
@arthurp

Description

@arthurp

This is best explained with an example:

julia> abstract type Super end

julia> Base.@kwdef struct S <: Super; v; end
ERROR: syntax: invalid function name "S <: Super"

julia> @macroexpand Base.@kwdef struct S <: Super; v; end
quote
    #= util.jl:660 =#
    begin
        $(Expr(:meta, :doc))
        struct S1 <: Super
            #= none:1 =#
            v
        end
    end
    (S1 <: Super)(; v) = (S1 <: Super)(v)
end

@kwdef is blindly taking the first argument of the struct Expr and using as the function name. But the first argument includes the supertype when it is present. This means the function name includes the supertype annotation which is invalid.

I think the fix for this is simple and safe: Check for the case where the struct "name" is not a Symbol and further deconstruct it to get the real struct name. Patch below.

From 22f0ccfe0e97ad157aca6a917ccc2c299a1329c8 Mon Sep 17 00:00:00 2001
From: Arthur Peters <[email protected]>
Date: Fri, 21 Sep 2018 12:32:24 -0500
Subject: [PATCH] Fix invalid code generation in @kwdef when struct has
 supertype.

---
 base/util.jl | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/base/util.jl b/base/util.jl
index 80c7907..d27dc03 100644
--- a/base/util.jl
+++ b/base/util.jl
@@ -652,7 +652,12 @@ Stacktrace:
 """
 macro kwdef(expr)
     expr = macroexpand(__module__, expr) # to expand @static
-    T = expr.args[2]
+    if expr.args[2] isa Symbol
+        T = expr.args[2]
+    else
+        @assert expr.args[2].head == :<:
+        T = expr.args[2].args[1]
+    end
     params_ex = Expr(:parameters)
     call_ex = Expr(:call, T)
     _kwdef!(expr.args[3], params_ex, call_ex)
-- 
2.17.1

(I explicitly release my copy rights, if any, to this patch, putting my contribution to this patch in the public domain.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions