November 20, 2022
https://issues.dlang.org/show_bug.cgi?id=17226

--- Comment #10 from Ali Cehreli <acehreli@yahoo.com> ---
(In reply to Paul Backus from comment #7)

> if the message expression throws, the assert's condition is never evaluated, and the program does not enter an invalid state.

Wait a minute... :) It shouldn't be the assert expression itself that puts the program into invalid state. assert throws because the program is already in an invalid state. Removing the evaluation of the assert expression does not change that fact.

If we accept that point, then even attempting to evaluate the assert expression is best-effort when the program is in an invalid state.

That and my earlier observation about attempting to dump call stack proves we are already in a best-effort business when the program is in invalid state.

--
November 23, 2022
https://issues.dlang.org/show_bug.cgi?id=17226

Bolpat <qs.il.paperinik@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |qs.il.paperinik@gmail.com

--- Comment #11 from Bolpat <qs.il.paperinik@gmail.com> ---
As Timon pointed out, requiring the evaluation of the assert msg to be nothrow is a limitation, I don’t think it is a major limitation. `assumeWontThrow` [1] is well-suited for this purpose.

I don’t think that
```d
import std.exception : assumeWontThrow;
assert(condition, assumeWontThrow(potentially throwing expr));
```
is too much to ask for. It documents clearly that the message-generating
expression could throw. That way, an Exception thrown by the message-generating
expression does not hide a bug.

[1] https://dlang.org/phobos/std_exception.html#assumeWontThrow

--
December 08, 2022
https://issues.dlang.org/show_bug.cgi?id=17226

Steven Schveighoffer <schveiguy@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |schveiguy@gmail.com

--- Comment #12 from Steven Schveighoffer <schveiguy@gmail.com> ---
What about creating a wrapper for format:

```d
string assertFormat(Args...)(string fmt, Args args)
{
   try {
     return format(fmt, args);
   } catch(Exception ex) {
     return "Error while evaluating assert message: " ~ ex.toString;
   }
}


// use like
assert(i == 42, assertFormat("Something %s", functionThatThrows()));
```

This solves the problem, and also doesn't throw away any information. Plus it's not unpleasant to use.

Yes, it's opt in. So what? It can just be a best practice recommendation.

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=17226

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P2

--
February 04, 2023
https://issues.dlang.org/show_bug.cgi?id=17226

Salih Dincer <salihdb@hotmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |salihdb@hotmail.com

--- Comment #13 from Salih Dincer <salihdb@hotmail.com> ---
(In reply to Steven Schveighoffer from comment #12)
> What about creating a wrapper for format:
> 
> ```d
> string assertFormat(Args...)(string fmt, Args args)
> {
>    try {
>      return format(fmt, args);
>    } catch(Exception ex) {
>      return "Error while evaluating assert message: " ~ ex.toString;
>    }
> }
> 
> 
> // use like
> assert(i == 42, assertFormat("Something %s", functionThatThrows()));
> ```
> 
> This solves the problem, and also doesn't throw away any information. Plus it's not unpleasant to use.
> 
> Yes, it's opt in. So what? It can just be a best practice recommendation.

alias format = assertFormat; /*
import std.format;//*/

auto foo(T)(T P) {
  //assert(P == 43, format("T: %s", T.stringof));/*
  static assert(is(T == uint), format("T:", "int"));//*/
}

> onlineapp.d(6): Error: static assert:  "Error while evaluating assert message: FormatException@/dlang/dmd/linux/bin64/../../src/phobos/std/format/package.d(785): Orphan format arguments: args[0..1]"
> onlineapp.d(13):        instantiated from here: `foo!int`

I think the problem is also with static. Because above is static assert I got at compile time.  But I got such 4 errors message with the following library possibilities (without assertFormat):

> /dlang/dmd/linux/bin64/../../src/phobos/std/exception.d(518): Error: uncaught CTFE exception `std.format.FormatException("Orphan format arguments: args[0..1]")`
> onlineapp.d(6):        called from here: `format("T:", "int")`
> onlineapp.d(6): Error: static assert:  __error
> onlineapp.d(13):        instantiated from here: `foo!int`


//alias format = assertFormat; /*
import std.format;//*/

auto foo(T)(T P) {
  //assert(P == 43, format("T: %s", T.stringof));/*
  static assert(is(T == uint), format("T:", "int"));//*/
}

import std.stdio;
void main() {
  enum char D = 68;
  assertFormat("Hello %s and World", D).writeln;
  foo!int(42);
}
string assertFormat(Args...)(string fmt, Args args)
{
  import std.format : _format = format;
  try
  {
    return _format(fmt, args);
  }
  catch(Exception ex)
  {
    enum m = "Error while evaluating assert message: ";
    return m ~ ex.toString;
  }
}

SDB@79

--
1 2
Next ›   Last »