Skip to content

Commit f559f57

Browse files
committed
factor out some commonalities in the find_stability family of functions
the logic for adding unstable attrs gets a bit messier when supporting multiple instances thereof. this keeps that from being duplicated in 3 places.
1 parent 6f4aa4d commit f559f57

File tree

1 file changed

+56
-55
lines changed

1 file changed

+56
-55
lines changed

compiler/rustc_attr/src/builtin.rs

Lines changed: 56 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -214,44 +214,30 @@ pub fn find_stability(
214214
attrs: &[Attribute],
215215
item_sp: Span,
216216
) -> Option<(Stability, Span)> {
217-
let mut stab: Option<(Stability, Span)> = None;
217+
let mut level: Option<(StabilityLevel, Span)> = None;
218218
let mut allowed_through_unstable_modules = false;
219219

220220
for attr in attrs {
221221
match attr.name_or_empty() {
222222
sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true,
223223
sym::unstable => {
224-
if stab.is_some() {
225-
sess.dcx()
226-
.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
224+
if try_add_unstability(sess, attr, &mut level).is_err() {
227225
break;
228226
}
229-
230-
if let Some(level) = parse_unstability(sess, attr) {
231-
stab = Some((Stability { level }, attr.span));
232-
}
233227
}
234228
sym::stable => {
235-
if stab.is_some() {
236-
sess.dcx()
237-
.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
229+
if try_add_stability(sess, attr, &mut level).is_err() {
238230
break;
239231
}
240-
if let Some(level) = parse_stability(sess, attr) {
241-
stab = Some((Stability { level }, attr.span));
242-
}
243232
}
244233
_ => {}
245234
}
246235
}
247236

248237
if allowed_through_unstable_modules {
249-
match &mut stab {
238+
match &mut level {
250239
Some((
251-
Stability {
252-
level: StabilityLevel::Stable { allowed_through_unstable_modules, .. },
253-
..
254-
},
240+
StabilityLevel::Stable { allowed_through_unstable_modules, .. },
255241
_,
256242
)) => *allowed_through_unstable_modules = true,
257243
_ => {
@@ -261,7 +247,8 @@ pub fn find_stability(
261247
}
262248
}
263249

264-
stab
250+
let (level, stab_sp) = level?;
251+
Some((Stability { level }, stab_sp))
265252
}
266253

267254
/// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable`
@@ -271,52 +258,35 @@ pub fn find_const_stability(
271258
attrs: &[Attribute],
272259
item_sp: Span,
273260
) -> Option<(ConstStability, Span)> {
274-
let mut const_stab: Option<(ConstStability, Span)> = None;
261+
let mut level: Option<(StabilityLevel, Span)> = None;
275262
let mut promotable = false;
276263

277264
for attr in attrs {
278265
match attr.name_or_empty() {
279266
sym::rustc_promotable => promotable = true,
280267
sym::rustc_const_unstable => {
281-
if const_stab.is_some() {
282-
sess.dcx()
283-
.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
268+
if try_add_unstability(sess, attr, &mut level).is_err() {
284269
break;
285270
}
286-
287-
if let Some(level) = parse_unstability(sess, attr) {
288-
const_stab =
289-
Some((ConstStability { level, promotable: false }, attr.span));
290-
}
291271
}
292272
sym::rustc_const_stable => {
293-
if const_stab.is_some() {
294-
sess.dcx()
295-
.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
273+
if try_add_stability(sess, attr, &mut level).is_err() {
296274
break;
297275
}
298-
if let Some(level) = parse_stability(sess, attr) {
299-
const_stab =
300-
Some((ConstStability { level, promotable: false }, attr.span));
301-
}
302276
}
303277
_ => {}
304278
}
305279
}
306280

307281
// Merge the const-unstable info into the stability info
308-
if promotable {
309-
match &mut const_stab {
310-
Some((stab, _)) => stab.promotable = promotable,
311-
_ => {
312-
_ = sess
313-
.dcx()
314-
.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp })
315-
}
282+
if let Some((level, stab_sp)) = level {
283+
Some((ConstStability { level, promotable }, stab_sp))
284+
} else {
285+
if promotable {
286+
sess.dcx().emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp });
316287
}
288+
None
317289
}
318-
319-
const_stab
320290
}
321291

322292
/// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`.
@@ -325,23 +295,54 @@ pub fn find_body_stability(
325295
sess: &Session,
326296
attrs: &[Attribute],
327297
) -> Option<(DefaultBodyStability, Span)> {
328-
let mut body_stab: Option<(DefaultBodyStability, Span)> = None;
298+
let mut level: Option<(StabilityLevel, Span)> = None;
329299

330300
for attr in attrs {
331301
if attr.has_name(sym::rustc_default_body_unstable) {
332-
if body_stab.is_some() {
333-
sess.dcx()
334-
.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
302+
if try_add_unstability(sess, attr, &mut level).is_err() {
335303
break;
336304
}
337-
338-
if let Some(level) = parse_unstability(sess, attr) {
339-
body_stab = Some((DefaultBodyStability { level }, attr.span));
340-
}
341305
}
342306
}
343307

344-
body_stab
308+
let (level, stab_sp) = level?;
309+
Some((DefaultBodyStability { level }, stab_sp))
310+
}
311+
312+
/// Collects stability info from one `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable`
313+
/// attribute, `attr`. Emits an error if the info it collects is inconsistent.
314+
fn try_add_unstability(
315+
sess: &Session,
316+
attr: &Attribute,
317+
level: &mut Option<(StabilityLevel, Span)>,
318+
) -> Result<(), ErrorGuaranteed> {
319+
if level.is_some() {
320+
return Err(
321+
sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span })
322+
)
323+
}
324+
if let Some(new_level) = parse_unstability(sess, attr) {
325+
*level = Some((new_level, attr.span));
326+
}
327+
Ok(())
328+
}
329+
330+
/// Collects stability info from a single `stable`/`rustc_const_stable` attribute, `attr`.
331+
/// Emits an error if the info it collects is inconsistent.
332+
fn try_add_stability(
333+
sess: &Session,
334+
attr: &Attribute,
335+
level: &mut Option<(StabilityLevel, Span)>,
336+
) -> Result<(), ErrorGuaranteed> {
337+
if level.is_some() {
338+
return Err(
339+
sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span })
340+
)
341+
}
342+
if let Some(new_level) = parse_stability(sess, attr) {
343+
*level = Some((new_level, attr.span));
344+
}
345+
Ok(())
345346
}
346347

347348
fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option<Symbol>) -> Option<()> {

0 commit comments

Comments
 (0)