On Friday, 16 December 2022 at 13:25:25 UTC, Nick Treleaven wrote:
> This pull disallows throwing an immutable object:
https://github.com/dlang/dmd/pull/14706
You can still throw a const object though, which would work for your enforce
.
Personally, I would prefer to have this resolved by:
- Actually placing immutable data in read only data sections. Why isn't the compiler doing it already?
- Having any immutable exception just fall through mutable catch blocks without matching any of them.
The modification of immutable exception data can be suppressed by defining a custom no-op Throwable.TraceInfo
, something like this:
class EmptyTraceInfo : Throwable.TraceInfo {
int opApply(scope int delegate(ref const(char[]))) const {
return 0;
}
int opApply(scope int delegate(ref size_t, ref const(char[]))) const {
return 0;
}
override string toString() const {
return "sorry, no backtrace here";
}
}
class ImmutableException : Exception {
static immutable empty_trace_info = new EmptyTraceInfo;
@nogc @trusted pure nothrow this(string msg, string file = __FILE__,
size_t line = __LINE__, Throwable nextInChain = null)
{
super(msg, file, line, nextInChain);
info = cast(Throwable.TraceInfo)empty_trace_info;
}
@nogc @trusted pure nothrow this(string msg, Throwable nextInChain,
string file = __FILE__, size_t line = __LINE__)
{
super(msg, file, line, nextInChain);
info = cast(Throwable.TraceInfo)empty_trace_info;
}
}
T enforce(string msg, T)(T cond) {
if (!cond) {
static immutable e = new ImmutableException(msg);
throw e;
}
return cond;
}
The default implementation is the source of GC allocations itself: https://github.com/dlang/dmd/blob/v2.101.1/druntime/src/rt/deh.d#L13-L21
This way immutable exceptions can work perfectly fine without any rogue GC allocations. But losing backtraces isn't nice and I'm trying to see what can be done. Maybe druntime can use its per-thread non-GC allocated storage for this: https://github.com/dlang/dmd/blob/v2.101.1/druntime/src/rt/dwarfeh.d#L146-L165 ?
Using const
instead of immutable
is just hiding the problem and I don't like this.