Skip to content

Commit 7812008

Browse files
Fix link to attr/derive bang macros
1 parent 3cbcc53 commit 7812008

File tree

11 files changed

+155
-47
lines changed

11 files changed

+155
-47
lines changed

src/librustdoc/formats/item_type.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ item_type! {
9999
// This number is reserved for use in JavaScript
100100
// Generic = 26,
101101
Attribute = 27,
102+
BangMacroAttribute = 28,
103+
BangMacroDerive = 29,
102104
}
103105

104106
impl<'a> From<&'a clean::Item> for ItemType {
@@ -128,10 +130,8 @@ impl<'a> From<&'a clean::Item> for ItemType {
128130
clean::ForeignFunctionItem(..) => ItemType::Function, // no ForeignFunction
129131
clean::ForeignStaticItem(..) => ItemType::Static, // no ForeignStatic
130132
clean::MacroItem(..) => ItemType::Macro,
131-
// Is this a good idea?
132-
clean::AttrMacroItem => ItemType::ProcAttribute,
133-
// Is this a good idea?
134-
clean::DeriveMacroItem => ItemType::ProcDerive,
133+
clean::AttrMacroItem => ItemType::BangMacroAttribute,
134+
clean::DeriveMacroItem => ItemType::BangMacroDerive,
135135
clean::PrimitiveItem(..) => ItemType::Primitive,
136136
clean::RequiredAssocConstItem(..)
137137
| clean::ProvidedAssocConstItem(..)
@@ -225,8 +225,8 @@ impl ItemType {
225225
ItemType::AssocConst => "associatedconstant",
226226
ItemType::ForeignType => "foreigntype",
227227
ItemType::Keyword => "keyword",
228-
ItemType::ProcAttribute => "attr",
229-
ItemType::ProcDerive => "derive",
228+
ItemType::ProcAttribute | ItemType::BangMacroAttribute => "attr",
229+
ItemType::ProcDerive | ItemType::BangMacroDerive => "derive",
230230
ItemType::TraitAlias => "traitalias",
231231
ItemType::Attribute => "attribute",
232232
}

src/librustdoc/html/render/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -523,10 +523,12 @@ impl AllTypes {
523523
ItemType::TypeAlias => self.type_aliases.insert(ItemEntry::new(new_url, name)),
524524
ItemType::Static => self.statics.insert(ItemEntry::new(new_url, name)),
525525
ItemType::Constant => self.constants.insert(ItemEntry::new(new_url, name)),
526-
ItemType::ProcAttribute => {
526+
ItemType::ProcAttribute | ItemType::BangMacroAttribute => {
527527
self.attribute_macros.insert(ItemEntry::new(new_url, name))
528528
}
529-
ItemType::ProcDerive => self.derive_macros.insert(ItemEntry::new(new_url, name)),
529+
ItemType::ProcDerive | ItemType::BangMacroDerive => {
530+
self.derive_macros.insert(ItemEntry::new(new_url, name))
531+
}
530532
ItemType::TraitAlias => self.trait_aliases.insert(ItemEntry::new(new_url, name)),
531533
_ => true,
532534
};
@@ -2610,8 +2612,8 @@ fn item_ty_to_section(ty: ItemType) -> ItemSection {
26102612
ItemType::ForeignType => ItemSection::ForeignTypes,
26112613
ItemType::Keyword => ItemSection::Keywords,
26122614
ItemType::Attribute => ItemSection::Attributes,
2613-
ItemType::ProcAttribute => ItemSection::AttributeMacros,
2614-
ItemType::ProcDerive => ItemSection::DeriveMacros,
2615+
ItemType::ProcAttribute | ItemType::BangMacroAttribute => ItemSection::AttributeMacros,
2616+
ItemType::ProcDerive | ItemType::BangMacroDerive => ItemSection::DeriveMacros,
26152617
ItemType::TraitAlias => ItemSection::TraitAliases,
26162618
}
26172619
}

src/librustdoc/html/render/print_item.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,14 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
314314
FxHashMap::default();
315315

316316
for (index, item) in items.iter().filter(|i| !i.is_stripped()).enumerate() {
317-
not_stripped_items.entry(item.type_()).or_default().push((index, item));
317+
// To prevent having new "bang macro attribute/derive" sections in the module,
318+
// we cheat by turning them into their "proc-macro equivalent".
319+
let type_ = match item.type_() {
320+
ItemType::BangMacroAttribute => ItemType::ProcAttribute,
321+
ItemType::BangMacroDerive => ItemType::ProcDerive,
322+
type_ => type_,
323+
};
324+
not_stripped_items.entry(type_).or_default().push((index, item));
318325
}
319326

320327
// the order of item types in the listing

src/librustdoc/html/static/js/rustdoc.d.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,27 @@ declare namespace rustdoc {
244244
traitParent: number?,
245245
deprecated: boolean,
246246
associatedItemDisambiguator: string?,
247+
/**
248+
* If `true`, this item is a `macro_rules!` macro that supports
249+
* multiple usage syntaxes, as described in RFC 3697 and 3698.
250+
* The syntax for such a macro looks like this:
251+
*
252+
* ```rust
253+
* /// Doc Comment.
254+
* macro_rules! NAME {
255+
* attr(key = $value:literal) ($attached:item) => { ... };
256+
* derive() ($attached:item) => { ... };
257+
* ($bang:tt) => { ... };
258+
* }
259+
* ```
260+
*
261+
* Each usage syntax gets a separate EntryData---one for the attr,
262+
* one for the derive, and one for the bang syntax---with a corresponding
263+
* `ty` field that can be used for filtering and presenting results.
264+
* But the documentation lives in a single `macro.NAME.html` page, and
265+
* this boolean flag is used for generating that HREF.
266+
*/
267+
isBangMacro: boolean,
247268
}
248269

249270
/**
@@ -300,7 +321,7 @@ declare namespace rustdoc {
300321

301322
type ItemType = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
302323
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
303-
21 | 22 | 23 | 24 | 25 | 26;
324+
21 | 22 | 23 | 24 | 25 | 26 | 28 | 29;
304325

305326
/**
306327
* The viewmodel for the search engine results page.

src/librustdoc/html/static/js/search.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ const itemTypes = [
120120
"traitalias", // 25
121121
"generic",
122122
"attribute",
123+
null, // bang macro attribute
124+
null, // bang macro derive
123125
];
124126

125127
// used for special search precedence
@@ -1640,7 +1642,7 @@ class DocSearch {
16401642
* ], [string]>}
16411643
*/
16421644
const raw = JSON.parse(encoded);
1643-
return {
1645+
const item = {
16441646
krate: raw[0],
16451647
ty: raw[1],
16461648
modulePath: raw[2] === 0 ? null : raw[2] - 1,
@@ -1649,7 +1651,15 @@ class DocSearch {
16491651
traitParent: raw[5] === 0 ? null : raw[5] - 1,
16501652
deprecated: raw[6] === 1 ? true : false,
16511653
associatedItemDisambiguator: raw.length === 7 ? null : raw[7],
1654+
isBangMacro: false,
16521655
};
1656+
if (item.ty === 28 || item.ty === 29) {
1657+
// "proc attribute" is 23, "proc derive" is 24 whereas "bang macro attribute" is 28 and
1658+
// "bang macro derive" is 29, so 5 of difference to go from the latter to the former.
1659+
item.ty -= 5;
1660+
item.isBangMacro = true;
1661+
}
1662+
return item;
16531663
}
16541664

16551665
/**
@@ -2146,7 +2156,7 @@ class DocSearch {
21462156
let displayPath;
21472157
let href;
21482158
let traitPath = null;
2149-
const type = itemTypes[item.ty];
2159+
const type = item.entry && item.entry.isBangMacro ? "macro" : itemTypes[item.ty];
21502160
const name = item.name;
21512161
let path = item.modulePath;
21522162
let exactPath = item.exactModulePath;
@@ -3949,7 +3959,7 @@ class DocSearch {
39493959
* @param {Promise<rustdoc.PlainResultObject|null>[]} data
39503960
* @returns {AsyncGenerator<rustdoc.ResultObject, boolean>}
39513961
*/
3952-
const flush = async function* (data) {
3962+
const flush = async function*(data) {
39533963
const satr = sortAndTransformResults(
39543964
await Promise.all(data),
39553965
null,

src/librustdoc/json/conversions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -898,8 +898,8 @@ impl FromClean<ItemType> for ItemKind {
898898
Keyword => ItemKind::Keyword,
899899
Attribute => ItemKind::Attribute,
900900
TraitAlias => ItemKind::TraitAlias,
901-
ProcAttribute => ItemKind::ProcAttribute,
902-
ProcDerive => ItemKind::ProcDerive,
901+
ProcAttribute | BangMacroAttribute => ItemKind::ProcAttribute,
902+
ProcDerive | BangMacroDerive => ItemKind::ProcDerive,
903903
}
904904
}
905905
}

tests/rustdoc-gui/attr-macros.goml

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,75 @@
22
// the sidebar and in the module.
33

44
go-to: "file://" + |DOC_PATH| + "/test_docs/macro.b.html"
5-
// It should be present twice in the sidebar.
6-
assert-count: ("#rustdoc-modnav a[href='macro.attr_macro.html']", 2)
7-
assert-count: ("//*[@id='rustdoc-modnav']//a[text()='attr_macro']", 2)
85
// We check that the current item in the sidebar is the correct one.
96
assert-text: ("#rustdoc-modnav .block.macro .current", "b")
107

11-
// We now go to the attribute macro page.
12-
click: "#rustdoc-modnav a[href='macro.attr_macro.html']"
13-
// It should be present twice in the sidebar.
14-
assert-count: ("#rustdoc-modnav a[href='macro.attr_macro.html']", 2)
15-
assert-count: ("//*[@id='rustdoc-modnav']//a[text()='attr_macro']", 2)
16-
// We check that the current item is the "attr_macro".
17-
assert-text: ("#rustdoc-modnav .block.macro .current", "attr_macro")
18-
// Since the item is present twice in the sidebar, we should have two "current" items.
19-
assert-count: ("#rustdoc-modnav .current", 2)
20-
// We check it has the expected information.
21-
assert-text: ("h3.macro-info", "ⓘ This is an attribute/function macro")
8+
define-function: (
9+
"check_macro",
10+
[name, info],
11+
block {
12+
// It should be present twice in the sidebar.
13+
assert-count: ("#rustdoc-modnav a[href='macro." + |name| + ".html']", 2)
14+
assert-count: ("//*[@id='rustdoc-modnav']//a[text()='" + |name| + "']", 2)
15+
16+
// We now go to the macro page.
17+
click: "#rustdoc-modnav a[href='macro." + |name| + ".html']"
18+
// It should be present twice in the sidebar.
19+
assert-count: ("#rustdoc-modnav a[href='macro." + |name| + ".html']", 2)
20+
assert-count: ("//*[@id='rustdoc-modnav']//a[text()='" + |name| + "']", 2)
21+
// We check that the current item is the macro.
22+
assert-text: ("#rustdoc-modnav .block.macro .current", |name|)
23+
// Since the item is present twice in the sidebar, we should have two "current" items.
24+
assert-count: ("#rustdoc-modnav .current", 2)
25+
// We check it has the expected information.
26+
assert-text: ("h3.macro-info", "ⓘ This is " + |info| + "/function macro")
27+
}
28+
)
29+
30+
call-function: ("check_macro", {"name": "attr_macro", "info": "an attribute"})
31+
call-function: ("check_macro", {"name": "derive_macro", "info": "a derive"})
32+
33+
define-function: (
34+
"crate_page",
35+
[name, section_id],
36+
block {
37+
// It should be only present twice.
38+
assert-count: ("#main-content a[href='macro." + |name| + ".html']", 2)
39+
// First in the "Macros" section.
40+
assert-text: ("#macros + .item-table a[href='macro." + |name| + ".html']", |name|)
41+
// Then in the other macro section.
42+
assert-text: (
43+
"#" + |section_id| + " + .item-table a[href='macro." + |name| + ".html']",
44+
|name|,
45+
)
46+
}
47+
)
2248

2349
// Now we check it's correctly listed in the crate page.
2450
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
25-
// It should be only present twice.
26-
assert-count: ("#main-content a[href='macro.attr_macro.html']", 2)
27-
// First in the "Macros" section.
28-
assert-text: ("#macros + .item-table a[href='macro.attr_macro.html']", "attr_macro")
29-
// Then in the "Attribute Macros" section.
30-
assert-text: ("#attribute-macros + .item-table a[href='macro.attr_macro.html']", "attr_macro")
51+
call-function: ("crate_page", {"name": "attr_macro", "section_id": "attribute-macros"})
52+
call-function: ("crate_page", {"name": "derive_macro", "section_id": "derives"})
53+
// We also check we don't have duplicated sections.
54+
assert-count: ("//*[@id='main-content']/h2[text()='Attribute Macros']", 1)
55+
assert-count: ("//*[@id='main-content']/h2[text()='Derive Macros']", 1)
56+
57+
define-function: (
58+
"all_items_page",
59+
[name, section_id],
60+
block {
61+
// It should be only present twice.
62+
assert-count: ("#main-content a[href='macro." + |name| + ".html']", 2)
63+
// First in the "Macros" section.
64+
assert-text: ("#macros + .all-items a[href='macro." + |name| + ".html']", |name|)
65+
// Then in the "Attribute Macros" section.
66+
assert-text: (
67+
"#" + |section_id| + " + .all-items a[href='macro." + |name| + ".html']",
68+
|name|,
69+
)
70+
}
71+
)
3172

3273
// And finally we check it's correctly listed in the "all items" page.
3374
go-to: "file://" + |DOC_PATH| + "/test_docs/all.html"
34-
// It should be only present twice.
35-
assert-count: ("#main-content a[href='macro.attr_macro.html']", 2)
36-
// First in the "Macros" section.
37-
assert-text: ("#macros + .all-items a[href='macro.attr_macro.html']", "attr_macro")
38-
// Then in the "Attribute Macros" section.
39-
assert-text: ("#attribute-macros + .all-items a[href='macro.attr_macro.html']", "attr_macro")
75+
call-function: ("all_items_page", {"name": "attr_macro", "section_id": "attribute-macros"})
76+
call-function: ("all_items_page", {"name": "derive_macro", "section_id": "derives"})

tests/rustdoc-gui/src/test_docs/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#![feature(doc_cfg)]
1010
#![feature(associated_type_defaults)]
1111
#![feature(macro_attr)]
12+
#![feature(macro_derive)]
1213

1314
/*!
1415
Enable the feature <span class="stab portability"><code>some-feature</code></span> to enjoy

tests/rustdoc-gui/src/test_docs/macros.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,17 @@ macro_rules! attr_macro {
99
attr() () => {};
1010
() => {};
1111
}
12+
13+
/// An attribute bang macro.
14+
#[macro_export]
15+
macro_rules! derive_macro {
16+
derive() () => {};
17+
() => {};
18+
}
19+
20+
#[macro_export]
21+
macro_rules! one_for_all_macro {
22+
attr() () => {};
23+
derive() () => {};
24+
() => {};
25+
}

tests/rustdoc-js/macro-kinds.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,24 @@ const EXPECTED = [
44
{
55
'query': 'macro:macro',
66
'others': [
7-
{ 'path': 'macro_kinds', 'name': 'macro1' },
8-
{ 'path': 'macro_kinds', 'name': 'macro3' },
7+
{ 'path': 'macro_kinds', 'name': 'macro1', 'href': '../macro_kinds/macro.macro1.html' },
8+
{ 'path': 'macro_kinds', 'name': 'macro3', 'href': '../macro_kinds/macro.macro3.html' },
99
],
1010
},
1111
{
1212
'query': 'attr:macro',
1313
'others': [
14-
{ 'path': 'macro_kinds', 'name': 'macro1' },
15-
{ 'path': 'macro_kinds', 'name': 'macro2' },
14+
{ 'path': 'macro_kinds', 'name': 'macro1', 'href': '../macro_kinds/macro.macro1.html' },
15+
{ 'path': 'macro_kinds', 'name': 'macro2', 'href': '../macro_kinds/attr.macro2.html' },
16+
],
17+
},
18+
{
19+
'query': 'derive:macro',
20+
'others': [
21+
{ 'path': 'macro_kinds', 'name': 'macro1', 'href': '../macro_kinds/macro.macro1.html' },
22+
{
23+
'path': 'macro_kinds', 'name': 'macro4', 'href': '../macro_kinds/derive.macro4.html'
24+
},
1625
],
1726
},
1827
];

0 commit comments

Comments
 (0)