Skip to content

Instantly share code, notes, and snippets.

@genkuroki
Last active September 18, 2020 07:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save genkuroki/bb8896c739616f5fa29a1f5edd2b04e1 to your computer and use it in GitHub Desktop.
Save genkuroki/bb8896c739616f5fa29a1f5edd2b04e1 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "https://docs.julialang.org/en/v1/stdlib/Test/#Test.@inferred\n\nhttps://github.com/JuliaLang/julia/blob/697e782ab86bfcdd7fd15550241fe162c51d9f98/stdlib/Test/src/Test.jl#L1302-L1358"
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "using Test: Test",
"execution_count": 1,
"outputs": []
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "?Test.@inferred",
"execution_count": 2,
"outputs": [
{
"output_type": "execute_result",
"execution_count": 2,
"data": {
"text/plain": "\u001b[36m @inferred [AllowedType] f(x)\u001b[39m\n\n Tests that the call expression \u001b[36mf(x)\u001b[39m returns a value of the same type\n inferred by the compiler. It is useful to check for type stability.\n\n \u001b[36mf(x)\u001b[39m can be any call expression. Returns the result of \u001b[36mf(x)\u001b[39m if the types\n match, and an \u001b[36mError\u001b[39m \u001b[36mResult\u001b[39m if it finds different types.\n\n Optionally, \u001b[36mAllowedType\u001b[39m relaxes the test, by making it pass when either the\n type of \u001b[36mf(x)\u001b[39m matches the inferred type modulo \u001b[36mAllowedType\u001b[39m, or when the\n return type is a subtype of \u001b[36mAllowedType\u001b[39m. This is useful when testing type\n stability of functions returning a small union such as \u001b[36mUnion{Nothing, T}\u001b[39m or\n \u001b[36mUnion{Missing, T}\u001b[39m.\n\n\u001b[36m julia> f(a) = a > 1 ? 1 : 1.0\u001b[39m\n\u001b[36m f (generic function with 1 method)\u001b[39m\n\u001b[36m \u001b[39m\n\u001b[36m julia> typeof(f(2))\u001b[39m\n\u001b[36m Int64\u001b[39m\n\u001b[36m \u001b[39m\n\u001b[36m julia> @code_warntype f(2)\u001b[39m\n\u001b[36m Variables\u001b[39m\n\u001b[36m #self#::Core.Const(f)\u001b[39m\n\u001b[36m a::Int64\u001b[39m\n\u001b[36m \u001b[39m\n\u001b[36m Body::UNION{FLOAT64, INT64}\u001b[39m\n\u001b[36m 1 ─ %1 = (a > 1)::Bool\u001b[39m\n\u001b[36m └── goto #3 if not %1\u001b[39m\n\u001b[36m 2 ─ return 1\u001b[39m\n\u001b[36m 3 ─ return 1.0\u001b[39m\n\u001b[36m \u001b[39m\n\u001b[36m julia> @inferred f(2)\u001b[39m\n\u001b[36m ERROR: return type Int64 does not match inferred return type Union{Float64, Int64}\u001b[39m\n\u001b[36m [...]\u001b[39m\n\u001b[36m \u001b[39m\n\u001b[36m julia> @inferred max(1, 2)\u001b[39m\n\u001b[36m 2\u001b[39m\n\u001b[36m \u001b[39m\n\u001b[36m julia> g(a) = a < 10 ? missing : 1.0\u001b[39m\n\u001b[36m g (generic function with 1 method)\u001b[39m\n\u001b[36m \u001b[39m\n\u001b[36m julia> @inferred g(20)\u001b[39m\n\u001b[36m ERROR: return type Float64 does not match inferred return type Union{Missing, Float64}\u001b[39m\n\u001b[36m [...]\u001b[39m\n\u001b[36m \u001b[39m\n\u001b[36m julia> @inferred Missing g(20)\u001b[39m\n\u001b[36m 1.0\u001b[39m\n\u001b[36m \u001b[39m\n\u001b[36m julia> h(a) = a < 10 ? missing : f(a)\u001b[39m\n\u001b[36m h (generic function with 1 method)\u001b[39m\n\u001b[36m \u001b[39m\n\u001b[36m julia> @inferred Missing h(20)\u001b[39m\n\u001b[36m ERROR: return type Int64 does not match inferred return type Union{Missing, Float64, Int64}\u001b[39m\n\u001b[36m [...]\u001b[39m",
"text/markdown": "```\n@inferred [AllowedType] f(x)\n```\n\nTests that the call expression `f(x)` returns a value of the same type inferred by the compiler. It is useful to check for type stability.\n\n`f(x)` can be any call expression. Returns the result of `f(x)` if the types match, and an `Error` `Result` if it finds different types.\n\nOptionally, `AllowedType` relaxes the test, by making it pass when either the type of `f(x)` matches the inferred type modulo `AllowedType`, or when the return type is a subtype of `AllowedType`. This is useful when testing type stability of functions returning a small union such as `Union{Nothing, T}` or `Union{Missing, T}`.\n\n```jldoctest; setup = :(using InteractiveUtils), filter = r\"begin\\n(.|\\n)*end\"\njulia> f(a) = a > 1 ? 1 : 1.0\nf (generic function with 1 method)\n\njulia> typeof(f(2))\nInt64\n\njulia> @code_warntype f(2)\nVariables\n #self#::Core.Const(f)\n a::Int64\n\nBody::UNION{FLOAT64, INT64}\n1 ─ %1 = (a > 1)::Bool\n└── goto #3 if not %1\n2 ─ return 1\n3 ─ return 1.0\n\njulia> @inferred f(2)\nERROR: return type Int64 does not match inferred return type Union{Float64, Int64}\n[...]\n\njulia> @inferred max(1, 2)\n2\n\njulia> g(a) = a < 10 ? missing : 1.0\ng (generic function with 1 method)\n\njulia> @inferred g(20)\nERROR: return type Float64 does not match inferred return type Union{Missing, Float64}\n[...]\n\njulia> @inferred Missing g(20)\n1.0\n\njulia> h(a) = a < 10 ? missing : f(a)\nh (generic function with 1 method)\n\njulia> @inferred Missing h(20)\nERROR: return type Int64 does not match inferred return type Union{Missing, Float64, Int64}\n[...]\n```\n",
"text/latex": "\\begin{verbatim}\n@inferred [AllowedType] f(x)\n\\end{verbatim}\nTests that the call expression \\texttt{f(x)} returns a value of the same type inferred by the compiler. It is useful to check for type stability.\n\n\\texttt{f(x)} can be any call expression. Returns the result of \\texttt{f(x)} if the types match, and an \\texttt{Error} \\texttt{Result} if it finds different types.\n\nOptionally, \\texttt{AllowedType} relaxes the test, by making it pass when either the type of \\texttt{f(x)} matches the inferred type modulo \\texttt{AllowedType}, or when the return type is a subtype of \\texttt{AllowedType}. This is useful when testing type stability of functions returning a small union such as \\texttt{Union\\{Nothing, T\\}} or \\texttt{Union\\{Missing, T\\}}.\n\n\\begin{verbatim}\njulia> f(a) = a > 1 ? 1 : 1.0\nf (generic function with 1 method)\n\njulia> typeof(f(2))\nInt64\n\njulia> @code_warntype f(2)\nVariables\n #self#::Core.Const(f)\n a::Int64\n\nBody::UNION{FLOAT64, INT64}\n1 ─ %1 = (a > 1)::Bool\n└── goto #3 if not %1\n2 ─ return 1\n3 ─ return 1.0\n\njulia> @inferred f(2)\nERROR: return type Int64 does not match inferred return type Union{Float64, Int64}\n[...]\n\njulia> @inferred max(1, 2)\n2\n\njulia> g(a) = a < 10 ? missing : 1.0\ng (generic function with 1 method)\n\njulia> @inferred g(20)\nERROR: return type Float64 does not match inferred return type Union{Missing, Float64}\n[...]\n\njulia> @inferred Missing g(20)\n1.0\n\njulia> h(a) = a < 10 ? missing : f(a)\nh (generic function with 1 method)\n\njulia> @inferred Missing h(20)\nERROR: return type Int64 does not match inferred return type Union{Missing, Float64, Int64}\n[...]\n\\end{verbatim}\n"
},
"metadata": {}
}
]
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "f(a) = a ≥ 0 ? a : float(a)",
"execution_count": 3,
"outputs": [
{
"output_type": "execute_result",
"execution_count": 3,
"data": {
"text/plain": "f (generic function with 1 method)"
},
"metadata": {}
}
]
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "Test.@inferred f(1.0)",
"execution_count": 4,
"outputs": [
{
"output_type": "execute_result",
"execution_count": 4,
"data": {
"text/plain": "1.0"
},
"metadata": {}
}
]
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "@code_warntype f(1.0)",
"execution_count": 5,
"outputs": [
{
"output_type": "stream",
"text": "Variables\n #self#\u001b[36m::Core.Const(f)\u001b[39m\n a\u001b[36m::Float64\u001b[39m\n\nBody\u001b[36m::Float64\u001b[39m\n\u001b[90m1 ─\u001b[39m %1 = (a ≥ 0)\u001b[36m::Bool\u001b[39m\n\u001b[90m└──\u001b[39m goto #3 if not %1\n\u001b[90m2 ─\u001b[39m return a\n\u001b[90m3 ─\u001b[39m %4 = Main.float(a)\u001b[36m::Float64\u001b[39m\n\u001b[90m└──\u001b[39m return %4\n",
"name": "stdout"
}
]
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "Test.@inferred f(1)",
"execution_count": 6,
"outputs": [
{
"output_type": "error",
"ename": "LoadError",
"evalue": "return type Int64 does not match inferred return type Union{Float64, Int64}",
"traceback": [
"return type Int64 does not match inferred return type Union{Float64, Int64}",
"",
"Stacktrace:",
" [1] error(s::String)",
" @ Base .\\error.jl:33",
" [2] top-level scope",
" @ In[6]:1",
" [3] eval",
" @ .\\boot.jl:345 [inlined]",
" [4] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)",
" @ Base .\\loading.jl:1019"
]
}
]
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "@code_warntype f(1)",
"execution_count": 7,
"outputs": [
{
"output_type": "stream",
"text": "Variables\n #self#\u001b[36m::Core.Const(f)\u001b[39m\n a\u001b[36m::Int64\u001b[39m\n\nBody\u001b[91m\u001b[1m::Union{Float64, Int64}\u001b[22m\u001b[39m\n\u001b[90m1 ─\u001b[39m %1 = (a ≥ 0)\u001b[36m::Bool\u001b[39m\n\u001b[90m└──\u001b[39m goto #3 if not %1\n\u001b[90m2 ─\u001b[39m return a\n\u001b[90m3 ─\u001b[39m %4 = Main.float(a)\u001b[36m::Float64\u001b[39m\n\u001b[90m└──\u001b[39m return %4\n",
"name": "stdout"
}
]
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "Test.@inferred Union{Float64, Int64} f(1)",
"execution_count": 8,
"outputs": [
{
"output_type": "execute_result",
"execution_count": 8,
"data": {
"text/plain": "1"
},
"metadata": {}
}
]
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "g(x, y) = x > 0 ? x : y",
"execution_count": 9,
"outputs": [
{
"output_type": "execute_result",
"execution_count": 9,
"data": {
"text/plain": "g (generic function with 1 method)"
},
"metadata": {}
}
]
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "Test.@inferred g(1, 2)",
"execution_count": 10,
"outputs": [
{
"output_type": "execute_result",
"execution_count": 10,
"data": {
"text/plain": "1"
},
"metadata": {}
}
]
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "Test.@inferred g(1, 2.0)",
"execution_count": 11,
"outputs": [
{
"output_type": "error",
"ename": "LoadError",
"evalue": "return type Int64 does not match inferred return type Union{Float64, Int64}",
"traceback": [
"return type Int64 does not match inferred return type Union{Float64, Int64}",
"",
"Stacktrace:",
" [1] error(s::String)",
" @ Base .\\error.jl:33",
" [2] top-level scope",
" @ In[11]:1",
" [3] eval",
" @ .\\boot.jl:345 [inlined]",
" [4] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)",
" @ Base .\\loading.jl:1019"
]
}
]
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "Test.@inferred Union{Float64, Int64} g(1, 2.0)",
"execution_count": 12,
"outputs": [
{
"output_type": "execute_result",
"execution_count": 12,
"data": {
"text/plain": "1"
},
"metadata": {}
}
]
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "",
"execution_count": null,
"outputs": []
}
],
"metadata": {
"kernelspec": {
"name": "julia-1.6-o3-depwarn",
"display_name": "Julia 1.6.0-DEV depwarn -O3",
"language": "julia"
},
"language_info": {
"file_extension": ".jl",
"name": "julia",
"mimetype": "application/julia",
"version": "1.6.0"
},
"toc": {
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": false,
"base_numbering": 1,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
},
"@webio": {
"lastKernelId": null,
"lastCommId": null
},
"gist": {
"id": "bb8896c739616f5fa29a1f5edd2b04e1",
"data": {
"description": "@inferred",
"public": true
}
},
"_draft": {
"nbviewer_url": "https://gist.github.com/bb8896c739616f5fa29a1f5edd2b04e1"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment