Skip to content

Commit 5f93edd

Browse files
Prevent some attributes from being merged with others on reexports
1 parent 9bb6e60 commit 5f93edd

File tree

1 file changed

+89
-8
lines changed

1 file changed

+89
-8
lines changed

src/librustdoc/clean/mod.rs

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2126,6 +2126,87 @@ fn get_all_import_attributes<'hir>(
21262126
}
21272127
}
21282128

2129+
/// When inlining items, we merge its attributes (and all the reexports attributes too) with the
2130+
/// final reexport. For example:
2131+
///
2132+
/// ```
2133+
/// #[doc(hidden, cfg(feature = "foo"))]
2134+
/// pub struct Foo;
2135+
///
2136+
/// #[doc(cfg(feature = "bar"))]
2137+
/// #[doc(hidden, no_inline)]
2138+
/// pub use Foo as Foo1;
2139+
///
2140+
/// #[doc(inline)]
2141+
/// pub use Foo2 as Bar;
2142+
/// ```
2143+
///
2144+
/// So `Bar` at the end will have both `cfg(feature = "...")`. However, we don't want to merge all
2145+
/// attributes so we filter out the following ones:
2146+
/// * `doc(inline)`
2147+
/// * `doc(no_inline)`
2148+
/// * `doc(hidden)`
2149+
fn add_without_unwanted_attributes(attrs: &mut Vec<ast::Attribute>, new_attrs: &[ast::Attribute]) {
2150+
use rustc_ast::token::{Token, TokenKind};
2151+
use rustc_ast::tokenstream::{TokenStream, TokenTree};
2152+
2153+
for attr in new_attrs {
2154+
let mut attr = attr.clone();
2155+
match attr.kind {
2156+
ast::AttrKind::Normal(ref mut normal) => {
2157+
if let [ident] = &*normal.item.path.segments {
2158+
let ident = ident.ident.name;
2159+
if ident == sym::doc {
2160+
match normal.item.args {
2161+
ast::AttrArgs::Delimited(ref mut args) => {
2162+
let mut tokens = Vec::with_capacity(args.tokens.len());
2163+
let mut skip_next_comma = false;
2164+
for token in args.tokens.clone().into_trees() {
2165+
match token {
2166+
TokenTree::Token(
2167+
Token {
2168+
kind:
2169+
TokenKind::Ident(
2170+
sym::hidden | sym::inline | sym::no_inline,
2171+
_,
2172+
),
2173+
..
2174+
},
2175+
_,
2176+
) => {
2177+
skip_next_comma = true;
2178+
continue;
2179+
}
2180+
TokenTree::Token(
2181+
Token { kind: TokenKind::Comma, .. },
2182+
_,
2183+
) if skip_next_comma => {
2184+
skip_next_comma = false;
2185+
continue;
2186+
}
2187+
_ => {}
2188+
}
2189+
skip_next_comma = false;
2190+
tokens.push(token);
2191+
}
2192+
args.tokens = TokenStream::new(tokens);
2193+
attrs.push(attr);
2194+
}
2195+
ast::AttrArgs::Empty | ast::AttrArgs::Eq(..) => {
2196+
attrs.push(attr);
2197+
continue;
2198+
}
2199+
}
2200+
}
2201+
}
2202+
}
2203+
ast::AttrKind::DocComment(..) => {
2204+
attrs.push(attr);
2205+
}
2206+
}
2207+
}
2208+
}
2209+
21292210
fn clean_maybe_renamed_item<'tcx>(
21302211
cx: &mut DocContext<'tcx>,
21312212
item: &hir::Item<'tcx>,
@@ -2216,17 +2297,17 @@ fn clean_maybe_renamed_item<'tcx>(
22162297
extra_attrs.extend_from_slice(inline::load_attrs(cx, import_id.to_def_id()));
22172298
// Then we get all the various imports' attributes.
22182299
get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs);
2300+
add_without_unwanted_attributes(&mut extra_attrs, inline::load_attrs(cx, def_id));
2301+
} else {
2302+
// We only keep the item's attributes.
2303+
extra_attrs.extend_from_slice(inline::load_attrs(cx, def_id));
22192304
}
22202305

2221-
let mut item = if !extra_attrs.is_empty() {
2222-
extra_attrs.extend_from_slice(inline::load_attrs(cx, def_id));
2223-
let attrs = Attributes::from_ast(&extra_attrs);
2224-
let cfg = extra_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
2306+
let attrs = Attributes::from_ast(&extra_attrs);
2307+
let cfg = extra_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
22252308

2226-
Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg)
2227-
} else {
2228-
Item::from_def_id_and_parts(def_id, Some(name), kind, cx)
2229-
};
2309+
let mut item =
2310+
Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg);
22302311
item.inline_stmt_id = import_id.map(|def_id| def_id.to_def_id());
22312312
vec![item]
22322313
})

0 commit comments

Comments
 (0)