@@ -286,57 +286,149 @@ do
286286end
287287
288288
289- do -- errors in __close
290- local log = {}
291- local function foo (err )
289+ -- auxiliary functions for testing warnings in '__close'
290+ local function prepwarn ()
291+ warn (" @off" ) -- do not show (lots of) warnings
292+ if not T then
293+ _WARN = " OFF" -- signal that warnings are not being captured
294+ else
295+ warn (" @store" ) -- to test the warnings
296+ end
297+ end
298+
299+
300+ local function endwarn ()
301+ assert (T or _WARN == " OFF" )
302+ warn (" @on" ) -- back to normal
303+ warn (" @normal" )
304+ _WARN = nil
305+ end
306+
307+
308+ local function checkwarn (msg )
309+ assert (_WARN == " OFF" or string.find (_WARN , msg ))
310+ end
311+
312+
313+ do print (" testing errors in __close" )
314+
315+ prepwarn ()
316+
317+ -- original error is in __close
318+ local function foo ()
319+
292320 local x <close> =
293- func2close (function (self , msg ) log [# log + 1 ] = msg ; error (1 ) end )
321+ func2close (function (self , msg )
322+ assert (string.find (msg , " @z" ))
323+ error (" @x" )
324+ end )
325+
294326 local x1 <close> =
295- func2close (function (self , msg ) log [# log + 1 ] = msg ; end )
327+ func2close (function (self , msg )
328+ checkwarn (" @y" )
329+ assert (string.find (msg , " @z" ))
330+ end )
331+
296332 local gc <close> = func2close (function () collectgarbage () end )
333+
297334 local y <close> =
298- func2close (function (self , msg ) log [# log + 1 ] = msg ; error (2 ) end )
335+ func2close (function (self , msg )
336+ assert (string.find (msg , " @z" )) -- error in 'z'
337+ error (" @y" )
338+ end )
339+
340+ local first = true
299341 local z <close> =
342+ -- 'z' close is called twice
300343 func2close (function (self , msg )
301- log [# log + 1 ] = (msg or 10 ) + 1 ;
302- error (3 )
344+ if first then
345+ assert (msg == nil )
346+ first = false
347+ else
348+ assert (string.find (msg , " @z" )) -- own error
349+ end
350+ error (" @z" )
303351 end )
304- if err then error (4 ) end
352+
353+ return 200
305354 end
355+
306356 local stat , msg = pcall (foo , false )
307- assert (msg == 3 )
308- -- 'z' close is called twice
309- assert (log [1 ] == 11 and log [2 ] == 4 and log [3 ] == 3 and log [4 ] == 3
310- and log [5 ] == 3 and # log == 5 )
357+ assert (string.find (msg , " @z" ))
358+ checkwarn (" @x" )
359+
360+
361+ -- original error not in __close
362+ local function foo ()
363+
364+ local x <close> =
365+ func2close (function (self , msg )
366+ assert (msg == 4 )
367+ end )
368+
369+ local x1 <close> =
370+ func2close (function (self , msg )
371+ checkwarn (" @y" )
372+ assert (msg == 4 )
373+ error (" @x1" )
374+ end )
375+
376+ local gc <close> = func2close (function () collectgarbage () end )
377+
378+ local y <close> =
379+ func2close (function (self , msg )
380+ assert (msg == 4 ) -- error in body
381+ error (" @y" )
382+ end )
383+
384+ local first = true
385+ local z <close> =
386+ func2close (function (self , msg )
387+ checkwarn (" @z" )
388+ -- 'z' close is called once
389+ assert (first and msg == 4 )
390+ first = false
391+ error (" @z" )
392+ end )
393+
394+ error (4 ) -- original error
395+ end
311396
312- log = {}
313397 local stat , msg = pcall (foo , true )
314398 assert (msg == 4 )
315- -- 'z' close is called once
316- assert (log [1 ] == 5 and log [2 ] == 4 and log [3 ] == 4 and log [4 ] == 4
317- and # log == 4 )
399+ checkwarn (" @x1" ) -- last error
318400
319401 -- error leaving a block
320402 local function foo (...)
321403 do
322- local x1 <close> = func2close (function () error (" Y" ) end )
323- local x123 <close> = func2close (function () error (" X" ) end )
404+ local x1 <close> =
405+ func2close (function ()
406+ checkwarn (" @X" )
407+ error (" @Y" )
408+ end )
409+
410+ local x123 <close> =
411+ func2close (function ()
412+ error (" @X" )
413+ end )
324414 end
415+ os.exit (false ) -- should not run
325416 end
326417
327418 local st , msg = xpcall (foo , debug.traceback )
328- assert (string.match (msg , " ^[^ ]* X" ))
419+ assert (string.match (msg , " ^[^ ]* @ X" ))
329420 assert (string.find (msg , " in metamethod 'close'" ))
330421
331422 -- error in toclose in vararg function
332423 local function foo (...)
333- local x123 <close> = func2close (function () error (" X" ) end )
424+ local x123 <close> = func2close (function () error (" @ X" ) end )
334425 end
335426
336427 local st , msg = xpcall (foo , debug.traceback )
337- assert (string.match (msg , " ^[^ ]* X" ))
428+ assert (string.match (msg , " ^[^ ]* @ X" ))
338429
339430 assert (string.find (msg , " in metamethod 'close'" ))
431+ endwarn ()
340432end
341433
342434
361453
362454if rawget (_G , " T" ) then
363455
456+ warn (" @off" )
457+
364458 -- memory error inside closing function
365459 local function foo ()
366460 local y <close> = func2close (function () T .alloccount () end )
@@ -437,7 +531,7 @@ if rawget(_G, "T") then
437531
438532 local s = string.rep (" a" , lim )
439533
440- -- concat this table needs two buffer resizes (one for each 's')
534+ -- concat this table needs two buffer resizes (one for each 's')
441535 local a = {s , s }
442536
443537 collectgarbage ()
@@ -472,6 +566,8 @@ if rawget(_G, "T") then
472566
473567 print ' +'
474568 end
569+
570+ warn (" @on" )
475571end
476572
477573
@@ -501,17 +597,20 @@ end
501597
502598
503599do
600+ prepwarn ()
601+
504602 -- error in a wrapped coroutine raising errors when closing a variable
505603 local x = 0
506604 local co = coroutine.wrap (function ()
507- local xx <close> = func2close (function () x = x + 1 ; error (" YYY" ) end )
508- local xv <close> = func2close (function () x = x + 1 ; error (" XXX" ) end )
605+ local xx <close> = func2close (function () x = x + 1 ; error (" @ YYY" ) end )
606+ local xv <close> = func2close (function () x = x + 1 ; error (" @ XXX" ) end )
509607 coroutine.yield (100 )
510608 error (200 )
511609 end )
512610 assert (co () == 100 ); assert (x == 0 )
513611 local st , msg = pcall (co ); assert (x == 2 )
514612 assert (not st and msg == 200 ) -- should get first error raised
613+ checkwarn (" @YYY" )
515614
516615 local x = 0
517616 local y = 0
526625 assert (x == 2 and y == 1 ) -- first close is called twice
527626 -- should get first error raised
528627 assert (not st and string.find (msg , " %w+%.%w+:%d+: XXX" ))
628+ checkwarn (" YYY" )
629+
630+ endwarn ()
529631end
530632
531633
0 commit comments