@@ -43,23 +43,22 @@ crate struct InvalidCfgError {
43
43
44
44
impl Cfg {
45
45
/// Parses a `NestedMetaItem` into a `Cfg`.
46
- fn parse_nested ( nested_cfg : & NestedMetaItem ) -> Result < Cfg , InvalidCfgError > {
46
+ fn parse_nested (
47
+ nested_cfg : & NestedMetaItem ,
48
+ exclude : & [ Symbol ] ,
49
+ ) -> Result < Option < Cfg > , InvalidCfgError > {
47
50
match nested_cfg {
48
- NestedMetaItem :: MetaItem ( ref cfg) => Cfg :: parse ( cfg) ,
51
+ NestedMetaItem :: MetaItem ( ref cfg) => Cfg :: parse_without ( cfg, exclude ) ,
49
52
NestedMetaItem :: Literal ( ref lit) => {
50
53
Err ( InvalidCfgError { msg : "unexpected literal" , span : lit. span } )
51
54
}
52
55
}
53
56
}
54
57
55
- /// Parses a `MetaItem` into a `Cfg`.
56
- ///
57
- /// The `MetaItem` should be the content of the `#[cfg(...)]`, e.g., `unix` or
58
- /// `target_os = "redox"`.
59
- ///
60
- /// If the content is not properly formatted, it will return an error indicating what and where
61
- /// the error is.
62
- crate fn parse ( cfg : & MetaItem ) -> Result < Cfg , InvalidCfgError > {
58
+ crate fn parse_without (
59
+ cfg : & MetaItem ,
60
+ exclude : & [ Symbol ] ,
61
+ ) -> Result < Option < Cfg > , InvalidCfgError > {
63
62
let name = match cfg. ident ( ) {
64
63
Some ( ident) => ident. name ,
65
64
None => {
@@ -70,9 +69,21 @@ impl Cfg {
70
69
}
71
70
} ;
72
71
match cfg. kind {
73
- MetaItemKind :: Word => Ok ( Cfg :: Cfg ( name, None ) ) ,
72
+ MetaItemKind :: Word => {
73
+ if exclude. contains ( & name) {
74
+ Ok ( None )
75
+ } else {
76
+ Ok ( Some ( Cfg :: Cfg ( name, None ) ) )
77
+ }
78
+ }
74
79
MetaItemKind :: NameValue ( ref lit) => match lit. kind {
75
- LitKind :: Str ( value, _) => Ok ( Cfg :: Cfg ( name, Some ( value) ) ) ,
80
+ LitKind :: Str ( value, _) => {
81
+ if exclude. contains ( & name) {
82
+ Ok ( None )
83
+ } else {
84
+ Ok ( Some ( Cfg :: Cfg ( name, Some ( value) ) ) )
85
+ }
86
+ }
76
87
_ => Err ( InvalidCfgError {
77
88
// FIXME: if the main #[cfg] syntax decided to support non-string literals,
78
89
// this should be changed as well.
@@ -81,23 +92,43 @@ impl Cfg {
81
92
} ) ,
82
93
} ,
83
94
MetaItemKind :: List ( ref items) => {
84
- let mut sub_cfgs = items. iter ( ) . map ( Cfg :: parse_nested) ;
85
- match name {
95
+ let sub_cfgs = items. iter ( ) . filter_map ( |i| match Cfg :: parse_nested ( i, exclude) {
96
+ Ok ( Some ( c) ) => Some ( Ok ( c) ) ,
97
+ Err ( e) => Some ( Err ( e) ) ,
98
+ _ => None ,
99
+ } ) ;
100
+ let ret = match name {
86
101
sym:: all => sub_cfgs. fold ( Ok ( Cfg :: True ) , |x, y| Ok ( x? & y?) ) ,
87
102
sym:: any => sub_cfgs. fold ( Ok ( Cfg :: False ) , |x, y| Ok ( x? | y?) ) ,
88
103
sym:: not => {
104
+ let mut sub_cfgs = sub_cfgs. collect :: < Vec < _ > > ( ) ;
89
105
if sub_cfgs. len ( ) == 1 {
90
- Ok ( !sub_cfgs. next ( ) . unwrap ( ) ?)
106
+ Ok ( !sub_cfgs. pop ( ) . unwrap ( ) ?)
91
107
} else {
92
108
Err ( InvalidCfgError { msg : "expected 1 cfg-pattern" , span : cfg. span } )
93
109
}
94
110
}
95
111
_ => Err ( InvalidCfgError { msg : "invalid predicate" , span : cfg. span } ) ,
112
+ } ;
113
+ match ret {
114
+ Ok ( c) => Ok ( Some ( c) ) ,
115
+ Err ( e) => Err ( e) ,
96
116
}
97
117
}
98
118
}
99
119
}
100
120
121
+ /// Parses a `MetaItem` into a `Cfg`.
122
+ ///
123
+ /// The `MetaItem` should be the content of the `#[cfg(...)]`, e.g., `unix` or
124
+ /// `target_os = "redox"`.
125
+ ///
126
+ /// If the content is not properly formatted, it will return an error indicating what and where
127
+ /// the error is.
128
+ crate fn parse ( cfg : & MetaItem ) -> Result < Cfg , InvalidCfgError > {
129
+ Self :: parse_without ( cfg, & [ ] ) . map ( |ret| ret. unwrap ( ) )
130
+ }
131
+
101
132
/// Checks whether the given configuration can be matched in the current session.
102
133
///
103
134
/// Equivalent to `attr::cfg_matches`.
0 commit comments