Skip to content

Commit

Permalink
fix some bitrot in inline_incompletematch (from #7075) now that #10380
Browse files Browse the repository at this point in the history
…is merged and it works & can be tested
  • Loading branch information
vtjnash committed Apr 26, 2015
1 parent d3843d0 commit 965561a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
5 changes: 3 additions & 2 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2319,8 +2319,9 @@ function inlineable(f::ANY, e::Expr, atype::ANY, sv::StaticVarInfo, enclosing_as
push!(newcall.args, argtype===Any ? name : SymbolNode(name, argtype))
end
body.args = Any[Expr(:return, newcall)]
ast = Expr(:lambda, newnames, Any[[], locals, []], body)
ast = Expr(:lambda, newnames, Any[[], locals, [], 0], body)
need_mod_annotate = false
needcopy = false
else
return NF
end
Expand Down Expand Up @@ -2435,7 +2436,7 @@ function inlineable(f::ANY, e::Expr, atype::ANY, sv::StaticVarInfo, enclosing_as
argexprs2 = t.args
icall = LabelNode(label_counter(body.args)+1)
partmatch = Expr(:gotoifnot, false, icall.label)
thrw = Expr(:call, :throw, Expr(:call, Main.Base.MethodError, (f, :inline), t))
thrw = Expr(:call, :throw, Expr(:call, TopNode(:MethodError), Expr(:call, top_tuple, e.args[1], QuoteNode(:inline)), t))

This comment has been minimized.

Copy link
@JeffBezanson

JeffBezanson Apr 26, 2015

Member

This is kind of a hack; nobody would expect MethodError.f to be a tuple. I think it's too obscure.

This comment has been minimized.

Copy link
@vtjnash

vtjnash Apr 26, 2015

Author Member

would it be better to add a field, or just drop it entirely? it is certainly a bit of a hack, but it helps with tracing no method errors back to type inference errors.

thrw.typ = Bottom
end

Expand Down
33 changes: 22 additions & 11 deletions base/replutil.jl
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,15 @@ showerror(io::IO, ex::AssertionError) = print(io, "AssertionError: $(ex.msg)")

function showerror(io::IO, ex::MethodError)
print(io, "MethodError: ")
name = isgeneric(ex.f) ? ex.f.env.name : :anonymous
if isa(ex.f, DataType)
print(io, "`$(ex.f)` has no method matching $(ex.f)(")
if isa(ex.f, Tuple)
f = ex.f[1]
print(io, "<inline> ")
else
f = ex.f
end
name = isgeneric(f) ? f.env.name : :anonymous
if isa(f, DataType)
print(io, "`$(f)` has no method matching $(f)(")
else
print(io, "`$(name)` has no method matching $(name)(")
end
Expand All @@ -138,10 +144,10 @@ function showerror(io::IO, ex::MethodError)
i == length(ex.args) || print(io, ", ")
end
print(io, ")")
# Check for local functions that shaddow methods in Base
# Check for local functions that shadow methods in Base
if isdefined(Base, name)
f = eval(Base, name)
if f !== ex.f && isgeneric(f) && applicable(f, ex.args...)
basef = eval(Base, name)
if basef !== f && isgeneric(basef) && applicable(basef, ex.args...)
println(io)
print(io, "you may have intended to import Base.$(name)")
end
Expand All @@ -154,14 +160,14 @@ function showerror(io::IO, ex::MethodError)
hasrows |= isrow
push!(vec_args, isrow ? vec(arg) : arg)
end
if hasrows && applicable(ex.f, vec_args...)
if hasrows && applicable(f, vec_args...)
print(io, "\n\nYou might have used a 2d row vector where a 1d column vector was required.")
print(io, "\nNote the difference between 1d column vector [1,2,3] and 2d row vector [1 2 3].")
print(io, "\nYou can convert to a column vector with the vec() function.")
end
# Give a helpful error message if the user likely called a type constructor
# and sees a no method error for convert
if ex.f == Base.convert && !isempty(ex.args) && isa(ex.args[1], Type)
if f == Base.convert && !isempty(ex.args) && isa(ex.args[1], Type)
println(io)
print(io, "This may have arisen from a call to the constructor $(ex.args[1])(...),")
print(io, "\nsince type constructors fall back to convert methods.")
Expand All @@ -175,16 +181,21 @@ const UNSHOWN_METHODS = ObjectIdDict(
function show_method_candidates(io::IO, ex::MethodError)
# Displays the closest candidates of the given function by looping over the
# functions methods and counting the number of matching arguments.
if isa(ex.f, Tuple)
f = ex.f[1]
else
f = ex.f
end

lines = []
# These functions are special cased to only show if first argument is matched.
special = ex.f in [convert, getindex, setindex!]
funcs = [ex.f]
special = f in [convert, getindex, setindex!]
funcs = [f]

# An incorrect call method produces a MethodError for convert.
# It also happens that users type convert when they mean call. So
# pool MethodErrors for these two functions.
ex.f === convert && push!(funcs, call)
f === convert && push!(funcs, call)

for func in funcs
name = isgeneric(func) ? func.env.name : :anonymous
Expand Down

0 comments on commit 965561a

Please sign in to comment.