@@ -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
347348fn insert_or_error ( sess : & Session , meta : & MetaItem , item : & mut Option < Symbol > ) -> Option < ( ) > {
0 commit comments