Skip to content

Commit 87f62c3

Browse files
committed
Separate find_*_stability.
1 parent 61c35e6 commit 87f62c3

File tree

3 files changed

+101
-117
lines changed

3 files changed

+101
-117
lines changed

Diff for: compiler/rustc_attr/src/builtin.rs

+93-113
Original file line numberDiff line numberDiff line change
@@ -232,118 +232,89 @@ pub fn find_stability(
232232
sess: &Session,
233233
attrs: &[Attribute],
234234
item_sp: Span,
235-
) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>, Option<(DefaultBodyStability, Span)>)
236-
{
237-
find_stability_generic(sess, attrs.iter(), item_sp)
235+
) -> Option<(Stability, Span)> {
236+
let mut stab: Option<(Stability, Span)> = None;
237+
let mut allowed_through_unstable_modules = false;
238+
239+
for attr in attrs {
240+
match attr.name_or_empty() {
241+
sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true,
242+
sym::unstable => {
243+
if stab.is_some() {
244+
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
245+
break;
246+
}
247+
248+
if let Some((feature, level)) = parse_unstability(sess, attr) {
249+
stab = Some((Stability { level, feature }, attr.span));
250+
}
251+
}
252+
sym::stable => {
253+
if stab.is_some() {
254+
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
255+
break;
256+
}
257+
if let Some((feature, level)) = parse_stability(sess, attr) {
258+
stab = Some((Stability { level, feature }, attr.span));
259+
}
260+
}
261+
_ => {}
262+
}
263+
}
264+
265+
if allowed_through_unstable_modules {
266+
match &mut stab {
267+
Some((
268+
Stability {
269+
level: StabilityLevel::Stable { allowed_through_unstable_modules, .. },
270+
..
271+
},
272+
_,
273+
)) => *allowed_through_unstable_modules = true,
274+
_ => {
275+
sess.emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp });
276+
}
277+
}
278+
}
279+
280+
stab
238281
}
239282

240-
fn find_stability_generic<'a, I>(
283+
/// Collects stability info from all stability attributes in `attrs`.
284+
/// Returns `None` if no stability attributes are found.
285+
pub fn find_const_stability(
241286
sess: &Session,
242-
attrs_iter: I,
287+
attrs: &[Attribute],
243288
item_sp: Span,
244-
) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>, Option<(DefaultBodyStability, Span)>)
245-
where
246-
I: Iterator<Item = &'a Attribute>,
247-
{
248-
let mut stab: Option<(Stability, Span)> = None;
289+
) -> Option<(ConstStability, Span)> {
249290
let mut const_stab: Option<(ConstStability, Span)> = None;
250-
let mut body_stab: Option<(DefaultBodyStability, Span)> = None;
251291
let mut promotable = false;
252-
let mut allowed_through_unstable_modules = false;
253-
254-
for attr in attrs_iter {
255-
if ![
256-
sym::rustc_const_unstable,
257-
sym::rustc_const_stable,
258-
sym::unstable,
259-
sym::stable,
260-
sym::rustc_promotable,
261-
sym::rustc_allowed_through_unstable_modules,
262-
sym::rustc_default_body_unstable,
263-
]
264-
.iter()
265-
.any(|&s| attr.has_name(s))
266-
{
267-
continue; // not a stability level
268-
}
269292

270-
let meta = attr.meta();
271-
272-
if attr.has_name(sym::rustc_promotable) {
273-
promotable = true;
274-
} else if attr.has_name(sym::rustc_allowed_through_unstable_modules) {
275-
allowed_through_unstable_modules = true;
276-
} else if let Some(meta) = &meta {
277-
let meta_name = meta.name_or_empty();
278-
match meta_name {
279-
sym::rustc_const_unstable | sym::rustc_default_body_unstable | sym::unstable => {
280-
if meta_name == sym::unstable && stab.is_some() {
281-
handle_errors(
282-
&sess.parse_sess,
283-
attr.span,
284-
AttrError::MultipleStabilityLevels,
285-
);
286-
break;
287-
} else if meta_name == sym::rustc_const_unstable && const_stab.is_some() {
288-
handle_errors(
289-
&sess.parse_sess,
290-
attr.span,
291-
AttrError::MultipleStabilityLevels,
292-
);
293-
break;
294-
} else if meta_name == sym::rustc_default_body_unstable && body_stab.is_some() {
295-
handle_errors(
296-
&sess.parse_sess,
297-
attr.span,
298-
AttrError::MultipleStabilityLevels,
299-
);
300-
break;
301-
}
293+
for attr in attrs {
294+
match attr.name_or_empty() {
295+
sym::rustc_promotable => promotable = true,
296+
sym::rustc_const_unstable => {
297+
if const_stab.is_some() {
298+
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
299+
break;
300+
}
302301

303-
if let Some((feature, level)) = parse_unstability(sess, attr) {
304-
if sym::unstable == meta_name {
305-
stab = Some((Stability { level, feature }, attr.span));
306-
} else if sym::rustc_const_unstable == meta_name {
307-
const_stab = Some((
308-
ConstStability { level, feature, promotable: false },
309-
attr.span,
310-
));
311-
} else if sym::rustc_default_body_unstable == meta_name {
312-
body_stab = Some((DefaultBodyStability { level, feature }, attr.span));
313-
} else {
314-
unreachable!("Unknown stability attribute {meta_name}");
315-
}
316-
}
302+
if let Some((feature, level)) = parse_unstability(sess, attr) {
303+
const_stab =
304+
Some((ConstStability { level, feature, promotable: false }, attr.span));
317305
}
318-
sym::rustc_const_stable | sym::stable => {
319-
if meta_name == sym::stable && stab.is_some() {
320-
handle_errors(
321-
&sess.parse_sess,
322-
attr.span,
323-
AttrError::MultipleStabilityLevels,
324-
);
325-
break;
326-
} else if meta_name == sym::rustc_const_stable && const_stab.is_some() {
327-
handle_errors(
328-
&sess.parse_sess,
329-
attr.span,
330-
AttrError::MultipleStabilityLevels,
331-
);
332-
break;
333-
}
334-
if let Some((feature, level)) = parse_stability(sess, attr) {
335-
if sym::stable == meta_name {
336-
stab = Some((Stability { level, feature }, attr.span));
337-
} else {
338-
const_stab = Some((
339-
ConstStability { level, feature, promotable: false },
340-
attr.span,
341-
));
342-
}
343-
}
306+
}
307+
sym::rustc_const_stable => {
308+
if const_stab.is_some() {
309+
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
310+
break;
311+
}
312+
if let Some((feature, level)) = parse_stability(sess, attr) {
313+
const_stab =
314+
Some((ConstStability { level, feature, promotable: false }, attr.span));
344315
}
345-
_ => unreachable!(),
346316
}
317+
_ => {}
347318
}
348319
}
349320

@@ -355,22 +326,31 @@ where
355326
}
356327
}
357328

358-
if allowed_through_unstable_modules {
359-
match &mut stab {
360-
Some((
361-
Stability {
362-
level: StabilityLevel::Stable { allowed_through_unstable_modules, .. },
363-
..
364-
},
365-
_,
366-
)) => *allowed_through_unstable_modules = true,
367-
_ => {
368-
sess.emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp });
329+
const_stab
330+
}
331+
332+
/// Collects stability info from all stability attributes in `attrs`.
333+
/// Returns `None` if no stability attributes are found.
334+
pub fn find_body_stability(
335+
sess: &Session,
336+
attrs: &[Attribute],
337+
) -> Option<(DefaultBodyStability, Span)> {
338+
let mut body_stab: Option<(DefaultBodyStability, Span)> = None;
339+
340+
for attr in attrs {
341+
if attr.has_name(sym::rustc_default_body_unstable) {
342+
if body_stab.is_some() {
343+
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
344+
break;
345+
}
346+
347+
if let Some((feature, level)) = parse_unstability(sess, attr) {
348+
body_stab = Some((DefaultBodyStability { level, feature }, attr.span));
369349
}
370350
}
371351
}
372352

373-
(stab, const_stab, body_stab)
353+
body_stab
374354
}
375355

376356
fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, StabilityLevel)> {

Diff for: compiler/rustc_expand/src/base.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,9 @@ impl SyntaxExtension {
794794
)
795795
})
796796
.unwrap_or_else(|| (None, helper_attrs));
797-
let (stability, const_stability, body_stability) = attr::find_stability(&sess, attrs, span);
797+
let stability = attr::find_stability(&sess, attrs, span);
798+
let const_stability = attr::find_const_stability(&sess, attrs, span);
799+
let body_stability = attr::find_body_stability(&sess, attrs);
798800
if let Some((_, sp)) = const_stability {
799801
sess.emit_err(MacroConstStability {
800802
span: sp,

Diff for: compiler/rustc_passes/src/stability.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
206206

207207
let attrs = self.tcx.hir().attrs(self.tcx.hir().local_def_id_to_hir_id(def_id));
208208
debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs);
209-
let (stab, const_stab, body_stab) = attr::find_stability(&self.tcx.sess, attrs, item_sp);
209+
let stab = attr::find_stability(&self.tcx.sess, attrs, item_sp);
210+
let const_stab = attr::find_const_stability(&self.tcx.sess, attrs, item_sp);
211+
let body_stab = attr::find_body_stability(&self.tcx.sess, attrs);
210212
let mut const_span = None;
211213

212214
let const_stab = const_stab.map(|(const_stab, const_span_node)| {
@@ -769,8 +771,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
769771
let features = self.tcx.features();
770772
if features.staged_api {
771773
let attrs = self.tcx.hir().attrs(item.hir_id());
772-
let (stab, const_stab, _) =
773-
attr::find_stability(&self.tcx.sess, attrs, item.span);
774+
let stab = attr::find_stability(&self.tcx.sess, attrs, item.span);
775+
let const_stab = attr::find_const_stability(&self.tcx.sess, attrs, item.span);
774776

775777
// If this impl block has an #[unstable] attribute, give an
776778
// error if all involved types and traits are stable, because

0 commit comments

Comments
 (0)