Skip to content

Commit 71b0ea6

Browse files
authored
Rollup merge of #77672 - Nemo157:simplify-cfg, r=jyn514
Simplify doc-cfg rendering based on the current context For sub-items on a page don't show cfg that has already been rendered on a parent item. At its simplest this means not showing anything that is shown in the portability message at the top of the page, but also for things like fields of an enum variant if that variant itself is cfg-gated then don't repeat those cfg on each field of the variant. This does not touch trait implementation rendering, as that is more complex and there are existing issues around how it deals with doc-cfg that need to be fixed first. ### Screenshots, left is current, right is new: ![image](https://user-images.githubusercontent.com/81079/95387261-c2e6a200-08f0-11eb-90d4-0a9734acd922.png) ![image](https://user-images.githubusercontent.com/81079/95387458-06411080-08f1-11eb-81f7-5dd7f37695dd.png) ![image](https://user-images.githubusercontent.com/81079/95387702-6637b700-08f1-11eb-82f4-46b6cd9b24f2.png) ![image](https://user-images.githubusercontent.com/81079/95387905-b9aa0500-08f1-11eb-8d95-8b618d31d419.png) ![image](https://user-images.githubusercontent.com/81079/95388300-5bc9ed00-08f2-11eb-9ac9-b92cbdb60b89.png) cc #43781
2 parents 9b8c0eb + 4409cb2 commit 71b0ea6

File tree

6 files changed

+334
-52
lines changed

6 files changed

+334
-52
lines changed

src/librustdoc/clean/cfg.rs

+31
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,37 @@ impl Cfg {
201201
_ => false,
202202
}
203203
}
204+
205+
/// Attempt to simplify this cfg by assuming that `assume` is already known to be true, will
206+
/// return `None` if simplification managed to completely eliminate any requirements from this
207+
/// `Cfg`.
208+
///
209+
/// See `tests::test_simplify_with` for examples.
210+
pub(crate) fn simplify_with(&self, assume: &Cfg) -> Option<Cfg> {
211+
if self == assume {
212+
return None;
213+
}
214+
215+
if let Cfg::All(a) = self {
216+
let mut sub_cfgs: Vec<Cfg> = if let Cfg::All(b) = assume {
217+
a.iter().filter(|a| !b.contains(a)).cloned().collect()
218+
} else {
219+
a.iter().filter(|&a| a != assume).cloned().collect()
220+
};
221+
let len = sub_cfgs.len();
222+
return match len {
223+
0 => None,
224+
1 => sub_cfgs.pop(),
225+
_ => Some(Cfg::All(sub_cfgs)),
226+
};
227+
} else if let Cfg::All(b) = assume {
228+
if b.contains(self) {
229+
return None;
230+
}
231+
}
232+
233+
Some(self.clone())
234+
}
204235
}
205236

206237
impl ops::Not for Cfg {

src/librustdoc/clean/cfg/tests.rs

+36
Original file line numberDiff line numberDiff line change
@@ -433,3 +433,39 @@ fn test_render_long_html() {
433433
);
434434
})
435435
}
436+
437+
#[test]
438+
fn test_simplify_with() {
439+
// This is a tiny subset of things that could be simplified, but it likely covers 90% of
440+
// real world usecases well.
441+
with_default_session_globals(|| {
442+
let foo = word_cfg("foo");
443+
let bar = word_cfg("bar");
444+
let baz = word_cfg("baz");
445+
let quux = word_cfg("quux");
446+
447+
let foobar = Cfg::All(vec![foo.clone(), bar.clone()]);
448+
let barbaz = Cfg::All(vec![bar.clone(), baz.clone()]);
449+
let foobarbaz = Cfg::All(vec![foo.clone(), bar.clone(), baz.clone()]);
450+
let bazquux = Cfg::All(vec![baz.clone(), quux.clone()]);
451+
452+
// Unrelated cfgs don't affect each other
453+
assert_eq!(foo.simplify_with(&bar).as_ref(), Some(&foo));
454+
assert_eq!(foobar.simplify_with(&bazquux).as_ref(), Some(&foobar));
455+
456+
// Identical cfgs are eliminated
457+
assert_eq!(foo.simplify_with(&foo), None);
458+
assert_eq!(foobar.simplify_with(&foobar), None);
459+
460+
// Multiple cfgs eliminate a single assumed cfg
461+
assert_eq!(foobar.simplify_with(&foo).as_ref(), Some(&bar));
462+
assert_eq!(foobar.simplify_with(&bar).as_ref(), Some(&foo));
463+
464+
// A single cfg is eliminated by multiple assumed cfg containing it
465+
assert_eq!(foo.simplify_with(&foobar), None);
466+
467+
// Multiple cfgs eliminate the matching subset of multiple assumed cfg
468+
assert_eq!(foobar.simplify_with(&barbaz).as_ref(), Some(&foo));
469+
assert_eq!(foobar.simplify_with(&foobarbaz), None);
470+
});
471+
}

0 commit comments

Comments
 (0)