mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-27 23:22:58 +00:00
Separate find_*_stability.
This commit is contained in:
parent
17f1db672e
commit
5f9c004d35
@ -232,126 +232,33 @@ pub fn find_stability(
|
||||
sess: &Session,
|
||||
attrs: &[Attribute],
|
||||
item_sp: Span,
|
||||
) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>, Option<(DefaultBodyStability, Span)>)
|
||||
{
|
||||
find_stability_generic(sess, attrs.iter(), item_sp)
|
||||
}
|
||||
|
||||
fn find_stability_generic<'a, I>(
|
||||
sess: &Session,
|
||||
attrs_iter: I,
|
||||
item_sp: Span,
|
||||
) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>, Option<(DefaultBodyStability, Span)>)
|
||||
where
|
||||
I: Iterator<Item = &'a Attribute>,
|
||||
{
|
||||
) -> Option<(Stability, Span)> {
|
||||
let mut stab: Option<(Stability, Span)> = None;
|
||||
let mut const_stab: Option<(ConstStability, Span)> = None;
|
||||
let mut body_stab: Option<(DefaultBodyStability, Span)> = None;
|
||||
let mut promotable = false;
|
||||
let mut allowed_through_unstable_modules = false;
|
||||
|
||||
for attr in attrs_iter {
|
||||
if ![
|
||||
sym::rustc_const_unstable,
|
||||
sym::rustc_const_stable,
|
||||
sym::unstable,
|
||||
sym::stable,
|
||||
sym::rustc_promotable,
|
||||
sym::rustc_allowed_through_unstable_modules,
|
||||
sym::rustc_default_body_unstable,
|
||||
]
|
||||
.iter()
|
||||
.any(|&s| attr.has_name(s))
|
||||
{
|
||||
continue; // not a stability level
|
||||
}
|
||||
|
||||
let meta = attr.meta();
|
||||
|
||||
if attr.has_name(sym::rustc_promotable) {
|
||||
promotable = true;
|
||||
} else if attr.has_name(sym::rustc_allowed_through_unstable_modules) {
|
||||
allowed_through_unstable_modules = true;
|
||||
} else if let Some(meta) = &meta {
|
||||
let meta_name = meta.name_or_empty();
|
||||
match meta_name {
|
||||
sym::rustc_const_unstable | sym::rustc_default_body_unstable | sym::unstable => {
|
||||
if meta_name == sym::unstable && stab.is_some() {
|
||||
handle_errors(
|
||||
&sess.parse_sess,
|
||||
attr.span,
|
||||
AttrError::MultipleStabilityLevels,
|
||||
);
|
||||
break;
|
||||
} else if meta_name == sym::rustc_const_unstable && const_stab.is_some() {
|
||||
handle_errors(
|
||||
&sess.parse_sess,
|
||||
attr.span,
|
||||
AttrError::MultipleStabilityLevels,
|
||||
);
|
||||
break;
|
||||
} else if meta_name == sym::rustc_default_body_unstable && body_stab.is_some() {
|
||||
handle_errors(
|
||||
&sess.parse_sess,
|
||||
attr.span,
|
||||
AttrError::MultipleStabilityLevels,
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
if let Some((feature, level)) = parse_unstability(sess, attr) {
|
||||
if sym::unstable == meta_name {
|
||||
stab = Some((Stability { level, feature }, attr.span));
|
||||
} else if sym::rustc_const_unstable == meta_name {
|
||||
const_stab = Some((
|
||||
ConstStability { level, feature, promotable: false },
|
||||
attr.span,
|
||||
));
|
||||
} else if sym::rustc_default_body_unstable == meta_name {
|
||||
body_stab = Some((DefaultBodyStability { level, feature }, attr.span));
|
||||
} else {
|
||||
unreachable!("Unknown stability attribute {meta_name}");
|
||||
}
|
||||
}
|
||||
for attr in attrs {
|
||||
match attr.name_or_empty() {
|
||||
sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true,
|
||||
sym::unstable => {
|
||||
if stab.is_some() {
|
||||
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
|
||||
break;
|
||||
}
|
||||
sym::rustc_const_stable | sym::stable => {
|
||||
if meta_name == sym::stable && stab.is_some() {
|
||||
handle_errors(
|
||||
&sess.parse_sess,
|
||||
attr.span,
|
||||
AttrError::MultipleStabilityLevels,
|
||||
);
|
||||
break;
|
||||
} else if meta_name == sym::rustc_const_stable && const_stab.is_some() {
|
||||
handle_errors(
|
||||
&sess.parse_sess,
|
||||
attr.span,
|
||||
AttrError::MultipleStabilityLevels,
|
||||
);
|
||||
break;
|
||||
}
|
||||
if let Some((feature, level)) = parse_stability(sess, attr) {
|
||||
if sym::stable == meta_name {
|
||||
stab = Some((Stability { level, feature }, attr.span));
|
||||
} else {
|
||||
const_stab = Some((
|
||||
ConstStability { level, feature, promotable: false },
|
||||
attr.span,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((feature, level)) = parse_unstability(sess, attr) {
|
||||
stab = Some((Stability { level, feature }, attr.span));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Merge the const-unstable info into the stability info
|
||||
if promotable {
|
||||
match &mut const_stab {
|
||||
Some((stab, _)) => stab.promotable = promotable,
|
||||
_ => _ = sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp }),
|
||||
sym::stable => {
|
||||
if stab.is_some() {
|
||||
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
|
||||
break;
|
||||
}
|
||||
if let Some((feature, level)) = parse_stability(sess, attr) {
|
||||
stab = Some((Stability { level, feature }, attr.span));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,7 +277,80 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
(stab, const_stab, body_stab)
|
||||
stab
|
||||
}
|
||||
|
||||
/// Collects stability info from all stability attributes in `attrs`.
|
||||
/// Returns `None` if no stability attributes are found.
|
||||
pub fn find_const_stability(
|
||||
sess: &Session,
|
||||
attrs: &[Attribute],
|
||||
item_sp: Span,
|
||||
) -> Option<(ConstStability, Span)> {
|
||||
let mut const_stab: Option<(ConstStability, Span)> = None;
|
||||
let mut promotable = false;
|
||||
|
||||
for attr in attrs {
|
||||
match attr.name_or_empty() {
|
||||
sym::rustc_promotable => promotable = true,
|
||||
sym::rustc_const_unstable => {
|
||||
if const_stab.is_some() {
|
||||
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
|
||||
break;
|
||||
}
|
||||
|
||||
if let Some((feature, level)) = parse_unstability(sess, attr) {
|
||||
const_stab =
|
||||
Some((ConstStability { level, feature, promotable: false }, attr.span));
|
||||
}
|
||||
}
|
||||
sym::rustc_const_stable => {
|
||||
if const_stab.is_some() {
|
||||
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
|
||||
break;
|
||||
}
|
||||
if let Some((feature, level)) = parse_stability(sess, attr) {
|
||||
const_stab =
|
||||
Some((ConstStability { level, feature, promotable: false }, attr.span));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Merge the const-unstable info into the stability info
|
||||
if promotable {
|
||||
match &mut const_stab {
|
||||
Some((stab, _)) => stab.promotable = promotable,
|
||||
_ => _ = sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp }),
|
||||
}
|
||||
}
|
||||
|
||||
const_stab
|
||||
}
|
||||
|
||||
/// Collects stability info from all stability attributes in `attrs`.
|
||||
/// Returns `None` if no stability attributes are found.
|
||||
pub fn find_body_stability(
|
||||
sess: &Session,
|
||||
attrs: &[Attribute],
|
||||
) -> Option<(DefaultBodyStability, Span)> {
|
||||
let mut body_stab: Option<(DefaultBodyStability, Span)> = None;
|
||||
|
||||
for attr in attrs {
|
||||
if attr.has_name(sym::rustc_default_body_unstable) {
|
||||
if body_stab.is_some() {
|
||||
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels);
|
||||
break;
|
||||
}
|
||||
|
||||
if let Some((feature, level)) = parse_unstability(sess, attr) {
|
||||
body_stab = Some((DefaultBodyStability { level, feature }, attr.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body_stab
|
||||
}
|
||||
|
||||
fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, StabilityLevel)> {
|
||||
|
@ -793,7 +793,9 @@ impl SyntaxExtension {
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| (None, helper_attrs));
|
||||
let (stability, const_stability, body_stability) = attr::find_stability(&sess, attrs, span);
|
||||
let stability = attr::find_stability(&sess, attrs, span);
|
||||
let const_stability = attr::find_const_stability(&sess, attrs, span);
|
||||
let body_stability = attr::find_body_stability(&sess, attrs);
|
||||
if let Some((_, sp)) = const_stability {
|
||||
sess.emit_err(errors::MacroConstStability {
|
||||
span: sp,
|
||||
|
@ -159,7 +159,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
let (stab, const_stab, body_stab) = attr::find_stability(&self.tcx.sess, attrs, item_sp);
|
||||
let stab = attr::find_stability(&self.tcx.sess, attrs, item_sp);
|
||||
let const_stab = attr::find_const_stability(&self.tcx.sess, attrs, item_sp);
|
||||
let body_stab = attr::find_body_stability(&self.tcx.sess, attrs);
|
||||
let mut const_span = None;
|
||||
|
||||
let const_stab = const_stab.map(|(const_stab, const_span_node)| {
|
||||
@ -742,8 +744,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
||||
let features = self.tcx.features();
|
||||
if features.staged_api {
|
||||
let attrs = self.tcx.hir().attrs(item.hir_id());
|
||||
let (stab, const_stab, _) =
|
||||
attr::find_stability(&self.tcx.sess, attrs, item.span);
|
||||
let stab = attr::find_stability(&self.tcx.sess, attrs, item.span);
|
||||
let const_stab = attr::find_const_stability(&self.tcx.sess, attrs, item.span);
|
||||
|
||||
// If this impl block has an #[unstable] attribute, give an
|
||||
// error if all involved types and traits are stable, because
|
||||
|
Loading…
Reference in New Issue
Block a user