From edfdb7114a05cde58a0c88eb6f9548e85efb6f99 Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Sun, 10 Apr 2016 09:52:13 -0400 Subject: [PATCH] Show variable names and remove spurious type warning in typed ast. Fixes #15714 --- base/interactiveutil.jl | 3 ++- base/show.jl | 32 ++++++++++++++++++++++++++++---- test/reflection.jl | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/base/interactiveutil.jl b/base/interactiveutil.jl index 586ffcf936d86..653ebae0ef2ff 100644 --- a/base/interactiveutil.jl +++ b/base/interactiveutil.jl @@ -237,7 +237,8 @@ function code_warntype(io::IO, f, t::ANY) print(emph_io, "\nBody:\n ") body = Expr(:body); body.args = uncompressed_ast(li) body.typ = li.rettype - show_unquoted(emph_io, body, 2) + # Fix slot names and types in function body + show_unquoted(IOContext(emph_io, :LAMBDAINFO => li), body, 2) print(emph_io, '\n') end nothing diff --git a/base/show.jl b/base/show.jl index 8099aab04c04a..f880a11683eda 100644 --- a/base/show.jl +++ b/base/show.jl @@ -210,9 +210,11 @@ end function show(io::IO, l::LambdaInfo) println(io, "LambdaInfo for ", l.name) + # Fix slot names and types in function body + lambda_io = IOContext(io, :LAMBDAINFO => l) body = Expr(:body); body.args = uncompressed_ast(l) body.typ = l.rettype - show(io, body) + show(lambda_io, body) end function show_delim_array(io::IO, itr::Union{AbstractArray,SimpleVector}, op, delim, cl, delim_one, @@ -496,10 +498,32 @@ show_unquoted(io::IO, ex::TopNode, ::Int, ::Int) = print(io,"top(",ex.nam show_unquoted(io::IO, ex::GlobalRef, ::Int, ::Int) = print(io, ex.mod, '.', ex.name) function show_unquoted(io::IO, ex::Slot, ::Int, ::Int) - print(io, "_", ex.id) + li = get(io, :LAMBDAINFO, false) + typ = ex.typ + slotid = ex.id + name_printed = false + if isa(li, LambdaInfo) + li = li::LambdaInfo + slotnames = li.slotnames + if isa(slotnames, Array) && slotid <= length(slotnames::Array) + name = li.slotnames[slotid] + print(io, name) + name_printed = true + end + slottypes = li.slottypes + if isa(slottypes, Array) && slotid <= length(slottypes::Array) + slottype = li.slottypes[slotid] + # The Slot in assignment can somehow have a Any type + slottype <: typ && (typ = slottype) + end + end + if !name_printed + print(io, '_') + end + print(io, '@', slotid) emphstate = typeemphasize(io) - if emphstate || ex.typ !== Any - show_expr_type(io, ex.typ, emphstate) + if emphstate || typ !== Any + show_expr_type(io, typ, emphstate) end end diff --git a/test/reflection.jl b/test/reflection.jl index e7c747a915769..650219dbef400 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -278,3 +278,44 @@ let @test methods(m,Tuple{Int, Int})[1]==@which MacroTest.@macrotest 1 1 @test functionloc(@which @macrotest 1 1) == @functionloc @macrotest 1 1 end + +# issue #15714 +# show variable names for slots and suppress spurious type warnings +function f15714(array_var15714) + for index_var15714 in eachindex(array_var15714) + array_var15714[index_var15714] += 0 + end +end + +let str, li = code_typed(f15714, Tuple{Vector{Float32}})[1] + for str in (sprint(io->code_warntype(io, f15714, Tuple{Vector{Float32}})), + sprint(io->show(io, li))) + @test contains(str, "index_var15714@") + @test contains(str, "array_var15714@") + @test !contains(str, "Any") + @test !contains(str, "ANY") + # Check that we are not printing the bare slot numbers + for i in 1:length(li.slotnames) + @test !contains(str, "_@$i") + end + end + # Make sure printing an AST outside LambdaInfo still works. + str = sprint(io->show(io, Base.uncompressed_ast(li))) + index_var_found = false + array_var_found = false + # Check that we are printing the slot numbers when we don't have the context + # Use the variable names that we know should be present in the optimized AST + for i in 2:length(li.slotnames) + if li.slotnames[i] === :index_var15714 + index_var_found = true + elseif li.slotnames[i] === :array_var15714 + array_var_found = true + else + continue + end + @test contains(str, "_@$i") + end + # Make sure the variables are found and we actually tested something above. + @test index_var_found + @test array_var_found +end