Skip to content

Commit 7cf3536

Browse files
committed
Querify lookup_deprecation_entry.
1 parent 11d96b5 commit 7cf3536

File tree

4 files changed

+86
-66
lines changed

4 files changed

+86
-66
lines changed

compiler/rustc_attr/src/builtin.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -797,11 +797,7 @@ pub struct Deprecation {
797797
}
798798

799799
/// Finds the deprecation attribute. `None` if none exists.
800-
pub fn find_deprecation(sess: &Session, attrs: &[Attribute]) -> Option<(Deprecation, Span)> {
801-
find_deprecation_generic(sess, attrs.iter())
802-
}
803-
804-
fn find_deprecation_generic<'a, I>(sess: &Session, attrs_iter: I) -> Option<(Deprecation, Span)>
800+
pub fn find_deprecation<'a, I>(sess: &Session, attrs_iter: I) -> Option<(Deprecation, Span)>
805801
where
806802
I: Iterator<Item = &'a Attribute>,
807803
{

compiler/rustc_expand/src/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ impl SyntaxExtension {
814814
allow_internal_unstable: (!allow_internal_unstable.is_empty())
815815
.then(|| allow_internal_unstable.into()),
816816
stability: stability.map(|(s, _)| s),
817-
deprecation: attr::find_deprecation(&sess, attrs).map(|(d, _)| d),
817+
deprecation: attr::find_deprecation(&sess, attrs.iter()).map(|(d, _)| d),
818818
helper_attrs,
819819
edition,
820820
builtin_name,

compiler/rustc_middle/src/middle/stability.rs

-5
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ pub struct Index {
6262
pub stab_map: FxHashMap<LocalDefId, Stability>,
6363
pub const_stab_map: FxHashMap<LocalDefId, ConstStability>,
6464
pub default_body_stab_map: FxHashMap<LocalDefId, DefaultBodyStability>,
65-
pub depr_map: FxHashMap<LocalDefId, DeprecationEntry>,
6665
/// Mapping from feature name to feature name based on the `implied_by` field of `#[unstable]`
6766
/// attributes. If a `#[unstable(feature = "implier", implied_by = "impliee")]` attribute
6867
/// exists, then this map will have a `impliee -> implier` entry.
@@ -90,10 +89,6 @@ impl Index {
9089
pub fn local_default_body_stability(&self, def_id: LocalDefId) -> Option<DefaultBodyStability> {
9190
self.default_body_stab_map.get(&def_id).copied()
9291
}
93-
94-
pub fn local_deprecation_entry(&self, def_id: LocalDefId) -> Option<DeprecationEntry> {
95-
self.depr_map.get(&def_id).cloned()
96-
}
9792
}
9893

9994
pub fn report_unstable(

compiler/rustc_passes/src/stability.rs

+84-55
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
1515
use rustc_errors::Applicability;
1616
use rustc_hir as hir;
1717
use rustc_hir::def::{DefKind, Res};
18-
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
18+
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
1919
use rustc_hir::hir_id::CRATE_HIR_ID;
2020
use rustc_hir::intravisit::{self, Visitor};
2121
use rustc_hir::{FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant};
2222
use rustc_middle::hir::nested_filter;
2323
use rustc_middle::middle::privacy::EffectiveVisibilities;
2424
use rustc_middle::middle::stability::{AllowUnstable, DeprecationEntry, Index};
25-
use rustc_middle::ty::{query::Providers, TyCtxt};
25+
use rustc_middle::ty::{query::Providers, DefIdTree, TyCtxt};
2626
use rustc_session::lint;
2727
use rustc_session::lint::builtin::{INEFFECTIVE_UNSTABLE_TRAIT_IMPL, USELESS_DEPRECATED};
2828
use rustc_span::symbol::{sym, Symbol};
@@ -90,13 +90,84 @@ impl InheritStability {
9090
}
9191
}
9292

93+
fn inherit_deprecation(def_kind: DefKind) -> InheritDeprecation {
94+
match def_kind {
95+
DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => InheritDeprecation::No,
96+
_ => InheritDeprecation::Yes,
97+
}
98+
}
99+
100+
fn annotation_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> AnnotationKind {
101+
match tcx.hir().get_by_def_id(def_id) {
102+
hir::Node::Item(i) => match i.kind {
103+
// Inherent impls and foreign modules serve only as containers for other items,
104+
// they don't have their own stability. They still can be annotated as unstable
105+
// and propagate this unstability to children, but this annotation is completely
106+
// optional. They inherit stability from their parents when unannotated.
107+
hir::ItemKind::Impl(hir::Impl { of_trait: None, .. })
108+
| hir::ItemKind::ForeignMod { .. } => AnnotationKind::Container,
109+
hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => {
110+
AnnotationKind::DeprecationProhibited
111+
}
112+
_ => AnnotationKind::Required,
113+
},
114+
hir::Node::ImplItem(ii) => {
115+
let item = tcx.hir().expect_item(tcx.hir().get_parent_item(ii.hir_id()).def_id);
116+
match item.kind {
117+
hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => {
118+
AnnotationKind::Prohibited
119+
}
120+
_ => AnnotationKind::Required,
121+
}
122+
}
123+
hir::Node::GenericParam(p) => match &p.kind {
124+
// Allow stability attributes on default generic arguments.
125+
hir::GenericParamKind::Type { default: Some(_), .. }
126+
| hir::GenericParamKind::Const { default: Some(_), .. } => AnnotationKind::Container,
127+
_ => AnnotationKind::Prohibited,
128+
},
129+
130+
_ => AnnotationKind::Required,
131+
}
132+
}
133+
134+
fn lookup_deprecation_entry(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DeprecationEntry> {
135+
let def_id = def_id.expect_local();
136+
let attrs = tcx.get_attrs(def_id.to_def_id(), sym::deprecated);
137+
138+
let depr = attr::find_deprecation(&tcx.sess, attrs);
139+
let Some((depr, span)) = &depr else {
140+
if inherit_deprecation(tcx.def_kind(def_id)).yes() {
141+
let parent_id = tcx.opt_local_parent(def_id)?;
142+
let parent_depr = tcx.lookup_deprecation_entry(parent_id)?;
143+
info!("tagging child {:?} as deprecated from parent", def_id);
144+
return Some(parent_depr);
145+
}
146+
147+
return None;
148+
};
149+
150+
let kind = annotation_kind(tcx, def_id);
151+
if matches!(kind, AnnotationKind::Prohibited | AnnotationKind::DeprecationProhibited) {
152+
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
153+
tcx.emit_spanned_lint(
154+
USELESS_DEPRECATED,
155+
hir_id,
156+
*span,
157+
errors::DeprecatedAnnotationHasNoEffect { span: *span },
158+
);
159+
}
160+
161+
// `Deprecation` is just two pointers, no need to intern it
162+
Some(DeprecationEntry::local(*depr, def_id))
163+
}
164+
93165
/// A private tree-walker for producing an `Index`.
94166
struct Annotator<'a, 'tcx> {
95167
tcx: TyCtxt<'tcx>,
96168
index: &'a mut Index,
97169
parent_stab: Option<Stability>,
98170
parent_const_stab: Option<ConstStability>,
99-
parent_depr: Option<DeprecationEntry>,
100171
in_trait_impl: bool,
101172
}
102173

@@ -117,34 +188,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
117188
) where
118189
F: FnOnce(&mut Self),
119190
{
120-
let attrs = self.tcx.hir().attrs(self.tcx.hir().local_def_id_to_hir_id(def_id));
121-
debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs);
122-
123-
let depr = attr::find_deprecation(&self.tcx.sess, attrs);
124-
let mut is_deprecated = false;
125-
if let Some((depr, span)) = &depr {
126-
is_deprecated = true;
127-
128-
if matches!(kind, AnnotationKind::Prohibited | AnnotationKind::DeprecationProhibited) {
129-
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
130-
self.tcx.emit_spanned_lint(
131-
USELESS_DEPRECATED,
132-
hir_id,
133-
*span,
134-
errors::DeprecatedAnnotationHasNoEffect { span: *span },
135-
);
136-
}
137-
138-
// `Deprecation` is just two pointers, no need to intern it
139-
let depr_entry = DeprecationEntry::local(*depr, def_id);
140-
self.index.depr_map.insert(def_id, depr_entry);
141-
} else if let Some(parent_depr) = self.parent_depr {
142-
if inherit_deprecation.yes() {
143-
is_deprecated = true;
144-
info!("tagging child {:?} as deprecated from parent", def_id);
145-
self.index.depr_map.insert(def_id, parent_depr);
146-
}
147-
}
191+
let depr = self.tcx.lookup_deprecation_entry(def_id);
192+
let is_deprecated = depr.is_some();
148193

149194
if !self.tcx.features().staged_api {
150195
// Propagate unstability. This can happen even for non-staged-api crates in case
@@ -155,15 +200,12 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
155200
}
156201
}
157202

158-
self.recurse_with_stability_attrs(
159-
depr.map(|(d, _)| DeprecationEntry::local(d, def_id)),
160-
None,
161-
None,
162-
visit_children,
163-
);
203+
self.recurse_with_stability_attrs(None, None, visit_children);
164204
return;
165205
}
166206

207+
let attrs = self.tcx.hir().attrs(self.tcx.hir().local_def_id_to_hir_id(def_id));
208+
debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs);
167209
let (stab, const_stab, body_stab) = attr::find_stability(&self.tcx.sess, attrs, item_sp);
168210
let mut const_span = None;
169211

@@ -201,9 +243,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
201243
}
202244
}
203245

204-
if let Some((rustc_attr::Deprecation { is_since_rustc_version: true, .. }, span)) = &depr {
205-
if stab.is_none() {
206-
self.tcx.sess.emit_err(DeprecatedAttribute { span: *span });
246+
if stab.is_none() && depr.map_or(false, |d| d.attr.is_since_rustc_version) {
247+
if let Some(attr) = attrs.iter().find(|attr| attr.has_name(sym::deprecated)) {
248+
self.tcx.sess.emit_err(DeprecatedAttribute { span: attr.span });
207249
}
208250
}
209251

@@ -227,7 +269,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
227269
// Check if deprecated_since < stable_since. If it is,
228270
// this is *almost surely* an accident.
229271
if let (&Some(dep_since), &attr::Stable { since: stab_since, .. }) =
230-
(&depr.as_ref().and_then(|(d, _)| d.since), &stab.level)
272+
(&depr.as_ref().and_then(|d| d.attr.since), &stab.level)
231273
{
232274
// Explicit version of iter::order::lt to handle parse errors properly
233275
for (dep_v, stab_v) in
@@ -282,7 +324,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
282324
}
283325

284326
self.recurse_with_stability_attrs(
285-
depr.map(|(d, _)| DeprecationEntry::local(d, def_id)),
286327
stab,
287328
if inherit_const_stability.yes() { const_stab } else { None },
288329
visit_children,
@@ -291,19 +332,14 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
291332

292333
fn recurse_with_stability_attrs(
293334
&mut self,
294-
depr: Option<DeprecationEntry>,
295335
stab: Option<Stability>,
296336
const_stab: Option<ConstStability>,
297337
f: impl FnOnce(&mut Self),
298338
) {
299339
// These will be `Some` if this item changes the corresponding stability attribute.
300-
let mut replaced_parent_depr = None;
301340
let mut replaced_parent_stab = None;
302341
let mut replaced_parent_const_stab = None;
303342

304-
if let Some(depr) = depr {
305-
replaced_parent_depr = Some(replace(&mut self.parent_depr, Some(depr)));
306-
}
307343
if let Some(stab) = stab {
308344
replaced_parent_stab = Some(replace(&mut self.parent_stab, Some(stab)));
309345
}
@@ -314,9 +350,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
314350

315351
f(self);
316352

317-
if let Some(orig_parent_depr) = replaced_parent_depr {
318-
self.parent_depr = orig_parent_depr;
319-
}
320353
if let Some(orig_parent_stab) = replaced_parent_stab {
321354
self.parent_stab = orig_parent_stab;
322355
}
@@ -627,7 +660,6 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
627660
stab_map: Default::default(),
628661
const_stab_map: Default::default(),
629662
default_body_stab_map: Default::default(),
630-
depr_map: Default::default(),
631663
implications: Default::default(),
632664
};
633665

@@ -637,7 +669,6 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
637669
index: &mut index,
638670
parent_stab: None,
639671
parent_const_stab: None,
640-
parent_depr: None,
641672
in_trait_impl: false,
642673
};
643674

@@ -690,9 +721,7 @@ pub(crate) fn provide(providers: &mut Providers) {
690721
lookup_default_body_stability: |tcx, id| {
691722
tcx.stability().local_default_body_stability(id.expect_local())
692723
},
693-
lookup_deprecation_entry: |tcx, id| {
694-
tcx.stability().local_deprecation_entry(id.expect_local())
695-
},
724+
lookup_deprecation_entry,
696725
..*providers
697726
};
698727
}

0 commit comments

Comments
 (0)