@@ -214,44 +214,30 @@ pub fn find_stability(
214
214
attrs : & [ Attribute ] ,
215
215
item_sp : Span ,
216
216
) -> Option < ( Stability , Span ) > {
217
- let mut stab : Option < ( Stability , Span ) > = None ;
217
+ let mut level : Option < ( StabilityLevel , Span ) > = None ;
218
218
let mut allowed_through_unstable_modules = false ;
219
219
220
220
for attr in attrs {
221
221
match attr. name_or_empty ( ) {
222
222
sym:: rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true ,
223
223
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 ( ) {
227
225
break ;
228
226
}
229
-
230
- if let Some ( level) = parse_unstability ( sess, attr) {
231
- stab = Some ( ( Stability { level } , attr. span ) ) ;
232
- }
233
227
}
234
228
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 ( ) {
238
230
break ;
239
231
}
240
- if let Some ( level) = parse_stability ( sess, attr) {
241
- stab = Some ( ( Stability { level } , attr. span ) ) ;
242
- }
243
232
}
244
233
_ => { }
245
234
}
246
235
}
247
236
248
237
if allowed_through_unstable_modules {
249
- match & mut stab {
238
+ match & mut level {
250
239
Some ( (
251
- Stability {
252
- level : StabilityLevel :: Stable { allowed_through_unstable_modules, .. } ,
253
- ..
254
- } ,
240
+ StabilityLevel :: Stable { allowed_through_unstable_modules, .. } ,
255
241
_,
256
242
) ) => * allowed_through_unstable_modules = true ,
257
243
_ => {
@@ -261,7 +247,8 @@ pub fn find_stability(
261
247
}
262
248
}
263
249
264
- stab
250
+ let ( level, stab_sp) = level?;
251
+ Some ( ( Stability { level } , stab_sp) )
265
252
}
266
253
267
254
/// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable`
@@ -271,52 +258,35 @@ pub fn find_const_stability(
271
258
attrs : & [ Attribute ] ,
272
259
item_sp : Span ,
273
260
) -> Option < ( ConstStability , Span ) > {
274
- let mut const_stab : Option < ( ConstStability , Span ) > = None ;
261
+ let mut level : Option < ( StabilityLevel , Span ) > = None ;
275
262
let mut promotable = false ;
276
263
277
264
for attr in attrs {
278
265
match attr. name_or_empty ( ) {
279
266
sym:: rustc_promotable => promotable = true ,
280
267
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 ( ) {
284
269
break ;
285
270
}
286
-
287
- if let Some ( level) = parse_unstability ( sess, attr) {
288
- const_stab =
289
- Some ( ( ConstStability { level, promotable : false } , attr. span ) ) ;
290
- }
291
271
}
292
272
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 ( ) {
296
274
break ;
297
275
}
298
- if let Some ( level) = parse_stability ( sess, attr) {
299
- const_stab =
300
- Some ( ( ConstStability { level, promotable : false } , attr. span ) ) ;
301
- }
302
276
}
303
277
_ => { }
304
278
}
305
279
}
306
280
307
281
// 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 } ) ;
316
287
}
288
+ None
317
289
}
318
-
319
- const_stab
320
290
}
321
291
322
292
/// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`.
@@ -325,23 +295,54 @@ pub fn find_body_stability(
325
295
sess : & Session ,
326
296
attrs : & [ Attribute ] ,
327
297
) -> Option < ( DefaultBodyStability , Span ) > {
328
- let mut body_stab : Option < ( DefaultBodyStability , Span ) > = None ;
298
+ let mut level : Option < ( StabilityLevel , Span ) > = None ;
329
299
330
300
for attr in attrs {
331
301
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 ( ) {
335
303
break ;
336
304
}
337
-
338
- if let Some ( level) = parse_unstability ( sess, attr) {
339
- body_stab = Some ( ( DefaultBodyStability { level } , attr. span ) ) ;
340
- }
341
305
}
342
306
}
343
307
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 ( ( ) )
345
346
}
346
347
347
348
fn insert_or_error ( sess : & Session , meta : & MetaItem , item : & mut Option < Symbol > ) -> Option < ( ) > {
0 commit comments