From 4bd10b6fe81c0a56eb9e01e24fba10e655966870 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 29 Dec 2020 13:15:54 -0300 Subject: Better error messages for calling non-callable objects When available, use the calling code to find a suitable name for what was being called; this is particularly useful for errors of non-callable metamethods. This commit also improved the debug information for order metamethods. --- testes/db.lua | 6 ++++-- testes/errors.lua | 14 +++++++++++++- testes/locals.lua | 17 ++++++++++++++++- 3 files changed, 33 insertions(+), 4 deletions(-) (limited to 'testes') diff --git a/testes/db.lua b/testes/db.lua index fdb0da4a..ce559ad9 100644 --- a/testes/db.lua +++ b/testes/db.lua @@ -823,8 +823,10 @@ assert(a + 30000 == "add" and a - 3.0 == "sub" and a * 3.0 == "mul" and -a == "unm" and #a == "len" and a & 3 == "band") assert(a|3 == "bor" and 3~a == "bxor" and a<<3 == "shl" and a>>1 == "shr") assert (a==b and a.op == "eq") -assert (a>=b and a.op == "order") -assert (a>b and a.op == "order") +assert (a>=b and a.op == "le") +assert ("x">=a and a.op == "le") +assert (a>b and a.op == "lt") +assert (a>10 and a.op == "lt") assert(~a == "bnot") do -- testing for-iterator name diff --git a/testes/errors.lua b/testes/errors.lua index a3f07021..4249f570 100644 --- a/testes/errors.lua +++ b/testes/errors.lua @@ -24,8 +24,9 @@ local function doit (s) end -local function checkmessage (prog, msg) +local function checkmessage (prog, msg, debug) local m = doit(prog) + if debug then print(m) end assert(string.find(m, msg, 1, true)) end @@ -120,6 +121,17 @@ assert(not string.find(doit"a={13}; local bbbb=1; a[bbbb](3)", "'bbbb'")) checkmessage("a={13}; local bbbb=1; a[bbbb](3)", "number") checkmessage("a=(1)..{}", "a table value") +-- calls +checkmessage("local a; a(13)", "local 'a'") +checkmessage([[ + local a = setmetatable({}, {__add = 34}) + a = a + 1 +]], "metamethod 'add'") +checkmessage([[ + local a = setmetatable({}, {__lt = {}}) + a = a > a +]], "metamethod 'lt'") + -- tail calls checkmessage("local a={}; return a.bbbb(3)", "field 'bbbb'") checkmessage("a={}; do local a=1 end; return a:bbbb(3)", "method 'bbbb'") diff --git a/testes/locals.lua b/testes/locals.lua index 1b43609b..add023ca 100644 --- a/testes/locals.lua +++ b/testes/locals.lua @@ -459,7 +459,22 @@ do -- errors due to non-closable values getmetatable(xyz).__close = nil -- remove metamethod end local stat, msg = pcall(foo) - assert(not stat and string.find(msg, "attempt to call a nil value")) + assert(not stat and string.find(msg, "metamethod 'close'")) + + local function foo () + local a1 = func2close(function (_, msg) + assert(string.find(msg, "number value")) + error(12) + end) + local a2 = setmetatable({}, {__close = print}) + local a3 = func2close(function (_, msg) + assert(msg == nil) + error(123) + end) + getmetatable(a2).__close = 4 -- invalidate metamethod + end + local stat, msg = pcall(foo) + assert(not stat and msg == 12) end -- cgit v1.2.3-55-g6feb