From 62a745327b6330024b6a3a4d6e5c1a6d325a894d Mon Sep 17 00:00:00 2001 From: Fernando Chorney Date: Thu, 11 Jun 2020 14:12:43 -0500 Subject: [PATCH] Add 2 arg @inferred (#706) * Add 2 arg @inferred * Update version to 3.12.0 * Update src/Compat.jl Use using instead of import Co-authored-by: Curtis Vogt Co-authored-by: Curtis Vogt --- Project.toml | 2 +- README.md | 3 +++ src/Compat.jl | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ test/runtests.jl | 9 +++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 0f346dbfb..3884a49e2 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "Compat" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "3.11.0" +version = "3.12.0" [deps] Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" diff --git a/README.md b/README.md index ee611674e..cfe74e35f 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ Please check the list below for the specific syntax you need. ## Supported features +* `@inferred [AllowedType] f(x)` is defined ([#27516]). (since Compat 3.12.0) + * Search a character in a string with `findfirst`, `findnext`, `findlast` and `findprev` ([#31664]). (since Compat 3.12.0) * `∘(f) = f` is defined ([#34251]). (since Compat 3.11.0) @@ -160,3 +162,4 @@ Note that you should specify the correct minimum version for `Compat` in the [#30268]: https://github.com/JuliaLang/julia/pull/30268 [#34251]: https://github.com/JuliaLang/julia/pull/34251 [#35577]: https://github.com/JuliaLang/julia/pull/35577 +[#27516]: https://github.com/JuliaLang/julia/pull/27516 diff --git a/src/Compat.jl b/src/Compat.jl index 76596c381..f379c44e3 100644 --- a/src/Compat.jl +++ b/src/Compat.jl @@ -414,6 +414,56 @@ if VERSION < v"1.5.0-DEV.681" Base.union(r::Base.OneTo, s::Base.OneTo) = Base.OneTo(max(r.stop,s.stop)) end +# https://github.com/JuliaLang/julia/pull/27516 +if VERSION < v"1.2.0-DEV.77" + import Test: @inferred + using Core.Compiler: typesubtract + + macro inferred(allow, ex) + _inferred(ex, __module__, allow) + end + + function _inferred(ex, mod, allow = :(Union{})) + if Meta.isexpr(ex, :ref) + ex = Expr(:call, :getindex, ex.args...) + end + Meta.isexpr(ex, :call)|| error("@inferred requires a call expression") + farg = ex.args[1] + if isa(farg, Symbol) && first(string(farg)) == '.' + farg = Symbol(string(farg)[2:end]) + ex = Expr(:call, GlobalRef(Base.Test, :_materialize_broadcasted), + farg, ex.args[2:end]...) + end + Base.remove_linenums!(quote + let + allow = $(esc(allow)) + allow isa Type || throw(ArgumentError("@inferred requires a type as second argument")) + $(if any(a->(Meta.isexpr(a, :kw) || Meta.isexpr(a, :parameters)), ex.args) + # Has keywords + args = gensym() + kwargs = gensym() + quote + $(esc(args)), $(esc(kwargs)), result = $(esc(Expr(:call, _args_and_call, ex.args[2:end]..., ex.args[1]))) + inftypes = $(gen_call_with_extracted_types(mod, Base.return_types, :($(ex.args[1])($(args)...; $(kwargs)...)))) + end + else + # No keywords + quote + args = ($([esc(ex.args[i]) for i = 2:length(ex.args)]...),) + result = $(esc(ex.args[1]))(args...) + inftypes = Base.return_types($(esc(ex.args[1])), Base.typesof(args...)) + end + end) + @assert length(inftypes) == 1 + rettype = result isa Type ? Type{result} : typeof(result) + rettype <: allow || rettype == typesubtract(inftypes[1], allow) || error("return type $rettype does not match inferred return type $(inftypes[1])") + result + end + end) + end + #export @inferred +end + include("deprecated.jl") end # module Compat diff --git a/test/runtests.jl b/test/runtests.jl index bfbb37079..fd08efe16 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -455,4 +455,13 @@ end @test union(Base.OneTo(3), Base.OneTo(4)) === Base.OneTo(4) end +# https://github.com/JuliaLang/julia/pull/27516 +@testset "two arg @inferred" begin + g(a) = a < 10 ? missing : 1 + @test ismissing(g(9)) + @test g(10) == 1 + @inferred Missing g(9) + @inferred Missing g(10) +end + nothing