diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 84799298f..2cdde32d0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: version: - # - '1.3' # minimum supported version + - '1.3' # minimum supported version - '1' # current stable version os: - ubuntu-latest diff --git a/docs/make.jl b/docs/make.jl index 3076dc4ff..f2435dd72 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -18,6 +18,9 @@ makedocs(; r"(Array{.+,\s?1}|Vector{.+})", # Older versions will show "Array{...,2}" instead of "Matrix{...}". r"(Array{.+,\s?2}|Matrix{.+})", + # Errors from macros sometimes result in `LoadError: LoadError:` + # rather than `LoadError:`, depending on Julia version. + r"ERROR: (LoadError:\s)+", ], ) diff --git a/src/submodel_macro.jl b/src/submodel_macro.jl index 5ffed3c42..230802def 100644 --- a/src/submodel_macro.jl +++ b/src/submodel_macro.jl @@ -212,17 +212,23 @@ function submodel(prefix_expr, expr, ctx=esc(:__context__)) if prefix_left !== :prefix error("$(prefix_left) is not a valid kwarg") end + + # The user expects `@submodel ...` to return the + # return-value of the `...`, hence we need to capture + # the return-value and handle it correctly. + @gensym retval + # `prefix=false` => don't prefix, i.e. do nothing to `ctx`. # `prefix=true` => automatically determine prefix. # `prefix=...` => use it. args_assign = getargs_assignment(expr) return if args_assign === nothing ctx = prefix_submodel_context(prefix, ctx) - # In this case we only want to get the `__varinfo__`. quote - $(esc(:__varinfo__)) = last( - $(DynamicPPL._evaluate!!)($(esc(expr)), $(esc(:__varinfo__)), $(ctx)) + $retval, $(esc(:__varinfo__)) = $(DynamicPPL._evaluate!!)( + $(esc(expr)), $(esc(:__varinfo__)), $(ctx) ) + $retval end else L, R = args_assign @@ -235,9 +241,10 @@ function submodel(prefix_expr, expr, ctx=esc(:__context__)) ) end quote - $(esc(L)), $(esc(:__varinfo__)) = $(DynamicPPL._evaluate!!)( + $retval, $(esc(:__varinfo__)) = $(DynamicPPL._evaluate!!)( $(esc(R)), $(esc(:__varinfo__)), $(ctx) ) + $(esc(L)) = $retval end end end diff --git a/test/compiler.jl b/test/compiler.jl index 4c76cf1ab..0544bb5f6 100644 --- a/test/compiler.jl +++ b/test/compiler.jl @@ -570,5 +570,15 @@ end @model demo() = x ~ Normal() retval, svi = DynamicPPL.evaluate!!(demo(), SimpleVarInfo(), SamplingContext()) + + # Return-value when using `@submodel` + @model inner() = x ~ Normal() + # Without assignment. + @model outer() = @submodel inner() + @test outer()() isa Real + + # With assignment. + @model outer() = @submodel x = inner() + @test outer()() isa Real end end diff --git a/test/runtests.jl b/test/runtests.jl index 3372b6371..dfc8d7acf 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -66,6 +66,9 @@ include("test_util.jl") r"(Array{.+,\s?1}|Vector{.+})", # Older versions will show "Array{...,2}" instead of "Matrix{...}". r"(Array{.+,\s?2}|Matrix{.+})", + # Errors from macros sometimes result in `LoadError: LoadError:` + # rather than `LoadError:`, depending on Julia version. + r"ERROR: (LoadError:\s)+", ] doctest(DynamicPPL; manual=false, doctestfilters=doctestfilters) end diff --git a/test/turing/Project.toml b/test/turing/Project.toml index f8cb2bd63..9c7103841 100644 --- a/test/turing/Project.toml +++ b/test/turing/Project.toml @@ -5,6 +5,6 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" Turing = "fce5fe82-541a-59a6-adf8-730c64b5f9a0" [compat] -DynamicPPL = "0.16" +DynamicPPL = "0.17" Turing = "0.18, 0.19" julia = "1.3"