@@ -194,7 +194,7 @@ module std.experimental.checkedint;
194194import std.traits : isFloatingPoint, isIntegral, isNumeric, isUnsigned, Unqual;
195195
196196// /
197- @system unittest
197+ @safe unittest
198198{
199199 int [] concatAndAdd (int [] a, int [] b, int offset)
200200 {
@@ -996,7 +996,7 @@ if (is(typeof(Checked!(T, Hook)(value))))
996996}
997997
998998// /
999- @system unittest
999+ @safe unittest
10001000{
10011001 static assert (is (typeof (checked(42 )) == Checked! int ));
10021002 assert (checked(42 ) == Checked! int (42 ));
@@ -1159,7 +1159,7 @@ static:
11591159 }
11601160}
11611161
1162- @system unittest
1162+ @safe unittest
11631163{
11641164 void test (T)()
11651165 {
@@ -1368,8 +1368,24 @@ default behavior.
13681368*/
13691369struct Warn
13701370{
1371- import std.stdio : stderr;
13721371static :
1372+
1373+ private void _writefln (Args... )(Args args)
1374+ {
1375+ import std.format : format;
1376+ import std.functional : forward;
1377+ import std.stdio : stderr;
1378+ auto msg = format(args);
1379+ () @trusted {
1380+ import core.thread : thread_resumeAll, thread_suspendAll;
1381+ thread_suspendAll;
1382+ scope (exit) thread_resumeAll;
1383+ scope (failure) assert (0 , " Thread suspension while printing'" ~ msg ~ " ' from CheckedInt failed." );
1384+ // this can be done @safe-ly, because it happens just before the program terminates
1385+ // and all other threads have been suspended
1386+ stderr.lockingTextWriter.put(msg);
1387+ }();
1388+ }
13731389 /**
13741390
13751391 Called automatically upon a bad cast from `src` to type `Dst` (one that
@@ -1385,7 +1401,7 @@ static:
13851401 */
13861402 Dst onBadCast (Dst, Src)(Src src)
13871403 {
1388- stderr.writefln (" Erroneous cast: cast(%s) %s(%s)" ,
1404+ _writefln (" Erroneous cast: cast(%s) %s(%s)" ,
13891405 Dst.stringof, Src.stringof, src);
13901406 return cast (Dst) src;
13911407 }
@@ -1404,14 +1420,14 @@ static:
14041420 */
14051421 Lhs onLowerBound (Rhs, T)(Rhs rhs, T bound)
14061422 {
1407- stderr.writefln (" Lower bound error: %s(%s) < %s(%s)" ,
1423+ _writefln (" Lower bound error: %s(%s) < %s(%s)" ,
14081424 Rhs.stringof, rhs, T.stringof, bound);
14091425 return cast (T) rhs;
14101426 }
14111427 // / ditto
14121428 T onUpperBound (Rhs, T)(Rhs rhs, T bound)
14131429 {
1414- stderr.writefln (" Upper bound error: %s(%s) > %s(%s)" ,
1430+ _writefln (" Upper bound error: %s(%s) > %s(%s)" ,
14151431 Rhs.stringof, rhs, T.stringof, bound);
14161432 return cast (T) rhs;
14171433 }
@@ -1438,7 +1454,7 @@ static:
14381454 auto result = opChecked! " ==" (lhs, rhs, error);
14391455 if (error)
14401456 {
1441- stderr.writefln (" Erroneous comparison: %s(%s) == %s(%s)" ,
1457+ _writefln (" Erroneous comparison: %s(%s) == %s(%s)" ,
14421458 Lhs.stringof, lhs, Rhs.stringof, rhs);
14431459 return lhs == rhs;
14441460 }
@@ -1477,7 +1493,7 @@ static:
14771493 auto result = opChecked! " cmp" (lhs, rhs, error);
14781494 if (error)
14791495 {
1480- stderr.writefln (" Erroneous ordering comparison: %s(%s) and %s(%s)" ,
1496+ _writefln (" Erroneous ordering comparison: %s(%s) and %s(%s)" ,
14811497 Lhs.stringof, lhs, Rhs.stringof, rhs);
14821498 return lhs < rhs ? - 1 : lhs > rhs;
14831499 }
@@ -1510,21 +1526,21 @@ static:
15101526 */
15111527 typeof (~ Lhs()) onOverflow (string x, Lhs)(ref Lhs lhs)
15121528 {
1513- stderr.writefln (" Overflow on unary operator: %s%s(%s)" ,
1529+ _writefln (" Overflow on unary operator: %s%s(%s)" ,
15141530 x, Lhs.stringof, lhs);
15151531 return mixin (x ~ " lhs" );
15161532 }
15171533 // / ditto
15181534 typeof (Lhs() + Rhs()) onOverflow(string x, Lhs, Rhs)(Lhs lhs, Rhs rhs)
15191535 {
1520- stderr.writefln (" Overflow on binary operator: %s(%s) %s %s(%s)" ,
1536+ _writefln (" Overflow on binary operator: %s(%s) %s %s(%s)" ,
15211537 Lhs.stringof, lhs, x, Rhs.stringof, rhs);
15221538 return mixin (" lhs" ~ x ~ " rhs" );
15231539 }
15241540}
15251541
15261542// /
1527- @system unittest
1543+ @safe unittest
15281544{
15291545 auto x = checked! Warn(42 );
15301546 short x1 = cast (short ) x;
0 commit comments