@@ -214,54 +214,40 @@ 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 {
250
- Some ( (
251
- Stability {
252
- level : StabilityLevel :: Stable { allowed_through_unstable_modules, .. } ,
253
- ..
254
- } ,
255
- _,
256
- ) ) => * allowed_through_unstable_modules = true ,
238
+ match & mut level {
239
+ Some ( ( StabilityLevel :: Stable { allowed_through_unstable_modules, .. } , _) ) => {
240
+ * allowed_through_unstable_modules = true
241
+ }
257
242
_ => {
258
243
sess. dcx ( )
259
244
. emit_err ( session_diagnostics:: RustcAllowedUnstablePairing { span : item_sp } ) ;
260
245
}
261
246
}
262
247
}
263
248
264
- stab
249
+ let ( level, stab_sp) = level?;
250
+ Some ( ( Stability { level } , stab_sp) )
265
251
}
266
252
267
253
/// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable`
@@ -271,50 +257,35 @@ pub fn find_const_stability(
271
257
attrs : & [ Attribute ] ,
272
258
item_sp : Span ,
273
259
) -> Option < ( ConstStability , Span ) > {
274
- let mut const_stab : Option < ( ConstStability , Span ) > = None ;
260
+ let mut level : Option < ( StabilityLevel , Span ) > = None ;
275
261
let mut promotable = false ;
276
262
277
263
for attr in attrs {
278
264
match attr. name_or_empty ( ) {
279
265
sym:: rustc_promotable => promotable = true ,
280
266
sym:: rustc_const_unstable => {
281
- if const_stab. is_some ( ) {
282
- sess. dcx ( )
283
- . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
267
+ if try_add_unstability ( sess, attr, & mut level) . is_err ( ) {
284
268
break ;
285
269
}
286
-
287
- if let Some ( level) = parse_unstability ( sess, attr) {
288
- const_stab = Some ( ( ConstStability { level, promotable : false } , attr. span ) ) ;
289
- }
290
270
}
291
271
sym:: rustc_const_stable => {
292
- if const_stab. is_some ( ) {
293
- sess. dcx ( )
294
- . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
272
+ if try_add_stability ( sess, attr, & mut level) . is_err ( ) {
295
273
break ;
296
274
}
297
- if let Some ( level) = parse_stability ( sess, attr) {
298
- const_stab = Some ( ( ConstStability { level, promotable : false } , attr. span ) ) ;
299
- }
300
275
}
301
276
_ => { }
302
277
}
303
278
}
304
279
305
280
// Merge the const-unstable info into the stability info
306
- if promotable {
307
- match & mut const_stab {
308
- Some ( ( stab, _) ) => stab. promotable = promotable,
309
- _ => {
310
- _ = sess
311
- . dcx ( )
312
- . emit_err ( session_diagnostics:: RustcPromotablePairing { span : item_sp } )
313
- }
281
+ if let Some ( ( level, stab_sp) ) = level {
282
+ Some ( ( ConstStability { level, promotable } , stab_sp) )
283
+ } else {
284
+ if promotable {
285
+ sess. dcx ( ) . emit_err ( session_diagnostics:: RustcPromotablePairing { span : item_sp } ) ;
314
286
}
287
+ None
315
288
}
316
-
317
- const_stab
318
289
}
319
290
320
291
/// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`.
@@ -323,23 +294,54 @@ pub fn find_body_stability(
323
294
sess : & Session ,
324
295
attrs : & [ Attribute ] ,
325
296
) -> Option < ( DefaultBodyStability , Span ) > {
326
- let mut body_stab : Option < ( DefaultBodyStability , Span ) > = None ;
297
+ let mut level : Option < ( StabilityLevel , Span ) > = None ;
327
298
328
299
for attr in attrs {
329
300
if attr. has_name ( sym:: rustc_default_body_unstable) {
330
- if body_stab. is_some ( ) {
331
- sess. dcx ( )
332
- . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
301
+ if try_add_unstability ( sess, attr, & mut level) . is_err ( ) {
333
302
break ;
334
303
}
335
-
336
- if let Some ( level) = parse_unstability ( sess, attr) {
337
- body_stab = Some ( ( DefaultBodyStability { level } , attr. span ) ) ;
338
- }
339
304
}
340
305
}
341
306
342
- body_stab
307
+ let ( level, stab_sp) = level?;
308
+ Some ( ( DefaultBodyStability { level } , stab_sp) )
309
+ }
310
+
311
+ /// Collects stability info from one `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable`
312
+ /// attribute, `attr`. Emits an error if the info it collects is inconsistent.
313
+ fn try_add_unstability (
314
+ sess : & Session ,
315
+ attr : & Attribute ,
316
+ level : & mut Option < ( StabilityLevel , Span ) > ,
317
+ ) -> Result < ( ) , ErrorGuaranteed > {
318
+ if level. is_some ( ) {
319
+ return Err ( sess
320
+ . dcx ( )
321
+ . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ) ;
322
+ }
323
+ if let Some ( new_level) = parse_unstability ( sess, attr) {
324
+ * level = Some ( ( new_level, attr. span ) ) ;
325
+ }
326
+ Ok ( ( ) )
327
+ }
328
+
329
+ /// Collects stability info from a single `stable`/`rustc_const_stable` attribute, `attr`.
330
+ /// Emits an error if the info it collects is inconsistent.
331
+ fn try_add_stability (
332
+ sess : & Session ,
333
+ attr : & Attribute ,
334
+ level : & mut Option < ( StabilityLevel , Span ) > ,
335
+ ) -> Result < ( ) , ErrorGuaranteed > {
336
+ if level. is_some ( ) {
337
+ return Err ( sess
338
+ . dcx ( )
339
+ . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ) ;
340
+ }
341
+ if let Some ( new_level) = parse_stability ( sess, attr) {
342
+ * level = Some ( ( new_level, attr. span ) ) ;
343
+ }
344
+ Ok ( ( ) )
343
345
}
344
346
345
347
fn insert_or_error ( sess : & Session , meta : & MetaItem , item : & mut Option < Symbol > ) -> Option < ( ) > {
0 commit comments