@@ -214,54 +214,40 @@ 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 {
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+ }
257242 _ => {
258243 sess. dcx ( )
259244 . emit_err ( session_diagnostics:: RustcAllowedUnstablePairing { span : item_sp } ) ;
260245 }
261246 }
262247 }
263248
264- stab
249+ let ( level, stab_sp) = level?;
250+ Some ( ( Stability { level } , stab_sp) )
265251}
266252
267253/// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable`
@@ -271,50 +257,35 @@ pub fn find_const_stability(
271257 attrs : & [ Attribute ] ,
272258 item_sp : Span ,
273259) -> Option < ( ConstStability , Span ) > {
274- let mut const_stab : Option < ( ConstStability , Span ) > = None ;
260+ let mut level : Option < ( StabilityLevel , Span ) > = None ;
275261 let mut promotable = false ;
276262
277263 for attr in attrs {
278264 match attr. name_or_empty ( ) {
279265 sym:: rustc_promotable => promotable = true ,
280266 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 ( ) {
284268 break ;
285269 }
286-
287- if let Some ( level) = parse_unstability ( sess, attr) {
288- const_stab = Some ( ( ConstStability { level, promotable : false } , attr. span ) ) ;
289- }
290270 }
291271 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 ( ) {
295273 break ;
296274 }
297- if let Some ( level) = parse_stability ( sess, attr) {
298- const_stab = Some ( ( ConstStability { level, promotable : false } , attr. span ) ) ;
299- }
300275 }
301276 _ => { }
302277 }
303278 }
304279
305280 // 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 } ) ;
314286 }
287+ None
315288 }
316-
317- const_stab
318289}
319290
320291/// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`.
@@ -323,23 +294,54 @@ pub fn find_body_stability(
323294 sess : & Session ,
324295 attrs : & [ Attribute ] ,
325296) -> Option < ( DefaultBodyStability , Span ) > {
326- let mut body_stab : Option < ( DefaultBodyStability , Span ) > = None ;
297+ let mut level : Option < ( StabilityLevel , Span ) > = None ;
327298
328299 for attr in attrs {
329300 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 ( ) {
333302 break ;
334303 }
335-
336- if let Some ( level) = parse_unstability ( sess, attr) {
337- body_stab = Some ( ( DefaultBodyStability { level } , attr. span ) ) ;
338- }
339304 }
340305 }
341306
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 ( ( ) )
343345}
344346
345347fn insert_or_error ( sess : & Session , meta : & MetaItem , item : & mut Option < Symbol > ) -> Option < ( ) > {
0 commit comments