Skip to content

Commit 0a5abca

Browse files
Use early return when forbidding unstable attrs
1 parent 70f7879 commit 0a5abca

File tree

1 file changed

+129
-117
lines changed

1 file changed

+129
-117
lines changed

src/librustc_passes/stability.rs

Lines changed: 129 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -58,144 +58,156 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
5858
) where
5959
F: FnOnce(&mut Self),
6060
{
61-
if self.tcx.features().staged_api {
62-
// This crate explicitly wants staged API.
63-
debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs);
64-
if let Some(..) = attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp) {
65-
self.tcx.sess.span_err(
66-
item_sp,
67-
"`#[deprecated]` cannot be used in staged API; \
68-
use `#[rustc_deprecated]` instead",
69-
);
70-
}
71-
let (stab, const_stab) =
72-
attr::find_stability(&self.tcx.sess.parse_sess, attrs, item_sp);
73-
if let Some(const_stab) = const_stab {
74-
let const_stab = self.tcx.intern_const_stability(const_stab);
75-
self.index.const_stab_map.insert(hir_id, const_stab);
61+
if !self.tcx.features().staged_api {
62+
self.forbid_staged_api_attrs(hir_id, attrs, item_sp, kind, visit_children);
63+
return;
64+
}
65+
66+
// This crate explicitly wants staged API.
67+
debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs);
68+
if let Some(..) = attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp) {
69+
self.tcx.sess.span_err(
70+
item_sp,
71+
"`#[deprecated]` cannot be used in staged API; \
72+
use `#[rustc_deprecated]` instead",
73+
);
74+
}
75+
let (stab, const_stab) =
76+
attr::find_stability(&self.tcx.sess.parse_sess, attrs, item_sp);
77+
if let Some(const_stab) = const_stab {
78+
let const_stab = self.tcx.intern_const_stability(const_stab);
79+
self.index.const_stab_map.insert(hir_id, const_stab);
80+
}
81+
if let Some(mut stab) = stab {
82+
// Error if prohibited, or can't inherit anything from a container.
83+
if kind == AnnotationKind::Prohibited
84+
|| (kind == AnnotationKind::Container
85+
&& stab.level.is_stable()
86+
&& stab.rustc_depr.is_none())
87+
{
88+
self.tcx.sess.span_err(item_sp, "This stability annotation is useless");
7689
}
77-
if let Some(mut stab) = stab {
78-
// Error if prohibited, or can't inherit anything from a container.
79-
if kind == AnnotationKind::Prohibited
80-
|| (kind == AnnotationKind::Container
81-
&& stab.level.is_stable()
82-
&& stab.rustc_depr.is_none())
83-
{
84-
self.tcx.sess.span_err(item_sp, "This stability annotation is useless");
85-
}
8690

87-
debug!("annotate: found {:?}", stab);
88-
// If parent is deprecated and we're not, inherit this by merging
89-
// deprecated_since and its reason.
90-
if let Some(parent_stab) = self.parent_stab {
91-
if parent_stab.rustc_depr.is_some() && stab.rustc_depr.is_none() {
92-
stab.rustc_depr = parent_stab.rustc_depr
93-
}
91+
debug!("annotate: found {:?}", stab);
92+
// If parent is deprecated and we're not, inherit this by merging
93+
// deprecated_since and its reason.
94+
if let Some(parent_stab) = self.parent_stab {
95+
if parent_stab.rustc_depr.is_some() && stab.rustc_depr.is_none() {
96+
stab.rustc_depr = parent_stab.rustc_depr
9497
}
98+
}
9599

96-
let stab = self.tcx.intern_stability(stab);
97-
98-
// Check if deprecated_since < stable_since. If it is,
99-
// this is *almost surely* an accident.
100-
if let (
101-
&Some(attr::RustcDeprecation { since: dep_since, .. }),
102-
&attr::Stable { since: stab_since },
103-
) = (&stab.rustc_depr, &stab.level)
100+
let stab = self.tcx.intern_stability(stab);
101+
102+
// Check if deprecated_since < stable_since. If it is,
103+
// this is *almost surely* an accident.
104+
if let (
105+
&Some(attr::RustcDeprecation { since: dep_since, .. }),
106+
&attr::Stable { since: stab_since },
107+
) = (&stab.rustc_depr, &stab.level)
108+
{
109+
// Explicit version of iter::order::lt to handle parse errors properly
110+
for (dep_v, stab_v) in
111+
dep_since.as_str().split('.').zip(stab_since.as_str().split('.'))
104112
{
105-
// Explicit version of iter::order::lt to handle parse errors properly
106-
for (dep_v, stab_v) in
107-
dep_since.as_str().split('.').zip(stab_since.as_str().split('.'))
108-
{
109-
if let (Ok(dep_v), Ok(stab_v)) = (dep_v.parse::<u64>(), stab_v.parse()) {
110-
match dep_v.cmp(&stab_v) {
111-
Ordering::Less => {
112-
self.tcx.sess.span_err(
113-
item_sp,
114-
"An API can't be stabilized \
115-
after it is deprecated",
116-
);
117-
break;
118-
}
119-
Ordering::Equal => continue,
120-
Ordering::Greater => break,
113+
if let (Ok(dep_v), Ok(stab_v)) = (dep_v.parse::<u64>(), stab_v.parse()) {
114+
match dep_v.cmp(&stab_v) {
115+
Ordering::Less => {
116+
self.tcx.sess.span_err(
117+
item_sp,
118+
"An API can't be stabilized \
119+
after it is deprecated",
120+
);
121+
break;
121122
}
122-
} else {
123-
// Act like it isn't less because the question is now nonsensical,
124-
// and this makes us not do anything else interesting.
125-
self.tcx.sess.span_err(
126-
item_sp,
127-
"Invalid stability or deprecation \
128-
version found",
129-
);
130-
break;
123+
Ordering::Equal => continue,
124+
Ordering::Greater => break,
131125
}
126+
} else {
127+
// Act like it isn't less because the question is now nonsensical,
128+
// and this makes us not do anything else interesting.
129+
self.tcx.sess.span_err(
130+
item_sp,
131+
"Invalid stability or deprecation \
132+
version found",
133+
);
134+
break;
132135
}
133136
}
137+
}
134138

135-
self.index.stab_map.insert(hir_id, stab);
139+
self.index.stab_map.insert(hir_id, stab);
136140

137-
let orig_parent_stab = replace(&mut self.parent_stab, Some(stab));
138-
visit_children(self);
139-
self.parent_stab = orig_parent_stab;
140-
} else {
141-
debug!("annotate: not found, parent = {:?}", self.parent_stab);
142-
if let Some(stab) = self.parent_stab {
143-
if stab.level.is_unstable() {
144-
self.index.stab_map.insert(hir_id, stab);
145-
}
146-
}
147-
visit_children(self);
148-
}
141+
let orig_parent_stab = replace(&mut self.parent_stab, Some(stab));
142+
visit_children(self);
143+
self.parent_stab = orig_parent_stab;
149144
} else {
150-
// Emit errors for non-staged-api crates.
151-
let unstable_attrs = [
152-
sym::unstable,
153-
sym::stable,
154-
sym::rustc_deprecated,
155-
sym::rustc_const_unstable,
156-
sym::rustc_const_stable,
157-
];
158-
for attr in attrs {
159-
let name = attr.name_or_empty();
160-
if unstable_attrs.contains(&name) {
161-
attr::mark_used(attr);
162-
struct_span_err!(
163-
self.tcx.sess,
164-
attr.span,
165-
E0734,
166-
"stability attributes may not be used outside of the standard library",
167-
)
168-
.emit();
169-
}
170-
}
171-
172-
// Propagate unstability. This can happen even for non-staged-api crates in case
173-
// -Zforce-unstable-if-unmarked is set.
145+
debug!("annotate: not found, parent = {:?}", self.parent_stab);
174146
if let Some(stab) = self.parent_stab {
175147
if stab.level.is_unstable() {
176148
self.index.stab_map.insert(hir_id, stab);
177149
}
178150
}
151+
visit_children(self);
152+
}
153+
}
179154

180-
if let Some(depr) = attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp) {
181-
if kind == AnnotationKind::Prohibited {
182-
self.tcx.sess.span_err(item_sp, "This deprecation annotation is useless");
183-
}
155+
fn forbid_staged_api_attrs(
156+
&mut self,
157+
hir_id: HirId,
158+
attrs: &[Attribute],
159+
item_sp: Span,
160+
kind: AnnotationKind,
161+
visit_children: impl FnOnce(&mut Self),
162+
) {
163+
// Emit errors for non-staged-api crates.
164+
let unstable_attrs = [
165+
sym::unstable,
166+
sym::stable,
167+
sym::rustc_deprecated,
168+
sym::rustc_const_unstable,
169+
sym::rustc_const_stable,
170+
];
171+
for attr in attrs {
172+
let name = attr.name_or_empty();
173+
if unstable_attrs.contains(&name) {
174+
attr::mark_used(attr);
175+
struct_span_err!(
176+
self.tcx.sess,
177+
attr.span,
178+
E0734,
179+
"stability attributes may not be used outside of the standard library",
180+
)
181+
.emit();
182+
}
183+
}
184184

185-
// `Deprecation` is just two pointers, no need to intern it
186-
let depr_entry = DeprecationEntry::local(depr, hir_id);
187-
self.index.depr_map.insert(hir_id, depr_entry.clone());
188-
189-
let orig_parent_depr = replace(&mut self.parent_depr, Some(depr_entry));
190-
visit_children(self);
191-
self.parent_depr = orig_parent_depr;
192-
} else if let Some(parent_depr) = self.parent_depr.clone() {
193-
self.index.depr_map.insert(hir_id, parent_depr);
194-
visit_children(self);
195-
} else {
196-
visit_children(self);
185+
// Propagate unstability. This can happen even for non-staged-api crates in case
186+
// -Zforce-unstable-if-unmarked is set.
187+
if let Some(stab) = self.parent_stab {
188+
if stab.level.is_unstable() {
189+
self.index.stab_map.insert(hir_id, stab);
197190
}
198191
}
192+
193+
if let Some(depr) = attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp) {
194+
if kind == AnnotationKind::Prohibited {
195+
self.tcx.sess.span_err(item_sp, "This deprecation annotation is useless");
196+
}
197+
198+
// `Deprecation` is just two pointers, no need to intern it
199+
let depr_entry = DeprecationEntry::local(depr, hir_id);
200+
self.index.depr_map.insert(hir_id, depr_entry.clone());
201+
202+
let orig_parent_depr = replace(&mut self.parent_depr, Some(depr_entry));
203+
visit_children(self);
204+
self.parent_depr = orig_parent_depr;
205+
} else if let Some(parent_depr) = self.parent_depr.clone() {
206+
self.index.depr_map.insert(hir_id, parent_depr);
207+
visit_children(self);
208+
} else {
209+
visit_children(self);
210+
}
199211
}
200212
}
201213

0 commit comments

Comments
 (0)