@@ -225,54 +225,40 @@ pub fn find_stability(
225
225
attrs : & [ Attribute ] ,
226
226
item_sp : Span ,
227
227
) -> Option < ( Stability , Span ) > {
228
- let mut stab : Option < ( Stability , Span ) > = None ;
228
+ let mut level : Option < ( StabilityLevel , Span ) > = None ;
229
229
let mut allowed_through_unstable_modules = false ;
230
230
231
231
for attr in attrs {
232
232
match attr. name_or_empty ( ) {
233
233
sym:: rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true ,
234
234
sym:: unstable => {
235
- if stab. is_some ( ) {
236
- sess. dcx ( )
237
- . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
235
+ if try_add_unstability ( sess, attr, & mut level) . is_err ( ) {
238
236
break ;
239
237
}
240
-
241
- if let Some ( level) = parse_unstability ( sess, attr) {
242
- stab = Some ( ( Stability { level } , attr. span ) ) ;
243
- }
244
238
}
245
239
sym:: stable => {
246
- if stab. is_some ( ) {
247
- sess. dcx ( )
248
- . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
240
+ if try_add_stability ( sess, attr, & mut level) . is_err ( ) {
249
241
break ;
250
242
}
251
- if let Some ( level) = parse_stability ( sess, attr) {
252
- stab = Some ( ( Stability { level } , attr. span ) ) ;
253
- }
254
243
}
255
244
_ => { }
256
245
}
257
246
}
258
247
259
248
if allowed_through_unstable_modules {
260
- match & mut stab {
261
- Some ( (
262
- Stability {
263
- level : StabilityLevel :: Stable { allowed_through_unstable_modules, .. } ,
264
- ..
265
- } ,
266
- _,
267
- ) ) => * allowed_through_unstable_modules = true ,
249
+ match & mut level {
250
+ Some ( ( StabilityLevel :: Stable { allowed_through_unstable_modules, .. } , _) ) => {
251
+ * allowed_through_unstable_modules = true
252
+ }
268
253
_ => {
269
254
sess. dcx ( )
270
255
. emit_err ( session_diagnostics:: RustcAllowedUnstablePairing { span : item_sp } ) ;
271
256
}
272
257
}
273
258
}
274
259
275
- stab
260
+ let ( level, stab_sp) = level?;
261
+ Some ( ( Stability { level } , stab_sp) )
276
262
}
277
263
278
264
/// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable`
@@ -282,7 +268,7 @@ pub fn find_const_stability(
282
268
attrs : & [ Attribute ] ,
283
269
item_sp : Span ,
284
270
) -> Option < ( ConstStability , Span ) > {
285
- let mut const_stab : Option < ( ConstStability , Span ) > = None ;
271
+ let mut level : Option < ( StabilityLevel , Span ) > = None ;
286
272
let mut promotable = false ;
287
273
let mut const_stable_indirect = false ;
288
274
@@ -291,67 +277,38 @@ pub fn find_const_stability(
291
277
sym:: rustc_promotable => promotable = true ,
292
278
sym:: rustc_const_stable_indirect => const_stable_indirect = true ,
293
279
sym:: rustc_const_unstable => {
294
- if const_stab. is_some ( ) {
295
- sess. dcx ( )
296
- . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
280
+ if try_add_unstability ( sess, attr, & mut level) . is_err ( ) {
297
281
break ;
298
282
}
299
-
300
- if let Some ( level) = parse_unstability ( sess, attr) {
301
- const_stab = Some ( (
302
- ConstStability { level, const_stable_indirect : false , promotable : false } ,
303
- attr. span ,
304
- ) ) ;
305
- }
306
283
}
307
284
sym:: rustc_const_stable => {
308
- if const_stab. is_some ( ) {
309
- sess. dcx ( )
310
- . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
285
+ if try_add_stability ( sess, attr, & mut level) . is_err ( ) {
311
286
break ;
312
287
}
313
- if let Some ( level) = parse_stability ( sess, attr) {
314
- const_stab = Some ( (
315
- ConstStability { level, const_stable_indirect : false , promotable : false } ,
316
- attr. span ,
317
- ) ) ;
318
- }
319
288
}
320
289
_ => { }
321
290
}
322
291
}
323
292
324
293
// Merge promotable and const_stable_indirect into stability info
325
- if promotable {
326
- match & mut const_stab {
327
- Some ( ( stab, _) ) => stab. promotable = promotable,
328
- _ => {
329
- _ = sess
330
- . dcx ( )
331
- . emit_err ( session_diagnostics:: RustcPromotablePairing { span : item_sp } )
332
- }
294
+ if let Some ( ( level, stab_sp) ) = level {
295
+ if level. is_stable ( ) && const_stable_indirect {
296
+ sess. dcx ( )
297
+ . emit_err ( session_diagnostics:: RustcConstStableIndirectPairing { span : item_sp } ) ;
298
+ const_stable_indirect = false ;
333
299
}
334
- }
335
- if const_stable_indirect {
336
- match & mut const_stab {
337
- Some ( ( stab, _) ) => {
338
- if stab. is_const_unstable ( ) {
339
- stab. const_stable_indirect = true ;
340
- } else {
341
- _ = sess. dcx ( ) . emit_err ( session_diagnostics:: RustcConstStableIndirectPairing {
342
- span : item_sp,
343
- } )
344
- }
345
- }
346
- _ => {
347
- // This function has no const stability attribute, but has `const_stable_indirect`.
348
- // We ignore that; unmarked functions are subject to recursive const stability
349
- // checks by default so we do carry out the user's intent.
350
- }
300
+ let const_stab = ConstStability { level, const_stable_indirect, promotable } ;
301
+
302
+ Some ( ( const_stab, stab_sp) )
303
+ } else {
304
+ if promotable {
305
+ sess. dcx ( ) . emit_err ( session_diagnostics:: RustcPromotablePairing { span : item_sp } ) ;
351
306
}
307
+ // This function has no const stability attribute, but may have `const_stable_indirect`.
308
+ // We ignore that; unmarked functions are subject to recursive const stability
309
+ // checks by default so we do carry out the user's intent.
310
+ None
352
311
}
353
-
354
- const_stab
355
312
}
356
313
357
314
/// Calculates the const stability for a const function in a `-Zforce-unstable-if-unmarked` crate
@@ -375,23 +332,54 @@ pub fn find_body_stability(
375
332
sess : & Session ,
376
333
attrs : & [ Attribute ] ,
377
334
) -> Option < ( DefaultBodyStability , Span ) > {
378
- let mut body_stab : Option < ( DefaultBodyStability , Span ) > = None ;
335
+ let mut level : Option < ( StabilityLevel , Span ) > = None ;
379
336
380
337
for attr in attrs {
381
338
if attr. has_name ( sym:: rustc_default_body_unstable) {
382
- if body_stab. is_some ( ) {
383
- sess. dcx ( )
384
- . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
339
+ if try_add_unstability ( sess, attr, & mut level) . is_err ( ) {
385
340
break ;
386
341
}
387
-
388
- if let Some ( level) = parse_unstability ( sess, attr) {
389
- body_stab = Some ( ( DefaultBodyStability { level } , attr. span ) ) ;
390
- }
391
342
}
392
343
}
393
344
394
- body_stab
345
+ let ( level, stab_sp) = level?;
346
+ Some ( ( DefaultBodyStability { level } , stab_sp) )
347
+ }
348
+
349
+ /// Collects stability info from one `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable`
350
+ /// attribute, `attr`. Emits an error if the info it collects is inconsistent.
351
+ fn try_add_unstability (
352
+ sess : & Session ,
353
+ attr : & Attribute ,
354
+ level : & mut Option < ( StabilityLevel , Span ) > ,
355
+ ) -> Result < ( ) , ErrorGuaranteed > {
356
+ if level. is_some ( ) {
357
+ return Err ( sess
358
+ . dcx ( )
359
+ . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ) ;
360
+ }
361
+ if let Some ( new_level) = parse_unstability ( sess, attr) {
362
+ * level = Some ( ( new_level, attr. span ) ) ;
363
+ }
364
+ Ok ( ( ) )
365
+ }
366
+
367
+ /// Collects stability info from a single `stable`/`rustc_const_stable` attribute, `attr`.
368
+ /// Emits an error if the info it collects is inconsistent.
369
+ fn try_add_stability (
370
+ sess : & Session ,
371
+ attr : & Attribute ,
372
+ level : & mut Option < ( StabilityLevel , Span ) > ,
373
+ ) -> Result < ( ) , ErrorGuaranteed > {
374
+ if level. is_some ( ) {
375
+ return Err ( sess
376
+ . dcx ( )
377
+ . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ) ;
378
+ }
379
+ if let Some ( new_level) = parse_stability ( sess, attr) {
380
+ * level = Some ( ( new_level, attr. span ) ) ;
381
+ }
382
+ Ok ( ( ) )
395
383
}
396
384
397
385
fn insert_or_error ( sess : & Session , meta : & MetaItem , item : & mut Option < Symbol > ) -> Option < ( ) > {
0 commit comments