Skip to content

Commit 727f904

Browse files
author
Timothée Delabrouille
committed
cfg taken out of Attributes, put in Item
check item.is_fake() instead of self_id.is_some() Remove empty branching in Attributes::from_ast diverse small refacto after Josha review cfg computation moved in merge_attrs refacto use from_ast twice for coherence take cfg out of Attributes and move it to Item
1 parent b4f1dfd commit 727f904

File tree

12 files changed

+104
-85
lines changed

12 files changed

+104
-85
lines changed

src/librustdoc/clean/auto_trait.rs

+1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
126126
synthetic: true,
127127
blanket_impl: None,
128128
}),
129+
cfg: None,
129130
})
130131
}
131132

src/librustdoc/clean/blanket_impl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
128128
synthetic: false,
129129
blanket_impl: Some(trait_ref.self_ty().clean(self.cx)),
130130
}),
131+
cfg: None,
131132
});
132133
}
133134
}

src/librustdoc/clean/inline.rs

+28-18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Support for inlining external documentation into the current AST.
22
33
use std::iter::once;
4+
use std::sync::Arc;
45

56
use rustc_ast as ast;
67
use rustc_data_structures::fx::FxHashSet;
@@ -15,7 +16,7 @@ use rustc_span::hygiene::MacroKind;
1516
use rustc_span::symbol::{kw, sym, Symbol};
1617
use rustc_span::Span;
1718

18-
use crate::clean::{self, Attributes, GetDefId, ToSource};
19+
use crate::clean::{self, Attributes, AttributesExt, GetDefId, ToSource};
1920
use crate::core::DocContext;
2021
use crate::formats::item_type::ItemType;
2122

@@ -120,11 +121,16 @@ crate fn try_inline(
120121
_ => return None,
121122
};
122123

123-
let target_attrs = load_attrs(cx, did);
124-
let attrs = box merge_attrs(cx, Some(parent_module), target_attrs, attrs_clone);
125-
124+
let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs_clone);
126125
cx.inlined.insert(did);
127-
ret.push(clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, attrs, cx));
126+
ret.push(clean::Item::from_def_id_and_attrs_and_parts(
127+
did,
128+
Some(name),
129+
kind,
130+
box attrs,
131+
cx,
132+
cfg,
133+
));
128134
Some(ret)
129135
}
130136

@@ -288,22 +294,24 @@ fn merge_attrs(
288294
parent_module: Option<DefId>,
289295
old_attrs: Attrs<'_>,
290296
new_attrs: Option<Attrs<'_>>,
291-
) -> clean::Attributes {
297+
) -> (clean::Attributes, Option<Arc<clean::cfg::Cfg>>) {
292298
// NOTE: If we have additional attributes (from a re-export),
293299
// always insert them first. This ensure that re-export
294300
// doc comments show up before the original doc comments
295301
// when we render them.
296302
if let Some(inner) = new_attrs {
297-
if let Some(new_id) = parent_module {
298-
let diag = cx.sess().diagnostic();
299-
Attributes::from_ast(diag, old_attrs, Some((inner, new_id)))
300-
} else {
301-
let mut both = inner.to_vec();
302-
both.extend_from_slice(old_attrs);
303-
both.clean(cx)
304-
}
303+
let mut both = inner.to_vec();
304+
both.extend_from_slice(old_attrs);
305+
(
306+
if let Some(new_id) = parent_module {
307+
Attributes::from_ast(old_attrs, Some((inner, new_id)))
308+
} else {
309+
Attributes::from_ast(&both, None)
310+
},
311+
both.cfg(cx.sess().diagnostic()),
312+
)
305313
} else {
306-
old_attrs.clean(cx)
314+
(old_attrs.clean(cx), old_attrs.cfg(cx.sess().diagnostic()))
307315
}
308316
}
309317

@@ -414,8 +422,8 @@ crate fn build_impl(
414422

415423
debug!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id());
416424

417-
let attrs = box merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs);
418-
debug!("merged_attrs={:?}", attrs);
425+
let (merged_attrs, cfg) = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs);
426+
debug!("merged_attrs={:?}", merged_attrs);
419427

420428
ret.push(clean::Item::from_def_id_and_attrs_and_parts(
421429
did,
@@ -432,8 +440,9 @@ crate fn build_impl(
432440
synthetic: false,
433441
blanket_impl: None,
434442
}),
435-
attrs,
443+
box merged_attrs,
436444
cx,
445+
cfg,
437446
));
438447
}
439448

@@ -479,6 +488,7 @@ fn build_module(
479488
},
480489
true,
481490
)),
491+
cfg: None,
482492
});
483493
} else if let Some(i) = try_inline(cx, did, item.res, item.ident.name, None, visited) {
484494
items.extend(i)

src/librustdoc/clean/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ impl Clean<Item> for doctree::Module<'_> {
122122
}
123123

124124
impl Clean<Attributes> for [ast::Attribute] {
125-
fn clean(&self, cx: &mut DocContext<'_>) -> Attributes {
126-
Attributes::from_ast(cx.sess().diagnostic(), self, None)
125+
fn clean(&self, _cx: &mut DocContext<'_>) -> Attributes {
126+
Attributes::from_ast(self, None)
127127
}
128128
}
129129

@@ -1998,13 +1998,15 @@ fn clean_extern_crate(
19981998
return items;
19991999
}
20002000
}
2001+
20012002
// FIXME: using `from_def_id_and_kind` breaks `rustdoc/masked` for some reason
20022003
vec![Item {
20032004
name: Some(name),
20042005
attrs: box attrs.clean(cx),
20052006
def_id: crate_def_id,
20062007
visibility: krate.vis.clean(cx),
20072008
kind: box ExternCrateItem { src: orig_name },
2009+
cfg: attrs.cfg(cx.sess().diagnostic()),
20082010
}]
20092011
}
20102012

src/librustdoc/clean/types.rs

+53-37
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,13 @@ crate struct Item {
219219
/// E.g., struct vs enum vs function.
220220
crate kind: Box<ItemKind>,
221221
crate def_id: DefId,
222+
223+
crate cfg: Option<Arc<Cfg>>,
222224
}
223225

224226
// `Item` is used a lot. Make sure it doesn't unintentionally get bigger.
225227
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
226-
rustc_data_structures::static_assert_size!(Item, 40);
228+
rustc_data_structures::static_assert_size!(Item, 48);
227229

228230
impl fmt::Debug for Item {
229231
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -235,6 +237,7 @@ impl fmt::Debug for Item {
235237
.field("kind", &self.kind)
236238
.field("visibility", &self.visibility)
237239
.field("def_id", def_id)
240+
.field("cfg", &self.cfg)
238241
.finish()
239242
}
240243
}
@@ -262,6 +265,10 @@ impl Item {
262265
if self.is_fake() { None } else { tcx.lookup_deprecation(self.def_id) }
263266
}
264267

268+
crate fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool {
269+
if self.is_fake() { false } else { tcx.get_attrs(self.def_id).inner_docs() }
270+
}
271+
265272
crate fn span(&self, tcx: TyCtxt<'_>) -> Span {
266273
let kind = match &*self.kind {
267274
ItemKind::StrippedItem(k) => k,
@@ -305,12 +312,15 @@ impl Item {
305312
kind: ItemKind,
306313
cx: &mut DocContext<'_>,
307314
) -> Item {
315+
let ast_attrs = cx.tcx.get_attrs(def_id);
316+
308317
Self::from_def_id_and_attrs_and_parts(
309318
def_id,
310319
name,
311320
kind,
312-
box cx.tcx.get_attrs(def_id).clean(cx),
321+
box ast_attrs.clean(cx),
313322
cx,
323+
ast_attrs.cfg(cx.sess().diagnostic()),
314324
)
315325
}
316326

@@ -320,6 +330,7 @@ impl Item {
320330
kind: ItemKind,
321331
attrs: Box<Attributes>,
322332
cx: &mut DocContext<'_>,
333+
cfg: Option<Arc<Cfg>>,
323334
) -> Item {
324335
debug!("name={:?}, def_id={:?}", name, def_id);
325336

@@ -329,6 +340,7 @@ impl Item {
329340
name,
330341
attrs,
331342
visibility: cx.tcx.visibility(def_id).clean(cx),
343+
cfg,
332344
}
333345
}
334346

@@ -668,6 +680,8 @@ crate trait AttributesExt {
668680
fn inner_docs(&self) -> bool;
669681

670682
fn other_attrs(&self) -> Vec<ast::Attribute>;
683+
684+
fn cfg(&self, diagnostic: &::rustc_errors::Handler) -> Option<Arc<Cfg>>;
671685
}
672686

673687
impl AttributesExt for [ast::Attribute] {
@@ -691,6 +705,41 @@ impl AttributesExt for [ast::Attribute] {
691705
fn other_attrs(&self) -> Vec<ast::Attribute> {
692706
self.iter().filter(|attr| attr.doc_str().is_none()).cloned().collect()
693707
}
708+
709+
fn cfg(&self, diagnostic: &::rustc_errors::Handler) -> Option<Arc<Cfg>> {
710+
let mut cfg = Cfg::True;
711+
712+
for attr in self.iter() {
713+
if attr.doc_str().is_none() && attr.has_name(sym::doc) {
714+
if let Some(mi) = attr.meta() {
715+
if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
716+
// Extracted #[doc(cfg(...))]
717+
match Cfg::parse(cfg_mi) {
718+
Ok(new_cfg) => cfg &= new_cfg,
719+
Err(e) => diagnostic.span_err(e.span, e.msg),
720+
}
721+
}
722+
}
723+
}
724+
}
725+
726+
for attr in self.lists(sym::target_feature) {
727+
if attr.has_name(sym::enable) {
728+
if let Some(feat) = attr.value_str() {
729+
let meta = attr::mk_name_value_item_str(
730+
Ident::with_dummy_span(sym::target_feature),
731+
feat,
732+
DUMMY_SP,
733+
);
734+
if let Ok(feat_cfg) = Cfg::parse(&meta) {
735+
cfg &= feat_cfg;
736+
}
737+
}
738+
}
739+
}
740+
741+
if cfg == Cfg::True { None } else { Some(Arc::new(cfg)) }
742+
}
694743
}
695744

696745
crate trait NestedAttributesExt {
@@ -799,7 +848,6 @@ impl<'a> FromIterator<&'a DocFragment> for String {
799848
crate struct Attributes {
800849
crate doc_strings: Vec<DocFragment>,
801850
crate other_attrs: Vec<ast::Attribute>,
802-
crate cfg: Option<Arc<Cfg>>,
803851
}
804852

805853
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
@@ -914,12 +962,10 @@ impl Attributes {
914962
}
915963

916964
crate fn from_ast(
917-
diagnostic: &::rustc_errors::Handler,
918965
attrs: &[ast::Attribute],
919966
additional_attrs: Option<(&[ast::Attribute], DefId)>,
920967
) -> Attributes {
921968
let mut doc_strings: Vec<DocFragment> = vec![];
922-
let mut cfg = Cfg::True;
923969
let mut doc_line = 0;
924970

925971
fn update_need_backline(doc_strings: &mut Vec<DocFragment>, frag: &DocFragment) {
@@ -967,14 +1013,7 @@ impl Attributes {
9671013
} else {
9681014
if attr.has_name(sym::doc) {
9691015
if let Some(mi) = attr.meta() {
970-
if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
971-
// Extracted #[doc(cfg(...))]
972-
match Cfg::parse(cfg_mi) {
973-
Ok(new_cfg) => cfg &= new_cfg,
974-
Err(e) => diagnostic.span_err(e.span, e.msg),
975-
}
976-
} else if let Some((filename, contents)) = Attributes::extract_include(&mi)
977-
{
1016+
if let Some((filename, contents)) = Attributes::extract_include(&mi) {
9781017
let line = doc_line;
9791018
doc_line += contents.as_str().lines().count();
9801019
let frag = DocFragment {
@@ -1004,28 +1043,7 @@ impl Attributes {
10041043
.filter_map(clean_attr)
10051044
.collect();
10061045

1007-
// treat #[target_feature(enable = "feat")] attributes as if they were
1008-
// #[doc(cfg(target_feature = "feat"))] attributes as well
1009-
for attr in attrs.lists(sym::target_feature) {
1010-
if attr.has_name(sym::enable) {
1011-
if let Some(feat) = attr.value_str() {
1012-
let meta = attr::mk_name_value_item_str(
1013-
Ident::with_dummy_span(sym::target_feature),
1014-
feat,
1015-
DUMMY_SP,
1016-
);
1017-
if let Ok(feat_cfg) = Cfg::parse(&meta) {
1018-
cfg &= feat_cfg;
1019-
}
1020-
}
1021-
}
1022-
}
1023-
1024-
Attributes {
1025-
doc_strings,
1026-
other_attrs,
1027-
cfg: if cfg == Cfg::True { None } else { Some(Arc::new(cfg)) },
1028-
}
1046+
Attributes { doc_strings, other_attrs }
10291047
}
10301048

10311049
/// Finds the `doc` attribute as a NameValue and returns the corresponding
@@ -1091,7 +1109,6 @@ impl Attributes {
10911109
impl PartialEq for Attributes {
10921110
fn eq(&self, rhs: &Self) -> bool {
10931111
self.doc_strings == rhs.doc_strings
1094-
&& self.cfg == rhs.cfg
10951112
&& self
10961113
.other_attrs
10971114
.iter()
@@ -1105,7 +1122,6 @@ impl Eq for Attributes {}
11051122
impl Hash for Attributes {
11061123
fn hash<H: Hasher>(&self, hasher: &mut H) {
11071124
self.doc_strings.hash(hasher);
1108-
self.cfg.hash(hasher);
11091125
for attr in &self.other_attrs {
11101126
attr.id.hash(hasher);
11111127
}

src/librustdoc/doctest.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1093,9 +1093,9 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> {
10931093
nested: F,
10941094
) {
10951095
let ast_attrs = self.tcx.hir().attrs(hir_id);
1096+
let mut attrs = Attributes::from_ast(ast_attrs, None);
10961097

1097-
let mut attrs = Attributes::from_ast(self.sess.diagnostic(), ast_attrs, None);
1098-
if let Some(ref cfg) = attrs.cfg {
1098+
if let Some(ref cfg) = ast_attrs.cfg(self.sess.diagnostic()) {
10991099
if !cfg.matches(&self.sess.parse_sess, Some(&self.sess.features_untracked())) {
11001100
return;
11011101
}

src/librustdoc/html/render/cache.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ use serde::ser::{Serialize, SerializeStruct, Serializer};
99

1010
use crate::clean;
1111
use crate::clean::types::{
12-
AttributesExt, FnDecl, FnRetTy, GenericBound, Generics, GetDefId, Type, TypeKind,
13-
WherePredicate,
12+
AttributesExt, FnDecl, FnRetTy, GenericBound, Generics, GetDefId, Type, WherePredicate,
1413
};
1514
use crate::formats::cache::Cache;
1615
use crate::formats::item_type::ItemType;

src/librustdoc/html/render/mod.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -608,17 +608,12 @@ fn document_item_info(
608608
}
609609

610610
fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option<String> {
611-
let cfg = match (&item.attrs.cfg, parent.and_then(|p| p.attrs.cfg.as_ref())) {
611+
let cfg = match (&item.cfg, parent.and_then(|p| p.cfg.as_ref())) {
612612
(Some(cfg), Some(parent_cfg)) => cfg.simplify_with(parent_cfg),
613613
(cfg, _) => cfg.as_deref().cloned(),
614614
};
615615

616-
debug!(
617-
"Portability {:?} - {:?} = {:?}",
618-
item.attrs.cfg,
619-
parent.and_then(|p| p.attrs.cfg.as_ref()),
620-
cfg
621-
);
616+
debug!("Portability {:?} - {:?} = {:?}", item.cfg, parent.and_then(|p| p.cfg.as_ref()), cfg);
622617

623618
Some(format!("<div class=\"stab portability\">{}</div>", cfg?.render_long_html()))
624619
}

0 commit comments

Comments
 (0)