From 313151b1005777201c9f2f9fae9d94e6867787f5 Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Thu, 3 Sep 2026 03:03:24 -0700 Subject: [PATCH 1/7] Add DDoc behavior flags for noalloc/nogc/nothrow/pure. --- compiler/src/dmd/doc.d | 118 +++++++++++++++++++ compiler/src/dmd/res/default_ddoc_theme.ddoc | 32 +++++ 2 files changed, 150 insertions(+) diff --git a/compiler/src/dmd/doc.d b/compiler/src/dmd/doc.d index 34327ee4419b..18f89de7b694 100644 --- a/compiler/src/dmd/doc.d +++ b/compiler/src/dmd/doc.d @@ -1344,6 +1344,122 @@ void emitVisibility(ref OutBuffer buf, Visibility vis) buf.writeByte(' '); } +/**************************************************** + * Emit the behavior-flag badges (`@nogc`, `nothrow`, `pure`, and the + * manual-only `no-alloc`) directly under a declaration's title. + * + * A flag is emitted automatically when the matching attribute is present on any + * of the documented declarations. Flag macros written manually anywhere in the + * comment body are moved here too. Duplicates are collapsed into one badge. + * Params: + * buf = buffer holding the description, which the flags are inserted into + * start = the index in `buf` where the description begins + * a = the declarations sharing this documentation comment + */ +void emitBehaviorFlags(ref OutBuffer buf, size_t start, Dsymbols* a) +{ + static immutable string[4] names = ["NOALLOC", "NOGC", "NOTHROW", "PURE"]; + bool[4] present; + + bool matchAt(size_t pos, string name) + { + if (pos + 3 + name.length > buf.length || buf[pos] != '$' || buf[pos + 1] != '(') + return false; + foreach (k, ch; name) + if (buf[pos + 2 + k] != ch) + return false; + return buf[pos + 2 + name.length] == ')'; + } + + // Pull any manually-written flag macros out of the body. + for (size_t i = start; i < buf.length;) + { + bool removed = false; + foreach (fi, name; names) + if (matchAt(i, name)) + { + present[fi] = true; + buf.remove(i, name.length + 3); + removed = true; + break; + } + if (!removed) + ++i; + } + + // Add flags implied by the declarations' attributes (NOALLOC has none). + foreach (sym; *a) + { + if (TypeFunction tf = isTypeFunction(sym)) + { + if (tf.isNogc) + present[1] = true; + if (tf.isNothrow) + present[2] = true; + if (tf.purity != PURE.impure) + present[3] = true; + } + } + + bool any = false; + foreach (p; present) + any |= p; + if (!any) + return; + + OutBuffer flags; + flags.writestring("$(DDOC_FLAGS "); + foreach (fi, name; names) + if (present[fi]) + { + flags.writestring("$("); + flags.writestring(name); + flags.writeByte(')'); + } + flags.writeByte(')'); + buf.insert(start, flags[]); +} + +unittest +{ + // No flags: buffer is left untouched. + Dsymbols a; + OutBuffer buf; + buf.writestring("no flags here"); + emitBehaviorFlags(buf, 0, &a); + assert(buf[] == "no flags here"); +} + +unittest +{ + // Manual flag macros are hoisted to the front and duplicates collapsed. + Dsymbols a; + OutBuffer buf; + buf.writestring("text $(NOGC) more $(PURE) and $(NOGC) end"); + emitBehaviorFlags(buf, 0, &a); + assert(buf[] == "$(DDOC_FLAGS $(NOGC)$(PURE))text more and end"); +} + +unittest +{ + // Flags are always emitted in canonical order regardless of input order. + Dsymbols a; + OutBuffer buf; + buf.writestring("$(PURE)$(NOTHROW)$(NOALLOC)"); + emitBehaviorFlags(buf, 0, &a); + assert(buf[] == "$(DDOC_FLAGS $(NOALLOC)$(NOTHROW)$(PURE))"); +} + +unittest +{ + // Text before `start` is not scanned or modified. + Dsymbols a; + OutBuffer buf; + buf.writestring("$(NOGC)|$(PURE)"); + emitBehaviorFlags(buf, 8, &a); + assert(buf[] == "$(NOGC)|$(DDOC_FLAGS $(PURE))"); +} + void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc) { extern (C++) final class EmitComment : Visitor @@ -1439,6 +1555,7 @@ void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc) // Put the ddoc comment as the document 'description' buf.writestring(ddoc_decl_dd_s); { + size_t iDescStart = buf.length; dc.writeSections(sc, &dc.a, *buf); foreach (sym; dc.a) if (ScopeDsymbol sds = sym.isScopeDsymbol()) @@ -1446,6 +1563,7 @@ void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc) emitMemberComments(sds, *buf, sc); break; } + emitBehaviorFlags(*buf, iDescStart, &dc.a); } buf.writestring(ddoc_decl_dd_e); buf.writeByte(')'); diff --git a/compiler/src/dmd/res/default_ddoc_theme.ddoc b/compiler/src/dmd/res/default_ddoc_theme.ddoc index 9b8349cbcf0f..8180e5c88688 100644 --- a/compiler/src/dmd/res/default_ddoc_theme.ddoc +++ b/compiler/src/dmd/res/default_ddoc_theme.ddoc @@ -65,6 +65,12 @@ YELLOW = $0 BLACK = $0 WHITE = $0 +NOALLOC = no‑alloc +NOGC = @nogc +NOTHROW = nothrow +PURE = pure +DDOC_FLAGS =
$0
$(LF) + D_CODE =
@@ -164,6 +170,32 @@ DDOC = .color_black { color: black; } .color_white { color: white; } + .ddoc_flags { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin: 6px 0 4px; + } + + .ddoc_flag { + display: inline-block; + margin: 2px 4px 2px 0; + padding: 2px 8px; + border-radius: 4px; + font-family: Menlo, monospace; + font-size: 11px; + font-weight: bold; + line-height: 1.6; + color: #ffffff; + white-space: nowrap; + vertical-align: middle; + } + + .ddoc_flag_noalloc { background-color: #8e44ad; } + .ddoc_flag_nogc { background-color: #d33682; } + .ddoc_flag_nothrow { background-color: #859901; } + .ddoc_flag_pure { background-color: #268bd2; } + .font_big { font-size: 1.2em; } From 29dec53f277c1f805666647b0e72655e8e18e72e Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Thu, 3 Sep 2026 03:28:04 -0700 Subject: [PATCH 2/7] Update DDoc spec. Add changelog entry. --- changelog/dmd.ddoc-behavior-flags.dd | 37 +++++++++++++++++++++++ spec/ddoc.dd | 45 ++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 changelog/dmd.ddoc-behavior-flags.dd diff --git a/changelog/dmd.ddoc-behavior-flags.dd b/changelog/dmd.ddoc-behavior-flags.dd new file mode 100644 index 000000000000..7b1550d7ea69 --- /dev/null +++ b/changelog/dmd.ddoc-behavior-flags.dd @@ -0,0 +1,37 @@ +Ddoc now emits behavior-flag badges for function guarantees + +Documented functions now display badge-like $(I behavior flags) under their +title, similar to the build-status badges seen in project READMEs. Four flags +are available, each shown only when it applies and each in a distinct color: + +$(UL +$(LI `$(DOLLAR)(NOGC)` $(MDASH) emitted automatically for `@nogc` functions) +$(LI `$(DOLLAR)(NOTHROW)` $(MDASH) emitted automatically for `nothrow` functions) +$(LI `$(DOLLAR)(PURE)` $(MDASH) emitted automatically for `pure` functions) +$(LI `$(DOLLAR)(NOALLOC)` $(MDASH) a manual-only "no-alloc" flag with no +corresponding language attribute) +) + +The `$(DOLLAR)(NOGC)`, `$(DOLLAR)(NOTHROW)` and `$(DOLLAR)(PURE)` flags appear +automatically whenever the matching attribute is present on the documented +declaration. Any flag may also be written manually anywhere in a documentation +comment; manually-written flags are moved to appear under the declaration's +title, and duplicate flags $(MDASH) whether written manually or added +automatically $(MDASH) are collapsed into a single badge. + +------- +/++ +Copy `n` bytes. + +$(DOLLAR)(NOALLOC) ++/ +void* fastCopy(void* dst, const(void)* src, size_t n) @nogc nothrow pure; +------- + +The example above renders a `no-alloc` badge (written manually) next to the +`@nogc`, `nothrow` and `pure` badges (added automatically from the attributes). + +The badges and their grouping container are produced by the new `NOALLOC`, +`NOGC`, `NOTHROW`, `PURE` and `DDOC_FLAGS` macros, which can be redefined like +any other Ddoc macro. See $(LINK2 $(ROOT_DIR)spec/ddoc.html#behavior_flags, +Behavior Flags) for details. diff --git a/spec/ddoc.dd b/spec/ddoc.dd index c14ff3f0e83f..af12b958babd 100644 --- a/spec/ddoc.dd +++ b/spec/ddoc.dd @@ -853,6 +853,46 @@ To prevent unintended emphasis of an identifier, it can be preceded by an underscore ($(UNDERSCORE)). The underscore will be stripped from the output. ) +$(H3 $(LNAME2 behavior_flags, Behavior Flags)) + +$(P +Functions can advertise behavioral guarantees with badge-like $(I behavior flags) +that are displayed under the declaration, similar to the build-status badges +seen in project READMEs. Four flags are available: `$(DOLLAR)(NOALLOC)` (does not +allocate), `$(DOLLAR)(NOGC)` (is `@nogc`), `$(DOLLAR)(NOTHROW)` (is `nothrow`) +and `$(DOLLAR)(PURE)` (is `pure`). Each flag is shown only when it applies, and +each is rendered in a distinct color. +) + +$(P +The `$(DOLLAR)(NOGC)`, `$(DOLLAR)(NOTHROW)` and `$(DOLLAR)(PURE)` flags are +emitted automatically when the corresponding `@nogc`, `nothrow` or `pure` +attribute is present on the documented declaration. The `$(DOLLAR)(NOALLOC)` flag +has no corresponding language attribute and is only shown when written manually. +) + +$(P +Any flag may also be written manually anywhere in a documentation comment. +Manually-written flags are moved to appear under the declaration's title, and +duplicate flags $(MDASH) whether written manually or added automatically from an +attribute $(MDASH) are collapsed into a single badge. +) + +------------------------------------ +/++ +Copy `n` bytes. + +$(DOLLAR)(NOALLOC) ++/ +void* fastCopy(void* dst, const(void)* src, size_t n) @nogc nothrow pure; +------------------------------------ + +$(P +The example above renders a `no-alloc` badge (written manually) next to the +`@nogc`, `nothrow` and `pure` badges (added automatically from the attributes), +all shown under the function's title. +) + $(H3 $(LNAME2 character_entities, Character Entities)) $(P @@ -1083,6 +1123,10 @@ $(P $(TROW $(ARGS $(D YELLOW)), $(ARGS argument is set to be yellow)) $(TROW $(ARGS $(D BLACK)), $(ARGS argument is set to be black)) $(TROW $(ARGS $(D WHITE)), $(ARGS argument is set to be white)) + $(TROW $(ARGS $(D NOALLOC)), $(ARGS behavior flag badge: does not allocate)) + $(TROW $(ARGS $(D NOGC)), $(ARGS behavior flag badge: $(D @nogc))) + $(TROW $(ARGS $(D NOTHROW)), $(ARGS behavior flag badge: $(D nothrow))) + $(TROW $(ARGS $(D PURE)), $(ARGS behavior flag badge: $(D pure))) $(TROW $(ARGS $(D D_CODE)), $(ARGS argument is D code)) $(TROW $(ARGS $(D D_INLINECODE)), $(ARGS argument is inline D code)) $(TROW $(ARGS $(D LF)), $(ARGS Insert a line feed (newline))) @@ -1198,6 +1242,7 @@ $(P $(TROW $(ARGS $(D DDOC_KEYWORD)), $(ARGS Highlighting of D keywords.)) $(TROW $(ARGS $(D DDOC_PARAM)), $(ARGS Highlighting of function parameters.)) $(TROW $(ARGS $(D DDOC_BACKQUOTED)), $(ARGS Inserts inline code.)) + $(TROW $(ARGS $(D DDOC_FLAGS)), $(ARGS Container for the behavior flag badges emitted under a declaration.)) $(TROW $(ARGS $(D DDOC_AUTO_PSYMBOL_SUPPRESS)), $(ARGS Highlighting of auto-detected symbol that starts with underscore)) $(TROW $(ARGS $(D DDOC_AUTO_PSYMBOL)), $(ARGS Highlighting of auto-detected symbol)) $(TROW $(ARGS $(D DDOC_AUTO_KEYWORD)), $(ARGS Highlighting of auto-detected keywords)) From 8dd149007bfc175a152d972f607ab28eb5538e01 Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Thu, 3 Sep 2026 03:45:12 -0700 Subject: [PATCH 3/7] Fix DDoc tests. Fixed bug where class/struct types would have the flags applied to them if a member was marked as such. --- compiler/src/dmd/doc.d | 4 +- .../test/compilable/extra-files/ddoc10.html | 6 +- .../test/compilable/extra-files/ddoc14.html | 63 ++++++++++++------- .../test/compilable/extra-files/ddocYear.html | 28 ++++++++- 4 files changed, 76 insertions(+), 25 deletions(-) diff --git a/compiler/src/dmd/doc.d b/compiler/src/dmd/doc.d index 18f89de7b694..8e5259a42e7a 100644 --- a/compiler/src/dmd/doc.d +++ b/compiler/src/dmd/doc.d @@ -1557,13 +1557,15 @@ void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc) { size_t iDescStart = buf.length; dc.writeSections(sc, &dc.a, *buf); + // Emit flags from this declaration's own sections, before + // members are written, so nested member flags aren't consumed. + emitBehaviorFlags(*buf, iDescStart, &dc.a); foreach (sym; dc.a) if (ScopeDsymbol sds = sym.isScopeDsymbol()) { emitMemberComments(sds, *buf, sc); break; } - emitBehaviorFlags(*buf, iDescStart, &dc.a); } buf.writestring(ddoc_decl_dd_e); buf.writeByte(')'); diff --git a/compiler/test/compilable/extra-files/ddoc10.html b/compiler/test/compilable/extra-files/ddoc10.html index 033fc27b325e..1ac5ef39b25e 100644 --- a/compiler/test/compilable/extra-files/ddoc10.html +++ b/compiler/test/compilable/extra-files/ddoc10.html @@ -582,7 +582,8 @@

Declaration

- +
nothrowpure
+
@@ -607,7 +608,8 @@

Declaration

- +
nothrowpure
+
diff --git a/compiler/test/compilable/extra-files/ddoc14.html b/compiler/test/compilable/extra-files/ddoc14.html index 375589c38492..175eb09d5fbc 100644 --- a/compiler/test/compilable/extra-files/ddoc14.html +++ b/compiler/test/compilable/extra-files/ddoc14.html @@ -117,7 +117,8 @@

Declaration

-
+
nothrowpure
+

2 @@ -149,7 +150,8 @@

Declaration

-
+
nothrowpure
+

3 @@ -181,7 +183,8 @@

Declaration

-
+
nothrowpure
+

5 @@ -213,7 +216,8 @@

Declaration

-
+
nothrowpure
+

6 @@ -245,7 +249,8 @@

Declaration

-
+
nothrowpure
+

7 @@ -277,7 +282,8 @@

Declaration

-
+
nothrowpure
+

9 @@ -309,7 +315,8 @@

Declaration

-
+
nothrowpure
+

10 @@ -440,7 +447,8 @@

Declaration

-
+
nothrowpure
+

2 @@ -472,7 +480,8 @@

Declaration

-
+
nothrowpure
+

3 @@ -504,7 +513,8 @@

Declaration

-
+
nothrowpure
+

5 @@ -536,7 +546,8 @@

Declaration

-
+
nothrowpure
+

6 @@ -568,7 +579,8 @@

Declaration

-
+
nothrowpure
+

7 @@ -600,7 +612,8 @@

Declaration

-
+
nothrowpure
+

9 @@ -632,7 +645,8 @@

Declaration

-
+
nothrowpure
+

10 @@ -733,7 +747,8 @@

Declaration

-
+
nothrowpure
+

2 @@ -765,7 +780,8 @@

Declaration

-
+
nothrowpure
+

3 @@ -797,7 +813,8 @@

Declaration

-
+
nothrowpure
+

5 @@ -829,7 +846,8 @@

Declaration

-
+
nothrowpure
+

6 @@ -861,7 +879,8 @@

Declaration

-
+
nothrowpure
+

7 @@ -893,7 +912,8 @@

Declaration

-
+
nothrowpure
+

9 @@ -925,7 +945,8 @@

Declaration

-
+
nothrowpure
+

10 diff --git a/compiler/test/compilable/extra-files/ddocYear.html b/compiler/test/compilable/extra-files/ddocYear.html index 4b2239f19716..5154cb9a8f48 100644 --- a/compiler/test/compilable/extra-files/ddocYear.html +++ b/compiler/test/compilable/extra-files/ddocYear.html @@ -64,6 +64,32 @@ .color_black { color: black; } .color_white { color: white; } + .ddoc_flags { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin: 6px 0 4px; + } + + .ddoc_flag { + display: inline-block; + margin: 2px 4px 2px 0; + padding: 2px 8px; + border-radius: 4px; + font-family: Menlo, monospace; + font-size: 11px; + font-weight: bold; + line-height: 1.6; + color: #ffffff; + white-space: nowrap; + vertical-align: middle; + } + + .ddoc_flag_noalloc { background-color: #8e44ad; } + .ddoc_flag_nogc { background-color: #d33682; } + .ddoc_flag_nothrow { background-color: #859901; } + .ddoc_flag_pure { background-color: #268bd2; } + .font_big { font-size: 1.2em; } @@ -543,7 +569,7 @@

Declaration

- __YEAR__ + 2026

From 0a91ccadf2762ce549bf557e8559d940f5ab3ce7 Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Thu, 3 Sep 2026 03:57:24 -0700 Subject: [PATCH 4/7] Fix ddocYear.html --- compiler/test/compilable/extra-files/ddocYear.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/test/compilable/extra-files/ddocYear.html b/compiler/test/compilable/extra-files/ddocYear.html index 5154cb9a8f48..65f1db8ded77 100644 --- a/compiler/test/compilable/extra-files/ddocYear.html +++ b/compiler/test/compilable/extra-files/ddocYear.html @@ -569,7 +569,7 @@

Declaration

- 2026 + __YEAR__

From 955d71d4d3c7b14073cb98ed46b4c23b3f39d108 Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Thu, 3 Sep 2026 06:37:03 -0700 Subject: [PATCH 5/7] Improve flag language. Fix margins. --- changelog/dmd.ddoc-behavior-flags.dd | 20 +++++---- compiler/src/dmd/res/default_ddoc_theme.ddoc | 19 ++++++--- .../test/compilable/extra-files/ddoc10.html | 4 +- .../test/compilable/extra-files/ddoc14.html | 42 +++++++++---------- .../test/compilable/extra-files/ddocYear.html | 9 +++- spec/ddoc.dd | 25 ++++++----- 6 files changed, 69 insertions(+), 50 deletions(-) diff --git a/changelog/dmd.ddoc-behavior-flags.dd b/changelog/dmd.ddoc-behavior-flags.dd index 7b1550d7ea69..082083337891 100644 --- a/changelog/dmd.ddoc-behavior-flags.dd +++ b/changelog/dmd.ddoc-behavior-flags.dd @@ -1,15 +1,16 @@ Ddoc now emits behavior-flag badges for function guarantees Documented functions now display badge-like $(I behavior flags) under their -title, similar to the build-status badges seen in project READMEs. Four flags -are available, each shown only when it applies and each in a distinct color: +title, similar to the build-status badges seen in project READMEs. When any are +present, the badges are introduced by a `Behaviors:` label. Four flags are +available, each shown only when it applies and each in a distinct color: $(UL -$(LI `$(DOLLAR)(NOGC)` $(MDASH) emitted automatically for `@nogc` functions) -$(LI `$(DOLLAR)(NOTHROW)` $(MDASH) emitted automatically for `nothrow` functions) -$(LI `$(DOLLAR)(PURE)` $(MDASH) emitted automatically for `pure` functions) -$(LI `$(DOLLAR)(NOALLOC)` $(MDASH) a manual-only "no-alloc" flag with no -corresponding language attribute) +$(LI `$(DOLLAR)(NOGC)` (rendered $(I No GC)) $(MDASH) emitted automatically for `@nogc` functions) +$(LI `$(DOLLAR)(NOTHROW)` (rendered $(I No Exceptions Thrown)) $(MDASH) emitted automatically for `nothrow` functions) +$(LI `$(DOLLAR)(PURE)` (rendered $(I Is Pure)) $(MDASH) emitted automatically for `pure` functions) +$(LI `$(DOLLAR)(NOALLOC)` (rendered $(I No Allocations)) $(MDASH) a manual-only +flag with no corresponding language attribute) ) The `$(DOLLAR)(NOGC)`, `$(DOLLAR)(NOTHROW)` and `$(DOLLAR)(PURE)` flags appear @@ -28,8 +29,9 @@ $(DOLLAR)(NOALLOC) void* fastCopy(void* dst, const(void)* src, size_t n) @nogc nothrow pure; ------- -The example above renders a `no-alloc` badge (written manually) next to the -`@nogc`, `nothrow` and `pure` badges (added automatically from the attributes). +The example above renders a $(I No Allocations) badge (written manually) next to +the $(I No GC), $(I No Exceptions Thrown) and $(I Is Pure) badges (added +automatically from the attributes), all shown after a `Behaviors:` label. The badges and their grouping container are produced by the new `NOALLOC`, `NOGC`, `NOTHROW`, `PURE` and `DDOC_FLAGS` macros, which can be redefined like diff --git a/compiler/src/dmd/res/default_ddoc_theme.ddoc b/compiler/src/dmd/res/default_ddoc_theme.ddoc index 8180e5c88688..28e1db2563d2 100644 --- a/compiler/src/dmd/res/default_ddoc_theme.ddoc +++ b/compiler/src/dmd/res/default_ddoc_theme.ddoc @@ -65,11 +65,11 @@ YELLOW = $0 BLACK = $0 WHITE = $0 -NOALLOC = no‑alloc -NOGC = @nogc -NOTHROW = nothrow -PURE = pure -DDOC_FLAGS =
$0
$(LF) +NOALLOC = No Allocations +NOGC = No GC +NOTHROW = No Exceptions Thrown +PURE = Is Pure +DDOC_FLAGS =
Behaviors:$0
$(LF) D_CODE =
@@ -174,7 +174,14 @@ DDOC = display: flex; flex-wrap: wrap; gap: 6px; - margin: 6px 0 4px; + margin: 0px 5px 5px 5px; + } + + .ddoc_flags_label { + align-self: center; + font-weight: bold; + font-size: 11px; + margin-right: 2px; } .ddoc_flag { diff --git a/compiler/test/compilable/extra-files/ddoc10.html b/compiler/test/compilable/extra-files/ddoc10.html index 1ac5ef39b25e..5f5e50ebc182 100644 --- a/compiler/test/compilable/extra-files/ddoc10.html +++ b/compiler/test/compilable/extra-files/ddoc10.html @@ -582,7 +582,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure
@@ -608,7 +608,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure
diff --git a/compiler/test/compilable/extra-files/ddoc14.html b/compiler/test/compilable/extra-files/ddoc14.html index 175eb09d5fbc..dbb11e160cdf 100644 --- a/compiler/test/compilable/extra-files/ddoc14.html +++ b/compiler/test/compilable/extra-files/ddoc14.html @@ -117,7 +117,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -150,7 +150,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -183,7 +183,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -216,7 +216,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -249,7 +249,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -282,7 +282,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -315,7 +315,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -447,7 +447,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -480,7 +480,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -513,7 +513,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -546,7 +546,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -579,7 +579,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -612,7 +612,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -645,7 +645,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -747,7 +747,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -780,7 +780,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -813,7 +813,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -846,7 +846,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -879,7 +879,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -912,7 +912,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

@@ -945,7 +945,7 @@

Declaration

-
nothrowpure
+
Behaviors:No Exceptions ThrownIs Pure

diff --git a/compiler/test/compilable/extra-files/ddocYear.html b/compiler/test/compilable/extra-files/ddocYear.html index 65f1db8ded77..5ab3aa3f5f40 100644 --- a/compiler/test/compilable/extra-files/ddocYear.html +++ b/compiler/test/compilable/extra-files/ddocYear.html @@ -68,7 +68,14 @@ display: flex; flex-wrap: wrap; gap: 6px; - margin: 6px 0 4px; + margin: 0px 5px 5px 5px; + } + + .ddoc_flags_label { + align-self: center; + font-weight: bold; + font-size: 11px; + margin-right: 2px; } .ddoc_flag { diff --git a/spec/ddoc.dd b/spec/ddoc.dd index af12b958babd..2e2718527e3e 100644 --- a/spec/ddoc.dd +++ b/spec/ddoc.dd @@ -858,10 +858,12 @@ $(H3 $(LNAME2 behavior_flags, Behavior Flags)) $(P Functions can advertise behavioral guarantees with badge-like $(I behavior flags) that are displayed under the declaration, similar to the build-status badges -seen in project READMEs. Four flags are available: `$(DOLLAR)(NOALLOC)` (does not -allocate), `$(DOLLAR)(NOGC)` (is `@nogc`), `$(DOLLAR)(NOTHROW)` (is `nothrow`) -and `$(DOLLAR)(PURE)` (is `pure`). Each flag is shown only when it applies, and -each is rendered in a distinct color. +seen in project READMEs. When any are present, the badges are introduced by a +$(D Behaviors:) label. Four flags are available: `$(DOLLAR)(NOALLOC)` (rendered +$(I No Allocations)), `$(DOLLAR)(NOGC)` (rendered $(I No GC)), +`$(DOLLAR)(NOTHROW)` (rendered $(I No Exceptions Thrown)) and `$(DOLLAR)(PURE)` +(rendered $(I Is Pure)). Each flag is shown only when it applies, and each is +rendered in a distinct color. ) $(P @@ -888,9 +890,10 @@ void* fastCopy(void* dst, const(void)* src, size_t n) @nogc nothrow pure; ------------------------------------ $(P -The example above renders a `no-alloc` badge (written manually) next to the -`@nogc`, `nothrow` and `pure` badges (added automatically from the attributes), -all shown under the function's title. +The example above renders a $(I No Allocations) badge (written manually) next to +the $(I No GC), $(I No Exceptions Thrown) and $(I Is Pure) badges (added +automatically from the attributes), all shown under the function's title after a +$(D Behaviors:) label. ) $(H3 $(LNAME2 character_entities, Character Entities)) @@ -1123,10 +1126,10 @@ $(P $(TROW $(ARGS $(D YELLOW)), $(ARGS argument is set to be yellow)) $(TROW $(ARGS $(D BLACK)), $(ARGS argument is set to be black)) $(TROW $(ARGS $(D WHITE)), $(ARGS argument is set to be white)) - $(TROW $(ARGS $(D NOALLOC)), $(ARGS behavior flag badge: does not allocate)) - $(TROW $(ARGS $(D NOGC)), $(ARGS behavior flag badge: $(D @nogc))) - $(TROW $(ARGS $(D NOTHROW)), $(ARGS behavior flag badge: $(D nothrow))) - $(TROW $(ARGS $(D PURE)), $(ARGS behavior flag badge: $(D pure))) + $(TROW $(ARGS $(D NOALLOC)), $(ARGS behavior flag badge for functions that do not allocate)) + $(TROW $(ARGS $(D NOGC)), $(ARGS behavior flag badge for $(D @nogc) functions)) + $(TROW $(ARGS $(D NOTHROW)), $(ARGS behavior flag badge for $(D nothrow) functions)) + $(TROW $(ARGS $(D PURE)), $(ARGS behavior flag badge for $(D pure) functions)) $(TROW $(ARGS $(D D_CODE)), $(ARGS argument is D code)) $(TROW $(ARGS $(D D_INLINECODE)), $(ARGS argument is inline D code)) $(TROW $(ARGS $(D LF)), $(ARGS Insert a line feed (newline))) From a44e25f496766ec4a72a0e30566c03c0754fa786 Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Thu, 3 Sep 2026 06:45:12 -0700 Subject: [PATCH 6/7] Add 'current'. --- compiler/src/dmd/res/default_ddoc_theme.ddoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dmd/res/default_ddoc_theme.ddoc b/compiler/src/dmd/res/default_ddoc_theme.ddoc index 28e1db2563d2..88a58f19441c 100644 --- a/compiler/src/dmd/res/default_ddoc_theme.ddoc +++ b/compiler/src/dmd/res/default_ddoc_theme.ddoc @@ -69,7 +69,7 @@ NOALLOC = No NOGC = No GC NOTHROW = No Exceptions Thrown PURE = Is Pure -DDOC_FLAGS =

Behaviors:$0
$(LF) +DDOC_FLAGS =
Current Behaviors:$0
$(LF) D_CODE =
From 5cff681791967b1e4bca2e52f5f8b46fbc3846b5 Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Thu, 3 Sep 2026 06:59:33 -0700 Subject: [PATCH 7/7] Fix tests. --- changelog/dmd.ddoc-behavior-flags.dd | 4 +- .../test/compilable/extra-files/ddoc10.html | 4 +- .../test/compilable/extra-files/ddoc14.html | 42 +++++++++---------- spec/ddoc.dd | 4 +- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/changelog/dmd.ddoc-behavior-flags.dd b/changelog/dmd.ddoc-behavior-flags.dd index 082083337891..7c7cae6d79cd 100644 --- a/changelog/dmd.ddoc-behavior-flags.dd +++ b/changelog/dmd.ddoc-behavior-flags.dd @@ -2,7 +2,7 @@ Ddoc now emits behavior-flag badges for function guarantees Documented functions now display badge-like $(I behavior flags) under their title, similar to the build-status badges seen in project READMEs. When any are -present, the badges are introduced by a `Behaviors:` label. Four flags are +present, the badges are introduced by a `Current Behaviors:` label. Four flags are available, each shown only when it applies and each in a distinct color: $(UL @@ -31,7 +31,7 @@ void* fastCopy(void* dst, const(void)* src, size_t n) @nogc nothrow pure; The example above renders a $(I No Allocations) badge (written manually) next to the $(I No GC), $(I No Exceptions Thrown) and $(I Is Pure) badges (added -automatically from the attributes), all shown after a `Behaviors:` label. +automatically from the attributes), all shown after a `Current Behaviors:` label. The badges and their grouping container are produced by the new `NOALLOC`, `NOGC`, `NOTHROW`, `PURE` and `DDOC_FLAGS` macros, which can be redefined like diff --git a/compiler/test/compilable/extra-files/ddoc10.html b/compiler/test/compilable/extra-files/ddoc10.html index 5f5e50ebc182..42874197f3c8 100644 --- a/compiler/test/compilable/extra-files/ddoc10.html +++ b/compiler/test/compilable/extra-files/ddoc10.html @@ -582,7 +582,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure
@@ -608,7 +608,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure
diff --git a/compiler/test/compilable/extra-files/ddoc14.html b/compiler/test/compilable/extra-files/ddoc14.html index dbb11e160cdf..d228759b0f1e 100644 --- a/compiler/test/compilable/extra-files/ddoc14.html +++ b/compiler/test/compilable/extra-files/ddoc14.html @@ -117,7 +117,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -150,7 +150,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -183,7 +183,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -216,7 +216,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -249,7 +249,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -282,7 +282,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -315,7 +315,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -447,7 +447,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -480,7 +480,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -513,7 +513,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -546,7 +546,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -579,7 +579,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -612,7 +612,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -645,7 +645,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -747,7 +747,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -780,7 +780,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -813,7 +813,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -846,7 +846,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -879,7 +879,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -912,7 +912,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

@@ -945,7 +945,7 @@

Declaration

-
Behaviors:No Exceptions ThrownIs Pure
+
Current Behaviors:No Exceptions ThrownIs Pure

diff --git a/spec/ddoc.dd b/spec/ddoc.dd index 2e2718527e3e..80ca10a27a0d 100644 --- a/spec/ddoc.dd +++ b/spec/ddoc.dd @@ -859,7 +859,7 @@ $(P Functions can advertise behavioral guarantees with badge-like $(I behavior flags) that are displayed under the declaration, similar to the build-status badges seen in project READMEs. When any are present, the badges are introduced by a -$(D Behaviors:) label. Four flags are available: `$(DOLLAR)(NOALLOC)` (rendered +$(D Current Behaviors:) label. Four flags are available: `$(DOLLAR)(NOALLOC)` (rendered $(I No Allocations)), `$(DOLLAR)(NOGC)` (rendered $(I No GC)), `$(DOLLAR)(NOTHROW)` (rendered $(I No Exceptions Thrown)) and `$(DOLLAR)(PURE)` (rendered $(I Is Pure)). Each flag is shown only when it applies, and each is @@ -893,7 +893,7 @@ $(P The example above renders a $(I No Allocations) badge (written manually) next to the $(I No GC), $(I No Exceptions Thrown) and $(I Is Pure) badges (added automatically from the attributes), all shown under the function's title after a -$(D Behaviors:) label. +$(D Current Behaviors:) label. ) $(H3 $(LNAME2 character_entities, Character Entities))