From b87a50ade33172069464aacf464e54b8f09af7cf Mon Sep 17 00:00:00 2001 From: David Widmann Date: Tue, 8 Mar 2022 23:38:03 +0100 Subject: [PATCH 1/5] Fix anonymous argument with type parameter --- Project.toml | 2 +- src/compiler.jl | 2 +- test/compiler.jl | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index ede0b23f5..7d025634a 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DynamicPPL" uuid = "366bfd00-2699-11ea-058f-f148b4cae6d8" -version = "0.17.9" +version = "0.17.10" [deps] AbstractMCMC = "80f14c24-f653-4e6a-9b94-39d6b0f70001" diff --git a/src/compiler.jl b/src/compiler.jl index e851dd310..37bf7fbf3 100644 --- a/src/compiler.jl +++ b/src/compiler.jl @@ -262,7 +262,7 @@ function build_model_info(input_expr) # Extract the names of the arguments. allargs_syms = map(allargs_exprs) do arg MacroTools.@match arg begin - (::Type{T_}) | (name_::Type{T_}) => T + (::S_{T_}) | (name_::Type{T_}) => T name_::T_ => name x_ => x end diff --git a/test/compiler.jl b/test/compiler.jl index 8babe32ac..f59f013ac 100644 --- a/test/compiler.jl +++ b/test/compiler.jl @@ -602,4 +602,10 @@ end @test !DynamicPPL.hasmissing(Matrix{Real}) @test !DynamicPPL.hasmissing(Vector{Matrix{Float32}}) end + + @testset "issue #393: anonymous argument with type parameter" begin + @model f_393(::Val{ispredict}=Val(false)) where {ispredict} = ispredict ? 0 : 1 + @test f_393()() == 1 + @test f_393(Val(true))() == 0 + end end From 2272a8310b130678a1d10317cba084c260aecce0 Mon Sep 17 00:00:00 2001 From: David Widmann Date: Wed, 9 Mar 2022 21:29:24 +0100 Subject: [PATCH 2/5] Add gensymed names to unnamed arguments --- src/compiler.jl | 6 ++++-- src/utils.jl | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/compiler.jl b/src/compiler.jl index 37bf7fbf3..ee763a3c6 100644 --- a/src/compiler.jl +++ b/src/compiler.jl @@ -245,6 +245,9 @@ function build_model_info(input_expr) return modelinfo end + # Ensure that all arguments have a name, i.e., are of the form `name` or `name::T` + addargnames!(modeldef[:args]) + # Extract the positional and keyword arguments from the model definition. allargs = vcat(modeldef[:args], modeldef[:kwargs]) @@ -262,8 +265,7 @@ function build_model_info(input_expr) # Extract the names of the arguments. allargs_syms = map(allargs_exprs) do arg MacroTools.@match arg begin - (::S_{T_}) | (name_::Type{T_}) => T - name_::T_ => name + (name_::_) => name x_ => x end end diff --git a/src/utils.jl b/src/utils.jl index d8f9090d1..043e54f8c 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -74,6 +74,48 @@ macro addlogprob!(ex) end end +""" + addargnames!(args) + +Adds names to unnamed arguments in `args`. + +The names are generated with `gensym(:arg)` to avoid conflicts with other variable names. + +# Examples + +```jldoctest +julia> args = :(f(x::Int, y, ::Type{T}=Float64)).args[2:end] +3-element Vector{Any}: + :(x::Int) + :y + :($(Expr(:kw, :(::Type{T}), :Float64))) + +julia> addargnames!(args) + +julia> args +3-element Vector{Any}: + :(x::Int) + :y + :($(Expr(:kw, :(var"##arg#301"::Type{T}), :Float64))) +``` +""" +function addargnames!(args) + if isempty(args) + return nothing + end + + @inbounds for i in eachindex(args) + arg = args[i] + if MacroTools.@capture(arg, ::T_) + args[i] = Expr(:(::), gensym(:arg), T) + elseif MacroTools.@capture(arg, ::T_ = val_) + args[i] = Expr(:kw, Expr(:(::), gensym(:arg), T), val) + end + end + + return nothing +end + """ getargs_dottilde(x) From 3d717fdb4bcbf91c923bc0d288e7954adea09f92 Mon Sep 17 00:00:00 2001 From: David Widmann Date: Wed, 9 Mar 2022 21:34:09 +0100 Subject: [PATCH 3/5] Fix doctest --- src/utils.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.jl b/src/utils.jl index 043e54f8c..f9a3327c9 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -90,7 +90,7 @@ julia> args = :(f(x::Int, y, ::Type{T}=Float64)).args[2:end] :y :($(Expr(:kw, :(::Type{T}), :Float64))) -julia> addargnames!(args) +julia> DynamicPPL.addargnames!(args) julia> args 3-element Vector{Any}: From b099e2740aeb01d6949906378aa68edbcff46ce4 Mon Sep 17 00:00:00 2001 From: David Widmann Date: Wed, 9 Mar 2022 21:43:55 +0100 Subject: [PATCH 4/5] Add doctest filter --- src/utils.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.jl b/src/utils.jl index f9a3327c9..ffc3ef98d 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -83,7 +83,7 @@ The names are generated with `gensym(:arg)` to avoid conflicts with other variab # Examples -```jldoctest +```jldoctest; filter = r"var\"##arg#[0-9]+\"" julia> args = :(f(x::Int, y, ::Type{T}=Float64)).args[2:end] 3-element Vector{Any}: :(x::Int) From 1ede7b17311b83f398865cbb83981e4fa58cef49 Mon Sep 17 00:00:00 2001 From: David Widmann Date: Wed, 9 Mar 2022 21:50:14 +0100 Subject: [PATCH 5/5] Escape " --- src/utils.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.jl b/src/utils.jl index ffc3ef98d..821eba38e 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -83,7 +83,7 @@ The names are generated with `gensym(:arg)` to avoid conflicts with other variab # Examples -```jldoctest; filter = r"var\"##arg#[0-9]+\"" +```jldoctest; filter = r"var\\"##arg#[0-9]+\\"" julia> args = :(f(x::Int, y, ::Type{T}=Float64)).args[2:end] 3-element Vector{Any}: :(x::Int)