@@ -227,14 +227,22 @@ impl Cfg {
227227 }
228228
229229 fn should_append_only_to_description ( & self ) -> bool {
230- match self . 0 {
231- CfgEntry :: Any ( ..)
232- | CfgEntry :: All ( ..)
233- | CfgEntry :: NameValue { .. }
234- | CfgEntry :: Version ( ..)
235- | CfgEntry :: Not ( CfgEntry :: NameValue { .. } , _) => true ,
236- CfgEntry :: Not ( ..) | CfgEntry :: Bool ( ..) => false ,
230+ fn should_append_only_to_description ( cfg : & CfgEntry ) -> bool {
231+ match cfg {
232+ CfgEntry :: NameValue { .. }
233+ | CfgEntry :: Version ( ..)
234+ | CfgEntry :: Not ( CfgEntry :: NameValue { .. } , _) => true ,
235+ CfgEntry :: Any ( a, _) | CfgEntry :: All ( a, _) => {
236+ if a. is_empty ( ) {
237+ false
238+ } else {
239+ a. iter ( ) . any ( |sub| should_append_only_to_description ( sub) )
240+ }
241+ }
242+ CfgEntry :: Not ( ..) | CfgEntry :: Bool ( ..) => false ,
243+ }
237244 }
245+ should_append_only_to_description ( & self . 0 )
238246 }
239247
240248 fn should_use_with_in_description ( & self ) -> bool {
@@ -309,7 +317,19 @@ impl Cfg {
309317 }
310318
311319 fn omit_preposition ( & self ) -> bool {
312- matches ! ( self . 0 , CfgEntry :: Bool ( ..) )
320+ fn omit_preposition ( cfg : & CfgEntry ) -> bool {
321+ match cfg {
322+ CfgEntry :: NameValue { .. }
323+ | CfgEntry :: Version ( ..)
324+ | CfgEntry :: Not ( CfgEntry :: NameValue { .. } , _) => false ,
325+ CfgEntry :: Any ( a, _) | CfgEntry :: All ( a, _) => {
326+ a. is_empty ( ) || matches ! ( a. as_slice( ) , [ a] if omit_preposition( & a) )
327+ }
328+ CfgEntry :: Not ( a, _) => omit_preposition ( a) ,
329+ CfgEntry :: Bool ( ..) => true ,
330+ }
331+ }
332+ omit_preposition ( & self . 0 )
313333 }
314334
315335 pub ( crate ) fn inner ( & self ) -> & CfgEntry {
@@ -459,15 +479,20 @@ impl Display<'_> {
459479 use fmt:: Display as _;
460480
461481 let short_longhand = self . 1 . is_long ( ) && {
462- let all_crate_features = sub_cfgs. iter ( ) . all ( |sub_cfg| {
463- matches ! ( sub_cfg, CfgEntry :: NameValue { name: sym:: feature, value: Some ( _) , .. } )
464- } ) ;
465- let all_target_features = sub_cfgs. iter ( ) . all ( |sub_cfg| {
466- matches ! (
467- sub_cfg,
468- CfgEntry :: NameValue { name: sym:: target_feature, value: Some ( _) , .. }
469- )
470- } ) ;
482+ let all_crate_features = !sub_cfgs. is_empty ( )
483+ && sub_cfgs. iter ( ) . all ( |sub_cfg| {
484+ matches ! (
485+ sub_cfg,
486+ CfgEntry :: NameValue { name: sym:: feature, value: Some ( _) , .. }
487+ )
488+ } ) ;
489+ let all_target_features = !sub_cfgs. is_empty ( )
490+ && sub_cfgs. iter ( ) . all ( |sub_cfg| {
491+ matches ! (
492+ sub_cfg,
493+ CfgEntry :: NameValue { name: sym:: target_feature, value: Some ( _) , .. }
494+ )
495+ } ) ;
471496
472497 if all_crate_features {
473498 fmt. write_str ( "crate features " ) ?;
@@ -506,20 +531,45 @@ impl Display<'_> {
506531
507532impl fmt:: Display for Display < ' _ > {
508533 fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
534+ fn display_bool ( fmt : & mut fmt:: Formatter < ' _ > , value : bool ) -> fmt:: Result {
535+ if value { fmt. write_str ( "everywhere" ) } else { fmt. write_str ( "nowhere" ) }
536+ }
537+
509538 match & self . 0 {
510- CfgEntry :: Not ( CfgEntry :: Any ( sub_cfgs, _) , _) => {
511- let separator = if sub_cfgs. iter ( ) . all ( is_simple_cfg) { " nor " } else { ", nor " } ;
512- fmt. write_str ( "neither " ) ?;
513-
514- sub_cfgs
515- . iter ( )
516- . map ( |sub_cfg| {
517- Wrapped :: with_parens ( )
518- . when ( is_any_cfg ( sub_cfg) )
519- . wrap ( Display ( sub_cfg, self . 1 ) )
520- } )
521- . joined ( separator, fmt)
522- }
539+ CfgEntry :: Not ( CfgEntry :: Not ( sub_cfg, _) , _) => Display ( sub_cfg, self . 1 ) . fmt ( fmt) ,
540+ CfgEntry :: Not ( CfgEntry :: Any ( sub_cfgs, _) , _) => match sub_cfgs. as_slice ( ) {
541+ // `not(any())` is `true` because `any()` is `false`.
542+ [ ] => display_bool ( fmt, true ) ,
543+ [ CfgEntry :: Bool ( value, _) ] => display_bool ( fmt, !* value) ,
544+ sub_cfgs => {
545+ let separator =
546+ if sub_cfgs. iter ( ) . all ( is_simple_cfg) { " nor " } else { ", nor " } ;
547+ if sub_cfgs. len ( ) > 1 {
548+ fmt. write_str ( "neither " ) ?;
549+ } else {
550+ fmt. write_str ( "not(" ) ?;
551+ }
552+
553+ sub_cfgs
554+ . iter ( )
555+ . map ( |sub_cfg| {
556+ Wrapped :: with_parens ( )
557+ . when ( is_any_cfg ( sub_cfg) )
558+ . wrap ( Display ( sub_cfg, self . 1 ) )
559+ } )
560+ . joined ( separator, fmt) ?;
561+ if sub_cfgs. len ( ) == 1 {
562+ fmt. write_str ( ")" ) ?;
563+ }
564+ Ok ( ( ) )
565+ }
566+ } ,
567+ CfgEntry :: Not ( s @ CfgEntry :: All ( sub_cfgs, _) , _) => match sub_cfgs. as_slice ( ) {
568+ // `not(all())` is `false` because `all()` is `true`.
569+ [ ] => display_bool ( fmt, false ) ,
570+ [ CfgEntry :: Bool ( value, _) ] => display_bool ( fmt, !* value) ,
571+ _ => write ! ( fmt, "not ({})" , Display ( s, self . 1 ) ) ,
572+ } ,
523573 CfgEntry :: Not ( simple @ CfgEntry :: NameValue { .. } , _) => {
524574 write ! ( fmt, "non-{}" , Display ( simple, self . 1 ) )
525575 }
@@ -531,13 +581,7 @@ impl fmt::Display for Display<'_> {
531581 }
532582 CfgEntry :: All ( sub_cfgs, _) => self . display_sub_cfgs ( fmt, sub_cfgs. as_slice ( ) , " and " ) ,
533583
534- CfgEntry :: Bool ( v, _) => {
535- if * v {
536- fmt. write_str ( "everywhere" )
537- } else {
538- fmt. write_str ( "nowhere" )
539- }
540- }
584+ CfgEntry :: Bool ( v, _) => display_bool ( fmt, * v) ,
541585
542586 & CfgEntry :: NameValue { name, value, .. } => {
543587 let human_readable = match ( * name, value) {
0 commit comments