|
6 | 6 | use std::fmt::{self, Write};
|
7 | 7 | use std::{mem, ops};
|
8 | 8 |
|
| 9 | +use itertools::Itertools; |
9 | 10 | use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit};
|
10 | 11 | use rustc_data_structures::fx::FxHashSet;
|
11 | 12 | use rustc_feature::Features;
|
@@ -389,98 +390,84 @@ fn write_with_opt_paren<T: fmt::Display>(
|
389 | 390 | Ok(())
|
390 | 391 | }
|
391 | 392 |
|
| 393 | +impl Display<'_> { |
| 394 | + fn display_quantified_sub_cfgs( |
| 395 | + &self, |
| 396 | + fmt: &mut fmt::Formatter<'_>, |
| 397 | + sub_cfgs: &[Cfg], |
| 398 | + separator: &str, |
| 399 | + ) -> fmt::Result { |
| 400 | + use fmt::Display as _; |
| 401 | + |
| 402 | + let short_longhand = self.1.is_long() && { |
| 403 | + let all_crate_features = |
| 404 | + sub_cfgs.iter().all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::feature, Some(_)))); |
| 405 | + let all_target_features = sub_cfgs |
| 406 | + .iter() |
| 407 | + .all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::target_feature, Some(_)))); |
| 408 | + |
| 409 | + if all_crate_features { |
| 410 | + fmt.write_str("crate features ")?; |
| 411 | + true |
| 412 | + } else if all_target_features { |
| 413 | + fmt.write_str("target features ")?; |
| 414 | + true |
| 415 | + } else { |
| 416 | + false |
| 417 | + } |
| 418 | + }; |
| 419 | + |
| 420 | + sub_cfgs |
| 421 | + .iter() |
| 422 | + .map(|sub_cfg| { |
| 423 | + fmt::from_fn(move |f| { |
| 424 | + if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) { |
| 425 | + if self.1.is_html() { |
| 426 | + write!(f, "<code>{feat}</code>") |
| 427 | + } else { |
| 428 | + write!(f, "`{feat}`") |
| 429 | + } |
| 430 | + } else { |
| 431 | + write_with_opt_paren(f, !sub_cfg.is_all(), Display(sub_cfg, self.1)) |
| 432 | + } |
| 433 | + }) |
| 434 | + }) |
| 435 | + .format(separator) |
| 436 | + .fmt(fmt) |
| 437 | + } |
| 438 | +} |
| 439 | + |
392 | 440 | impl fmt::Display for Display<'_> {
|
393 | 441 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
394 | 442 | match *self.0 {
|
395 | 443 | Cfg::Not(ref child) => match **child {
|
396 | 444 | Cfg::Any(ref sub_cfgs) => {
|
397 | 445 | let separator =
|
398 | 446 | if sub_cfgs.iter().all(Cfg::is_simple) { " nor " } else { ", nor " };
|
399 |
| - for (i, sub_cfg) in sub_cfgs.iter().enumerate() { |
400 |
| - fmt.write_str(if i == 0 { "neither " } else { separator })?; |
401 |
| - write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(sub_cfg, self.1))?; |
402 |
| - } |
403 |
| - Ok(()) |
| 447 | + fmt.write_str("neither ")?; |
| 448 | + sub_cfgs |
| 449 | + .iter() |
| 450 | + .map(|sub_cfg| { |
| 451 | + fmt::from_fn(|fmt| { |
| 452 | + write_with_opt_paren( |
| 453 | + fmt, |
| 454 | + !sub_cfg.is_all(), |
| 455 | + Display(sub_cfg, self.1), |
| 456 | + ) |
| 457 | + }) |
| 458 | + }) |
| 459 | + .format(separator) |
| 460 | + .fmt(fmt) |
404 | 461 | }
|
405 | 462 | ref simple @ Cfg::Cfg(..) => write!(fmt, "non-{}", Display(simple, self.1)),
|
406 | 463 | ref c => write!(fmt, "not ({})", Display(c, self.1)),
|
407 | 464 | },
|
408 | 465 |
|
409 | 466 | Cfg::Any(ref sub_cfgs) => {
|
410 | 467 | let separator = if sub_cfgs.iter().all(Cfg::is_simple) { " or " } else { ", or " };
|
411 |
| - |
412 |
| - let short_longhand = self.1.is_long() && { |
413 |
| - let all_crate_features = sub_cfgs |
414 |
| - .iter() |
415 |
| - .all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::feature, Some(_)))); |
416 |
| - let all_target_features = sub_cfgs |
417 |
| - .iter() |
418 |
| - .all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::target_feature, Some(_)))); |
419 |
| - |
420 |
| - if all_crate_features { |
421 |
| - fmt.write_str("crate features ")?; |
422 |
| - true |
423 |
| - } else if all_target_features { |
424 |
| - fmt.write_str("target features ")?; |
425 |
| - true |
426 |
| - } else { |
427 |
| - false |
428 |
| - } |
429 |
| - }; |
430 |
| - |
431 |
| - for (i, sub_cfg) in sub_cfgs.iter().enumerate() { |
432 |
| - if i != 0 { |
433 |
| - fmt.write_str(separator)?; |
434 |
| - } |
435 |
| - if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) { |
436 |
| - if self.1.is_html() { |
437 |
| - write!(fmt, "<code>{feat}</code>")?; |
438 |
| - } else { |
439 |
| - write!(fmt, "`{feat}`")?; |
440 |
| - } |
441 |
| - } else { |
442 |
| - write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(sub_cfg, self.1))?; |
443 |
| - } |
444 |
| - } |
445 |
| - Ok(()) |
446 |
| - } |
447 |
| - |
448 |
| - Cfg::All(ref sub_cfgs) => { |
449 |
| - let short_longhand = self.1.is_long() && { |
450 |
| - let all_crate_features = sub_cfgs |
451 |
| - .iter() |
452 |
| - .all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::feature, Some(_)))); |
453 |
| - let all_target_features = sub_cfgs |
454 |
| - .iter() |
455 |
| - .all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::target_feature, Some(_)))); |
456 |
| - |
457 |
| - if all_crate_features { |
458 |
| - fmt.write_str("crate features ")?; |
459 |
| - true |
460 |
| - } else if all_target_features { |
461 |
| - fmt.write_str("target features ")?; |
462 |
| - true |
463 |
| - } else { |
464 |
| - false |
465 |
| - } |
466 |
| - }; |
467 |
| - |
468 |
| - for (i, sub_cfg) in sub_cfgs.iter().enumerate() { |
469 |
| - if i != 0 { |
470 |
| - fmt.write_str(" and ")?; |
471 |
| - } |
472 |
| - if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) { |
473 |
| - if self.1.is_html() { |
474 |
| - write!(fmt, "<code>{feat}</code>")?; |
475 |
| - } else { |
476 |
| - write!(fmt, "`{feat}`")?; |
477 |
| - } |
478 |
| - } else { |
479 |
| - write_with_opt_paren(fmt, !sub_cfg.is_simple(), Display(sub_cfg, self.1))?; |
480 |
| - } |
481 |
| - } |
482 |
| - Ok(()) |
| 468 | + self.display_quantified_sub_cfgs(fmt, sub_cfgs, separator) |
483 | 469 | }
|
| 470 | + Cfg::All(ref sub_cfgs) => self.display_quantified_sub_cfgs(fmt, sub_cfgs, " and "), |
484 | 471 |
|
485 | 472 | Cfg::True => fmt.write_str("everywhere"),
|
486 | 473 | Cfg::False => fmt.write_str("nowhere"),
|
|
0 commit comments