Skip to content

Commit 001be2f

Browse files
Make parse_cfg_entry output ErrorGuaranteed on failure
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
1 parent f5711a5 commit 001be2f

File tree

3 files changed

+35
-37
lines changed

3 files changed

+35
-37
lines changed

compiler/rustc_attr_parsing/src/attributes/cfg.rs

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_session::config::ExpectedValues;
1212
use rustc_session::lint::BuiltinLintDiag;
1313
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
1414
use rustc_session::parse::{ParseSess, feature_err};
15-
use rustc_span::{Span, Symbol, sym};
15+
use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
1616
use thin_vec::ThinVec;
1717

1818
use crate::context::{AcceptContext, ShouldEmit, Stage};
@@ -47,20 +47,19 @@ pub fn parse_cfg<'c, S: Stage>(
4747
cx.expected_single_argument(list.span);
4848
return None;
4949
};
50-
parse_cfg_entry(cx, single)
50+
parse_cfg_entry(cx, single).ok()
5151
}
5252

5353
pub(crate) fn parse_cfg_entry<S: Stage>(
5454
cx: &mut AcceptContext<'_, '_, S>,
5555
item: &MetaItemOrLitParser<'_>,
56-
) -> Option<CfgEntry> {
57-
Some(match item {
56+
) -> Result<CfgEntry, ErrorGuaranteed> {
57+
Ok(match item {
5858
MetaItemOrLitParser::MetaItemParser(meta) => match meta.args() {
5959
ArgParser::List(list) => match meta.path().word_sym() {
6060
Some(sym::not) => {
6161
let Some(single) = list.single() else {
62-
cx.expected_single_argument(list.span);
63-
return None;
62+
return Err(cx.expected_single_argument(list.span));
6463
};
6564
CfgEntry::Not(Box::new(parse_cfg_entry(cx, single)?), list.span)
6665
}
@@ -75,49 +74,47 @@ pub(crate) fn parse_cfg_entry<S: Stage>(
7574
Some(sym::target) => parse_cfg_entry_target(cx, list, meta.span())?,
7675
Some(sym::version) => parse_cfg_entry_version(cx, list, meta.span())?,
7776
_ => {
78-
cx.emit_err(session_diagnostics::InvalidPredicate {
77+
return Err(cx.emit_err(session_diagnostics::InvalidPredicate {
7978
span: meta.span(),
8079
predicate: meta.path().to_string(),
81-
});
82-
return None;
80+
}));
8381
}
8482
},
8583
a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => {
8684
let Some(name) = meta.path().word_sym() else {
87-
cx.expected_identifier(meta.path().span());
88-
return None;
85+
return Err(cx.expected_identifier(meta.path().span()));
8986
};
9087
parse_name_value(name, meta.path().span(), a.name_value(), meta.span(), cx)?
9188
}
9289
},
9390
MetaItemOrLitParser::Lit(lit) => match lit.kind {
9491
LitKind::Bool(b) => CfgEntry::Bool(b, lit.span),
95-
_ => {
96-
cx.expected_identifier(lit.span);
97-
return None;
98-
}
92+
_ => return Err(cx.expected_identifier(lit.span)),
9993
},
100-
MetaItemOrLitParser::Err(_, _) => return None,
94+
MetaItemOrLitParser::Err(_, err) => return Err(*err),
10195
})
10296
}
10397

10498
fn parse_cfg_entry_version<S: Stage>(
10599
cx: &mut AcceptContext<'_, '_, S>,
106100
list: &MetaItemListParser<'_>,
107101
meta_span: Span,
108-
) -> Option<CfgEntry> {
102+
) -> Result<CfgEntry, ErrorGuaranteed> {
109103
try_gate_cfg(sym::version, meta_span, cx.sess(), cx.features_option());
110104
let Some(version) = list.single() else {
111-
cx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { span: list.span });
112-
return None;
105+
return Err(
106+
cx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { span: list.span })
107+
);
113108
};
114109
let Some(version_lit) = version.lit() else {
115-
cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version.span() });
116-
return None;
110+
return Err(
111+
cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version.span() })
112+
);
117113
};
118114
let Some(version_str) = version_lit.value_str() else {
119-
cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version_lit.span });
120-
return None;
115+
return Err(
116+
cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version_lit.span })
117+
);
121118
};
122119

123120
let min_version = parse_version(version_str).or_else(|| {
@@ -127,14 +124,14 @@ fn parse_cfg_entry_version<S: Stage>(
127124
None
128125
});
129126

130-
Some(CfgEntry::Version(min_version, list.span))
127+
Ok(CfgEntry::Version(min_version, list.span))
131128
}
132129

133130
fn parse_cfg_entry_target<S: Stage>(
134131
cx: &mut AcceptContext<'_, '_, S>,
135132
list: &MetaItemListParser<'_>,
136133
meta_span: Span,
137-
) -> Option<CfgEntry> {
134+
) -> Result<CfgEntry, ErrorGuaranteed> {
138135
if let Some(features) = cx.features_option()
139136
&& !features.cfg_target_compact()
140137
{
@@ -161,17 +158,16 @@ fn parse_cfg_entry_target<S: Stage>(
161158

162159
// Then, parse it as a name-value item
163160
let Some(name) = sub_item.path().word_sym() else {
164-
cx.expected_identifier(sub_item.path().span());
165-
return None;
161+
return Err(cx.expected_identifier(sub_item.path().span()));
166162
};
167163
let name = Symbol::intern(&format!("target_{name}"));
168-
if let Some(cfg) =
164+
if let Ok(cfg) =
169165
parse_name_value(name, sub_item.path().span(), Some(nv), sub_item.span(), cx)
170166
{
171167
result.push(cfg);
172168
}
173169
}
174-
Some(CfgEntry::All(result, list.span))
170+
Ok(CfgEntry::All(result, list.span))
175171
}
176172

177173
fn parse_name_value<S: Stage>(
@@ -180,21 +176,22 @@ fn parse_name_value<S: Stage>(
180176
value: Option<&NameValueParser>,
181177
span: Span,
182178
cx: &mut AcceptContext<'_, '_, S>,
183-
) -> Option<CfgEntry> {
179+
) -> Result<CfgEntry, ErrorGuaranteed> {
184180
try_gate_cfg(name, span, cx.sess(), cx.features_option());
185181

186182
let value = match value {
187183
None => None,
188184
Some(value) => {
189185
let Some(value_str) = value.value_as_str() else {
190-
cx.expected_string_literal(value.value_span, Some(value.value_as_lit()));
191-
return None;
186+
return Err(
187+
cx.expected_string_literal(value.value_span, Some(value.value_as_lit()))
188+
);
192189
};
193190
Some((value_str, value.value_span))
194191
}
195192
};
196193

197-
Some(CfgEntry::NameValue { name, name_span, value, span })
194+
Ok(CfgEntry::NameValue { name, name_span, value, span })
198195
}
199196

200197
pub fn eval_config_entry(
@@ -406,7 +403,8 @@ fn parse_cfg_attr_internal<'a>(
406403
parse_cfg_entry,
407404
&CFG_ATTR_TEMPLATE,
408405
)
409-
.ok_or_else(|| {
406+
.map_err(|_err: ErrorGuaranteed| {
407+
// We have an `ErrorGuaranteed` so this delayed bug cannot fail, but we need a `Diag` for the `PResult` so we make one anyways
410408
let mut diag = sess.dcx().struct_err(
411409
"cfg_entry parsing failing with `ShouldEmit::ErrorsAndLints` should emit a error.",
412410
);

compiler/rustc_attr_parsing/src/attributes/link_attrs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ impl LinkParser {
396396
)
397397
.emit();
398398
}
399-
*cfg = parse_cfg_entry(cx, link_cfg);
399+
*cfg = parse_cfg_entry(cx, link_cfg).ok();
400400
true
401401
}
402402

compiler/rustc_attr_parsing/src/interface.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,9 @@ impl<'sess> AttributeParser<'sess, Early> {
168168
features: Option<&'sess Features>,
169169
emit_errors: ShouldEmit,
170170
args: &I,
171-
parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &I) -> Option<T>,
171+
parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &I) -> T,
172172
template: &AttributeTemplate,
173-
) -> Option<T> {
173+
) -> T {
174174
let mut parser = Self {
175175
features,
176176
tools: Vec::new(),

0 commit comments

Comments
 (0)