5
5
* by the compiler whenever `-checkaction=context` is used.
6
6
* There are two hooks, one for unary expressions, and one for binary.
7
7
* When used, the compiler will rewrite `assert(a >= b)` as
8
- * `assert(a >= b, _d_assert_fail!">="( a, b))`.
8
+ * `assert(a >= b, _d_assert_fail!(typeof(a))( ">=", a, b))`.
9
9
* Temporaries will be created to avoid side effects if deemed necessary
10
10
* by the compiler.
11
11
*
@@ -80,7 +80,7 @@ template _d_assert_fail(A...)
80
80
}
81
81
}
82
82
83
- // / Combines the supplied arguments into one string "valA token valB"
83
+ // / Combines the supplied arguments into one string ` "valA token valB"`
84
84
private string combine (const scope string [] valA, const scope string token,
85
85
const scope string [] valB) pure nothrow @nogc @safe
86
86
{
@@ -127,8 +127,7 @@ private string combine(const scope string[] valA, const scope string token,
127
127
return (() @trusted => cast (string ) buffer)();
128
128
}
129
129
130
- // Yields the appropriate printf format token for a type T
131
- // Indended to be used by miniFormat
130
+ // / Yields the appropriate `printf` format token for a type `T`
132
131
private template getPrintfFormat (T)
133
132
{
134
133
static if (is (T == long ))
@@ -157,13 +156,28 @@ private template getPrintfFormat(T)
157
156
}
158
157
159
158
/**
160
- Minimalistic formatting for use in _d_assert_fail to keep the compilation
161
- overhead small and avoid the use of Phobos.
162
- */
159
+ * Generates a textual representation of `v` without relying on Phobos.
160
+ * The value is formatted as follows:
161
+ *
162
+ * - primitive types and arrays yield their respective literals
163
+ * - pointers are printed as hexadecimal numbers
164
+ * - enum members are represented by their name
165
+ * - user-defined types are formatted by either calling `toString`
166
+ * if defined or printing all members, e.g. `S(1, 2)`
167
+ *
168
+ * Note that unions are rejected because this method cannot determine which
169
+ * member is valid when calling this method.
170
+ *
171
+ * Params:
172
+ * v = the value to print
173
+ *
174
+ * Returns: a string respresenting `v` or `V.stringof` if `V` is not supported
175
+ */
163
176
private string miniFormat (V)(const scope ref V v)
164
177
{
165
178
import core.internal.traits : isAggregateType;
166
179
180
+ // / `shared` values are formatted as their base type
167
181
static if (is (V == shared T, T))
168
182
{
169
183
// Use atomics to avoid race conditions whenever possible
@@ -199,6 +213,7 @@ private string miniFormat(V)(const scope ref V v)
199
213
{
200
214
return v ? " true" : " false" ;
201
215
}
216
+ // Detect vectors which match isIntegral / isFloating
202
217
else static if (is (V == __vector (ET [N]), ET , size_t N))
203
218
{
204
219
string msg = " [" ;
@@ -249,6 +264,7 @@ private string miniFormat(V)(const scope ref V v)
249
264
import core.stdc.stdio : sprintf;
250
265
import core.stdc.config : LD = c_long_double;
251
266
267
+ // No suitable replacement for sprintf in druntime ATM
252
268
if (__ctfe)
253
269
return ' <' ~ V.stringof ~ " not supported>" ;
254
270
@@ -461,7 +477,7 @@ private bool[] calcFieldOverlap(const scope size_t[] offsets)
461
477
// -> core.atomic -> core.thread -> core.thread.osthread
462
478
import core.atomic : atomicLoad;
463
479
464
- // Inverts a comparison token for use in _d_assert_fail
480
+ // / Negates a comparison token, e.g. `==` is mapped to `!=`
465
481
private string invertCompToken (scope string comp) pure nothrow @nogc @safe
466
482
{
467
483
switch (comp)
@@ -491,6 +507,7 @@ private string invertCompToken(scope string comp) pure nothrow @nogc @safe
491
507
}
492
508
}
493
509
510
+ // / Casts the function pointer to include `@safe`, `@nogc`, ...
494
511
private auto assumeFakeAttributes (T)(T t) @trusted
495
512
{
496
513
import core.internal.traits : Parameters, ReturnType;
@@ -500,12 +517,15 @@ private auto assumeFakeAttributes(T)(T t) @trusted
500
517
return cast (type) t;
501
518
}
502
519
520
+ // / Wrapper for `miniFormat` which assumes that the implementation is `@safe`, `@nogc`, ...
521
+ // / s.t. it does not violate the constraints of the the function containing the `assert`.
503
522
private string miniFormatFakeAttributes (T)(const scope ref T t)
504
523
{
505
524
alias miniT = miniFormat! T;
506
525
return assumeFakeAttributes (&miniT)(t);
507
526
}
508
527
528
+ // / Allocates an array of `t` bytes while pretending to be `@safe`, `@nogc`, ...
509
529
private auto pureAlloc (size_t t)
510
530
{
511
531
static auto alloc (size_t len)
0 commit comments