Skip to content

Commit 76a6846

Browse files
Improve code and docs
1 parent cbe154c commit 76a6846

9 files changed

Lines changed: 63 additions & 43 deletions

File tree

src/librustdoc/clean/mod.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,13 +2899,6 @@ fn clean_maybe_renamed_item<'tcx>(
28992899
fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
29002900
}),
29012901
ItemKind::Macro(_, macro_def, kinds) => match kinds {
2902-
MacroKinds::BANG => MacroItem(
2903-
Macro {
2904-
source: display_macro_source(cx.tcx, name, macro_def),
2905-
macro_rules: macro_def.macro_rules,
2906-
},
2907-
MacroKinds::BANG,
2908-
),
29092902
MacroKinds::ATTR => clean_proc_macro(item, &mut name, MacroKind::Attr, cx.tcx),
29102903
MacroKinds::DERIVE => clean_proc_macro(item, &mut name, MacroKind::Derive, cx.tcx),
29112904
_ => MacroItem(

src/librustdoc/clean/types.rs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -745,31 +745,30 @@ impl Item {
745745
find_attr!(&self.attrs.other_attrs, NonExhaustive(..))
746746
}
747747

748-
/// Returns a documentation-level item type from the item.
748+
/// Returns a documentation-level item type from the item. In case of a `macro_rules!` which
749+
/// contains an attr/derive kind, it will always return `ItemType::Macro`. If you want all
750+
/// kinds, you need to use [`Item::types`].
749751
pub(crate) fn type_(&self) -> ItemType {
750752
ItemType::from(self)
751753
}
752754

753-
// FIXME: Return an iterator instead of a `ThinVec`.
754-
pub(crate) fn types(&self) -> ThinVec<ItemType> {
755+
/// Returns an item types. There is only one case where it can return more than one kind:
756+
/// for `macro_rules!` items which contain an attr/derive kind.
757+
pub(crate) fn types(&self) -> impl Iterator<Item = ItemType> {
755758
if let ItemKind::MacroItem(_, macro_kinds) = self.kind {
756-
let mut types = ThinVec::with_capacity(3);
757-
for kind in macro_kinds.iter() {
758-
match kind {
759-
MacroKinds::ATTR => types.push(ItemType::BangMacroAttribute),
760-
MacroKinds::DERIVE => types.push(ItemType::BangMacroDerive),
761-
MacroKinds::BANG => types.push(ItemType::Macro),
762-
_ => panic!("unsupported macro kind {kind:?}"),
763-
}
764-
}
765-
return types;
759+
Either::Right(macro_kinds.iter().map(|kind| match kind {
760+
MacroKinds::ATTR => ItemType::BangMacroAttribute,
761+
MacroKinds::DERIVE => ItemType::BangMacroDerive,
762+
MacroKinds::BANG => ItemType::Macro,
763+
_ => panic!("unsupported macro kind {kind:?}"),
764+
}))
765+
} else {
766+
Either::Left(std::iter::once(self.type_()))
766767
}
767-
let mut types = ThinVec::with_capacity(1);
768-
types.push(self.type_());
769-
types
770768
}
771769

772-
pub(crate) fn is_macro_rules(&self) -> bool {
770+
/// Returns true if this a macro declared with the `macro` keyword or with `macro_rules!.
771+
pub(crate) fn is_bang_macro_or_macro_rules(&self) -> bool {
773772
matches!(self.kind, ItemKind::MacroItem(..))
774773
}
775774

@@ -946,8 +945,12 @@ pub(crate) enum ItemKind {
946945
ForeignStaticItem(Static, hir::Safety),
947946
/// `type`s from an extern block
948947
ForeignTypeItem,
949-
/// A bang macro. it can be multiple things (macro, derive and attribute, potentially multiple
950-
/// at once). Don't forget to look into the `MacroKinds` values.
948+
/// A macro defined with `macro_rules` or the `macro` keyword. It can be multiple things (macro,
949+
/// derive and attribute, potentially multiple at once). Don't forget to look into the
950+
///`MacroKinds` values.
951+
///
952+
/// If a `macro_rules!` only contains a `attr`/`derive` branch, then it's not stored in this
953+
/// variant but in the `ProcMacroItem` variant.
951954
MacroItem(Macro, MacroKinds),
952955
ProcMacroItem(ProcMacro),
953956
PrimitiveItem(PrimitiveType),

src/librustdoc/clean/utils.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::{ascii, mem};
55

66
use rustc_ast as ast;
77
use rustc_ast::join_path_idents;
8+
use rustc_ast::token::{Token, TokenKind};
89
use rustc_ast::tokenstream::TokenTree;
910
use rustc_data_structures::thin_vec::{ThinVec, thin_vec};
1011
use rustc_hir as hir;
@@ -617,9 +618,18 @@ fn render_macro_arms(
617618
.unwrap();
618619
// We skip the `=>`, macro "body" and the delimiter closing that "body" since we don't
619620
// render them.
620-
tokens.next();
621-
tokens.next();
622-
tokens.next();
621+
let _token = tokens.next();
622+
// The `=>`.
623+
debug_assert_matches!(
624+
_token,
625+
Some(TokenTree::Token(Token { kind: TokenKind::FatArrow, .. }, _))
626+
);
627+
let _token = tokens.next();
628+
// The arm body.
629+
debug_assert_matches!(_token, Some(TokenTree::Delimited(..)));
630+
// The delimiter (which may be omitted on the last arm's body).
631+
let _token = tokens.next();
632+
debug_assert_matches!(_token, None | Some(TokenTree::Token(Token { .. }, _)));
623633
}
624634
out
625635
}

src/librustdoc/formats/cache.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,8 @@ impl DocFolder for CacheBuilder<'_, '_> {
382382
| clean::RequiredAssocTypeItem(..)
383383
| clean::AssocTypeItem(..)
384384
| clean::StrippedItem(..)
385-
| clean::AttributeItem
386-
| clean::KeywordItem => {
385+
| clean::KeywordItem
386+
| clean::AttributeItem => {
387387
// FIXME: Do these need handling?
388388
// The person writing this comment doesn't know.
389389
// So would rather leave them to an expert,
@@ -599,7 +599,7 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It
599599
let is_unstable = item.is_unstable();
600600
let mut types = item.types();
601601
let index_item = IndexItem {
602-
ty: types.pop().unwrap(),
602+
ty: types.next().unwrap(),
603603
defid: Some(defid),
604604
name,
605605
module_path: parent_path.to_vec(),

src/librustdoc/formats/item_type.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ item_type! {
101101
// This number is reserved for use in JavaScript
102102
// Generic = 26,
103103
Attribute = 27,
104+
// The two next ones represent an attr/derive macro declared as a `macro_rules!`. We need this
105+
// distinction because they will point to a `macro.[name].html` file and not
106+
// `[attr|derive].[name].html` file, so the link generation needs to take it into account while
107+
// still having the filtering working as expected.
104108
BangMacroAttribute = 28,
105109
BangMacroDerive = 29,
106110
}

src/librustdoc/html/render/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ impl<'tcx> Context<'tcx> {
351351
Some(s) => s,
352352
};
353353

354-
let is_macro_rules = item.is_macro_rules();
354+
let is_macro_rules = item.is_bang_macro_or_macro_rules();
355355
for type_ in item.types() {
356356
if inserted.entry(type_).or_default().insert(name) {
357357
let type_ = type_.to_string();

src/librustdoc/html/render/mod.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -536,13 +536,8 @@ impl AllTypes {
536536
let new_url = format!("{}/{}", url.join("/"), item.html_filename());
537537
url.push(name);
538538
let name = url.join("::");
539-
let mut types = item.types();
540-
if types.len() == 1 {
541-
self.add_item_entry(types.pop().unwrap(), new_url, name);
542-
} else {
543-
for type_ in types {
544-
self.add_item_entry(type_, new_url.clone(), name.clone());
545-
}
539+
for type_ in item.types() {
540+
self.add_item_entry(type_, new_url.clone(), name.clone());
546541
}
547542
}
548543
}

src/librustdoc/html/render/print_item.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,9 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item) -> impl fmt::Disp
129129
let item_vars = ItemVars {
130130
typ,
131131
name: item.name.as_ref().unwrap().as_str(),
132-
// If `type_` returns `None`, it means it's a bang macro with multiple kinds, but
132+
// It's fine to use `type_` here because, even if it's a bang macro with multiple kinds,
133133
// since we're generating its documentation page, we can default to the "parent" type,
134-
// ie "bang macro".
134+
// ie "macro".
135135
item_type: &item.type_().to_string(),
136136
path_components,
137137
stability_since_raw: &stability_since_raw,
@@ -464,7 +464,7 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
464464
stab_tags = print_extra_info_tags(tcx, myitem, item, None),
465465
class = type_,
466466
unsafety_flag = unsafety_flag,
467-
href = print_item_path(myitem),
467+
href = myitem.html_filename(),
468468
title1 = myitem.type_(),
469469
title2 = full_path(cx, myitem),
470470
)?;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// This test ensures that the `foo` decl macro is present in the module sidebar.
2+
3+
#![feature(decl_macro)]
4+
#![crate_name = "foo"]
5+
6+
//@has 'foo/bar/index.html'
7+
//@has - '//*[@id="rustdoc-modnav"]/ul[@class="block macro"]//a[@href="../macro.foo.html"]' 'foo'
8+
9+
pub macro foo {
10+
() => { "bar" }
11+
}
12+
13+
/// docs
14+
pub mod bar {
15+
}

0 commit comments

Comments
 (0)